There is a Python module called abc that provides the basics for using abstract baseclasses in Python. Although the abstractmethod decoration provides a way for defining abstract methods, using it is not enough to make sure the derived classes follow the signature of the abstract methods, i.e., using abstractmethod decoration only makes sure that a method with the same name has been defined in the derived classes and they do zero checking about the name and type of the methods’ parameters.
In this story, throughout an example, I will explain how to enforce the derived class of an abstract base class in Python to follow the same parameter types and names of the abstract methods’ parameters. In the example below, an abstract base class A has been defined that has an abstractmethod called a. The classes B and C have derived from A, whereas B follows the same signature of the abstract method a, while C does not. By running this script, you will receive a True followed by a False.
Throughout using __subclasshook__ one can customize the output of callingissubclass on two given classes. Elaborately, the __subclasshook__ method receives two classes C1 and C2, and returns True if C1 is a subclass of C2. Hence, we have defined __subclasshook__ in our abstract base class A to customize the behaviour of the issubclass method in a way that it returns True if:
1- All the abstract methods defined in A are also defined in the derived class
2- All the implemented abstract methods in the derived class have accept the exact same parameter as the abstract methods
Basically, in the __subclasshook__ method we access the base class and the subclass attributes by accessing the __dict__ of each. Then, we detect the attributes that are function in the base abstract class and return False if:
if method_name not in subclass_dict
or
subclass_dict[method_name].__annotations != cls_dict[method_name].__annotations