Update annotationlib from v3.14.3

This commit is contained in:
CPython Developers authored and Jeong, YunWon committed 2026-02-24 16:22:44 +09:00
1 parent e461a0a7b9
commit 2abc1386c6
2 files changed
+53 -7

No files matched your search

+12 -3
View File
@@ -279,7 +279,13 @@ class ForwardRef:
# because dictionaries are not hashable.
and self.__globals__ is other.__globals__
and self.__forward_is_class__ == other.__forward_is_class__
and self.__cell__ == other.__cell__
# Two separate cells are always considered unequal in forward refs.
and (
{name: id(cell) for name, cell in self.__cell__.items()}
== {name: id(cell) for name, cell in other.__cell__.items()}
if isinstance(self.__cell__, dict) and isinstance(other.__cell__, dict)
else self.__cell__ is other.__cell__
)
and self.__owner__ == other.__owner__
and (
(tuple(sorted(self.__extra_names__.items())) if self.__extra_names__ else None) ==
@@ -293,7 +299,10 @@ class ForwardRef:
self.__forward_module__,
id(self.__globals__), # dictionaries are not hashable, so hash by identity
self.__forward_is_class__,
tuple(sorted(self.__cell__.items())) if isinstance(self.__cell__, dict) else self.__cell__,
( # cells are not hashable as well
tuple(sorted([(name, id(cell)) for name, cell in self.__cell__.items()]))
if isinstance(self.__cell__, dict) else id(self.__cell__),
),
self.__owner__,
tuple(sorted(self.__extra_names__.items())) if self.__extra_names__ else None,
))
@@ -1096,7 +1105,7 @@ def _rewrite_star_unpack(arg):
"""If the given argument annotation expression is a star unpack e.g. `'*Ts'`
rewrite it to a valid expression.
"""
if arg.startswith("*"):
if arg.lstrip().startswith("*"):
return f"({arg},)[0]" # E.g. (*Ts,)[0] or (*tuple[int, int],)[0]
else:
return arg
+41 -4
View File
@@ -8,6 +8,7 @@ import functools
import itertools
import pickle
from string.templatelib import Template, Interpolation
import types
import typing
import sys
import unittest
@@ -120,8 +121,8 @@ class TestForwardRefFormat(unittest.TestCase):
beta: +some,
gamma: some < obj,
delta: some | {obj: module},
epsilon: some | {obj, module},
zeta: some | [obj],
epsilon: some | {obj},
zeta: some | [obj, module],
eta: some | (),
):
pass
@@ -157,11 +158,11 @@ class TestForwardRefFormat(unittest.TestCase):
epsilon_anno = anno["epsilon"]
self.assertIsInstance(epsilon_anno, ForwardRef)
self.assertEqual(epsilon_anno, support.EqualToForwardRef("some | {obj, module}", owner=f))
self.assertEqual(epsilon_anno, support.EqualToForwardRef("some | {obj}", owner=f))
zeta_anno = anno["zeta"]
self.assertIsInstance(zeta_anno, ForwardRef)
self.assertEqual(zeta_anno, support.EqualToForwardRef("some | [obj]", owner=f))
self.assertEqual(zeta_anno, support.EqualToForwardRef("some | [obj, module]", owner=f))
eta_anno = anno["eta"]
self.assertIsInstance(eta_anno, ForwardRef)
@@ -885,6 +886,9 @@ class TestGetAnnotations(unittest.TestCase):
def f(*args: "*tuple[int, ...]"): ...
self.assertEqual(get_annotations(f, eval_str=True),
{'args': (*tuple[int, ...],)[0]})
def f(*args: " *tuple[int, ...]"): ...
self.assertEqual(get_annotations(f, eval_str=True),
{'args': (*tuple[int, ...],)[0]})
def test_stringized_annotations_on_wrapper(self):
@@ -1859,6 +1863,39 @@ class TestForwardRefClass(unittest.TestCase):
self.assertNotEqual(hash(c3), hash(c4))
self.assertEqual(hash(c3), hash(ForwardRef("int", module=__name__)))
def test_forward_equality_and_hash_with_cells(self):
"""Regression test for GH-143831."""
class A:
def one(_) -> C1:
"""One cell."""
one_f = ForwardRef("C1", owner=one)
one_f_ga1 = get_annotations(one, format=Format.FORWARDREF)["return"]
one_f_ga2 = get_annotations(one, format=Format.FORWARDREF)["return"]
self.assertIsInstance(one_f_ga1.__cell__, types.CellType)
self.assertIs(one_f_ga1.__cell__, one_f_ga2.__cell__)
def two(_) -> C1 | C2:
"""Two cells."""
two_f_ga1 = get_annotations(two, format=Format.FORWARDREF)["return"]
two_f_ga2 = get_annotations(two, format=Format.FORWARDREF)["return"]
self.assertIsNot(two_f_ga1.__cell__, two_f_ga2.__cell__)
self.assertIsInstance(two_f_ga1.__cell__, dict)
self.assertIsInstance(two_f_ga2.__cell__, dict)
type C1 = None
type C2 = None
self.assertNotEqual(A.one_f, A.one_f_ga1)
self.assertNotEqual(hash(A.one_f), hash(A.one_f_ga1))
self.assertEqual(A.one_f_ga1, A.one_f_ga2)
self.assertEqual(hash(A.one_f_ga1), hash(A.one_f_ga2))
self.assertEqual(A.two_f_ga1, A.two_f_ga2)
self.assertEqual(hash(A.two_f_ga1), hash(A.two_f_ga2))
def test_forward_equality_namespace(self):
def namespace1():
a = ForwardRef("A")