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

Support both new and old style Union/Optional #687

Merged
merged 3 commits into from
Feb 24, 2023

Conversation

gvangool
Copy link
Contributor

The Python 3.10+ syntax of creating a union or optional type (with str | int), results in a different type than using the pre-Python 3.10 syntax (Union[str, int]).

>>> from typing import Optional, Union, get_origin
>>> get_origin(Union[int, str])
typing.Union
>>> get_origin(int | str)
<class 'types.UnionType'>
>>> get_origin(Optional[int])
typing.Union
>>> get_origin(int | None)
<class 'types.UnionType'>

I'm curious about how to update the test so that it works on both Python 3.9 and Python 3.10.
If you can point me in the right direction, I'll gladly update it.

This would fix #685.

The Python 3.10+ syntax of creating a union or optional type
(with `str | int`), results in a differnt type than using the pre-Python
3.10 syntax (`Union[str, int]`).

```pycon
>>> from typing import Optional, Union, get_origin
>>> get_origin(Union[int, str])
typing.Union
>>> get_origin(int | str)
<class 'types.UnionType'>
>>> get_origin(Optional[int])
typing.Union
>>> get_origin(int | None)
<class 'types.UnionType'>
```
@OtherBarry
Copy link
Contributor

@gvangool you should be able to only run the test if the version is 3.10+ using pytest skipif (docs).

You can then get a union value using eval:

example_union = eval("str | int")

Or define a function with union types using exec:

exec("""def example_func(something: int | str) -> int | str:\n    return something""")

These should both stop earlier python versions from complaining about the | operator. There might be a cleaner way to do it, but it's a difficult problem to google.

@vitalik
Copy link
Owner

vitalik commented Feb 23, 2023

Hi @gvangool
thank you for contribution, would you be able to add tests for this ?

@gvangool
Copy link
Contributor Author

@OtherBarry thanks for that pointer!
I realized after pushing that version that we can also use strings there.
So this version works on Python 3.10 and throws errors on 3.9:

TypeError: unsupported operand type(s) for |: 'ResolverMetaclass' and 'ResolverMetaclass'

@OtherBarry
Copy link
Contributor

@gvangool @vitalik might need to look into using some pragma: no cover comments in this PR.

I tried bumping the coverage CI job python version to 3.10, but naturally it just fails on the other side of the try-except.

vitalik added a commit that referenced this pull request Feb 24, 2023
vitalik added a commit that referenced this pull request Feb 24, 2023
@vitalik vitalik merged commit f015a7f into vitalik:master Feb 24, 2023
vitalik added a commit that referenced this pull request Feb 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Python 3.10: union compatibility (for payload)
3 participants