@@ -14,16 +14,21 @@ Post-History: 31-Jan-2021, 11-Feb-2021, 20-Feb-2021, 26-Feb-2021, 17-Jan-2022, 2
1414Abstract
1515========
1616
17- :pep: `589 ` defines syntax
18- for declaring a TypedDict with all required keys and syntax for defining
19- a TypedDict with :pep: `all potentially-missing keys <589#totality >` however it
20- does not provide any syntax to declare some keys as required and others
21- as potentially-missing. This PEP introduces two new syntaxes :
22- ``Required[] `` which can be used on individual items of a
17+ :pep: `589 ` defines notation
18+ for declaring a TypedDict with all required keys and notation for defining
19+ a TypedDict with :pep: `all potentially-missing keys <589#totality >`, however it
20+ does not provide a mechanism to declare some keys as required and others
21+ as potentially-missing. This PEP introduces two new notations :
22+ ``Required[] ``, which can be used on individual items of a
2323TypedDict to mark them as required, and
24- ``NotRequired[] `` which can be used on individual items
24+ ``NotRequired[] ``, which can be used on individual items
2525to mark them as potentially-missing.
2626
27+ This PEP makes no Python grammar changes. Correct usage
28+ of required and potentially-missing keys of TypedDicts is intended to be
29+ enforced only by static type checkers and need not be enforced by
30+ Python itself at runtime.
31+
2732
2833Motivation
2934==========
@@ -73,7 +78,7 @@ not support inheritance:
7378Rationale
7479=========
7580
76- One might think it unusual to propose syntax that prioritizes marking
81+ One might think it unusual to propose notation that prioritizes marking
7782*required * keys rather than *potentially-missing * keys, as is
7883customary in other languages like TypeScript:
7984
@@ -133,6 +138,7 @@ potentially-missing key:
133138
134139It is an error to use ``Required[] `` or ``NotRequired[] `` in any
135140location that is not an item of a TypedDict.
141+ Type checkers must enforce this restriction.
136142
137143It is valid to use ``Required[] `` and ``NotRequired[] `` even for
138144items where it is redundant, to enable additional explicitness if desired:
@@ -152,6 +158,9 @@ same time:
152158 title: str
153159 year: NotRequired[Required[int]] # ERROR
154160
161+ Type checkers must enforce this restriction.
162+ The runtime implementations of ``Required[] `` and ``NotRequired[] ``
163+ may also enforce this restriction.
155164
156165The :pep: `alternative functional syntax <589#alternative-syntax >`
157166for TypedDict also supports
@@ -291,7 +300,7 @@ required, define a ``total=False`` TypedDict
291300and mark those few keys that are required with ``Required[] ``.
292301
293302If some items accept ``None `` in addition to a regular value, it is
294- recommended that the ``TYPE|None `` syntax be preferred over
303+ recommended that the ``TYPE|None `` notation be preferred over
295304``Optional[TYPE] `` for marking such item values, to avoid using
296305``Required[] `` or ``NotRequired[] `` alongside ``Optional[] ``
297306within the same TypedDict definition:
@@ -397,7 +406,7 @@ Special syntax around the *key* of a TypedDict item
397406 opt1?: str # may not exist, but if exists, value is string
398407 opt2: Optional[str] # always exists, but may have None value
399408
400- This syntax would require Python grammar changes and it is not
409+ This notation would require Python grammar changes and it is not
401410believed that marking TypedDict items as required or potentially-missing
402411would meet the high bar required to make such grammar changes.
403412
@@ -407,7 +416,7 @@ would meet the high bar required to make such grammar changes.
407416 Optional[opt1]: str # may not exist, but if exists, value is string
408417 opt2: Optional[str] # always exists, but may have None value
409418
410- This syntax causes ``Optional[] `` to take on different meanings depending
419+ This notation causes ``Optional[] `` to take on different meanings depending
411420on where it is positioned, which is inconsistent and confusing.
412421
413422Also, “let’s just not put funny syntax before the colon.” [1 ]_
@@ -441,12 +450,12 @@ Such operators could be implemented on ``type`` via the ``__pos__``,
441450``__neg__ `` and ``__invert__ `` special methods without modifying the
442451grammar.
443452
444- It was decided that it would be prudent to introduce longform syntax
453+ It was decided that it would be prudent to introduce long-form notation
445454(i.e. ``Required[]`` and ``NotRequired[] ``) before introducing
446- any shortform syntax . Future PEPs may reconsider introducing this
447- or other shortform syntax options.
455+ any short-form notation . Future PEPs may reconsider introducing this
456+ or other short-form notation options.
448457
449- Note when reconsidering introducing this shortform syntax that
458+ Note when reconsidering introducing this short-form notation that
450459``+ ``, ``- ``, and ``~ `` already have existing meanings in the Python
451460typing world: covariant, contravariant, and invariant:
452461
@@ -578,7 +587,7 @@ Difficult to implement
578587''''''''''''''''''''''
579588
580589Eric Traut from the Pyright type checker team has stated that
581- implementing a ``Union[..., Missing] ``-style syntax would be
590+ implementing a ``Union[..., Missing] ``-style notation would be
582591difficult. [2 ]_
583592
584593Introduces a second null-like value into Python
@@ -596,8 +605,8 @@ distinguishing between its analogous constants ``null`` and
596605Replace Optional with Nullable. Repurpose Optional to mean “optional item”.
597606---------------------------------------------------------------------------
598607
599- ``Optional[] `` is too ubiquitous to deprecate. Although use of it
600- *may * fade over time in favor of the ``T|None `` syntax specified by :pep: `604 `.
608+ ``Optional[] `` is too ubiquitous to deprecate, although use of it
609+ *may * fade over time in favor of the ``T|None `` notation specified by :pep: `604 `.
601610
602611
603612Change Optional to mean “optional item” in certain contexts instead of “nullable”
0 commit comments