Skip to content

Commit a1cbace

Browse files
authored
gh-105509: Simplify implementation of typing.Annotated (#105510)
1 parent 8f9ea43 commit a1cbace

File tree

3 files changed

+17
-27
lines changed

3 files changed

+17
-27
lines changed

Lib/test/test_typing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8189,8 +8189,7 @@ class AnnotatedTests(BaseTestCase):
81898189

81908190
def test_new(self):
81918191
with self.assertRaisesRegex(
8192-
TypeError,
8193-
'Type Annotated cannot be instantiated',
8192+
TypeError, 'Cannot instantiate typing.Annotated',
81948193
):
81958194
Annotated()
81968195

Lib/typing.py

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,8 @@ def __mro_entries__(self, bases):
20012001
return (self.__origin__,)
20022002

20032003

2004-
class Annotated:
2004+
@_SpecialForm
2005+
def Annotated(self, params):
20052006
"""Add context-specific metadata to a type.
20062007
20072008
Example: Annotated[int, runtime_check.Unsigned] indicates to the
@@ -2048,30 +2049,17 @@ class Annotated:
20482049
where T1, T2 etc. are TypeVars, which would be invalid, because
20492050
only one type should be passed to Annotated.
20502051
"""
2051-
2052-
__slots__ = ()
2053-
2054-
def __new__(cls, *args, **kwargs):
2055-
raise TypeError("Type Annotated cannot be instantiated.")
2056-
2057-
@_tp_cache
2058-
def __class_getitem__(cls, params):
2059-
if not isinstance(params, tuple) or len(params) < 2:
2060-
raise TypeError("Annotated[...] should be used "
2061-
"with at least two arguments (a type and an "
2062-
"annotation).")
2063-
if _is_unpacked_typevartuple(params[0]):
2064-
raise TypeError("Annotated[...] should not be used with an "
2065-
"unpacked TypeVarTuple")
2066-
msg = "Annotated[t, ...]: t must be a type."
2067-
origin = _type_check(params[0], msg, allow_special_forms=True)
2068-
metadata = tuple(params[1:])
2069-
return _AnnotatedAlias(origin, metadata)
2070-
2071-
def __init_subclass__(cls, *args, **kwargs):
2072-
raise TypeError(
2073-
"Cannot subclass {}.Annotated".format(cls.__module__)
2074-
)
2052+
if not isinstance(params, tuple) or len(params) < 2:
2053+
raise TypeError("Annotated[...] should be used "
2054+
"with at least two arguments (a type and an "
2055+
"annotation).")
2056+
if _is_unpacked_typevartuple(params[0]):
2057+
raise TypeError("Annotated[...] should not be used with an "
2058+
"unpacked TypeVarTuple")
2059+
msg = "Annotated[t, ...]: t must be a type."
2060+
origin = _type_check(params[0], msg, allow_special_forms=True)
2061+
metadata = tuple(params[1:])
2062+
return _AnnotatedAlias(origin, metadata)
20752063

20762064

20772065
def runtime_checkable(cls):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:data:`typing.Annotated` is now implemented as an instance of
2+
``typing._SpecialForm`` rather than a class. This should have no user-facing
3+
impact for users of the :mod:`typing` module public API.

0 commit comments

Comments
 (0)