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" )
@@ -633,9 +633,9 @@ class ForwardRef(_Final, _root=True):
633
633
634
634
__slots__ = ('__forward_arg__' , '__forward_code__' ,
635
635
'__forward_evaluated__' , '__forward_value__' ,
636
- '__forward_is_argument__' )
636
+ '__forward_is_argument__' , '__forward_module__' )
637
637
638
- def __init__ (self , arg , is_argument = True ):
638
+ def __init__ (self , arg , is_argument = True , module = None ):
639
639
if not isinstance (arg , str ):
640
640
raise TypeError (f"Forward reference must be a string -- got { arg !r} " )
641
641
try :
@@ -647,6 +647,7 @@ def __init__(self, arg, is_argument=True):
647
647
self .__forward_evaluated__ = False
648
648
self .__forward_value__ = None
649
649
self .__forward_is_argument__ = is_argument
650
+ self .__forward_module__ = module
650
651
651
652
def _evaluate (self , globalns , localns , recursive_guard ):
652
653
if self .__forward_arg__ in recursive_guard :
@@ -658,6 +659,10 @@ def _evaluate(self, globalns, localns, recursive_guard):
658
659
globalns = localns
659
660
elif localns is None :
660
661
localns = globalns
662
+ if self .__forward_module__ is not None :
663
+ globalns = getattr (
664
+ sys .modules .get (self .__forward_module__ , None ), '__dict__' , globalns
665
+ )
661
666
type_ = _type_check (
662
667
eval (self .__forward_code__ , globalns , localns ),
663
668
"Forward references must evaluate to types." ,
@@ -2242,7 +2247,8 @@ def __new__(cls, name, bases, ns, total=True):
2242
2247
own_annotation_keys = set (own_annotations .keys ())
2243
2248
msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
2244
2249
own_annotations = {
2245
- n : _type_check (tp , msg ) for n , tp in own_annotations .items ()
2250
+ n : _type_check (tp , msg , module = tp_dict .__module__ )
2251
+ for n , tp in own_annotations .items ()
2246
2252
}
2247
2253
required_keys = set ()
2248
2254
optional_keys = set ()
0 commit comments