I'm writing a library where I need a method that takes a (potentially) abstract type, and returns an instance of a concrete subtype of that type:
# script.py
from typing import Type
from abc import ABC, abstractmethod
class AbstractClass(ABC):
@abstractmethod
def abstract_method(self):
pass
T = TypeVar('T', bound=AbstractClass)
def f(c: Type[T]) -> T:
# find concrete implementation of c based on
# environment configuration
...
f(AbstractClass) # doesn't type check
Running mypy script.py
yields:
error: Only concrete class can be given where "Type[AbstractClass]" is expected
I don't understand this error message and am having a hard time finding any documentation for it. Is there any way to annotate the function so that mypy
will type check this?
As a side note, PyCharm's type checker, which is what I use the most, type checks f
with no errors.
There exists a github issue about this misbehaviour (IMHO) in mypy. Basically, Type[_T]
with _T
being a TypeVar will never accept an abstract class.
The only sane solution I have seen is disabling this error, for example by including this in the mypy.ini
file:
[mypy]
# Allows Type[T] to refer to abstract classes, which is not otherwise supported.
# See https://github.com/python/mypy/issues/4717
disable_error_code = type-abstract
Quoting from the discussion:
Now that #14619 was merged, would disabling the type-abstract error code by default address all the main issues, or is there something else that would need to be done?
I'll add my 2¢ to the ticket later and hope, they will iron this out.