Fixes #132.
self._append(" parameter \\{} {}'{:b}\n",
param, len(value), value.value)
else:
- assert False
+ assert False, "Bad parameter {!r}".format(value)
for port, wire in ports.items():
self._append(" connect {} {}\n", port, wire)
self._append(" end\n")
class Attrs(OrderedDict):
def __init__(self, **attrs):
- for attr_key, attr_value in attrs.items():
- if not (attr_value is None or isinstance(attr_value, str)):
- raise TypeError("Attribute value must be None or str, not {!r}"
- .format(attr_value))
+ for key, value in attrs.items():
+ if not (value is None or isinstance(value, str) or hasattr(value, "__call__")):
+ raise TypeError("Value of attribute {} must be None, str, or callable, not {!r}"
+ .format(key, value))
super().__init__(**attrs)
for key, value in self.items():
if value is None:
items.append("!" + key)
+ elif hasattr(value, "__call__"):
+ items.append(key + "=" + repr(value))
else:
items.append(key + "=" + value)
return "(attrs {})".format(" ".join(items))
return dir, xdr
def resolve(resource, dir, xdr, name, attrs):
+ for attr_key, attr_value in attrs.items():
+ if hasattr(attr_value, "__call__"):
+ attr_value = attr_value(self)
+ assert attr_value is None or isinstance(attr_value, str)
+ if attr_value is None:
+ del attrs[attr_key]
+ else:
+ attrs[attr_key] = attr_value
+
if isinstance(resource.ios[0], Subsignal):
fields = OrderedDict()
for sub in resource.ios:
- sub_attrs = {k: v for k, v in {**attrs, **sub.attrs}.items() if v is not None}
fields[sub.name] = resolve(sub, dir[sub.name], xdr[sub.name],
name="{}__{}".format(name, sub.name),
- attrs=sub_attrs)
+ attrs={**attrs, **sub.attrs})
return Record([
(f_name, f.layout) for (f_name, f) in fields.items()
], fields=fields, name=name)
self.assertEqual(a["FOO"], None)
self.assertEqual(repr(a), "(attrs !FOO)")
+ def test_callable(self):
+ fn = lambda self: "FOO"
+ a = Attrs(FOO=fn)
+ self.assertEqual(a["FOO"], fn)
+ self.assertEqual(repr(a), "(attrs FOO={!r})".format(fn))
+
def test_wrong_value(self):
with self.assertRaises(TypeError,
- msg="Attribute value must be None or str, not 1"):
+ msg="Value of attribute FOO must be None, str, or callable, not 1"):
a = Attrs(FOO=1)