@@ -585,8 +585,34 @@ arguments of this type when constructed by calling the class object::
585585 year=2007,
586586 ) # Not OK. Extra items not allowed
587587
588- Interaction with Mapping[KT, VT]
589- --------------------------------
588+ Supported and Unsupported Operations
589+ ------------------------------------
590+
591+ This statement from the `typing spec
592+ <https://typing.python.org/en/latest/spec/typeddict.html#supported-and-unsupported-operations> `__
593+ still holds true.
594+
595+ Operations with arbitrary str keys (instead of string literals or other
596+ expressions with known string values) should generally be rejected.
597+
598+ This means that indexed accesses and assignments with arbitrary keys can still
599+ be rejected even when ``extra_items `` is specified.
600+
601+ Operations that already apply to ``NotRequired `` items should generally also
602+ apply to extra items, following the same rationale from the `typing spec
603+ <https://typing.python.org/en/latest/spec/typeddict.html#supported-and-unsupported-operations> `__
604+ :
605+
606+ The exact type checking rules are up to each type checker to decide. In some
607+ cases potentially unsafe operations may be accepted if the alternative is to
608+ generate false positive errors for idiomatic code.
609+
610+ Some operations are allowed due to the TypedDict being
611+ :term: `typing:assignable ` to ``Mapping[str, VT] `` or ``dict[str, VT] ``.
612+ The two following sections will expand on that.
613+
614+ Interaction with Mapping[str, VT]
615+ ---------------------------------
590616
591617A TypedDict type is :term: `typing:assignable ` to a type of the form ``Mapping[str, VT] ``
592618when all value types of the items in the TypedDict
@@ -618,12 +644,12 @@ and ``items()`` on such TypedDict types::
618644 reveal_type(movie.items()) # Revealed type is 'dict_items[str, str]'
619645 reveal_type(movie.values()) # Revealed type is 'dict_values[str, str]'
620646
621- Interaction with dict[KT , VT]
622- -----------------------------
647+ Interaction with dict[str , VT]
648+ ------------------------------
623649
624650Because the presence of ``extra_items `` on a closed TypedDict type
625651prohibits additional required keys in its :term: `typing:structural `
626- :term: `typing: subtypes <subtype> `, we can determine if the TypedDict type and
652+ :term: `subtypes <subtype> `, we can determine if the TypedDict type and
627653its structural subtypes will ever have any required key during static analysis.
628654
629655The TypedDict type is :term: `typing:assignable ` to ``dict[str, VT] `` if all
@@ -708,8 +734,25 @@ been removed in Python 3.13.
708734Because this is a type-checking feature, it can be made available to older
709735versions as long as the type checker supports it.
710736
711- Open Issues
712- ===========
737+ Rejected Ideas
738+ ==============
739+
740+ Use ``@final `` instead of ``closed `` Class Parameter
741+ -----------------------------------------------------
742+
743+ This was discussed `here <https://github.com/python/mypy/issues/7981 >`__.
744+
745+ Quoting a relevant `comment
746+ <https://github.com/python/mypy/issues/7981#issuecomment-2080161813> `__
747+ from Eric Traut:
748+
749+ The @final class decorator indicates that a class cannot be subclassed. This
750+ makes sense for classes that define nominal types. However, TypedDict is a
751+ structural type, similar to a Protocol. That means two TypedDict classes
752+ with different names but the same field definitions are equivalent types.
753+ Their names and hierarchies don't matter for determining type consistency.
754+ For that reason, @final has no impact on a TypedDict type consistency rules,
755+ nor should it change the behavior of items or values.
713756
714757Use a Special ``__extra_items__ `` Key with the ``closed `` Class Parameter
715758-------------------------------------------------------------------------
@@ -767,9 +810,6 @@ types altogether, but there are some disadvantages. `For example
767810- The types don't appear in an annotation context, so their evaluation will
768811 not be deferred.
769812
770- Rejected Ideas
771- ==============
772-
773813Allowing Extra Items without Specifying the Type
774814------------------------------------------------
775815
@@ -827,19 +867,24 @@ For example:
827867 [index : string ]: number | string
828868 }
829869
830- This is a known limitation discussed in `TypeScript's issue tracker
831- <https://github.com/microsoft/TypeScript/issues/17867> `__,
832- where it is suggested that there should be a way to exclude the defined keys
833- from the index signature so that it is possible to define a type like
834- ``MovieWithExtraNumber ``.
870+ While this restriction allows for sound indexed accesses with arbitrary keys,
871+ it comes with usability limitations discussed in `TypeScript's issue tracker
872+ <https://github.com/microsoft/TypeScript/issues/17867> `__.
873+ A suggestion was to allow excluding the defined keys from the index signature,
874+ to define a type like ``MovieWithExtraNumber ``. This probably involves
875+ subtraction types, which is beyond the scope of this PEP.
835876
836877Reference Implementation
837878========================
838879
839- An earlier revision of proposal is supported in `pyright 1.1.352
840- <https://github.com/microsoft/pyright/releases/tag/1.1.352> `_, and `pyanalyze
880+ This is supported in `pyright 1.1.386
881+ <https://github.com/microsoft/pyright/releases/tag/1.1.386> `_, and an earlier
882+ revision is supported in `pyanalyze
8418830.12.0 <https://github.com/quora/pyanalyze/releases/tag/v0.12.0> `_.
842884
885+ This is also supported in `typing-extensions 4.13.0rc1
886+ <https://pypi.org/project/typing-extensions/4.13.0rc1/> `_.
887+
843888Acknowledgments
844889===============
845890
0 commit comments