I'm reading the document about protocols and stuck with a Pylance error message. https://peps.python.org/pep-0544/#subtyping-relationships-with-other-types
Simplifying the code in this section, I wrote a code
from typing import Protocol, TypeVar
T = TypeVar("T", contravariant=True)
class ListLike(Protocol[T]):
def append(self, x: T) -> None:
...
class MockStack:
def append(self, x: int) -> None:
...
def populate(lst: ListLike[int]) -> int:
...
populate([1, 2, 3])
populate(MockStack())
I expect this snippet to pass type checking, since [1, 2, 3]
(as list[int]
) and MockStack()
(as MockStack
) both have the method append(self, x: int)
and therefore are structural subtypes of ListLike[int]
.
But pylance
in VS Code raises an error message:
Argument of type "list[int]" cannot be assigned to parameter "lst" of type "ListLike[int]" in function "populate"
"list[int]" is incompatible with protocol "ListLike[int]"
"append" is an incompatible type
Type "(__object: int, /) -> None" cannot be assigned to type "(x: T@ListLike) -> None"
Position-only parameter mismatch; expected 1 but received 0 (reportGeneralTypeIssues)
Could anyone give me suggestions to get around this?
environment: Apple M1 Pro, mac OS 13.5.1
VS Code version: 1.84.2
pylance
version: v2023.11.10
This warning is triggered by positional-only vs regular argument mismatch. Your
ListLike
definition permits.append(x=0)
call, and so any function that requestsListLike
is allowed to do such call.list.append
has only positional-only argument, so is not compatible with your protocol.You can redefine you protocol as
to make the type checker happy.