From 300c1771b229bb5900cf83629008d25b9d3c6663 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Sat, 6 Sep 2025 08:39:49 +0100 Subject: [PATCH] gh-137706: make typing._is_unpacked_typevartuple check for `True` instead of truthy (GH-137712) (cherry picked from commit 7e652f402f84b412ec46cec42cb103f489a0087e) Co-authored-by: David Ellis --- Lib/test/test_typing.py | 13 +++++++++++++ Lib/typing.py | 4 +++- .../2025-09-05-21-10-24.gh-issue-137706.0EztiJ.rst | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-09-05-21-10-24.gh-issue-137706.0EztiJ.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index cd552f9887d8a0..9d153e93a6c71c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -9811,6 +9811,19 @@ class B(str): ... self.assertIs(type(field_c2.__metadata__[0]), float) self.assertIs(type(field_c3.__metadata__[0]), bool) + def test_forwardref_partial_evaluation(self): + # Test that Annotated partially evaluates if it contains a ForwardRef + # See: https://github.com/python/cpython/issues/137706 + def f(x: Annotated[undefined, '']): pass + + ann = annotationlib.get_annotations(f, format=annotationlib.Format.FORWARDREF) + + # Test that the attributes are retrievable from the partially evaluated annotation + x_ann = ann['x'] + self.assertIs(get_origin(x_ann), Annotated) + self.assertEqual(x_ann.__origin__, EqualToForwardRef('undefined', owner=f)) + self.assertEqual(x_ann.__metadata__, ('',)) + class TypeAliasTests(BaseTestCase): def test_canonical_usage_with_variable_annotation(self): diff --git a/Lib/typing.py b/Lib/typing.py index d4a79ed5e35295..6780a79d4e0b2c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1011,8 +1011,10 @@ def evaluate_forward_ref( def _is_unpacked_typevartuple(x: Any) -> bool: + # Need to check 'is True' here + # See: https://github.com/python/cpython/issues/137706 return ((not isinstance(x, type)) and - getattr(x, '__typing_is_unpacked_typevartuple__', False)) + getattr(x, '__typing_is_unpacked_typevartuple__', False) is True) def _is_typevar_like(x: Any) -> bool: diff --git a/Misc/NEWS.d/next/Library/2025-09-05-21-10-24.gh-issue-137706.0EztiJ.rst b/Misc/NEWS.d/next/Library/2025-09-05-21-10-24.gh-issue-137706.0EztiJ.rst new file mode 100644 index 00000000000000..9eed50ec20a8f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-05-21-10-24.gh-issue-137706.0EztiJ.rst @@ -0,0 +1 @@ +Fix the partial evaluation of annotations that use ``typing.Annotated[T, x]`` where ``T`` is a forward reference.