@@ -159,19 +159,21 @@ def evaluate(
159
159
type_params = getattr (owner , "__type_params__" , None )
160
160
161
161
# Type parameters exist in their own scope, which is logically
162
- # between the locals and the globals. We simulate this by adding
163
- # them to the globals.
162
+ # between the locals and the globals.
163
+ type_param_scope = {}
164
164
if type_params is not None :
165
- globals = dict (globals )
166
165
for param in type_params :
167
- globals [param .__name__ ] = param
166
+ type_param_scope [param .__name__ ] = param
167
+
168
168
if self .__extra_names__ :
169
169
locals = {** locals , ** self .__extra_names__ }
170
170
171
171
arg = self .__forward_arg__
172
172
if arg .isidentifier () and not keyword .iskeyword (arg ):
173
173
if arg in locals :
174
174
return locals [arg ]
175
+ elif arg in type_param_scope :
176
+ return type_param_scope [arg ]
175
177
elif arg in globals :
176
178
return globals [arg ]
177
179
elif hasattr (builtins , arg ):
@@ -183,12 +185,12 @@ def evaluate(
183
185
else :
184
186
code = self .__forward_code__
185
187
try :
186
- return eval (code , globals = globals , locals = locals )
188
+ return eval (code , globals = globals , locals = { ** type_param_scope , ** locals } )
187
189
except Exception :
188
190
if not is_forwardref_format :
189
191
raise
190
192
new_locals = _StringifierDict (
191
- {** builtins .__dict__ , ** locals },
193
+ {** type_param_scope , ** builtins .__dict__ , ** locals },
192
194
globals = globals ,
193
195
owner = owner ,
194
196
is_class = self .__forward_is_class__ ,
0 commit comments