GenericAlias does not support union type expressions #86399
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
assignee = None closed_at = <Date 2020-11-09.04:11:33.989> created_at = <Date 2020-11-01.15:32:10.464> labels = ['interpreter-core', '3.10'] title = 'GenericAlias does not support union type expressions' updated_at = <Date 2021-11-21.10:53:44.595> user = 'https://github.com/Fidget-Spinner'
activity = <Date 2021-11-21.10:53:44.595> actor = 'nemeskeyd' assignee = 'none' closed = True closed_date = <Date 2020-11-09.04:11:33.989> closer = 'kj' components = ['Interpreter Core'] creation = <Date 2020-11-01.15:32:10.464> creator = 'kj' dependencies =  files =  hgrepos =  issue_num = 42233 keywords = ['patch'] message_count = 9.0 messages = ['380145', '380147', '380150', '380157', '380512', '380571', '406576', '406589', '406709'] nosy_count = 6.0 nosy_names = ['gvanrossum', 'serhiy.storchaka', 'nemeskeyd', 'levkivskyi', 'miss-islington', 'kj'] pr_nums = ['23077', '23081', '23082'] priority = 'normal' resolution = 'fixed' stage = 'resolved' status = 'closed' superseder = None type = None url = 'https://bugs.python.org/issue42233' versions = ['Python 3.10']
The text was updated successfully, but these errors were encountered:
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"
# purely rich compare
# check for GenericAlias and rich compare only for that
@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.