An upstream interface was given to me with all of its functions defined as non-abstract when in reality they should be decorated with @abstractmethod
s. I want to receive an error when I did not implement one of its functions when it's called. To do this, I would create a wrapper class and manually go through each of its defined functions and do something like this:
from abc import ABC, abstractmethod
class Foo(object):
def foo(self):
print("Foo")
class AbstractFoo(Foo, ABC):
@abstractmethod
def foo(self):
return super().foo()
class ConcreteFoo(AbstractFoo):
def foo(self):
print("Concrete Foo")
super().foo()
f = ConcreteFoo()
f.foo()
Which outputs:
Concrete Foo
Foo
I would like some way of just doing this to all functions defined by Foo. Obviously, inherited magic functions like __str__
and __repr__
should be forwarded appropriately.
Does anyone know a nice, pythonic way of doing this?
def validate_base_class_implemntation(cls):
base_cls_funcs = []
for attr in cls.__bases__[0].__dict__:
if callable(getattr(cls, attr)):
base_cls_funcs.append(attr)
cls_funcs = []
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
cls_funcs.append(attr)
missing_funcs = [x for x in base_cls_funcs if x not in cls_funcs]
if len(missing_funcs) > 0:
print("Not implemented functions are: {}".format(','.join(missing_funcs)))
raise Exception("Not implement function exception!")
return cls
class Foo(object):
def foo(self):
print("Foo")
def boo(self):
print("Wow")
@validate_base_class_implemntation
class ConcreteFoo(Foo):
def foo(self):
print("Concrete Foo")
super().foo()
f = ConcreteFoo()
f.foo()
Not sure in 100% if that what you meant.
this decorator checks that the class decorated implements all the base class function(in your case, they are not decorated with abstract). if there is a function that your decorated class does not implement, it raises exception.