Search code examples
pythonprotocolsmypypython-typing

mypy error occurred when argument name is different from the one defined in typing.Protocol


The following code first defines the protocol Proto and then define a function that takes a variable follows that protocol. Then define classes A and B that I thought both follows the protocol, although only the argument name of B.__call__ is different from the protocol (in Proto it's x and in B it'S y).

After checking the following code by mypy the following error was given

main.py:20: error: Argument 1 to "func" has incompatible type "B"; expected "Proto"

It seems that, Protocol not only enforce the type but also the argument name. Is this intended behavior? Or something wrong with mypy?

from typing import Protocol

class Proto(Protocol):

    def __call__(self, x: int) -> int:
        ...

def func(f: Proto):
    pass

class A:
    def __call__(self, x: int) -> int:
        return x

class B:
    def __call__(self, y: int) -> int:
        return y

func(A())
func(B())

Solution

  • You can call a Proto p as p(0) or p(x=0). B doesn't satisfy the second. If you want B to be valid, you can force a positional argument

    class Proto(Protocol):
        def __call__(self, x: int, /) -> int:
            ...