From 8e1dd55e63d18d40e78d941fc9233d2c77bcd3de Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Mon, 5 Oct 2020 12:40:52 +0800 Subject: [PATCH] bpo-41428: Documentation for PEP 604 (gh-22517) --- Doc/library/stdtypes.rst | 122 ++++++++++++++++++ Doc/library/types.rst | 5 + Doc/library/typing.rst | 4 + Doc/whatsnew/3.10.rst | 23 ++++ Misc/ACKS | 1 + .../2020-10-03-18-20-46.bpo-41428._ju1NE.rst | 1 + 6 files changed, 156 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 62f39da2a72..04dfea276d2 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -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`. 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 + `_ cannot be used:: + + >>> isinstance(1, int | list[int]) + Traceback (most recent call last): + File "", line 1, in + 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 + `_ cannot be used:: + + >>> issubclass(bool, bool | list[str]) + Traceback (most recent call last): + File "", line 1, in + 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 "", line 1, in + 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: diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 25fa750f2cc..e4a8dec5cb9 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -256,6 +256,11 @@ Standard names are defined for the following types: .. versionadded:: 3.10 +.. data:: Union + + The type of :ref:`union type expressions`. + + .. versionadded:: 3.10 .. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index f712dfea13f..a72632e61b0 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -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`. + .. data:: Optional Optional type. diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 957a3e791ec..9c3a0287d55 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -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 ====================== diff --git a/Misc/ACKS b/Misc/ACKS index 9be0e777ca2..08449fe0826 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1257,6 +1257,7 @@ Grant Olson Furkan Onder Koray Oner Ethan Onstott +Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup Jason Orendorff diff --git a/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst b/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst new file mode 100644 index 00000000000..2c333934560 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst @@ -0,0 +1 @@ +Add documentation for :pep:`604` (Allow writing union types as ``X | Y``).