Skip to content

Commit 6e7b813

Browse files
aha79andreas-h-sieAlexWaygoodFidget-Spinner
authored
bpo-46333: Honor module parameter in ForwardRef (pythonGH-30536)
The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have the same name. This affects the `__eq__`, `__repr__` and `__hash__` methods. Co-authored-by: Andreas Hangauer <[email protected]> Co-authored-by: Alex Waygood <[email protected]> Co-authored-by: Ken Jin <[email protected]>
1 parent de6043e commit 6e7b813

File tree

4 files changed

+20
-2
lines changed

4 files changed

+20
-2
lines changed

Lib/test/test_typing.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,6 +2800,10 @@ def test_forward_equality(self):
28002800
fr = typing.ForwardRef('int')
28012801
self.assertEqual(fr, typing.ForwardRef('int'))
28022802
self.assertNotEqual(List['int'], List[int])
2803+
self.assertNotEqual(fr, typing.ForwardRef('int', module=__name__))
2804+
frm = typing.ForwardRef('int', module=__name__)
2805+
self.assertEqual(frm, typing.ForwardRef('int', module=__name__))
2806+
self.assertNotEqual(frm, typing.ForwardRef('int', module='__other_name__'))
28032807

28042808
def test_forward_equality_gth(self):
28052809
c1 = typing.ForwardRef('C')
@@ -2836,6 +2840,14 @@ def foo(a: c1_gth, b: c2_gth):
28362840
self.assertEqual(hash(c1_gth), hash(c2_gth))
28372841
self.assertEqual(hash(c1), hash(c1_gth))
28382842

2843+
c3 = typing.ForwardRef('int', module=__name__)
2844+
c4 = typing.ForwardRef('int', module='__other_name__')
2845+
2846+
self.assertNotEqual(hash(c3), hash(c1))
2847+
self.assertNotEqual(hash(c3), hash(c1_gth))
2848+
self.assertNotEqual(hash(c3), hash(c4))
2849+
self.assertEqual(hash(c3), hash(typing.ForwardRef('int', module=__name__)))
2850+
28392851
def test_forward_equality_namespace(self):
28402852
class A:
28412853
pass

Lib/typing.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -767,10 +767,11 @@ def __eq__(self, other):
767767
if self.__forward_evaluated__ and other.__forward_evaluated__:
768768
return (self.__forward_arg__ == other.__forward_arg__ and
769769
self.__forward_value__ == other.__forward_value__)
770-
return self.__forward_arg__ == other.__forward_arg__
770+
return (self.__forward_arg__ == other.__forward_arg__ and
771+
self.__forward_module__ == other.__forward_module__)
771772

772773
def __hash__(self):
773-
return hash(self.__forward_arg__)
774+
return hash((self.__forward_arg__, self.__forward_module__))
774775

775776
def __or__(self, other):
776777
return Union[self, other]

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ Anders Hammarquist
680680
Mark Hammond
681681
Harald Hanche-Olsen
682682
Manus Hand
683+
Andreas Hangauer
683684
Milton L. Hankins
684685
Carl Bordum Hansen
685686
Stephen Hansen
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The :meth:`__eq__` and :meth:`__hash__` methods of
2+
:class:`typing.ForwardRef` now honor the ``module`` parameter of
3+
:class:`typing.ForwardRef`. Forward references from different
4+
modules are now differentiated.

0 commit comments

Comments
 (0)