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