125
125
# legitimate imports of those modules.
126
126
127
127
128
- def _type_convert (arg ):
128
+ def _type_convert (arg , module = None ):
129
129
"""For converting None to type(None), and strings to ForwardRef."""
130
130
if arg is None :
131
131
return type (None )
132
132
if isinstance (arg , str ):
133
- return ForwardRef (arg )
133
+ return ForwardRef (arg , module = module )
134
134
return arg
135
135
136
136
137
- def _type_check (arg , msg , is_argument = True ):
137
+ def _type_check (arg , msg , is_argument = True , module = None ):
138
138
"""Check that the argument is a type, and return it (internal helper).
139
139
140
140
As a special case, accept None and return type(None) instead. Also wrap strings
@@ -150,7 +150,7 @@ def _type_check(arg, msg, is_argument=True):
150
150
if is_argument :
151
151
invalid_generic_forms = invalid_generic_forms + (ClassVar , Final )
152
152
153
- arg = _type_convert (arg )
153
+ arg = _type_convert (arg , module = module )
154
154
if (isinstance (arg , _GenericAlias ) and
155
155
arg .__origin__ in invalid_generic_forms ):
156
156
raise TypeError (f"{ arg } is not valid as type argument" )
@@ -517,9 +517,9 @@ class ForwardRef(_Final, _root=True):
517
517
518
518
__slots__ = ('__forward_arg__' , '__forward_code__' ,
519
519
'__forward_evaluated__' , '__forward_value__' ,
520
- '__forward_is_argument__' )
520
+ '__forward_is_argument__' , '__forward_module__' )
521
521
522
- def __init__ (self , arg , is_argument = True ):
522
+ def __init__ (self , arg , is_argument = True , module = None ):
523
523
if not isinstance (arg , str ):
524
524
raise TypeError (f"Forward reference must be a string -- got { arg !r} " )
525
525
try :
@@ -531,6 +531,7 @@ def __init__(self, arg, is_argument=True):
531
531
self .__forward_evaluated__ = False
532
532
self .__forward_value__ = None
533
533
self .__forward_is_argument__ = is_argument
534
+ self .__forward_module__ = module
534
535
535
536
def _evaluate (self , globalns , localns , recursive_guard ):
536
537
if self .__forward_arg__ in recursive_guard :
@@ -542,6 +543,10 @@ def _evaluate(self, globalns, localns, recursive_guard):
542
543
globalns = localns
543
544
elif localns is None :
544
545
localns = globalns
546
+ if self .__forward_module__ is not None :
547
+ globalns = getattr (
548
+ sys .modules .get (self .__forward_module__ , None ), '__dict__' , globalns
549
+ )
545
550
type_ = _type_check (
546
551
eval (self .__forward_code__ , globalns , localns ),
547
552
"Forward references must evaluate to types." ,
@@ -1912,7 +1917,8 @@ def __new__(cls, name, bases, ns, total=True):
1912
1917
own_annotation_keys = set (own_annotations .keys ())
1913
1918
msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
1914
1919
own_annotations = {
1915
- n : _type_check (tp , msg ) for n , tp in own_annotations .items ()
1920
+ n : _type_check (tp , msg , module = tp_dict .__module__ )
1921
+ for n , tp in own_annotations .items ()
1916
1922
}
1917
1923
required_keys = set ()
1918
1924
optional_keys = set ()
0 commit comments