]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-136316: Make typing.evaluate_forward_ref better at evaluating nested forwardrefs...
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Sun, 6 Jul 2025 23:44:20 +0000 (16:44 -0700)
committerGitHub <noreply@github.com>
Sun, 6 Jul 2025 23:44:20 +0000 (16:44 -0700)
Lib/test/test_typing.py
Lib/test/typinganndata/fwdref_module.py [new file with mode: 0644]
Lib/typing.py
Misc/NEWS.d/next/Library/2025-07-05-06-56-16.gh-issue-136316.3zj_Do.rst [new file with mode: 0644]

index 932c7b9c0a526badbafe0131c9c77e2c88e6d409..b1615bbff383c250e3e534cc8151e28ba8217770 100644 (file)
@@ -7326,6 +7326,12 @@ class EvaluateForwardRefTests(BaseTestCase):
             list[EqualToForwardRef('A')],
         )
 
+    def test_with_module(self):
+        from test.typinganndata import fwdref_module
+
+        typing.evaluate_forward_ref(
+            fwdref_module.fw,)
+
 
 class CollectionsAbcTests(BaseTestCase):
 
diff --git a/Lib/test/typinganndata/fwdref_module.py b/Lib/test/typinganndata/fwdref_module.py
new file mode 100644 (file)
index 0000000..7347a7a
--- /dev/null
@@ -0,0 +1,6 @@
+from typing import ForwardRef
+
+MyList = list[int]
+MyDict = dict[str, 'MyList']
+
+fw = ForwardRef('MyDict', module=__name__)
index 3ef377b954205febb8d5d2ff9d417adcbe252121..f1455c273d31cada6376225f028a783750a0bd09 100644 (file)
@@ -438,7 +438,7 @@ class _Sentinel:
 
 
 def _eval_type(t, globalns, localns, type_params, *, recursive_guard=frozenset(),
-               format=None, owner=None):
+               format=None, owner=None, parent_fwdref=None):
     """Evaluate all forward references in the given type t.
 
     For use of globalns and localns see the docstring for get_type_hints().
@@ -456,7 +456,7 @@ def _eval_type(t, globalns, localns, type_params, *, recursive_guard=frozenset()
     if isinstance(t, (_GenericAlias, GenericAlias, Union)):
         if isinstance(t, GenericAlias):
             args = tuple(
-                _make_forward_ref(arg) if isinstance(arg, str) else arg
+                _make_forward_ref(arg, parent_fwdref=parent_fwdref) if isinstance(arg, str) else arg
                 for arg in t.__args__
             )
         else:
@@ -936,7 +936,12 @@ def TypeIs(self, parameters):
     return _GenericAlias(self, (item,))
 
 
-def _make_forward_ref(code, **kwargs):
+def _make_forward_ref(code, *, parent_fwdref=None, **kwargs):
+    if parent_fwdref is not None:
+        if parent_fwdref.__forward_module__ is not None:
+            kwargs['module'] = parent_fwdref.__forward_module__
+        if parent_fwdref.__owner__ is not None:
+            kwargs['owner'] = parent_fwdref.__owner__
     forward_ref = _lazy_annotationlib.ForwardRef(code, **kwargs)
     # For compatibility, eagerly compile the forwardref's code.
     forward_ref.__forward_code__
@@ -1001,6 +1006,7 @@ def evaluate_forward_ref(
         recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
         format=format,
         owner=owner,
+        parent_fwdref=forward_ref,
     )
 
 
diff --git a/Misc/NEWS.d/next/Library/2025-07-05-06-56-16.gh-issue-136316.3zj_Do.rst b/Misc/NEWS.d/next/Library/2025-07-05-06-56-16.gh-issue-136316.3zj_Do.rst
new file mode 100644 (file)
index 0000000..dd5cecd
--- /dev/null
@@ -0,0 +1,2 @@
+Improve support for evaluating nested forward references in
+:func:`typing.evaluate_forward_ref`.