From bf624a5c0a56e309486b8ae544d48a2a0dce0519 Mon Sep 17 00:00:00 2001
From: Viicos <65306057+Viicos@users.noreply.github.com>
Date: Wed, 23 Apr 2025 22:37:29 +0200
Subject: [PATCH 1/2] PEP 764: Second round of updates

---
 peps/pep-0764.rst | 112 +++++++++++++++++++++-------------------------
 1 file changed, 50 insertions(+), 62 deletions(-)

diff --git a/peps/pep-0764.rst b/peps/pep-0764.rst
index e6be0fc1efc..40a0ea63a03 100644
--- a/peps/pep-0764.rst
+++ b/peps/pep-0764.rst
@@ -1,5 +1,5 @@
 PEP: 764
-Title: Inlined typed dictionaries
+Title: Inline typed dictionaries
 Author: Victorien Plot <contact@vctrn.dev>
 Sponsor: Eric Traut <erictr at microsoft.com>
 Discussions-To: https://discuss.python.org/t/78779
@@ -20,7 +20,7 @@ typed dictionaries. In both scenarios, it requires defining a class or
 assigning to a value. In some situations, this can add unnecessary
 boilerplate, especially if the typed dictionary is only used once.
 
-This PEP proposes the addition of a new inlined syntax, by subscripting the
+This PEP proposes the addition of a new inline syntax, by subscripting the
 :class:`~typing.TypedDict` type::
 
     from typing import TypedDict
@@ -69,17 +69,17 @@ Taking a simple function returning some nested structured data as an example::
 Rationale
 =========
 
-The new inlined syntax can be used to resolve these problems::
+The new inline syntax can be used to resolve these problems::
 
     def get_movie() -> TypedDict[{'name': str, 'year': int, 'production': TypedDict[{'name': str, 'location': str}]}]:
         ...
 
 While less useful (as the functional or even the class-based syntax can be
-used), inlined typed dictionaries can be assigned to a variable, as an alias::
+used), inline type dictionaries can be assigned to a variable, as an alias::
 
-    InlinedTD = TypedDict[{'name': str}]
+    InlineTD = TypedDict[{'name': str}]
 
-    def get_movie() -> InlinedTD:
+    def get_movie() -> InlineTD:
         ...
 
 
@@ -96,11 +96,11 @@ comma-separated list of ``key: value`` pairs within braces constructor
 argument (i.e. it is not allowed to use a variable which was previously
 assigned a :class:`dict` instance).
 
-Inlined typed dictionaries can be referred to as *anonymous*, meaning they
+Inline typed dictionaries can be referred to as *anonymous*, meaning they
 don't have a specific name (see the `runtime behavior <Runtime behavior>`_
 section).
 
-It is possible to define a nested inlined dictionary::
+It is possible to define a nested inline dictionary::
 
     Movie = TypedDict[{'name': str, 'production': TypedDict[{'location': str}]}]
 
@@ -112,16 +112,16 @@ any :term:`typing:type qualifier` can be used for individual fields::
 
     Movie = TypedDict[{'name': NotRequired[str], 'year': ReadOnly[int]}]
 
-Inlined typed dictionaries are implicitly *total*, meaning all keys must be
+Inline typed dictionaries are implicitly *total*, meaning all keys must be
 present. Using the :data:`~typing.Required` type qualifier is thus redundant.
 
-Type variables are allowed in inlined typed dictionaries, provided that they
+Type variables are allowed in inline typed dictionaries, provided that they
 are bound to some outer scope::
 
     class C[T]:
-        inlined_td: TypedDict[{'name': T}]  # OK, `T` is scoped to the class `C`.
+        inline_td: TypedDict[{'name': T}]  # OK, `T` is scoped to the class `C`.
 
-    reveal_type(C[int]().inlined_td['name'])  # Revealed type is 'int'
+    reveal_type(C[int]().inline_td['name'])  # Revealed type is 'int'
 
 
     def fn[T](arg: T) -> TypedDict[{'name': T}]: ...  # OK: `T` is scoped to the function `fn`.
@@ -129,27 +129,34 @@ are bound to some outer scope::
     reveal_type(fn('a')['name'])  # Revealed type is 'str'
 
 
-    type InlinedTD[T] = TypedDict[{'name': T}]  # OK, `T` is scoped to the type alias.
+    type InlineTD[T] = TypedDict[{'name': T}]  # OK, `T` is scoped to the type alias.
 
 
     T = TypeVar('T')
 
-    InlinedTD = TypedDict[{'name': T}]  # OK, same as the previous type alias, but using the old-style syntax.
+    InlineTD = TypedDict[{'name': T}]  # OK, same as the previous type alias, but using the old-style syntax.
 
 
     def func():
-        InlinedTD = TypedDict[{'name': T}]  # Not OK: `T` refers to a type variable that is not bound to the scope of `func`.
+        InlineTD = TypedDict[{'name': T}]  # Not OK: `T` refers to a type variable that is not bound to the scope of `func`.
 
 
+Inline typed dictionaries can be extended::
+
+    InlineTD = TypedDict[{'a': int}]
+
+    class SubTD(InlineTD):
+        pass
+
 Typing specification changes
 ----------------------------
 
-The inlined typed dictionary adds a new kind of
+The inline typed dictionary adds a new kind of
 :term:`typing:type expression`. As such, the
 :external+typing:token:`~expression-grammar:type_expression` production will
-be updated to include the inlined syntax:
+be updated to include the inline syntax:
 
-.. productionlist:: inlined-typed-dictionaries-grammar
+.. productionlist:: inline-typed-dictionaries-grammar
     new-type_expression: `~expression-grammar:type_expression`
                        : | <TypedDict> '[' '{' (string: ':' `~expression-grammar:annotation_expression` ',')* '}' ']'
                        :       (where string is any string literal)
@@ -157,11 +164,7 @@ be updated to include the inlined syntax:
 Runtime behavior
 ----------------
 
-Although :class:`~typing.TypedDict` is commonly referred as a class, it is
-implemented as a function at runtime. To be made subscriptable, it will be
-changed to be a class.
-
-Creating an inlined typed dictionary results in a new class, so ``T1`` and
+Creating an inline typed dictionary results in a new class, so ``T1`` and
 ``T2`` are of the same type::
 
     from typing import TypedDict
@@ -169,8 +172,15 @@ Creating an inlined typed dictionary results in a new class, so ``T1`` and
     T1 = TypedDict('T1', {'a': int})
     T2 = TypedDict[{'a': int}]
 
-As inlined typed dictionaries are are meant to be *anonymous*, their
-:attr:`~type.__name__` attribute will be set to an empty string.
+As inline typed dictionaries are meant to be *anonymous*, their
+:attr:`~type.__name__` attribute will be set to the ``<inline TypedDict>``
+string literal. In the future, an explicit class attribute could be added
+to make them distinguishable from named classes.
+
+Although :class:`~typing.TypedDict` is documented as a class, the way it is
+defined is an implementation detail. The implementation will have to be tweaked
+so that :class:`~typing.TypedDict` can be made subscriptable.
+
 
 Backwards Compatibility
 =======================
@@ -187,12 +197,12 @@ There are no known security consequences arising from this PEP.
 How to Teach This
 =================
 
-The new inlined syntax will be documented both in the :mod:`typing` module
+The new inline syntax will be documented both in the :mod:`typing` module
 documentation and the :ref:`typing specification <typing:typed-dictionaries>`.
 
 When complex dictionary structures are used, having everything defined on a
 single line can hurt readability. Code formatters can help by formatting the
-inlined typed dictionary across multiple lines::
+inline type dictionary across multiple lines::
 
     def edit_movie(
         movie: TypedDict[{
@@ -214,6 +224,8 @@ Mypy supports a similar syntax as an :option:`experimental feature <mypy:mypy.--
     def test_values() -> {"int": int, "str": str}:
         return {"int": 42, "str": "test"}
 
+Support for this PEP is added in `this pull request <https://github.com/python/mypy/pull/18889>`_.
+
 Pyright added support for the new syntax in version `1.1.387`_.
 
 .. _1.1.387: https://github.com/microsoft/pyright/releases/tag/1.1.387
@@ -221,7 +233,9 @@ Pyright added support for the new syntax in version `1.1.387`_.
 Runtime implementation
 ----------------------
 
-A draft implementation is available `here <https://github.com/Viicos/cpython/commit/49e5a83f>`_.
+The necessary changes were first implemented in
+`typing_extensions <https://typing-extensions.readthedocs.io/en/latest/>`_
+in `this pull request <https://github.com/python/typing_extensions/pull/580>`_.
 
 
 Rejected Ideas
@@ -256,7 +270,7 @@ While this would avoid having to import :class:`~typing.TypedDict` from
   parametrization overloads. On the other hand, :class:`~typing.TypedDict` is
   already a :term:`special form <typing:special form>`.
 
-* If future work extends what inlined typed dictionaries can do, we don't have
+* If future work extends what inline typed dictionaries can do, we don't have
   to worry about impact of sharing the symbol with :class:`dict`.
 
 * :class:`typing.Dict` has been deprecated (although not planned for removal)
@@ -288,13 +302,13 @@ Extending other typed dictionaries
 Several syntaxes could be used to have the ability to extend other typed
 dictionaries::
 
-    InlinedBase = TypedDict[{'a': int}]
+    InlineBase = TypedDict[{'a': int}]
 
-    Inlined = TypedDict[InlinedBase, {'b': int}]
+    Inline = TypedDict[InlineBase, {'b': int}]
     # or, by providing a slice:
-    Inlined = TypedDict[{'b': int} : (InlinedBase,)]
+    Inline = TypedDict[{'b': int} : (InlineBase,)]
 
-As inlined typed dictionaries are meant to only support a subset of the
+As inline typed dictionaries are meant to only support a subset of the
 existing syntax, adding this extension mechanism isn't compelling
 enough to be supported, considering the added complexity.
 
@@ -305,37 +319,11 @@ use case.
 Open Issues
 ===========
 
-Should inlined typed dictionaries be proper classes?
-----------------------------------------------------
-
-The PEP currently defines inlined typed dictionaries as type objects, to be in
-line with the existing syntaxes. To work around the fact that they don't have
-a name, their :attr:`~type.__name__` attribute is set to an empty string.
-
-This is somewhat arbitrary, and an alternative name could be used as well
-(e.g. ``'<TypedDict>'``).
-
-Alternatively, inlined typed dictionaries could be defined as instances of a
-new (internal) typing class, e.g. :class:`!typing._InlinedTypedDict`. While
-this solves the naming issue, it requires extra logic in the runtime
-implementation to provide the introspection attributes (such as
-:attr:`~typing.TypedDict.__total__`), and tools relying on runtime
-introspection would have to add proper support for this new type.
-
-Depending on the outcome of the runtime implementation, we can more or less
-easily allow extending inlined typed dictionaries::
-
-    InlinedTD = TypedDict[{'a': int}]
-
-    # If `InlinedTD` is a typing._InlinedTypedDict instance, this adds complexity:
-    class SubTD(InlinedTD):
-        pass
-
-Inlined typed dictionaries and extra items
-------------------------------------------
+Inline typed dictionaries and extra items
+-----------------------------------------
 
 :pep:`728` introduces the concept of :ref:`closed <typed-dict-closed>` type
-dictionaries. If this PEP were to be accepted, inlined typed dictionaries
+dictionaries. If this PEP were to be accepted, inline typed dictionaries
 will be *closed* by default. This means :pep:`728` needs to be addressed
 first, so that this PEP can be updated accordingly.
 

From ea418fdcb6e65a002f8872be38e7a23bf048eabb Mon Sep 17 00:00:00 2001
From: Viicos <65306057+Viicos@users.noreply.github.com>
Date: Thu, 24 Apr 2025 10:56:47 +0200
Subject: [PATCH 2/2] Feedback

---
 peps/pep-0764.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/peps/pep-0764.rst b/peps/pep-0764.rst
index 40a0ea63a03..55d93e06a13 100644
--- a/peps/pep-0764.rst
+++ b/peps/pep-0764.rst
@@ -75,7 +75,7 @@ The new inline syntax can be used to resolve these problems::
         ...
 
 While less useful (as the functional or even the class-based syntax can be
-used), inline type dictionaries can be assigned to a variable, as an alias::
+used), inline typed dictionaries can be assigned to a variable, as an alias::
 
     InlineTD = TypedDict[{'name': str}]
 
@@ -224,7 +224,7 @@ Mypy supports a similar syntax as an :option:`experimental feature <mypy:mypy.--
     def test_values() -> {"int": int, "str": str}:
         return {"int": 42, "str": "test"}
 
-Support for this PEP is added in `this pull request <https://github.com/python/mypy/pull/18889>`_.
+Support for this PEP is added in `this pull request <https://github.com/python/mypy/pull/18889>`__.
 
 Pyright added support for the new syntax in version `1.1.387`_.
 
@@ -235,7 +235,7 @@ Runtime implementation
 
 The necessary changes were first implemented in
 `typing_extensions <https://typing-extensions.readthedocs.io/en/latest/>`_
-in `this pull request <https://github.com/python/typing_extensions/pull/580>`_.
+in `this pull request <https://github.com/python/typing_extensions/pull/580>`__.
 
 
 Rejected Ideas