Skip to content

Commit 470477a

Browse files
wanda-phiwhitequark
authored andcommitted
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.
1 parent c7da6c1 commit 470477a

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

amaranth/lib/wiring.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ def signature(self):
786786
cls = type(self)
787787
signature = Signature({})
788788
for base in cls.mro()[:cls.mro().index(Component)]:
789-
for name, annot in getattr(base, "__annotations__", {}).items():
789+
for name, annot in base.__dict__.get("__annotations__", {}).items():
790790
if name.startswith("_"):
791791
continue
792792
if (annot is Value or annot is Signal or annot is Const or

tests/test_lib_wiring.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,3 +887,16 @@ class PageBuffer(Component):
887887
r"'rand: In\(Signature\({}\)\.flip\(\)\)' or "
888888
r"'rand: Out\(Signature\({}\)\.flip\(\)\)'\?$"):
889889
PageBuffer()
890+
891+
def test_inherit(self):
892+
class A(Component):
893+
clk: In(1)
894+
895+
class B(A):
896+
rst: In(1)
897+
898+
class C(B):
899+
pass
900+
901+
c = C()
902+
self.assertEqual(c.signature, Signature({"clk": In(1), "rst": In(1)}))

0 commit comments

Comments
 (0)