I want to create a class that has some nested class that defines some contract in Python. A tenable example is a typed config object. My attempt at this is below:
from typing import Mapping
from abc import ABCMeta, abstractmethod
class BaseClass(metaclass=ABCMeta):
# If you want to implement BaseClass, you must also implement BaseConfig
class BaseConfig(metaclass=ABCMeta):
@abstractmethod
def to_dict(self) -> Mapping:
"""Converts the config to a dictionary"""
But unfortunately I can instantiate a subclass of BaseClass
without implementing BaseConfig
:
class Foo(BaseClass):
pass
if __name__ == "__main__":
foo = Foo()
Is there some way to enforce that a subclass must implement an inner class, too?
It doesn't seem like this is currently possible. The closest thing is to create two abstract classes (corresponding to outer and inner classes) and to force the implementer to provide the cls
constructor for the concrete inner class; e.g.:
from abc import ABCMeta, abstractmethod
class Inner(metaclass=ABCMeta):
@abstractmethod
def __str__(self):
pass
class Outer(metaclass=ABCMeta):
inner_cls = Inner
def shout(self, *args, **kwargs):
inner = self.inner_cls(*args, **kwargs)
print(f"My inner is {inner}!!!")
class FooInner(Inner):
def __str__(self):
return "FooInner"
class FooOuter(Outer):
inner_cls = FooInner
This requires Inner
to have at least one abstractmethod
otherwise it can be instantiated as a default inner_cls
implementation.