Skip to content

Commit

Permalink
PEP 655: Clarify there are no grammar changes or runtime enforcement. (
Browse files Browse the repository at this point in the history
…#2388)

Co-authored-by: CAM Gerlach <CAM.Gerlach@Gerlach.CAM>
  • Loading branch information
davidfstr and CAM-Gerlach committed Mar 9, 2022
1 parent 78e67c8 commit 20f7ce8
Showing 1 changed file with 27 additions and 18 deletions.
45 changes: 27 additions & 18 deletions pep-0655.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
==========
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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.

Expand All @@ -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]_
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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
Expand All @@ -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”
Expand Down

0 comments on commit 20f7ce8

Please sign in to comment.