Skip to content

Commit 3d01565

Browse files
[3.14] gh-136316: Make typing.evaluate_forward_ref better at evaluating nested forwardrefs (GH-136319) (#136346)
(cherry picked from commit 9312702)
1 parent bd97cb8 commit 3d01565

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

Lib/test/test_typing.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7328,6 +7328,12 @@ def test_partial_evaluation(self):
73287328
list[EqualToForwardRef('A')],
73297329
)
73307330

7331+
def test_with_module(self):
7332+
from test.typinganndata import fwdref_module
7333+
7334+
typing.evaluate_forward_ref(
7335+
fwdref_module.fw,)
7336+
73317337

73327338
class CollectionsAbcTests(BaseTestCase):
73337339

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from typing import ForwardRef
2+
3+
MyList = list[int]
4+
MyDict = dict[str, 'MyList']
5+
6+
fw = ForwardRef('MyDict', module=__name__)

Lib/typing.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ def __repr__(self):
430430

431431

432432
def _eval_type(t, globalns, localns, type_params=_sentinel, *, recursive_guard=frozenset(),
433-
format=None, owner=None):
433+
format=None, owner=None, parent_fwdref=None):
434434
"""Evaluate all forward references in the given type t.
435435
436436
For use of globalns and localns see the docstring for get_type_hints().
@@ -451,7 +451,7 @@ def _eval_type(t, globalns, localns, type_params=_sentinel, *, recursive_guard=f
451451
if isinstance(t, (_GenericAlias, GenericAlias, Union)):
452452
if isinstance(t, GenericAlias):
453453
args = tuple(
454-
_make_forward_ref(arg) if isinstance(arg, str) else arg
454+
_make_forward_ref(arg, parent_fwdref=parent_fwdref) if isinstance(arg, str) else arg
455455
for arg in t.__args__
456456
)
457457
is_unpacked = t.__unpacked__
@@ -936,7 +936,12 @@ def run(arg: Child | Unrelated):
936936
return _GenericAlias(self, (item,))
937937

938938

939-
def _make_forward_ref(code, **kwargs):
939+
def _make_forward_ref(code, *, parent_fwdref=None, **kwargs):
940+
if parent_fwdref is not None:
941+
if parent_fwdref.__forward_module__ is not None:
942+
kwargs['module'] = parent_fwdref.__forward_module__
943+
if parent_fwdref.__owner__ is not None:
944+
kwargs['owner'] = parent_fwdref.__owner__
940945
forward_ref = _lazy_annotationlib.ForwardRef(code, **kwargs)
941946
# For compatibility, eagerly compile the forwardref's code.
942947
forward_ref.__forward_code__
@@ -1001,6 +1006,7 @@ def evaluate_forward_ref(
10011006
recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
10021007
format=format,
10031008
owner=owner,
1009+
parent_fwdref=forward_ref,
10041010
)
10051011

10061012

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve support for evaluating nested forward references in
2+
:func:`typing.evaluate_forward_ref`.

0 commit comments

Comments
 (0)