mirror of
https://github.com/python/cpython.git
synced 2025-08-03 08:34:29 +00:00
gh-119180: PEP 649: Add __annotate__ attributes (#119209)
This commit is contained in:
parent
73ab83b27f
commit
e9875ecb5d
13 changed files with 324 additions and 18 deletions
|
@ -1564,7 +1564,7 @@ class SizeofTest(unittest.TestCase):
|
|||
check(x, size('3Pi2cP7P2ic??2P'))
|
||||
# function
|
||||
def func(): pass
|
||||
check(func, size('15Pi'))
|
||||
check(func, size('16Pi'))
|
||||
class c():
|
||||
@staticmethod
|
||||
def foo():
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import textwrap
|
||||
import types
|
||||
import unittest
|
||||
from test.support import run_code
|
||||
|
||||
|
@ -212,3 +213,46 @@ class TestSetupAnnotations(unittest.TestCase):
|
|||
case 0:
|
||||
x: int = 1
|
||||
""")
|
||||
|
||||
|
||||
class AnnotateTests(unittest.TestCase):
|
||||
"""See PEP 649."""
|
||||
def test_manual_annotate(self):
|
||||
def f():
|
||||
pass
|
||||
mod = types.ModuleType("mod")
|
||||
class X:
|
||||
pass
|
||||
|
||||
for obj in (f, mod, X):
|
||||
with self.subTest(obj=obj):
|
||||
self.check_annotations(obj)
|
||||
|
||||
def check_annotations(self, f):
|
||||
self.assertEqual(f.__annotations__, {})
|
||||
self.assertIs(f.__annotate__, None)
|
||||
|
||||
with self.assertRaisesRegex(TypeError, "__annotate__ must be callable or None"):
|
||||
f.__annotate__ = 42
|
||||
f.__annotate__ = lambda: 42
|
||||
with self.assertRaisesRegex(TypeError, r"takes 0 positional arguments but 1 was given"):
|
||||
print(f.__annotations__)
|
||||
|
||||
f.__annotate__ = lambda x: 42
|
||||
with self.assertRaisesRegex(TypeError, r"__annotate__ returned non-dict of type 'int'"):
|
||||
print(f.__annotations__)
|
||||
|
||||
f.__annotate__ = lambda x: {"x": x}
|
||||
self.assertEqual(f.__annotations__, {"x": 1})
|
||||
|
||||
# Setting annotate to None does not invalidate the cached __annotations__
|
||||
f.__annotate__ = None
|
||||
self.assertEqual(f.__annotations__, {"x": 1})
|
||||
|
||||
# But setting it to a new callable does
|
||||
f.__annotate__ = lambda x: {"y": x}
|
||||
self.assertEqual(f.__annotations__, {"y": 1})
|
||||
|
||||
# Setting f.__annotations__ also clears __annotate__
|
||||
f.__annotations__ = {"z": 43}
|
||||
self.assertIs(f.__annotate__, None)
|
||||
|
|
|
@ -3723,7 +3723,7 @@ class ProtocolTests(BaseTestCase):
|
|||
|
||||
acceptable_extra_attrs = {
|
||||
'_is_protocol', '_is_runtime_protocol', '__parameters__',
|
||||
'__init__', '__annotations__', '__subclasshook__',
|
||||
'__init__', '__annotations__', '__subclasshook__', '__annotate__',
|
||||
}
|
||||
self.assertLessEqual(vars(NonP).keys(), vars(C).keys() | acceptable_extra_attrs)
|
||||
self.assertLessEqual(
|
||||
|
|
|
@ -1889,6 +1889,7 @@ _SPECIAL_NAMES = frozenset({
|
|||
'__init__', '__module__', '__new__', '__slots__',
|
||||
'__subclasshook__', '__weakref__', '__class_getitem__',
|
||||
'__match_args__', '__static_attributes__', '__firstlineno__',
|
||||
'__annotate__',
|
||||
})
|
||||
|
||||
# These special attributes will be not collected as protocol members.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue