Why does mypy throw "Cannot instantiate abstract class" when it is not being instantiated

Question:

I have some code that, when run, runs successfully however mypy complains about it by throwing an error. Below is a simple contrived example that demonstrates the error:

from typing import List
from abc import ABC, abstractmethod


class Abc_(ABC):
    def __init__(self) -> None:
        pass

    @abstractmethod
    def f(self) -> str:
        return "Abc"


class A(Abc_):
    def f(self) -> str:
        return "a"


class B(Abc_):
    def f(self) -> str:
        return "b"


class C(Abc_):
    def f(self) -> str:
        return "c"


class DynamicClassInsantiator(object):

    CLASSES = [A, B, C]
    # CLASSES = [A, B]
    # CLASSES = [A, C]
    # CLASSES = [B, C]

    @property
    def stuff(self) -> List[str]:
        return [cls().f() for cls in self.CLASSES]


print(DynamicClassInsantiator().stuff)

If I run the file (python path/to/file.py) then it runs successfully and outputs:

[‘a’, ‘b’, ‘c’]

Running mypy upon that file returns:

error: Cannot instantiate abstract class "Abc_" with abstract attribute "f" [abstract]
Found 1 error in 1 file (checked 1 source file)

If I comment out CLASSES = [A, B, C] and replace it with any of the lines below it that are currently commented out then mypy no longer throws an error.

Success: no issues found in 1 source file

Here is my python & mypy version

➜ python --version     
Python 3.10.4
➜ mypy --version      
mypy 0.991 (compiled: yes)

Why does mypy complain about this code? I am not instantiating Abc_ (not intentionally, anyway)

Asked By: jamiet

||

Answers:

The issue is actually with the class variable CLASSES. If you add a type annotation MyPy should be appeased. Credit to
this post

Answered By: thrasherSince1991
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.