-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Narrowing unions with in
/__contains__
#8940
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
Comments
I think this seems reasonable to support, but I'm not sure how hard it would be. Perhaps @Michael0x2a has a better idea. |
This shares some aspects with my proposal to make immutable containers work like literal unions: #8689 |
mypy can already narrow unions in this case: def b(a: Union[int, str]): if a == 2: reveal_type(a) # int and it can narrow optionals in this case: def c(d: Optional[int], e: List[int]): if d in e: reveal_type(d) # int This pr allows it to narrow unions in that case: def f(g: Union[int, str, bool], h: List[Union[int, str]]): if g in h: reveal_type(g) # Union[int, str] else: reveal_type(g) # bool This is useful for (in my case) picking structures out of a tagged union. In terms of what still needs to be done - This is my first time contributing to mypy so I'm sure I've missed some edge cases - I'm sure I haven't added quite enough tests - some pointers in that direction would be quite welcome - I would really like this to also work if the collection items are scalar types like List[int] - I'm not sure if that's necessary for this PR though And any and all comments on the details or broad structure of the PR are welcome of course. Closes python#8940
@ethanhs Opened a PR with something that at least begins to implement the issue - interested in your (or @Michael0x2a 's, or really anybody's) thoughts. @antonagestam I think this would be quite similar to your feature request but would at least at the moment require extra annotation in your code, like
which is obviously ugly, but I think the proper solution is probably to have your |
Closing as a duplicate of #3229 |
It seems like you should be able to narrow a union of literals to a subset, or a union of unions of literals to just one of the unions, by checking if a value with such a union is
in
a container of one of the subset/sub unions (see the code example for something hopefully more coherent).This is really useful for, say, a deserialized JSON object that has different subsets of keys that map to differently-shaped objects, and you want to pass them to functions that take the appropriate parameters.
Really could be either - this is behavior I'm surprised by, but it could be not implemented rather than working incorrectly
Playground gist link: https://mypy-play.net/?mypy=latest&python=3.8&gist=18262b0bbd541a22d4f48c5bb628f00e
Code:
Do you see the same issue after installing mypy from Git master?
Happens on 3.7 and 3.8, mypy 0.770 and whatever playground has as "latest"
Defaults
(FYI if you were reading this shortly after I posted it and were annoyed by me editing it a lot - I'm really sorry, I accidentally posted it early and needed to actually fill it out)
The text was updated successfully, but these errors were encountered: