Skip to content

bpo-41428: Documentation for PEP 604 #22517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
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
122 changes: 122 additions & 0 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4743,6 +4743,128 @@ define these methods must provide them as a normal Python accessible method.
Compared to the overhead of setting up the runtime context, the overhead of a
single class dictionary lookup is negligible.

.. _types-union:

Union Type
==========

.. index::
object: Union
pair: union; type

A union object holds the value of the ``|`` (bitwise or) operation on
multiple :ref:`type objects<bltin-type-objects>`. These types are intended
primarily for type annotations. The union type expression enables cleaner
type hinting syntax compared to :data:`typing.Union`.

.. describe:: X | Y | ...

Defines a union object which holds types *X*, *Y*, and so forth. ``X | Y``
means either X or Y. It is equivalent to ``typing.Union[X, Y]``.
Example::

def square(number: int | float) -> int | float:
return number ** 2

.. describe:: union_object == other

Union objects can be tested for equality with other union objects. Details:

* Unions of unions are flattened, e.g.::

(int | str) | float == int | str | float

* Redundant types are removed, e.g.::

int | str | int == int | str

* When comparing unions, the order is ignored, e.g.::

int | str == str | int

* It is compatible with :data:`typing.Union`::

int | str == typing.Union[int, str]

* Optional types can be spelled as a union with ``None``::

str | None == typing.Optional[str]

.. describe:: isinstance(obj, union_object)

Calls to :func:`isinstance` are also supported with a Union object::

>>> isinstance("", int | str)
True

..
At the time of writing this, there is no documentation for parameterized
generics or PEP 585. Thus the link currently points to PEP 585 itself.
Please change the link for parameterized generics to reference the correct
documentation once documentation for PEP 585 becomes available.

However, union objects containing `parameterized generics
<https://www.python.org/dev/peps/pep-0585/>`_ cannot be used::

>>> isinstance(1, int | list[int])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: isinstance() argument 2 cannot contain a parameterized generic

.. describe:: issubclass(obj, union_object)

Calls to :func:`issubclass` are also supported with a Union Object.::

>>> issubclass(bool, int | str)
True

..
Once again, please change the link below for parameterized generics to
reference the correct documentation once documentation for PEP 585
becomes available.

However, union objects containing `parameterized generics
<https://www.python.org/dev/peps/pep-0585/>`_ cannot be used::

>>> issubclass(bool, bool | list[str])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: issubclass() argument 2 cannot contain a parameterized generic

The type for the Union object is :data:`types.Union`. An object cannot be
instantiated from the type::

>>> import types
>>> isinstance(int | str, types.Union)
True
>>> types.Union()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create 'types.Union' instances

.. note::
The :meth:`__or__` method for type objects was added to support the syntax
``X | Y``. If a metaclass implements :meth:`__or__`, the Union may
override it::

>>> class M(type):
... def __or__(self, other):
... return "Hello"
...
>>> class C(metaclass=M):
... pass
...
>>> C | int
'Hello'
>>> int | C
int | __main__.C

.. seealso::

:pep:`604` -- PEP proposing the ``X | Y`` syntax and the Union type.

.. versionadded:: 3.10


.. _typesother:

Expand Down
5 changes: 5 additions & 0 deletions Doc/library/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ Standard names are defined for the following types:

.. versionadded:: 3.10

.. data:: Union

The type of :ref:`union type expressions<types-union>`.

.. versionadded:: 3.10

.. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)

Expand Down
4 changes: 4 additions & 0 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,10 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. versionchanged:: 3.7
Don't remove explicit subclasses from unions at runtime.

.. versionchanged:: 3.10
Unions can now be written as ``X | Y``. See
:ref:`union type expressions<types-union>`.

.. data:: Optional

Optional type.
Expand Down
23 changes: 23 additions & 0 deletions Doc/whatsnew/3.10.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,29 @@ New Features
* :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used
to require that all the iterables have an equal length.

PEP604: New Type Operator
-------------------------

A new type union operator was introduced which enables the syntax ``X | Y``.
This provides a cleaner way of expressing 'either type X or type Y' instead of
using :data:`typing.Union`, especially in type hints (annotations).

In previous versions of Python, to apply a type hint for functions accepting
arguments of multiple types, :data:`typing.Union` was used::

def square(number: Union[int, float]) -> Union[int, float]:
return number ** 2


Now, type hints can be written in a more succinct manner::

def square(number: int | float) -> int | float:
return number ** 2


See :pep:`604` for more details.

(Contributed by Maggie Moss and Philippe Prados in :issue:`41428`.)

Other Language Changes
======================
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@ Grant Olson
Furkan Onder
Koray Oner
Ethan Onstott
Ken Jin Ooi
Piet van Oostrum
Tomas Oppelstrup
Jason Orendorff
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add documentation for :pep:`604` (Allow writing union types as ``X | Y``).