Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 57 additions & 4 deletions pep-0655.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Type: Standards Track
Content-Type: text/x-rst
Created: 30-Jan-2021
Python-Version: 3.11
Post-History: 31-Jan-2021, 11-Feb-2021, 20-Feb-2021, 26-Feb-2021, 17-Jan-2022
Post-History: 31-Jan-2021, 11-Feb-2021, 20-Feb-2021, 26-Feb-2021, 17-Jan-2022, 28-Jan-2022


Abstract
Expand Down Expand Up @@ -156,6 +156,11 @@ in any nesting order:
title: str
year: Annotated[NotRequired[int], ValueRange(-9999, 9999)] # ok

In particular allowing ``Annotated[]`` to be the outermost annotation
for an item allows better interoperability with non-typing uses of
annotations, which may always want ``Annotated[]`` as the outermost annotation.
[3]_


Interaction with ``get_type_hints()``
-------------------------------------
Expand Down Expand Up @@ -260,14 +265,61 @@ No:
# ick; avoid using both Optional and NotRequired
owner: NotRequired[Optional[str]]

Usage in Python <3.11
---------------------

If your code supports Python <3.11 and wishes to use ``Required[]`` or
``NotRequired[]`` then it should use ``typing_extensions.TypedDict`` rather
than ``typing.TypedDict`` because the latter will not understand
``(Not)Required[]``. In particular ``__required_keys__`` and
``__optional_keys__`` on the resulting TypedDict type will not be correct:

Yes (Python 3.11+ only):

::

from typing import NotRequired, TypedDict

class Dog(TypedDict):
name: str
owner: NotRequired[str|None]

Yes (Python <3.11 and 3.11+):

::

from __future__ import annotations # for Python 3.7-3.9

from typing_extensions import NotRequired, TypedDict # for Python <3.11 with (Not)Required

class Dog(TypedDict):
name: str
owner: NotRequired[str|None]

No (Python <3.11 and 3.11+):

::

from typing import TypedDict # oops: should import from typing_extensions instead
from typing_extensions import NotRequired

class Movie(TypedDict):
title: str
year: NotRequired[int]

assert Movie.__required_keys__ == frozenset({'title', 'year'}) # yikes
assert Movie.__optional_keys__ == frozenset() # yikes


Reference Implementation
========================

The `mypy <http://www.mypy-lang.org/>`__
`0.930 <https://mypy-lang.blogspot.com/2021/12/mypy-0930-released.html>`__
and `pyright <https://github.com/Microsoft/pyright>`__
`1.1.117 <https://github.com/microsoft/pyright/commit/7ed245b1845173090c6404e49912e8cbfb3417c8>`__
`0.930 <https://mypy-lang.blogspot.com/2021/12/mypy-0930-released.html>`__,
`pyright <https://github.com/Microsoft/pyright>`__
`1.1.117 <https://github.com/microsoft/pyright/commit/7ed245b1845173090c6404e49912e8cbfb3417c8>`__,
and `pyanalyze <https://github.com/quora/pyanalyze>`__
`0.4.0 <https://pyanalyze.readthedocs.io/en/latest/changelog.html#version-0-4-0-november-18-2021>`__
type checkers support ``Required`` and ``NotRequired``.

A reference implementation of the runtime component is provided in the
Expand Down Expand Up @@ -539,6 +591,7 @@ References

.. [2] https://mail.python.org/archives/list/typing-sig@python.org/message/S2VJSVG6WCIWPBZ54BOJPG56KXVSLZK6/

.. [3] https://bugs.python.org/issue46491

Copyright
=========
Expand Down