@@ -120,8 +120,21 @@ def evaluate(self, *, globals=None, locals=None, type_params=None, owner=None):
120
120
# (unless they are shadowed by assignments *in* the local namespace),
121
121
# as a way of emulating annotation scopes when calling `eval()`
122
122
type_params = getattr (self .__owner__ , "__type_params__" , None )
123
+
124
+ # type parameters require some special handling,
125
+ # as they exist in their own scope
126
+ # but `eval()` does not have a dedicated parameter for that scope.
127
+ # For classes, names in type parameter scopes should override
128
+ # names in the global scope (which here are called `localns`!),
129
+ # but should in turn be overridden by names in the class scope
130
+ # (which here are called `globalns`!)
123
131
if type_params is not None :
124
- locals = {param .__name__ : param for param in type_params } | locals
132
+ globals , locals = dict (globals ), dict (locals )
133
+ for param in type_params :
134
+ param_name = param .__name__
135
+ if not self .__forward_is_class__ or param_name not in globals :
136
+ globals [param_name ] = param
137
+ locals .pop (param_name , None )
125
138
126
139
code = self .__forward_code__
127
140
value = eval (code , globals = globals , locals = locals )
0 commit comments