-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
bpo-44957: Promote PEP 604 syntax in typing docs #27833
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -321,11 +321,11 @@ not generic but implicitly inherits from ``Iterable[Any]``:: | |
User defined generic type aliases are also supported. Examples:: | ||
|
||
from collections.abc import Iterable | ||
from typing import TypeVar, Union | ||
from typing import TypeVar | ||
S = TypeVar('S') | ||
Response = Union[Iterable[S], int] | ||
Response = Iterable[S] | int | ||
|
||
# Return type here is same as Union[Iterable[str], int] | ||
# Return type here is same as Iterable[str] | int | ||
def response(query: str) -> Response[str]: | ||
... | ||
|
||
|
@@ -588,9 +588,9 @@ These can be used as types in annotations using ``[]``, each having a unique syn | |
|
||
.. data:: Union | ||
|
||
Union type; ``Union[X, Y]`` means either X or Y. | ||
Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y. | ||
|
||
To define a union, use e.g. ``Union[int, str]``. Details: | ||
To define a union, use e.g. ``Union[int, str]`` or the shorthand ``int | str``. Details: | ||
|
||
* The arguments must be types and there must be at least one. | ||
|
||
|
@@ -604,18 +604,16 @@ These can be used as types in annotations using ``[]``, each having a unique syn | |
|
||
* Redundant arguments are skipped, e.g.:: | ||
|
||
Union[int, str, int] == Union[int, str] | ||
Union[int, str, int] == Union[int, str] == int | str | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a critique and slightly off topic: this threw me off a little bit, because in earlier versions of 3.10 this was false because they are different types at runtime. Only since rc1 this is true. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting, I didn't know that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the misinformation, but I was wrong 😉 . I think my memory is getting hazy, it was |
||
|
||
* When comparing unions, the argument order is ignored, e.g.:: | ||
|
||
Union[int, str] == Union[str, int] | ||
|
||
* You cannot subclass or instantiate a union. | ||
* You cannot subclass or instantiate a ``Union``. | ||
|
||
* You cannot write ``Union[X][Y]``. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I just noticed this and maybe this can be another PR (since it needs to be backported to 3.9) but isn't this inaccurate if X is a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least the sentence doesn't sound super relevant to me. All examples show how to use |
||
|
||
* You can use ``Optional[X]`` as a shorthand for ``Union[X, None]``. | ||
|
||
.. versionchanged:: 3.7 | ||
Don't remove explicit subclasses from unions at runtime. | ||
|
||
|
@@ -627,7 +625,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn | |
|
||
Optional type. | ||
|
||
``Optional[X]`` is equivalent to ``Union[X, None]``. | ||
``Optional[X]`` is equivalent to ``X | None`` (or ``Union[X, None]``). | ||
|
||
Note that this is not the same concept as an optional argument, | ||
which is one that has a default. An optional argument with a | ||
|
@@ -644,6 +642,10 @@ These can be used as types in annotations using ``[]``, each having a unique syn | |
def foo(arg: Optional[int] = None) -> None: | ||
... | ||
|
||
.. versionchanged:: 3.10 | ||
Optional can now be written as ``X | None``. See | ||
:ref:`union type expressions<types-union>`. | ||
|
||
.. data:: Callable | ||
|
||
Callable type; ``Callable[[int], str]`` is a function of (int) -> str. | ||
|
@@ -770,7 +772,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn | |
:ref:`type variables <generics>`, and unions of any of these types. | ||
For example:: | ||
|
||
def new_non_team_user(user_class: Type[Union[BasicUser, ProUser]]): ... | ||
def new_non_team_user(user_class: Type[BasicUser | ProUser]): ... | ||
|
||
``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent | ||
to ``type``, which is the root of Python's metaclass hierarchy. | ||
|
@@ -951,7 +953,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn | |
conditional code flow and applying the narrowing to a block of code. The | ||
conditional expression here is sometimes referred to as a "type guard":: | ||
|
||
def is_str(val: Union[str, float]): | ||
def is_str(val: str | float): | ||
# "isinstance" type guard | ||
if isinstance(val, str): | ||
# Type of ``val`` is narrowed to ``str`` | ||
|
@@ -2024,7 +2026,7 @@ Introspection helpers | |
For a typing object of the form ``X[Y, Z, ...]`` these functions return | ||
``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or | ||
:mod:`collections` class, it gets normalized to the original class. | ||
If ``X`` is a :class:`Union` or :class:`Literal` contained in another | ||
If ``X`` is a union or :class:`Literal` contained in another | ||
generic type, the order of ``(Y, Z, ...)`` may be different from the order | ||
of the original arguments ``[Y, Z, ...]`` due to type caching. | ||
For unsupported objects return ``None`` and ``()`` correspondingly. | ||
|
@@ -2049,7 +2051,7 @@ Introspection helpers | |
year: int | ||
|
||
is_typeddict(Film) # => True | ||
is_typeddict(Union[list, str]) # => False | ||
is_typeddict(list | str) # => False | ||
|
||
.. versionadded:: 3.10 | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Promote PEP 604 union syntax by using it where possible. Also, mention ``X | | ||
Y`` more prominently in section about ``Union`` and mention ``X | None`` at | ||
all in section about ``Optional``. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why did you change the
redundant arguments are skipped
bullet point, but not the others? I can see thatUnions of a single argument vanish
may not apply directly to the new syntax, but the others do right?If we manage to merge them, then perhaps we can shorten the contents of the
union_object == other
section here https://docs.python.org/3.10/library/stdtypes.html#types-union and just link to the typing version. That will save us from some repetition.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went a bit back and forth over this. In the end I decided that most of them apply mostly to
Union
:(X | Y) | Z
. So we could write one of the following:Union[Union[int, str], float] == Union[int, str, float] == int | str | float
Union[Union[int, str], float] == int | str | float
I kind of like the second one, since it emphasizes the new syntax, but I thought it might be a bit confusing.
Union[int, str, int] == Union[int, str]
andint | str | int == int | str
or only the latter (my preference). No idea why I chose this strange middle thing.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You points make sense. I would like to not outright replace the examples under
typing.Union
with only the PEP 604 version. For the same reason that we haven't changed examples undertyping.List
[1] to PEP 585 stylelist
and instead just changed every other use oftyping.List
elsewhere (same for every other PEP 585-ied type really). Considering at runtime they aren't the same, I'd hate if beginners tripped over some runtime corner case thinking they were. (e.g.isinstance(1, int | str)
works,isinstance(1, Union[int, str])
fails before 3.10)This is one tough pickle :(. So I'm OK with the status quo.
[1] https://docs.python.org/3.11/library/typing.html#typing.List