-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
Docs of typing.get_args
: Mention that due to caching of typing generics the order of arguments for Unions can be different from the one of the returned tuple
#86483
Comments
Due to caching of >>> from typing import List, Union, get_args
>>> get_args(get_args(List[Union[int, str]])[0])
(<class 'int'>, <class 'str'>)
>>> get_args(get_args(List[Union[str, int]])[0])
(<class 'int'>, <class 'str'>) This is because I understand that caching is useful to reduce the memory footprint of type hints, so I suggest to update the documentation of
This seems to imply that the returned objects are identical to the ones in the form >>> U1 = Union[int, str]
>>> U2 = Union[str, int]
>>> get_args(List[U1])[0] is U1
True
>>> get_args(List[U2])[0] is U2
False I'm not so much concerned about the identity, but the fact that a subsequent call to So I propose to add the following sentence to the
Or alternatively:
The second version is shorter but it's not completely accurate (since the order is actually not arbitrary). |
You're right, currently this happens for 2 reasons:
I find it mildly sad however that: >>> get_args(Union[int, str])
[int, str]
>>> get_args(Union[str, int])
[str, int] Which is slightly inconsistent with its behavior when nested in List. I don't think there's an easy way to fix this without breaking the cache (and also it makes sense that Unions' args aren't order dependent). So I'm all for updating the docs with your addition (slightly edited):
|
Agreed it's mildly sad, and I wish the cache could preserve the order in List[Union[int, str]], but for that to work we'd have to change how the cache works, which feels complex, or we'd have to chance things so that Union[int, str] != Union[str, int], which seems wrong as well (and we've had them equal for many releases so this would break code). Fixing the cache would require adding a new comparison method to all generic type objects, and that just doesn't seem worth the effort (but I'd be open to this solution in the future). So for now, let's document that get_args() may swap Union arguments. |
Dominik, would you like to submit a PR for this :) ? |
Thinking more about it, I came to realize that it's not the Union that sits at the root of this behavior, but rather the caching performed by generic types in general. So if we consider
then So I think it would be more accurate to add the following sentence instead:
Everything else follows from there (including flattening of nested Unions). |
Exactly! |
Thanks! |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: