Skip to content

Commit a17d59a

Browse files
[3.10] bpo-46333: Honor module parameter in ForwardRef (GH-30536) (GH-31379)
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]> (cherry picked from commit 6e7b813) Co-authored-by: aha79 <[email protected]> Automerge-Triggered-By: GH:JelleZijlstra
1 parent d4e4ef1 commit a17d59a

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
@@ -2658,6 +2658,10 @@ def test_forward_equality(self):
26582658
fr = typing.ForwardRef('int')
26592659
self.assertEqual(fr, typing.ForwardRef('int'))
26602660
self.assertNotEqual(List['int'], List[int])
2661+
self.assertNotEqual(fr, typing.ForwardRef('int', module=__name__))
2662+
frm = typing.ForwardRef('int', module=__name__)
2663+
self.assertEqual(frm, typing.ForwardRef('int', module=__name__))
2664+
self.assertNotEqual(frm, typing.ForwardRef('int', module='__other_name__'))
26612665

26622666
def test_forward_equality_gth(self):
26632667
c1 = typing.ForwardRef('C')
@@ -2694,6 +2698,14 @@ def foo(a: c1_gth, b: c2_gth):
26942698
self.assertEqual(hash(c1_gth), hash(c2_gth))
26952699
self.assertEqual(hash(c1), hash(c1_gth))
26962700

2701+
c3 = typing.ForwardRef('int', module=__name__)
2702+
c4 = typing.ForwardRef('int', module='__other_name__')
2703+
2704+
self.assertNotEqual(hash(c3), hash(c1))
2705+
self.assertNotEqual(hash(c3), hash(c1_gth))
2706+
self.assertNotEqual(hash(c3), hash(c4))
2707+
self.assertEqual(hash(c3), hash(typing.ForwardRef('int', module=__name__)))
2708+
26972709
def test_forward_equality_namespace(self):
26982710
class A:
26992711
pass

Lib/typing.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,10 +705,11 @@ def __eq__(self, other):
705705
if self.__forward_evaluated__ and other.__forward_evaluated__:
706706
return (self.__forward_arg__ == other.__forward_arg__ and
707707
self.__forward_value__ == other.__forward_value__)
708-
return self.__forward_arg__ == other.__forward_arg__
708+
return (self.__forward_arg__ == other.__forward_arg__ and
709+
self.__forward_module__ == other.__forward_module__)
709710

710711
def __hash__(self):
711-
return hash(self.__forward_arg__)
712+
return hash((self.__forward_arg__, self.__forward_module__))
712713

713714
def __repr__(self):
714715
return f'ForwardRef({self.__forward_arg__!r})'

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ Anders Hammarquist
677677
Mark Hammond
678678
Harald Hanche-Olsen
679679
Manus Hand
680+
Andreas Hangauer
680681
Milton L. Hankins
681682
Carl Bordum Hansen
682683
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)