-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed as duplicate of#15151
Labels
bugmypy got something wrongmypy got something wrong
Description
Trying to narrow T | Sequence[T] with isinstance clauses leads to type errors. I believe this has to do with the example below actually wanting T | (Sequence[T] & ¬T).
So in the first clause, I guess mypy thinks this could be either L & Foo = Foo or Sequence[L] & Foo, which is not necessarily an instance of L. (so maybe not a bug but nevertheless a serious divergence between type checkers).
To Reproduce
from collections.abc import Sequence
class Foo: ...
def concat[L: Foo, R: Foo](
left: L | Sequence[L],
right: R | Sequence[R], /
) -> list[L | R]:
match left, right:
case Foo(), Foo():
return list( (left, right) ) # ❌
case Foo(), [*rvalues]:
return list( (left, *rvalues) ) # ❌
case [*lvalues], Foo():
return list( (*lvalues, right) ) # ❌
case [*lvalues], [*rvalues]:
return list( (*lvalues, *rvalues) )
case _:
raise TypeError
def concat2[L: Foo, R: Foo](
left: L | Sequence[L],
right: R | Sequence[R], /
) -> list[L | R]:
if isinstance(left, Foo) and isinstance(right, Foo):
return list( (left, right) ) # ❌
elif isinstance(left, Foo) and isinstance(right, Sequence):
return list( (left, *right) ) # ❌
elif isinstance(left, Sequence) and isinstance(right, Foo):
return list( (*left, right) ) # ❌
elif isinstance(left, Sequence) and isinstance(right, Sequence):
return list( (*left, *right) )
else:
raise TypeErrorExpected Behavior
This code passes without issues in pyright-playground and ty-playground
Actual Behavior
mypy-playground emits 6 errors
main.py:14: error: Argument 1 to "SeqFoo" has incompatible type "tuple[Foo, Foo]"; expected "Iterable[L | R]" [arg-type]
main.py:16: error: Argument 1 to <tuple> has incompatible type "Foo"; expected "L | R" [arg-type]
main.py:18: error: Argument 2 to <tuple> has incompatible type "Foo"; expected "L | R" [arg-type]
main.py:29: error: Argument 1 to "SeqFoo" has incompatible type "tuple[Foo, Foo]"; expected "Iterable[L | R]" [arg-type]
main.py:31: error: Argument 1 to <tuple> has incompatible type "Foo"; expected "L | R" [arg-type]
main.py:33: error: Argument 2 to <tuple> has incompatible type "Foo"; expected "L | R" [arg-type]
Found 6 errors in 1 file (checked 1 source file)
At the very least, the error messages are misleading, since the problematic bit are the arguments to SeqFoo, not to tuple.
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrong