Skip to content

Commit 8e1dd55

Browse files
bpo-41428: Documentation for PEP 604 (pythongh-22517)
1 parent 40db798 commit 8e1dd55

File tree

6 files changed

+156
-0
lines changed

6 files changed

+156
-0
lines changed

Doc/library/stdtypes.rst

+122
Original file line numberDiff line numberDiff line change
@@ -4743,6 +4743,128 @@ define these methods must provide them as a normal Python accessible method.
47434743
Compared to the overhead of setting up the runtime context, the overhead of a
47444744
single class dictionary lookup is negligible.
47454745

4746+
.. _types-union:
4747+
4748+
Union Type
4749+
==========
4750+
4751+
.. index::
4752+
object: Union
4753+
pair: union; type
4754+
4755+
A union object holds the value of the ``|`` (bitwise or) operation on
4756+
multiple :ref:`type objects<bltin-type-objects>`. These types are intended
4757+
primarily for type annotations. The union type expression enables cleaner
4758+
type hinting syntax compared to :data:`typing.Union`.
4759+
4760+
.. describe:: X | Y | ...
4761+
4762+
Defines a union object which holds types *X*, *Y*, and so forth. ``X | Y``
4763+
means either X or Y. It is equivalent to ``typing.Union[X, Y]``.
4764+
Example::
4765+
4766+
def square(number: int | float) -> int | float:
4767+
return number ** 2
4768+
4769+
.. describe:: union_object == other
4770+
4771+
Union objects can be tested for equality with other union objects. Details:
4772+
4773+
* Unions of unions are flattened, e.g.::
4774+
4775+
(int | str) | float == int | str | float
4776+
4777+
* Redundant types are removed, e.g.::
4778+
4779+
int | str | int == int | str
4780+
4781+
* When comparing unions, the order is ignored, e.g.::
4782+
4783+
int | str == str | int
4784+
4785+
* It is compatible with :data:`typing.Union`::
4786+
4787+
int | str == typing.Union[int, str]
4788+
4789+
* Optional types can be spelled as a union with ``None``::
4790+
4791+
str | None == typing.Optional[str]
4792+
4793+
.. describe:: isinstance(obj, union_object)
4794+
4795+
Calls to :func:`isinstance` are also supported with a Union object::
4796+
4797+
>>> isinstance("", int | str)
4798+
True
4799+
4800+
..
4801+
At the time of writing this, there is no documentation for parameterized
4802+
generics or PEP 585. Thus the link currently points to PEP 585 itself.
4803+
Please change the link for parameterized generics to reference the correct
4804+
documentation once documentation for PEP 585 becomes available.
4805+
4806+
However, union objects containing `parameterized generics
4807+
<https://www.python.org/dev/peps/pep-0585/>`_ cannot be used::
4808+
4809+
>>> isinstance(1, int | list[int])
4810+
Traceback (most recent call last):
4811+
File "<stdin>", line 1, in <module>
4812+
TypeError: isinstance() argument 2 cannot contain a parameterized generic
4813+
4814+
.. describe:: issubclass(obj, union_object)
4815+
4816+
Calls to :func:`issubclass` are also supported with a Union Object.::
4817+
4818+
>>> issubclass(bool, int | str)
4819+
True
4820+
4821+
..
4822+
Once again, please change the link below for parameterized generics to
4823+
reference the correct documentation once documentation for PEP 585
4824+
becomes available.
4825+
4826+
However, union objects containing `parameterized generics
4827+
<https://www.python.org/dev/peps/pep-0585/>`_ cannot be used::
4828+
4829+
>>> issubclass(bool, bool | list[str])
4830+
Traceback (most recent call last):
4831+
File "<stdin>", line 1, in <module>
4832+
TypeError: issubclass() argument 2 cannot contain a parameterized generic
4833+
4834+
The type for the Union object is :data:`types.Union`. An object cannot be
4835+
instantiated from the type::
4836+
4837+
>>> import types
4838+
>>> isinstance(int | str, types.Union)
4839+
True
4840+
>>> types.Union()
4841+
Traceback (most recent call last):
4842+
File "<stdin>", line 1, in <module>
4843+
TypeError: cannot create 'types.Union' instances
4844+
4845+
.. note::
4846+
The :meth:`__or__` method for type objects was added to support the syntax
4847+
``X | Y``. If a metaclass implements :meth:`__or__`, the Union may
4848+
override it::
4849+
4850+
>>> class M(type):
4851+
... def __or__(self, other):
4852+
... return "Hello"
4853+
...
4854+
>>> class C(metaclass=M):
4855+
... pass
4856+
...
4857+
>>> C | int
4858+
'Hello'
4859+
>>> int | C
4860+
int | __main__.C
4861+
4862+
.. seealso::
4863+
4864+
:pep:`604` -- PEP proposing the ``X | Y`` syntax and the Union type.
4865+
4866+
.. versionadded:: 3.10
4867+
47464868

47474869
.. _typesother:
47484870

Doc/library/types.rst

+5
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ Standard names are defined for the following types:
256256

257257
.. versionadded:: 3.10
258258

259+
.. data:: Union
260+
261+
The type of :ref:`union type expressions<types-union>`.
262+
263+
.. versionadded:: 3.10
259264

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

Doc/library/typing.rst

+4
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ These can be used as types in annotations using ``[]``, each having a unique syn
544544
.. versionchanged:: 3.7
545545
Don't remove explicit subclasses from unions at runtime.
546546

547+
.. versionchanged:: 3.10
548+
Unions can now be written as ``X | Y``. See
549+
:ref:`union type expressions<types-union>`.
550+
547551
.. data:: Optional
548552

549553
Optional type.

Doc/whatsnew/3.10.rst

+23
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,29 @@ New Features
8282
* :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used
8383
to require that all the iterables have an equal length.
8484

85+
PEP604: New Type Operator
86+
-------------------------
87+
88+
A new type union operator was introduced which enables the syntax ``X | Y``.
89+
This provides a cleaner way of expressing 'either type X or type Y' instead of
90+
using :data:`typing.Union`, especially in type hints (annotations).
91+
92+
In previous versions of Python, to apply a type hint for functions accepting
93+
arguments of multiple types, :data:`typing.Union` was used::
94+
95+
def square(number: Union[int, float]) -> Union[int, float]:
96+
return number ** 2
97+
98+
99+
Now, type hints can be written in a more succinct manner::
100+
101+
def square(number: int | float) -> int | float:
102+
return number ** 2
103+
104+
105+
See :pep:`604` for more details.
106+
107+
(Contributed by Maggie Moss and Philippe Prados in :issue:`41428`.)
85108

86109
Other Language Changes
87110
======================

Misc/ACKS

+1
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ Grant Olson
12571257
Furkan Onder
12581258
Koray Oner
12591259
Ethan Onstott
1260+
Ken Jin Ooi
12601261
Piet van Oostrum
12611262
Tomas Oppelstrup
12621263
Jason Orendorff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add documentation for :pep:`604` (Allow writing union types as ``X | Y``).

0 commit comments

Comments
 (0)