Skip to content
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

GenericAlias does not support union type expressions #86399

Closed
Fidget-Spinner opened this issue Nov 1, 2020 · 9 comments
Closed

GenericAlias does not support union type expressions #86399

Fidget-Spinner opened this issue Nov 1, 2020 · 9 comments
Labels
3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@Fidget-Spinner
Copy link
Member

BPO 42233
Nosy @gvanrossum, @serhiy-storchaka, @ilevkivskyi, @miss-islington, @Fidget-Spinner
PRs
  • bpo-42233: Add union type expression support for GenericAlias and fix de-duplicating of GenericAlias #23077
  • bpo-42233: Correctly repr GenericAlias when used with typing module #23081
  • [3.9] bpo-42233: Correctly repr GenericAlias when used with typing module (GH-23081) #23082
  • 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

    GitHub fields:

    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'

    bugs.python.org fields:

    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']

    @Fidget-Spinner
    Copy link
    Member Author

    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

    @Fidget-Spinner Fidget-Spinner added 3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Nov 1, 2020
    @serhiy-storchaka
    Copy link
    Member

    There is also a problem with typing module.

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

    @Fidget-Spinner
    Copy link
    Member Author

    @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.

    @miss-islington
    Copy link
    Contributor

    New changeset 1f7dfb2 by kj in branch 'master':
    bpo-42233: Correctly repr GenericAlias when used with typing module (GH-23081)
    1f7dfb2

    @miss-islington
    Copy link
    Contributor

    New changeset e81e09b by Miss Islington (bot) in branch '3.9':
    bpo-42233: Correctly repr GenericAlias when used with typing module (GH-23081)
    e81e09b

    @gvanrossum
    Copy link
    Member

    New changeset 4eb41d0 by kj in branch 'master':
    bpo-42233: Add union type expression support for GenericAlias and fix de-duplicating of GenericAlias (GH-23077)
    4eb41d0

    @nemeskeyd
    Copy link
    Mannequin

    nemeskeyd mannequin commented Nov 19, 2021

    Guys, any chance the fix will land in 3.9? It is affected as well.

    @Fidget-Spinner
    Copy link
    Member Author

    @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!

    @nemeskeyd
    Copy link
    Mannequin

    nemeskeyd mannequin commented Nov 21, 2021

    @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.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs)
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants