Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Calling instance of adapter class plugged into port is causing mypy issues

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. 🙂

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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].

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading