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

get_origin gives inconsistent results for differently defined Unions #104

Open
bernt-matthias opened this issue Jun 8, 2023 · 3 comments
Labels

Comments

@bernt-matthias
Copy link

If I got it right, Union[X, Y] should be equivalent to X | Y . But I get inconsistent results for get_origin:

import typing
from types import UnionType

import typing_inspect

optional = typing.Optional[int]
union = typing.Union[int, None]
pipe = int | None 

print(typing_inspect.get_origin(optional)) # typing.Union
print(typing_inspect.get_origin(union)) # typing.Union
print(typing_inspect.get_origin(pipe)) # None

Note that also the python std lib behaves inconsistent wrt this:

import typing
from types import UnionType


# also behaves odd for python stdlib functions

print(typing.get_origin(union), typing.get_args(union))
print(typing.get_origin(optional), typing.get_args(optional))
print(typing.get_origin(pipe), typing.get_args(pipe))

assert typing.get_origin(union) is typing.Union
assert typing.get_origin(optional) is typing.Union
assert typing.get_origin(pipe) is not typing.Union

assert typing.get_origin(union) is not UnionType
assert typing.get_origin(optional) is not UnionType
assert typing.get_origin(pipe) is UnionType

I would expect that the behavior is equivalent, but I'm pretty new to the typing world. In the end I' looking for a way to check if something is a union and var is Union or var is UnionType does not seem right...

@ilevkivskyi
Copy link
Owner

Yes, I think it is a bug. We support X | Y syntax in is_union_type(). I am not sure what the value get_origin() should return (probably we should match typing behavior), but definitely not None.

@ilevkivskyi ilevkivskyi added the bug label Jun 8, 2023
@bernt-matthias
Copy link
Author

We support X | Y syntax in is_union_type()

Thanks for the tip. I guess this will work for me.

I am not sure what the value get_origin() should return

From the docs: Union type; Union[X, Y] is equivalent to X | Y .. so they should behave the same, or?

probably we should match typing behavior

Also a good idea. But maybe (just maybe) upstream is wrong :)

@JelleZijlstra
Copy link

In Python 3.13 we may well merge types.UnionType and typing.Union: python/cpython#105499. But in earlier Python versions we're not going to change the upstream behavior.

I would recommend typing-inspect to match the behavior of typing.get_origin, so get_origin(int | str) is types.UnionType and get_origin(Union[int, str]) is typing.Union.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants