Search code examples
pythonpython-typingmypy

Mypy doesn't raise error for missing unimplemented abstract method


When using Mypy to type-check abstract classes, no error is raised when a child class misses the required abstract methods or properties.

Expected Behavior: Since Cat does not implement the abstractmethod eat I expect mypy to raise an error.

Actual Behavior: Mypy is happy with the code as it is, even under --strict and does not raise an error.

My Environment

  • Python version: 3.8
  • Mypy version: 1.11.1
  • Mypy command-line flags: --strict
from abc import ABCMeta, abstractmethod

class Animal(metaclass=ABCMeta):
    @abstractmethod
    def eat(self, food: str) -> None: pass

class Cat(Animal):
    pass

Solution

  • As @STerliakov and @Barmar answered in the comments, mypy will catch the fact that Cat is missing the required abstract methods if it's directly instantiated (via Cat()).

    If you would like mypy to give an error on declaration of Cat, you may declare it as @final. Then, mypy will know it's not subclassable and tell you at declaration that it must implement all required abstract methods of Animal.

    As for whether it's better for the error to occur at class declaration vs. instantiation, that is case by case.

    If you are developing this package for others to use, that may mean you never instantiate Cat yourself. In that situation, prior to releasing your package, mypy would raise an error at class declaration time regarding any missing abstract methods. This protects you from releasing an uninstantiable class accidentally to your package consumers.

    If the error was revealed at class instantion time instead, that would not show up pre-release. Package consumers would then face the error themselves when using your package.