Closed as duplicate of#15151
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 TypeError
Expected 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
.