Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Protocol using keyword-only arguments requires implementation to have different signature

I'm on python 3.10. I'm using PyCharm's default type checker and MyPy. Here is the protocol I defined:

class OnSubscribeFunc(Protocol):
    def __call__(self, instrument: str, *, x: int) -> AsyncGenerator:
        ...

When create a method that implements it like this:

class A:
    async def subscribe(self, instrument: str, *, x: int):
        yield ...
a: OnSubscribeFunc = A().subscribe  # this apparently is where it gets it wrong

I get this warning: Expected type 'OnSubscribeFunc', got '(instrument: str, Any, x: int) -> AsyncGenerator' instead

If I remove the * from my implementation however, the warning disappears. I would expect it to be the other way around because not having the * allows the implementation to have non-keyword-only arguments which might not be what I'm aiming for with my protocol.

So for comparison - this implementation gives no warning:

class A:
    async def subscribe(self, instrument: str, x: int):
        yield ...

This does not make any sense to me, why does it behave like this and is this expected or is it a bug in my type checker?

like image 751
Tim Woocker Avatar asked May 16 '26 01:05

Tim Woocker


1 Answers

This is a known bug of PyCharm. Mypy and Pyright both accept your code as it is.

Put a # type: ignore or # noqa there and move on.

like image 63
InSync Avatar answered May 19 '26 04:05

InSync