PEP 655: Clarify there are no grammar changes or runtime enforcement. (#2388)
Co-authored-by: CAM Gerlach <CAM.Gerlach@Gerlach.CAM>
This commit is contained in:
parent
78e67c82b6
commit
20f7ce8aa7
45
pep-0655.rst
45
pep-0655.rst
|
@ -14,16 +14,21 @@ Post-History: 31-Jan-2021, 11-Feb-2021, 20-Feb-2021, 26-Feb-2021, 17-Jan-2022, 2
|
||||||
Abstract
|
Abstract
|
||||||
========
|
========
|
||||||
|
|
||||||
:pep:`589` defines syntax
|
:pep:`589` defines notation
|
||||||
for declaring a TypedDict with all required keys and syntax for defining
|
for declaring a TypedDict with all required keys and notation for defining
|
||||||
a TypedDict with :pep:`all potentially-missing keys <589#totality>` however it
|
a TypedDict with :pep:`all potentially-missing keys <589#totality>`, however it
|
||||||
does not provide any syntax to declare some keys as required and others
|
does not provide a mechanism to declare some keys as required and others
|
||||||
as potentially-missing. This PEP introduces two new syntaxes:
|
as potentially-missing. This PEP introduces two new notations:
|
||||||
``Required[]`` which can be used on individual items of a
|
``Required[]``, which can be used on individual items of a
|
||||||
TypedDict to mark them as required, and
|
TypedDict to mark them as required, and
|
||||||
``NotRequired[]`` which can be used on individual items
|
``NotRequired[]``, which can be used on individual items
|
||||||
to mark them as potentially-missing.
|
to mark them as potentially-missing.
|
||||||
|
|
||||||
|
This PEP makes no Python grammar changes. Correct usage
|
||||||
|
of required and potentially-missing keys of TypedDicts is intended to be
|
||||||
|
enforced only by static type checkers and need not be enforced by
|
||||||
|
Python itself at runtime.
|
||||||
|
|
||||||
|
|
||||||
Motivation
|
Motivation
|
||||||
==========
|
==========
|
||||||
|
@ -73,7 +78,7 @@ not support inheritance:
|
||||||
Rationale
|
Rationale
|
||||||
=========
|
=========
|
||||||
|
|
||||||
One might think it unusual to propose syntax that prioritizes marking
|
One might think it unusual to propose notation that prioritizes marking
|
||||||
*required* keys rather than *potentially-missing* keys, as is
|
*required* keys rather than *potentially-missing* keys, as is
|
||||||
customary in other languages like TypeScript:
|
customary in other languages like TypeScript:
|
||||||
|
|
||||||
|
@ -133,6 +138,7 @@ potentially-missing key:
|
||||||
|
|
||||||
It is an error to use ``Required[]`` or ``NotRequired[]`` in any
|
It is an error to use ``Required[]`` or ``NotRequired[]`` in any
|
||||||
location that is not an item of a TypedDict.
|
location that is not an item of a TypedDict.
|
||||||
|
Type checkers must enforce this restriction.
|
||||||
|
|
||||||
It is valid to use ``Required[]`` and ``NotRequired[]`` even for
|
It is valid to use ``Required[]`` and ``NotRequired[]`` even for
|
||||||
items where it is redundant, to enable additional explicitness if desired:
|
items where it is redundant, to enable additional explicitness if desired:
|
||||||
|
@ -152,6 +158,9 @@ same time:
|
||||||
title: str
|
title: str
|
||||||
year: NotRequired[Required[int]] # ERROR
|
year: NotRequired[Required[int]] # ERROR
|
||||||
|
|
||||||
|
Type checkers must enforce this restriction.
|
||||||
|
The runtime implementations of ``Required[]`` and ``NotRequired[]``
|
||||||
|
may also enforce this restriction.
|
||||||
|
|
||||||
The :pep:`alternative functional syntax <589#alternative-syntax>`
|
The :pep:`alternative functional syntax <589#alternative-syntax>`
|
||||||
for TypedDict also supports
|
for TypedDict also supports
|
||||||
|
@ -291,7 +300,7 @@ required, define a ``total=False`` TypedDict
|
||||||
and mark those few keys that are required with ``Required[]``.
|
and mark those few keys that are required with ``Required[]``.
|
||||||
|
|
||||||
If some items accept ``None`` in addition to a regular value, it is
|
If some items accept ``None`` in addition to a regular value, it is
|
||||||
recommended that the ``TYPE|None`` syntax be preferred over
|
recommended that the ``TYPE|None`` notation be preferred over
|
||||||
``Optional[TYPE]`` for marking such item values, to avoid using
|
``Optional[TYPE]`` for marking such item values, to avoid using
|
||||||
``Required[]`` or ``NotRequired[]`` alongside ``Optional[]``
|
``Required[]`` or ``NotRequired[]`` alongside ``Optional[]``
|
||||||
within the same TypedDict definition:
|
within the same TypedDict definition:
|
||||||
|
@ -397,7 +406,7 @@ Special syntax around the *key* of a TypedDict item
|
||||||
opt1?: str # may not exist, but if exists, value is string
|
opt1?: str # may not exist, but if exists, value is string
|
||||||
opt2: Optional[str] # always exists, but may have None value
|
opt2: Optional[str] # always exists, but may have None value
|
||||||
|
|
||||||
This syntax would require Python grammar changes and it is not
|
This notation would require Python grammar changes and it is not
|
||||||
believed that marking TypedDict items as required or potentially-missing
|
believed that marking TypedDict items as required or potentially-missing
|
||||||
would meet the high bar required to make such grammar changes.
|
would meet the high bar required to make such grammar changes.
|
||||||
|
|
||||||
|
@ -407,7 +416,7 @@ would meet the high bar required to make such grammar changes.
|
||||||
Optional[opt1]: str # may not exist, but if exists, value is string
|
Optional[opt1]: str # may not exist, but if exists, value is string
|
||||||
opt2: Optional[str] # always exists, but may have None value
|
opt2: Optional[str] # always exists, but may have None value
|
||||||
|
|
||||||
This syntax causes ``Optional[]`` to take on different meanings depending
|
This notation causes ``Optional[]`` to take on different meanings depending
|
||||||
on where it is positioned, which is inconsistent and confusing.
|
on where it is positioned, which is inconsistent and confusing.
|
||||||
|
|
||||||
Also, “let’s just not put funny syntax before the colon.” [1]_
|
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__``,
|
||||||
``__neg__`` and ``__invert__`` special methods without modifying the
|
``__neg__`` and ``__invert__`` special methods without modifying the
|
||||||
grammar.
|
grammar.
|
||||||
|
|
||||||
It was decided that it would be prudent to introduce longform syntax
|
It was decided that it would be prudent to introduce long-form notation
|
||||||
(i.e. ``Required[]`` and ``NotRequired[]``) before introducing
|
(i.e. ``Required[]`` and ``NotRequired[]``) before introducing
|
||||||
any shortform syntax. Future PEPs may reconsider introducing this
|
any short-form notation. Future PEPs may reconsider introducing this
|
||||||
or other shortform syntax options.
|
or other short-form notation options.
|
||||||
|
|
||||||
Note when reconsidering introducing this shortform syntax that
|
Note when reconsidering introducing this short-form notation that
|
||||||
``+``, ``-``, and ``~`` already have existing meanings in the Python
|
``+``, ``-``, and ``~`` already have existing meanings in the Python
|
||||||
typing world: covariant, contravariant, and invariant:
|
typing world: covariant, contravariant, and invariant:
|
||||||
|
|
||||||
|
@ -578,7 +587,7 @@ Difficult to implement
|
||||||
''''''''''''''''''''''
|
''''''''''''''''''''''
|
||||||
|
|
||||||
Eric Traut from the Pyright type checker team has stated that
|
Eric Traut from the Pyright type checker team has stated that
|
||||||
implementing a ``Union[..., Missing]``-style syntax would be
|
implementing a ``Union[..., Missing]``-style notation would be
|
||||||
difficult. [2]_
|
difficult. [2]_
|
||||||
|
|
||||||
Introduces a second null-like value into Python
|
Introduces a second null-like value into Python
|
||||||
|
@ -596,8 +605,8 @@ distinguishing between its analogous constants ``null`` and
|
||||||
Replace Optional with Nullable. Repurpose Optional to mean “optional item”.
|
Replace Optional with Nullable. Repurpose Optional to mean “optional item”.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
``Optional[]`` is too ubiquitous to deprecate. Although use of it
|
``Optional[]`` is too ubiquitous to deprecate, although use of it
|
||||||
*may* fade over time in favor of the ``T|None`` syntax specified by :pep:`604`.
|
*may* fade over time in favor of the ``T|None`` notation specified by :pep:`604`.
|
||||||
|
|
||||||
|
|
||||||
Change Optional to mean “optional item” in certain contexts instead of “nullable”
|
Change Optional to mean “optional item” in certain contexts instead of “nullable”
|
||||||
|
|
Loading…
Reference in New Issue