From 470477a88f02dfc4af7452ad05c4c067f72cd0bd Mon Sep 17 00:00:00 2001 From: Wanda Date: Sun, 8 Oct 2023 16:20:18 +0200 Subject: [PATCH] lib.wiring: fix `Component.signature` on subclasses without annotations. On Python <3.10, classes without annotations do not get an `__annotations__` member at all, so the `getattr` on a subclass falls back to the parent class `__annotations__`, attempting to create signature members twice. Fix that by looking at the `__dict__` instead. --- amaranth/lib/wiring.py | 2 +- tests/test_lib_wiring.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/amaranth/lib/wiring.py b/amaranth/lib/wiring.py index dac6009..0e99203 100644 --- a/amaranth/lib/wiring.py +++ b/amaranth/lib/wiring.py @@ -786,7 +786,7 @@ class Component(Elaboratable): cls = type(self) signature = Signature({}) for base in cls.mro()[:cls.mro().index(Component)]: - for name, annot in getattr(base, "__annotations__", {}).items(): + for name, annot in base.__dict__.get("__annotations__", {}).items(): if name.startswith("_"): continue if (annot is Value or annot is Signal or annot is Const or diff --git a/tests/test_lib_wiring.py b/tests/test_lib_wiring.py index aa23ced..560f479 100644 --- a/tests/test_lib_wiring.py +++ b/tests/test_lib_wiring.py @@ -887,3 +887,16 @@ class ComponentTestCase(unittest.TestCase): r"'rand: In\(Signature\({}\)\.flip\(\)\)' or " r"'rand: Out\(Signature\({}\)\.flip\(\)\)'\?$"): PageBuffer() + + def test_inherit(self): + class A(Component): + clk: In(1) + + class B(A): + rst: In(1) + + class C(B): + pass + + c = C() + self.assertEqual(c.signature, Signature({"clk": In(1), "rst": In(1)}))