Skip to content

Commit 20f7ce8

Browse files
PEP 655: Clarify there are no grammar changes or runtime enforcement. (#2388)
Co-authored-by: CAM Gerlach <CAM.Gerlach@Gerlach.CAM>
1 parent 78e67c8 commit 20f7ce8

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

pep-0655.rst

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ Post-History: 31-Jan-2021, 11-Feb-2021, 20-Feb-2021, 26-Feb-2021, 17-Jan-2022, 2
1414
Abstract
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
2323
TypedDict to mark them as required, and
24-
``NotRequired[]`` which can be used on individual items
24+
``NotRequired[]``, which can be used on individual items
2525
to 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

2833
Motivation
2934
==========
@@ -73,7 +78,7 @@ not support inheritance:
7378
Rationale
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
7883
customary in other languages like TypeScript:
7984

@@ -133,6 +138,7 @@ potentially-missing key:
133138

134139
It is an error to use ``Required[]`` or ``NotRequired[]`` in any
135140
location that is not an item of a TypedDict.
141+
Type checkers must enforce this restriction.
136142

137143
It is valid to use ``Required[]`` and ``NotRequired[]`` even for
138144
items 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

156165
The :pep:`alternative functional syntax <589#alternative-syntax>`
157166
for TypedDict also supports
@@ -291,7 +300,7 @@ required, define a ``total=False`` TypedDict
291300
and mark those few keys that are required with ``Required[]``.
292301

293302
If 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[]``
297306
within 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
401410
believed that marking TypedDict items as required or potentially-missing
402411
would 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
411420
on where it is positioned, which is inconsistent and confusing.
412421

413422
Also, “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
442451
grammar.
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
451460
typing world: covariant, contravariant, and invariant:
452461

@@ -578,7 +587,7 @@ Difficult to implement
578587
''''''''''''''''''''''
579588

580589
Eric 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
582591
difficult. [2]_
583592

584593
Introduces a second null-like value into Python
@@ -596,8 +605,8 @@ distinguishing between its analogous constants ``null`` and
596605
Replace 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

603612
Change Optional to mean “optional item” in certain contexts instead of “nullable”

0 commit comments

Comments
 (0)