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
fromcollections.abcimportSequenceclassFoo: ...
defconcat[L: Foo, R: Foo](
left: L|Sequence[L],
right: R|Sequence[R], /
) ->list[L|R]:
matchleft, right:
caseFoo(), Foo():
returnlist( (left, right) ) # ❌caseFoo(), [*rvalues]:
returnlist( (left, *rvalues) ) # ❌case [*lvalues], Foo():
returnlist( (*lvalues, right) ) # ❌case [*lvalues], [*rvalues]:
returnlist( (*lvalues, *rvalues) )
case _:
raiseTypeErrordefconcat2[L: Foo, R: Foo](
left: L|Sequence[L],
right: R|Sequence[R], /
) ->list[L|R]:
ifisinstance(left, Foo) andisinstance(right, Foo):
returnlist( (left, right) ) # ❌elifisinstance(left, Foo) andisinstance(right, Sequence):
returnlist( (left, *right) ) # ❌elifisinstance(left, Sequence) andisinstance(right, Foo):
returnlist( (*left, right) ) # ❌elifisinstance(left, Sequence) andisinstance(right, Sequence):
returnlist( (*left, *right) )
else:
raiseTypeError
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.
Trying to narrow
T | Sequence[T]withisinstanceclauses leads to type errors. I believe this has to do with the example below actually wantingT | (Sequence[T] & ¬T).So in the first clause, I guess
mypythinks this could be eitherL & Foo = FooorSequence[L] & Foo, which is not necessarily an instance ofL. (so maybe not a bug but nevertheless a serious divergence between type checkers).To Reproduce
Expected Behavior
This code passes without issues in
pyright-playgroundandty-playgroundActual Behavior
mypy-playgroundemits 6 errorsAt the very least, the error messages are misleading, since the problematic bit are the arguments to
SeqFoo, not totuple.