[issue44653] Parameter substitution in the union type does not work with typing.Union

Serhiy Storchaka report at bugs.python.org
Mon Jul 19 14:15:58 EDT 2021


Serhiy Storchaka <storchaka+cpython at gmail.com> added the comment:

There is also problem with other typing types:

>>> (int | T)[typing.List]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Each union argument must be a type, got typing.List
>>> (int | T)[typing.List[int]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Each union argument must be a type, got typing.List[int]
>>> (int | T)[typing.Hashable]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Each union argument must be a type, got typing.Hashable
>>> (int | T)[typing.Callable[[int], str]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Each union argument must be a type, got typing.Callable[[int], str]
>>> (int | T)[typing.ParamSpec('P')]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Each union argument must be a type, got ~P

Despite the fact that they support the | operator.

We can add one by one special support of different types supporting the | operator (ParamSpec, _GenericAlias, _CallableGenericAlias, _UnionGenericAlias, _LiteralGenericAlias, _ConcatenateGenericAlias, _AnnotatedAlias, _SpecialGenericAlias, _CallableType, _TupleType), but it is cumbersome and errorprone. We will need to synchronize code of unionobject.c with typing every time we add new kind of types.

PR 27247 uses more general approach. It calls the | operator for arguments after substitution. So all types which support the | operator are now automatically supported. But the result of parameter substitution can now be typing.Union instead of types.Union.

>>> import typing
>>> import collections.abc
>>> T = typing.TypeVar('T')
>>> (int | T)[list]
int | list
>>> (int | T)[typing.List]
typing.Union[int, typing.List]
>>> (int | T)[list[int]]
int | list[int]
>>> (int | T)[typing.List[int]]
typing.Union[int, typing.List[int]]
>>> (int | T)[collections.abc.Hashable]
int | collections.abc.Hashable
>>> (int | T)[typing.Hashable]
typing.Union[int, typing.Hashable]
>>> (int | T)[collections.abc.Sequence[int]]
int | collections.abc.Sequence[int]
>>> (int | T)[typing.Sequence[int]]
typing.Union[int, typing.Sequence[int]]
>>> (int | T)[collections.abc.Callable[[int], str]]
int | collections.abc.Callable[[int], str]
>>> (int | T)[typing.Callable[[int], str]]
typing.Union[int, typing.Callable[[int], str]]
>>> (int | T)[typing.TypeVar('S')]
int | ~S
>>> (int | T)[typing.ParamSpec('P')]
typing.Union[int, ~P]
>>> (int | T)[str | list]
int | str | list
>>> (int | T)[typing.Union[str, list]]
typing.Union[int, str, list]

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue44653>
_______________________________________


More information about the Python-bugs-list mailing list