Skip to content

Commit 1f3a63c

Browse files
committed
Reapply python#120272
1 parent f60f435 commit 1f3a63c

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

Lib/annotationlib.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,21 @@ def evaluate(self, *, globals=None, locals=None, type_params=None, owner=None):
120120
# (unless they are shadowed by assignments *in* the local namespace),
121121
# as a way of emulating annotation scopes when calling `eval()`
122122
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`!)
123131
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)
125138

126139
code = self.__forward_code__
127140
value = eval(code, globals=globals, locals=locals)

0 commit comments

Comments
 (0)