1
votes

I'm struggling with mypy not understanding that I want to pass a derived class where the code accepts an instance of the base class or any derived class, and calling a method on that passed instance.

My code:

from typing import Type
import abc

class Base(abc.ABC):
    @abc.abstractmethod
    def my_method(self):
        pass

class Derived(Base):
    def my_method(self):
        print("Derived")

def my_function(b: Type[Base]):
    b.my_method()  # line 14

d = Derived()
my_function(d)  # line 17

When I run this, it prints "Derived" (as expected). But mypy is unhappy with it:

mcve.py:14: error: Too few arguments for "my_method" of "Base"

mcve.py:17: error: Argument 1 to "my_function" has incompatible type "Derived"; expected "Type[Base]"

I assume that the line 14 error is because mypy doesn't see that the first argument is in front of the method call (the base.), which may be because of the error on line 17?

How do I get mypy to understand this code? Or what am I missing here?

2

2 Answers

4
votes

Type is used if you want to pass Base or a subclass of Base as an argument. You intend to pass an instance of such a class.

def my_function(b: Base):
    b.my_method()

The error on line 14 is taking your type hint literally, and thinks you mean to do something like Base.my_method(x) rather than x.my_method().

1
votes

You can simply use Base as the type for b:

def my_function(b: Base):
    b.my_method()

and mypy will accept it.