Open tusharsadhwani opened 2 years ago
Related to (but maybe not quite a duplicate of) #9718.
It's a superset of #9718. I'll be looking into implementing this then, starting with the literal narrowing case.
A superset of https://github.com/python/mypy/issues/9718, and a subset of #10977 :)
This issue seems to address narrowing both for in
but also for ==
. Should these two features be tracked independently (if their implementations would be rather decoupled) or is tracking them together preferred (if implementing one would likely solve the other)?
I couldn't find an issue specifically for narrowing literals in ==
equality comparisons, and I would have expected this to be implemented first, because it even feels more basic than the in
operator:
from typing import Literal
def takes_foo(s: Literal["foo"]) -> None:
...
def f(s: str) -> None:
if s == "foo":
takes_foo(s)
error: Argument 1 to "takes_foo" has incompatible type "str"; expected "Literal['foo']" [arg-type]
Pyright seems to understand this kind of narrowing well.
I opted for a clunky workaround using TypeIs
though it would be nice if this were automatic
MyLiteral = Literal["a", "b"]
def is_my_literal(s: str) -> TypeIs[MyLiteral]:
return s in ("a", "b")
This is similar to #3229 though that one doesn't ask for narrowing to Literal, possibly because the issue predates literal types.
Take this example code:
The current output of this is:
If mypy were to support type narrowing using chained
or
statements andin
statements, the output would look like:I think doing simple narrowing here would be relatively easy and very useful.