Repository: python/cpython
Pull request: gh-105509: Simplify the implementation of `typing.Annotated`
Closes #105509

<!-- gh-issue-number: gh-105509 -->
* Issue: gh-105509
<!-- /gh-issue-number -->


Problem statement:
Simplify the implementation of `typing.Annotated`
# Feature or enhancement

`typing.Annotated` is currently implemented as a class, but doesn't need to be. All other objects like it in the `typing` module are implemented as instances of `typing._SpecialForm`, and we can do the same here. This simplifies the code a lot (making it easier to maintain in the future), and should also be _slightly_ more performant.

<!-- gh-linked-prs -->
### Linked PRs
* gh-105510
<!-- /gh-linked-prs -->

Hints from issue discussion:

Commit message: news

Patch to review:
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 432fc88b1c072e..d5ce1b092d0b1c 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -7879,8 +7879,7 @@ class AnnotatedTests(BaseTestCase):
 
     def test_new(self):
         with self.assertRaisesRegex(
-            TypeError,
-            'Type Annotated cannot be instantiated',
+            TypeError, 'Cannot instantiate typing.Annotated',
         ):
             Annotated()
 
diff --git a/Lib/typing.py b/Lib/typing.py
index 27497741b24887..ec44e4a4851f89 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -1998,7 +1998,8 @@ def __mro_entries__(self, bases):
         return (self.__origin__,)
 
 
-class Annotated:
+@_SpecialForm
+def Annotated(self, params):
     """Add context-specific metadata to a type.
 
     Example: Annotated[int, runtime_check.Unsigned] indicates to the
@@ -2043,30 +2044,17 @@ class Annotated:
       where T1, T2 etc. are TypeVars, which would be invalid, because
       only one type should be passed to Annotated.
     """
-
-    __slots__ = ()
-
-    def __new__(cls, *args, **kwargs):
-        raise TypeError("Type Annotated cannot be instantiated.")
-
-    @_tp_cache
-    def __class_getitem__(cls, params):
-        if not isinstance(params, tuple) or len(params) < 2:
-            raise TypeError("Annotated[...] should be used "
-                            "with at least two arguments (a type and an "
-                            "annotation).")
-        if _is_unpacked_typevartuple(params[0]):
-            raise TypeError("Annotated[...] should not be used with an "
-                            "unpacked TypeVarTuple")
-        msg = "Annotated[t, ...]: t must be a type."
-        origin = _type_check(params[0], msg, allow_special_forms=True)
-        metadata = tuple(params[1:])
-        return _AnnotatedAlias(origin, metadata)
-
-    def __init_subclass__(cls, *args, **kwargs):
-        raise TypeError(
-            "Cannot subclass {}.Annotated".format(cls.__module__)
-        )
+    if not isinstance(params, tuple) or len(params) < 2:
+        raise TypeError("Annotated[...] should be used "
+                        "with at least two arguments (a type and an "
+                        "annotation).")
+    if _is_unpacked_typevartuple(params[0]):
+        raise TypeError("Annotated[...] should not be used with an "
+                        "unpacked TypeVarTuple")
+    msg = "Annotated[t, ...]: t must be a type."
+    origin = _type_check(params[0], msg, allow_special_forms=True)
+    metadata = tuple(params[1:])
+    return _AnnotatedAlias(origin, metadata)
 
 
 def runtime_checkable(cls):
diff --git a/Misc/NEWS.d/next/Library/2023-06-08-15-56-45.gh-issue-105509.YIG57j.rst b/Misc/NEWS.d/next/Library/2023-06-08-15-56-45.gh-issue-105509.YIG57j.rst
new file mode 100644
index 00000000000000..61c74fa8493ce0
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-08-15-56-45.gh-issue-105509.YIG57j.rst
@@ -0,0 +1,3 @@
+``typing.Annotated`` is now implemented as an instance of
+``typing._SpecialForm`` rather than a class. This should have no user-facing
+impact for users of the :mod:`typing` module public API.


Code review comments:
diff_hunk: @@ -0,0 +1,3 @@
+``typing.Annotated`` is now implemented as an instance of
path: Misc/NEWS.d/next/Library/2023-06-08-15-56-45.gh-issue-105509.YIG57j.rst
text: @user1:
```suggestion
:data:`typing.Annotated` is now implemented as an instance of
```