@@ -159,19 +159,21 @@ def evaluate(
159159 type_params = getattr (owner , "__type_params__" , None )
160160
161161 # 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 = {}
164164 if type_params is not None :
165- globals = dict (globals )
166165 for param in type_params :
167- globals [param .__name__ ] = param
166+ type_param_scope [param .__name__ ] = param
167+
168168 if self .__extra_names__ :
169169 locals = {** locals , ** self .__extra_names__ }
170170
171171 arg = self .__forward_arg__
172172 if arg .isidentifier () and not keyword .iskeyword (arg ):
173173 if arg in locals :
174174 return locals [arg ]
175+ elif arg in type_param_scope :
176+ return type_param_scope [arg ]
175177 elif arg in globals :
176178 return globals [arg ]
177179 elif hasattr (builtins , arg ):
@@ -183,15 +185,15 @@ def evaluate(
183185 else :
184186 code = self .__forward_code__
185187 try :
186- return eval (code , globals = globals , locals = locals )
188+ return eval (code , globals = globals , locals = { ** type_param_scope , ** locals } )
187189 except Exception :
188190 if not is_forwardref_format :
189191 raise
190192
191193 # All variables, in scoping order, should be checked before
192194 # triggering __missing__ to create a _Stringifier.
193195 new_locals = _StringifierDict (
194- {** builtins .__dict__ , ** globals , ** locals },
196+ {** builtins .__dict__ , ** globals , ** type_param_scope , ** locals },
195197 globals = globals ,
196198 owner = owner ,
197199 is_class = self .__forward_is_class__ ,
0 commit comments