From 44d5fac01cf6e2ce3ccbbbe24e81f5ea55e48c7e Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 31 Aug 2023 18:59:12 +0000 Subject: [PATCH] lib.wiring: fix equality of `FlippedSignature` with other object. Fixes #882. --- amaranth/lib/wiring.py | 8 +++++--- tests/test_lib_wiring.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/amaranth/lib/wiring.py b/amaranth/lib/wiring.py index 182bb06..67e480f 100644 --- a/amaranth/lib/wiring.py +++ b/amaranth/lib/wiring.py @@ -484,9 +484,11 @@ class FlippedSignature: return self.flip() == other.flip() else: # Delegate comparisons back to Signature (or its descendant) by flipping the arguments; - # equality must be reflexive but the implementation of __eq__ need not be, and we can - # take advantage of it here. - return other == self + # equality must be reflexive but the implementation of `__eq__` need not be, and we can + # take advantage of it here. This is done by returning `NotImplemented`, otherwise if + # the other object cannot be compared to a `FlippedSignature` either this will result + # in infinite recursion. + return NotImplemented # These methods do not access instance variables and so their implementation can be shared # between the normal and the flipped member collections. diff --git a/tests/test_lib_wiring.py b/tests/test_lib_wiring.py index b1bf74e..06e9bab 100644 --- a/tests/test_lib_wiring.py +++ b/tests/test_lib_wiring.py @@ -832,3 +832,15 @@ class ComponentTestCase(unittest.TestCase): r"a signature member; did you mean 'val2: In\(MockValueCastable\)' or " r"'val2: Out\(MockValueCastable\)'\?$"): C3().signature + + def test_bug_882(self): + class PageBuffer(Component): + rand: Signature({}).flip() + other: Out(1) + + with self.assertWarnsRegex(SyntaxWarning, + r"^Component '.+\.PageBuffer' has an annotation 'rand: Signature\({}\)\.flip\(\)', " + r"which is not a signature member; did you mean " + r"'rand: In\(Signature\({}\)\.flip\(\)\)' or " + r"'rand: Out\(Signature\({}\)\.flip\(\)\)'\?$"): + PageBuffer()