Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7327,6 +7327,12 @@ def test_partial_evaluation(self):
list[EqualToForwardRef('A')],
)

def test_with_module(self):
from test.typinganndata import fwdref_module

typing.evaluate_forward_ref(
fwdref_module.fw,)


class CollectionsAbcTests(BaseTestCase):

Expand Down
6 changes: 6 additions & 0 deletions Lib/test/typinganndata/fwdref_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from typing import ForwardRef

MyList = list[int]
MyDict = dict[str, 'MyList']

fw = ForwardRef('MyDict', module=__name__)
12 changes: 9 additions & 3 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ def __repr__(self):


def _eval_type(t, globalns, localns, type_params=_sentinel, *, 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().
Expand All @@ -451,7 +451,7 @@ def _eval_type(t, globalns, localns, type_params=_sentinel, *, recursive_guard=f
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__
)
is_unpacked = t.__unpacked__
Expand Down Expand Up @@ -936,7 +936,12 @@ def run(arg: Child | Unrelated):
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__
Expand Down Expand Up @@ -1001,6 +1006,7 @@ def evaluate_forward_ref(
recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
format=format,
owner=owner,
parent_fwdref=forward_ref,
)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improve support for evaluating nested forward references in
:func:`typing.evaluate_forward_ref`.
Loading