What I want is to enforce that when a child class inherits from a parent and that it overrides the parent method without explicitly calling it, an error is raised. The errror could be raised at initialization of the bad class or when calling the method.
The goal is to make sure that users of the Mother class performed some actions present in the mother method.
Example
class Mother():
def necessary_method(self):
# do some necessary stuff
class GoodChild(Mother):
def necessary_method(self):
# necessary parent call
super().necessary_method()
class BadChild(Mother):
def necessary_method(self):
# no parent call
return
upon calling:
good = GoodChild()
# works fine
bad = BadChild()
# exception could be raised here
good.necessary_method()
# works fine
bad.necessary_method()
# exception could be raised here
Is this really possible ? Any answer or workaround tricks is welcomed.
Yeah, it's definitely possible, at least during runtime. U can create a Metaclass that modifies how classes are created, the idea is to change the necessary_method signature by adding a mother_method_called flag that is only going to be true when the Mother version is called, otherwise it's going to raise a Value Error. For example in python3:
class MotherMetaClass(type):
def __new__(cls, name, bases, attrs):
method_name = 'necessary_method'
mother_class_name = 'Mother'
original_necessary_method = attrs.get(method_name)
def necessary_method_validated(*args, **kwargs):
original_necessary_method(*args, **kwargs)
if name == mother_class_name:
cls.mother_method_called = True
else:
if not cls.mother_method_called:
raise ValueError(f'Must call "super()" when overriding "{method_name}".')
cls.mother_method_called = False
attrs[method_name] = necessary_method_validated
return super().__new__(cls, name, bases, attrs)
class Mother(metaclass=MotherMetaClass):
def necessary_method(self):
print('Parent method called.')
class GoodChild(Mother):
def necessary_method(self):
super().necessary_method()
print('Good child method called.')
class BadChild(Mother):
def necessary_method(self):
print("Bad child method called.")
a = GoodChild()
a.necessary_method() # it's going to work properly
b = BadChild()
b.necessary_method() # it's going to raise Value Error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With