python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.39k stars 2.82k forks source link

Parameterized protocol structure ignored as argument #14798

Open markedwards opened 1 year ago

markedwards commented 1 year ago

Bug Report

Parameterized protocols seem to be largely or totally ignored when specified as argument types. Simple example:

from typing import Protocol, TypeVar

T = TypeVar("T")
T_co = TypeVar("T_co", covariant=True)

class Proto(Protocol[T_co]):
    def __call__(self, *, a: str) -> T_co:
        ...

class InvalidClass:
    def __init__(self, *, a: int) -> None:
        ...

def test(b: Proto[T]) -> T:
    return b(a="0")

test(InvalidClass)  # <-- should fail type checking

InvalidClass is accepted here even though it does not conform to the protocol. Here's a more detailed playground gist.

As demonstrated in the gist, the issue does not reproduce when a function is provided, only with a class. It also does not manifest with assignment, only with arguments. However, assigning with the parameter set to Any also produces an unexpected result, which might somehow be related.

markedwards commented 1 year ago

Possibly related to #14544, although that particular example seems to be fixed in mypy 1.0.