I want to implement a metaclass for wrapping methods to log additional information. But I also need to have abstractmethods
. I tried to extend ABCMeta
but it doesn't seem to enforce the @abstractmethod
decorator:
import types
import abc
def logfunc(fn, *args, **kwargs):
def fncomposite(*args, **kwargs):
rt = fn(*args, **kwargs)
print("Executed %s" % fn.__name__)
return rt
return fncomposite
class LoggerMeta(abc.ABCMeta):
def __new__(cls, clsname, bases, dct):
for name, value in dct.items():
if type(value) is types.FunctionType or type(value) is types.MethodType:
dct[name] = logfunc(value)
return super(LoggerMeta, cls).__new__(cls, clsname, bases, dct)
def __init__(cls, *args, **kwargs):
super(LoggerMeta, cls).__init__(*args, **kwargs)
if cls.__abstractmethods__:
raise TypeError("{} has not implemented abstract methods {}".format(
cls.__name__, ", ".join(cls.__abstractmethods__)))
class Foo(metaclass=LoggerMeta):
@abc.abstractmethod
def foo(self):
pass
class FooImpl(Foo):
def a(self):
pass
v = FooImpl()
v.foo()
When I run this it prints Executed foo
. However I expected it to fail because I have not implemented foo
in FooImpl
.
How can I fix this?