Skip to content
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

Inconsistent errors reported for protocol matching #13850

Closed
erictraut opened this issue Oct 9, 2022 · 1 comment
Closed

Inconsistent errors reported for protocol matching #13850

erictraut opened this issue Oct 9, 2022 · 1 comment
Labels
bug mypy got something wrong priority-0-high

Comments

@erictraut
Copy link

I ran into some strange behavior in mypy when investigating a bug reported against pyright.

Here is a sample that demonstrates the issue:

from typing import Generic, Protocol, TypeVar, overload

_T_co = TypeVar("_T_co", covariant=True)

class _NestedSequence(Protocol[_T_co]):
    @overload
    def __getitem__(self, index: int) -> _T_co | "_NestedSequence[_T_co]":
        ...

    @overload
    def __getitem__(self, index: slice) -> "_NestedSequence[_T_co]":
        ...

    # def __contains__(self, __s: object, /) -> bool:
    #     ...

class MySequence(Generic[_T_co]):
    @overload
    def __getitem__(self, index: int) -> _T_co:
        ...

    @overload
    def __getitem__(self, index: slice) -> "MySequence[_T_co]":
        ...

    def __getitem__(self, index: slice | int) -> "MySequence[_T_co]" | _T_co:
        ...

    def __contains__(self, __s: object, /) -> bool:
        ...

class MySequenceCopy(Generic[_T_co]):
    @overload
    def __getitem__(self, index: int) -> _T_co:
        ...

    @overload
    def __getitem__(self, index: slice) -> "MySequenceCopy[_T_co]":
        ...

    def __getitem__(self, index: slice | int) -> "MySequenceCopy[_T_co]" | _T_co:
        ...

    def __contains__(self, __s: object, /) -> bool:
        ...

def func1_1(x: MySequence[int]):
    _: _NestedSequence[int] = x  # (no error)

def func1_1_copy(x: MySequence[int]):
    _: _NestedSequence[int] = x  # error: Incompatible types in assignment

def func1_2(x: MySequence[MySequence[int]]):
    _: _NestedSequence[int] = x  # (no error)

def func2_1(x: MySequenceCopy[int]):
    _: _NestedSequence[int] = x  # error: Incompatible types in assignment

def func2_1_copy(x: MySequenceCopy[int]):
    _: _NestedSequence[int] = x  # error: Incompatible types in assignment

def func2_2(x: MySequenceCopy[MySequenceCopy[int]]):
    _: _NestedSequence[int] = x  # error: Incompatible types in assignment

a: _NestedSequence[int] = [[1, 2, 3]]  # error: List item 0/1/2 has incompatible type "int"; expected "_NestedSequence[int]"

Strange behavior 1: Function func1_1_copy is an exact copy of func1_1, yet mypy reports an error in func1_1_copy but not in func1_1.

Strange behavior 2: The protocol class MySequenceCopy is an exact copy of MySequence, so I would expect them to behave the same from a type checking perspective. func2_2 is a copy of func2_1 with MySequence replaced with MySequenceCopy, so I would expect the two to produce the same type checking results. Mypy emits no error for func1_2 but emits an error for func2_2.

Strange behavior 3: The protocol class _NestedSequence contains a commented-out __contains__ method. If this method is added back, I would expect there to be no change to the type checking results. Yet, when __contains__ is added here, all of the errors previously reported by mypy disappear. This includes the errors in the final line of the sample. I would not expect the addition of __contains__ to have any impact on the results.

I'm not sure if these three issues are related, but I suspect they are.

I'm using the latest published version of mypy (0.982).

@erictraut erictraut added the bug mypy got something wrong label Oct 9, 2022
@hauntsaninja hauntsaninja mentioned this issue Dec 19, 2022
17 tasks
@ilevkivskyi
Copy link
Member

On a recent master I see no errors (with or without the __contains__ in the initial protocol).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-0-high
Projects
None yet
Development

No branches or pull requests

3 participants