def wrap(cls): print("In wrap() for class %s" % cls.__name__) name = cls.__name__ class Wrapper(cls): def __init__(self, *args, **kwargs): print("In Wrapper(%s).__init__()" % name) super().__init__(*args, **kwargs) return Wrapper class Metaclass(type): def __new__(meta, name, bases, namespace): print("In Metaclass.__new__() for class %s" % name) cls = super().__new__(meta, name, bases, namespace) return cls if cls.__name__ == 'Wrapper' else wrap(cls) class A(metaclass = Metaclass): def __init__(self): print("In A.__init__()") super().__init__() @wrap class B: def __init__(self): print("In B.__init__()") super().__init__() print(A.mro()) print(B.mro()) B() # Works A() # Loops in A.__init__()