https://github.com/python/cpython/commit/1b376b82ac98517a55f13b5ec8645dc667762912
commit: 1b376b82ac98517a55f13b5ec8645dc667762912
branch: 3.14
author: Jelle Zijlstra <[email protected]>
committer: encukou <[email protected]>
date: 2025-11-03T15:07:22+01:00
summary:
[3.14] Revert "gh-137969: Fix evaluation of
`ref.evaluate(format=Format.FORWARDREF)` objects (GH-138075) (#140929)"
(GH-140931)
Revert "[3.14] gh-137969: Fix evaluation of
`ref.evaluate(format=Format.FORWARDREF)` objects (GH-138075) (#140929)"
This reverts commit cdb6fe89ae3a4bfbffb91290dbf9db0c4af85cd5.
files:
D Misc/NEWS.d/next/Library/2025-08-22-23-50-38.gh-issue-137969.Fkvis3.rst
M Lib/annotationlib.py
M Lib/test/test_annotationlib.py
diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py
index 26e7c200248d36..16dbb128bc9293 100644
--- a/Lib/annotationlib.py
+++ b/Lib/annotationlib.py
@@ -159,12 +159,12 @@ def evaluate(
type_params = getattr(owner, "__type_params__", None)
# Type parameters exist in their own scope, which is logically
- # between the locals and the globals.
- type_param_scope = {}
+ # between the locals and the globals. We simulate this by adding
+ # them to the globals.
if type_params is not None:
+ globals = dict(globals)
for param in type_params:
- type_param_scope[param.__name__] = param
-
+ globals[param.__name__] = param
if self.__extra_names__:
locals = {**locals, **self.__extra_names__}
@@ -172,8 +172,6 @@ def evaluate(
if arg.isidentifier() and not keyword.iskeyword(arg):
if arg in locals:
return locals[arg]
- elif arg in type_param_scope:
- return type_param_scope[arg]
elif arg in globals:
return globals[arg]
elif hasattr(builtins, arg):
@@ -185,7 +183,7 @@ def evaluate(
else:
code = self.__forward_code__
try:
- return eval(code, globals=globals, locals={**type_param_scope,
**locals})
+ return eval(code, globals=globals, locals=locals)
except Exception:
if not is_forwardref_format:
raise
@@ -193,7 +191,7 @@ def evaluate(
# All variables, in scoping order, should be checked before
# triggering __missing__ to create a _Stringifier.
new_locals = _StringifierDict(
- {**builtins.__dict__, **globals, **type_param_scope, **locals},
+ {**builtins.__dict__, **globals, **locals},
globals=globals,
owner=owner,
is_class=self.__forward_is_class__,
diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py
index 08f7161a2736e1..7b08f58bfb8ba2 100644
--- a/Lib/test/test_annotationlib.py
+++ b/Lib/test/test_annotationlib.py
@@ -1911,15 +1911,6 @@ def test_fwdref_invalid_syntax(self):
with self.assertRaises(SyntaxError):
fr.evaluate()
- def test_re_evaluate_generics(self):
- global alias
- class C:
- x: alias[int]
-
- evaluated = get_annotations(C,
format=Format.FORWARDREF)["x"].evaluate(format=Format.FORWARDREF)
- alias = list
- self.assertEqual(evaluated.evaluate(), list[int])
-
class TestAnnotationLib(unittest.TestCase):
def test__all__(self):
diff --git
a/Misc/NEWS.d/next/Library/2025-08-22-23-50-38.gh-issue-137969.Fkvis3.rst
b/Misc/NEWS.d/next/Library/2025-08-22-23-50-38.gh-issue-137969.Fkvis3.rst
deleted file mode 100644
index 59f9e6e3d331ec..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-08-22-23-50-38.gh-issue-137969.Fkvis3.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix :meth:`annotationlib.ForwardRef.evaluate` returning
:class:`annotationlib.ForwardRef`
-objects which do not update in new contexts.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]