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
|
||||
========
|
||||
|
||||
:pep:`589` defines syntax
|
||||
for declaring a TypedDict with all required keys and syntax for defining
|
||||
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
|
||||
as potentially-missing. This PEP introduces two new syntaxes:
|
||||
``Required[]`` which can be used on individual items of a
|
||||
:pep:`589` defines notation
|
||||
for declaring a TypedDict with all required keys and notation for defining
|
||||
a TypedDict with :pep:`all potentially-missing keys <589#totality>`, however it
|
||||
does not provide a mechanism to declare some keys as required and others
|
||||
as potentially-missing. This PEP introduces two new notations:
|
||||
``Required[]``, which can be used on individual items of a
|
||||
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.
|
||||
|
||||
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
|
||||
==========
|
||||
|
@ -73,7 +78,7 @@ not support inheritance:
|
|||
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
|
||||
customary in other languages like TypeScript:
|
||||
|
||||
|
@ -133,6 +138,7 @@ potentially-missing key:
|
|||
|
||||
It is an error to use ``Required[]`` or ``NotRequired[]`` in any
|
||||
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
|
||||
items where it is redundant, to enable additional explicitness if desired:
|
||||
|
@ -152,6 +158,9 @@ same time:
|
|||
title: str
|
||||
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>`
|
||||
for TypedDict also supports
|
||||
|
@ -291,7 +300,7 @@ required, define a ``total=False`` TypedDict
|
|||
and mark those few keys that are required with ``Required[]``.
|
||||
|
||||
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
|
||||
``Required[]`` or ``NotRequired[]`` alongside ``Optional[]``
|
||||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
any shortform syntax. Future PEPs may reconsider introducing this
|
||||
or other shortform syntax options.
|
||||
any short-form notation. Future PEPs may reconsider introducing this
|
||||
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
|
||||
typing world: covariant, contravariant, and invariant:
|
||||
|
||||
|
@ -578,7 +587,7 @@ Difficult to implement
|
|||
''''''''''''''''''''''
|
||||
|
||||
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]_
|
||||
|
||||
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”.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
``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`.
|
||||
``Optional[]`` is too ubiquitous to deprecate, although use of it
|
||||
*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”
|
||||
|
|
Loading…
Reference in New Issue