This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: GenericAlias does not support union type expressions
Type: Stage: resolved
Components: Interpreter Core Versions: Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: gvanrossum, kj, levkivskyi, miss-islington, nemeskeyd, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2020-11-01 15:32 by kj, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 23077 merged kj, 2020-11-01 15:38
PR 23081 merged kj, 2020-11-01 17:36
PR 23082 merged miss-islington, 2020-11-01 18:14
Messages (9)
msg380145 - (view) Author: Ken Jin (kj) * (Python committer) Date: 2020-11-01 15:32
Union type expressions added in PEP 604 throw an error when both operands are GenericAlias objects.

Eg the following works::

int | list[str]

The following throws TypeError::

list[int] | dict[float, str]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'types.GenericAlias' and 'types.GenericAlias'

I have submitted a PR to fix this. Coincidentally, it also fixes the fact that union expressions weren't de-duplicating GenericAlias properly.

Eg::
>>> list[int] | int | list[int]
list[int] | int | list[int]

For non-GenericAlias type expressions, the new code shouldn't be much slower. Rich compare is only used for GenericAlias objects. This isn't very scientific, but 

python -m timeit "int | str | float"

# original
1000000 loops, best of 5: 295 nsec per loop

# purely rich compare
1000000 loops, best of 5: 344 nsec per loop

# check  for GenericAlias and rich compare only for that
1000000 loops, best of 5: 297 nsec per loop
msg380147 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-11-01 15:39
There is also a problem with typing module.

>>> typing.List[int] | dict[float, str]
typing.Union[typing.List[int], dict]
msg380150 - (view) Author: Ken Jin (kj) * (Python committer) Date: 2020-11-01 16:00
@Serhiy, wow interesting find, it seems to be typing's repr problem rather than the actual types itself:

>>> typing.Union[dict[int, str], list[str]]
typing.Union[dict, list]

>>> typing.Union[dict[int, str], list[str]].__args__
(dict[int, str], list[str])

The __args__ seem to be correct, so I'm guessing the typing repr went wrong somewhere. That should be the case for your example too:

>>> alias = typing.List[int] | dict[float, str]
>>> alias
typing.Union[typing.List[int], dict]

>>> type(alias)
<class 'typing._UnionGenericAlias'>

>>> alias.__args__
(typing.List[int], dict[float, str])

I'll work on this. If I don't reply back in a week, someone else is free to take over this issue.
msg380157 - (view) Author: miss-islington (miss-islington) Date: 2020-11-01 18:13
New changeset 1f7dfb277e5b88cddc13e5024766be787a3e9127 by kj in branch 'master':
bpo-42233: Correctly repr GenericAlias when used with typing module (GH-23081)
https://github.com/python/cpython/commit/1f7dfb277e5b88cddc13e5024766be787a3e9127
msg380512 - (view) Author: miss-islington (miss-islington) Date: 2020-11-07 16:46
New changeset e81e09bfc8a29a44a649a962870a26fe0c097cfa by Miss Islington (bot) in branch '3.9':
bpo-42233: Correctly repr GenericAlias when used with typing module (GH-23081)
https://github.com/python/cpython/commit/e81e09bfc8a29a44a649a962870a26fe0c097cfa
msg380571 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2020-11-09 04:00
New changeset 4eb41d055e8307b8206f680287e492a6db068acd by kj in branch 'master':
bpo-42233: Add union type expression support for GenericAlias and fix de-duplicating of GenericAlias (GH-23077)
https://github.com/python/cpython/commit/4eb41d055e8307b8206f680287e492a6db068acd
msg406576 - (view) Author: Dávid Nemeskey (nemeskeyd) Date: 2021-11-19 10:24
Guys, any chance the fix will land in 3.9? It is affected as well.
msg406589 - (view) Author: Ken Jin (kj) * (Python committer) Date: 2021-11-19 14:35
@Dávid

No it won't land in 3.9. Union type expressions (PEP 604) were only officially added in 3.10. We don't backport new features, only bugfixes. Sorry!
msg406709 - (view) Author: Dávid Nemeskey (nemeskeyd) Date: 2021-11-21 10:53
@kj Sorry, for some reason, I thought the that issue affected Union as well, but I have just re-tested it and found that it works.
History
Date User Action Args
2022-04-11 14:59:37adminsetgithub: 86399
2021-11-21 10:53:44nemeskeydsetmessages: + msg406709
2021-11-19 14:35:18kjsetmessages: + msg406589
2021-11-19 10:24:28nemeskeydsetnosy: + nemeskeyd
messages: + msg406576
2020-11-09 04:11:33kjsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2020-11-09 04:00:40gvanrossumsetmessages: + msg380571
2020-11-07 16:46:16miss-islingtonsetmessages: + msg380512
2020-11-01 18:14:14miss-islingtonsetpull_requests: + pull_request22000
2020-11-01 18:13:47miss-islingtonsetnosy: + miss-islington
messages: + msg380157
2020-11-01 17:36:52kjsetpull_requests: + pull_request21999
2020-11-01 16:00:44kjsetmessages: + msg380150
2020-11-01 15:39:31serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg380147
2020-11-01 15:38:11kjsetkeywords: + patch
stage: patch review
pull_requests: + pull_request21997
2020-11-01 15:32:10kjcreate