gh-130117: Document why nested Union, Literal, and Annotated types referenced through a type alias are not flattened (#130119)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
Valentin Berlier 2025-05-06 04:05:16 +02:00 committed by GitHub
parent 529012e26f
commit b936ccdb6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1098,6 +1098,12 @@ These can be used as types in annotations. They all support subscription using
Union[Union[int, str], float] == Union[int, str, float]
However, this does not apply to unions referenced through a type
alias, to avoid forcing evaluation of the underlying :class:`TypeAliasType`::
type A = Union[int, str]
Union[A, float] != Union[int, str, float]
* Unions of a single argument vanish, e.g.::
Union[int] == int # The constructor actually returns int
@ -1230,6 +1236,32 @@ These can be used as types in annotations. They all support subscription using
is allowed as type argument to ``Literal[...]``, but type checkers may
impose restrictions. See :pep:`586` for more details about literal types.
Additional details:
* The arguments must be literal values and there must be at least one.
* Nested ``Literal`` types are flattened, e.g.::
assert Literal[Literal[1, 2], 3] == Literal[1, 2, 3]
However, this does not apply to ``Literal`` types referenced through a type
alias, to avoid forcing evaluation of the underlying :class:`TypeAliasType`::
type A = Literal[1, 2]
assert Literal[A, 3] != Literal[1, 2, 3]
* Redundant arguments are skipped, e.g.::
assert Literal[1, 2, 1] == Literal[1, 2]
* When comparing literals, the argument order is ignored, e.g.::
assert Literal[1, 2] == Literal[2, 1]
* You cannot subclass or instantiate a ``Literal``.
* You cannot write ``Literal[X][Y]``.
.. versionadded:: 3.8
.. versionchanged:: 3.9.1
@ -1400,6 +1432,14 @@ These can be used as types in annotations. They all support subscription using
int, ValueRange(3, 10), ctype("char")
]
However, this does not apply to ``Annotated`` types referenced through a type
alias, to avoid forcing evaluation of the underlying :class:`TypeAliasType`::
type From3To10[T] = Annotated[T, ValueRange(3, 10)]
assert Annotated[From3To10[int], ctype("char")] != Annotated[
int, ValueRange(3, 10), ctype("char")
]
Duplicated metadata elements are not removed::
assert Annotated[int, ValueRange(3, 10)] != Annotated[