Skip to content

Instantly share code, notes, and snippets.

@beam2d
Created January 7, 2019 09:25
Show Gist options
  • Save beam2d/7313131287076df108a106fae5c0ecf6 to your computer and use it in GitHub Desktop.
Save beam2d/7313131287076df108a106fae5c0ecf6 to your computer and use it in GitHub Desktop.
Ensure super __init__ is called
def ensure_init(cls):
def __new__(cls, *args, **kwargs):
def magic_init(self):
self.__class__ = cls
self.__init__(*args, **kwargs)
if not self.__ensure_init:
raise TypeError('super __init__ not called')
# magic to use custom init while pretending a cls instance
t = type('', (cls,), {'__init__': magic_init})
return object.__new__(t)
init = cls.__init__ # cls.__init__ will be rebound!
def __init__(self, *args, **kwargs):
self.__ensure_init = True
init(self, *args, **kwargs)
cls.__ensure_init = False # default value
cls.__init__ = __init__
cls.__new__ = staticmethod(__new__) # staticmethod needed in py2
return cls
from ensure_init import ensure_init
@ensure_init
class B(object):
def __init__(self):
print('B.__init__')
def f(self):
print('B.f')
class D1(B):
def __init__(self):
print('D1.__init__')
super(D1, self).__init__()
def f(self):
print('D1.f', type(self))
class D2(B):
def f(self):
print('D2.f', type(self))
class D3(B):
def __init__(self):
print('D3.__init__')
def f(self):
print('D3.f', type(self))
d1 = D1()
d1.f()
d2 = D2()
d2.f()
d3 = D3() # TypeError: super __init__ not called
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment