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

False positive of protocol conforming when Self is used in a base protocol #4966

Closed
Azureblade3808 opened this issue Apr 18, 2023 · 4 comments
Labels
addressed in next version Issue is fixed and will appear in next published version bug Something isn't working

Comments

@Azureblade3808
Copy link
Contributor

Azureblade3808 commented Apr 18, 2023

Describe the bug
When a protocol is inheriting another protocol, and the base protocol uses Self in some way, conforming to the derived protocol sometimes fails unexpectedly.

To Reproduce
See sample code.

Expected behavior
Both assignments in the last should type-check.

Screenshots or Code

from __future__ import annotations

from typing import Generic, Protocol, TypeVar
from typing_extensions import Self

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

class P0(Protocol[_V_co]):
    def f0(self, /) -> Self: ...
    def f1(self, /) -> _V_co: ...

class P1(P0[_V_co], Protocol[_V_co]):
    pass

class C(Generic[_V_co]):
    def f0(self, /) -> Self:
        raise NotImplementedError
    def f1(self, /) -> _V_co:
        raise NotImplementedError

a: P0[str] = C[str]()  # pass
b: P1[str] = C[str]()  # fail

image

VS Code extension or command-line
Pylance v2023.4.21 Pre-Release

Additional context
If C explicitly inherits P1[_V_co], no error is reported.

Mypy playground: https://mypy-play.net/?mypy=latest&python=3.10&gist=a26280d31899e845ae73aecf9068bafa

EDIT

A derived class is not needed to repro.

@erictraut erictraut added the bug Something isn't working label Apr 18, 2023
@erictraut
Copy link
Collaborator

Thanks for the bug report and great repro steps.

This will be addressed in the next release.

@erictraut erictraut added the addressed in next version Issue is fixed and will appear in next published version label Apr 27, 2023
erictraut pushed a commit that referenced this issue Apr 27, 2023
…ol matching when there are multiple levels of protocol inheritance and a method that uses `Self` in its signature. This addresses #4966.
erictraut pushed a commit that referenced this issue Apr 27, 2023
…ol matching when there are multiple levels of protocol inheritance and a method that uses `Self` in its signature. This addresses #4966.
@erictraut
Copy link
Collaborator

This is addressed in pyright 1.1.306, which I just published. It will also be included in a future release of pylance.

@Azureblade3808
Copy link
Contributor Author

Still works incorrectly over some cases in Pylance v2023.5.11 (Pyright 1.1.306).

from __future__ import annotations

from typing import Protocol, TypeVar
from typing_extensions import Self

_V_t = TypeVar("_V_t")
_V_co = TypeVar("_V_co")

class SetLike(Protocol[_V_co]):
    def __and__(self, right: Self, /) -> SetLike[_V_co]: ...
    # Other methods are omitted.

class MutableSetLike1(SetLike[_V_t], Protocol[_V_t]):
    def add(self, o: _V_t, /) -> None: ...
    # Other methods are omitted.
    
class MutableSetLike2(Protocol[_V_t]):
    def __and__(self, right: Self, /) -> SetLike[_V_t]: ...
    def add(self, o: _V_t, /) -> None: ...
    # Other methods are omitted.

SOME_SET: set[str] = {"A", "B", "C"}

a: SetLike[str] = SOME_SET
b: MutableSetLike1[str] = SOME_SET
c: MutableSetLike2[str] = SOME_SET

image

In the sample above, MutableSetLike1 and MutableSetLike2 should work equally, but the results are different.

Mypy playground: https://mypy-play.net/?mypy=latest&python=3.10&gist=d68e3371c260e7b333d059194b1b9774

@erictraut
Copy link
Collaborator

@Azureblade3808, this issue is closed. If you want to report a new bug, please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addressed in next version Issue is fixed and will appear in next published version bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants