134
134
# legitimate imports of those modules.
135
135
136
136
137
- def _type_convert (arg ):
137
+ def _type_convert (arg , module = None ):
138
138
"""For converting None to type(None), and strings to ForwardRef."""
139
139
if arg is None :
140
140
return type (None )
141
141
if isinstance (arg , str ):
142
- return ForwardRef (arg )
142
+ return ForwardRef (arg , module = module )
143
143
return arg
144
144
145
145
146
- def _type_check (arg , msg , is_argument = True ):
146
+ def _type_check (arg , msg , is_argument = True , module = None ):
147
147
"""Check that the argument is a type, and return it (internal helper).
148
148
149
149
As a special case, accept None and return type(None) instead. Also wrap strings
@@ -159,7 +159,7 @@ def _type_check(arg, msg, is_argument=True):
159
159
if is_argument :
160
160
invalid_generic_forms = invalid_generic_forms + (ClassVar , Final )
161
161
162
- arg = _type_convert (arg )
162
+ arg = _type_convert (arg , module = module )
163
163
if (isinstance (arg , _GenericAlias ) and
164
164
arg .__origin__ in invalid_generic_forms ):
165
165
raise TypeError (f"{ arg } is not valid as type argument" )
@@ -630,9 +630,9 @@ class ForwardRef(_Final, _root=True):
630
630
631
631
__slots__ = ('__forward_arg__' , '__forward_code__' ,
632
632
'__forward_evaluated__' , '__forward_value__' ,
633
- '__forward_is_argument__' )
633
+ '__forward_is_argument__' , '__forward_module__' )
634
634
635
- def __init__ (self , arg , is_argument = True ):
635
+ def __init__ (self , arg , is_argument = True , module = None ):
636
636
if not isinstance (arg , str ):
637
637
raise TypeError (f"Forward reference must be a string -- got { arg !r} " )
638
638
try :
@@ -644,6 +644,7 @@ def __init__(self, arg, is_argument=True):
644
644
self .__forward_evaluated__ = False
645
645
self .__forward_value__ = None
646
646
self .__forward_is_argument__ = is_argument
647
+ self .__forward_module__ = module
647
648
648
649
def _evaluate (self , globalns , localns , recursive_guard ):
649
650
if self .__forward_arg__ in recursive_guard :
@@ -655,6 +656,10 @@ def _evaluate(self, globalns, localns, recursive_guard):
655
656
globalns = localns
656
657
elif localns is None :
657
658
localns = globalns
659
+ if self .__forward_module__ is not None :
660
+ globalns = getattr (
661
+ sys .modules .get (self .__forward_module__ , None ), '__dict__' , globalns
662
+ )
658
663
type_ = _type_check (
659
664
eval (self .__forward_code__ , globalns , localns ),
660
665
"Forward references must evaluate to types." ,
@@ -2233,7 +2238,8 @@ def __new__(cls, name, bases, ns, total=True):
2233
2238
own_annotation_keys = set (own_annotations .keys ())
2234
2239
msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
2235
2240
own_annotations = {
2236
- n : _type_check (tp , msg ) for n , tp in own_annotations .items ()
2241
+ n : _type_check (tp , msg , module = tp_dict .__module__ )
2242
+ for n , tp in own_annotations .items ()
2237
2243
}
2238
2244
required_keys = set ()
2239
2245
optional_keys = set ()
0 commit comments