How do I get mypy to recognize that an argument of a function needs to be a subclass of a particular base class?
I suppose that taking a stab at an answer isn't a bad idea at this point, since I have enough information from the comments.
You need to first enforce that f
is implemented by subclasses of A
. Otherwise, you could implement a subclass that doesn't implement f
, and static typechecking would (rightfully) point out that there is nothing preventing that from occurring. You could use Union[B, C]
if you only wanted some subclasses to implement f
, but you've already stated that this is undesirable for extensibility reasons.
What you should do is have the function accept instances of the superclass A
, and raise an error whenever f
as defined in the superclass is invoked:
from abc import ABC, abstractmethod
class A(ABC):
@abstractmethod
def f(self, x):
raise NotImplementedError("This method should be defined in subclasses of A.")
class B(A):
def f(self, x):
print(x)
class C(A):
def f(self, x):
print(x, "in C")
Then, call_f()
would look like the following:
def call_f(instance: A) -> None:
instance.f("Hello")