I'm currently plugging an Adapter into a port in a handler which can help you get an instance of that port. Here is a simple setup to reproduce:
from typing import Protocol
class SomePort(Protocol):
def caller(self):
raise NotImplementedError
class SomeAdapter:
def caller(self):
print("Called")
class SomeController:
@staticmethod
def get_instance(port: SomePort) -> SomePort:
return port()
instance = SomeController.get_instance(port=SomeAdapter)
instance.caller()
This is working just fine in code but in mypy
I'm getting the following issues:
$ mypy --version
mypy 0.931
$ mypy test/test.py
test/test.py:17: error: "SomePort" not callable
test/test.py:20: error: Argument "port" to "get_instance" of "SomeController" has incompatible type "Type[SomeAdapter]"; expected "SomePort"
anything I've misunderstood here? Running the script prints Called
just fine, but mypy is unhappy about the way I've set this up. Any help is appreciated. :)
If you want the port
parameter in SomeController.get_instance
to accept a class that is a subtype of SomePort
, you need to annotate it with type[SomePort]
instead of SomePort
.
The latter (as you have it in your example) would express that port
should be an instance of the type SomePort
. Since SomePort
is not callable (no __call__
method defined), you get that first Mypy error. And because SomeAdapter
is a class that follows the SomePort
protocol rather than an instance of such a class, you get that second error.
If you are on Python <3.9
use typing.Type
instead of the built-in type
, i.e. typing.Type[SomePort]
.