Welcome, guest | Sign In | My Account | Store | Cart
class SuperWrapper(object):
	"""Make sure descriptor super(cls) is invoked
        even when called on a class."""
	def __init__(self, cls):
		self.cls = cls
	def __get__(self, obj, cls):
		if obj is None:
			return super(self.cls, cls)
		else:
			return super(self.cls, obj)

class SuperMeta(type):
	"Automatically add attribute __sup for every class."
	def __init__(cls, name, bases, clsdict):
		setattr(cls, '_{}__sup'.format(name), SuperWrapper(cls))
		super(SuperMeta, cls).__init__(name, bases, clsdict)

# Usage examples:

class A(object):
	__metaclass__ = SuperMeta
	def meth(self):
		print 'A.meth(%s)' % self
	@classmethod
	def clsmeth(cls):
		print 'A.clsmeth(%s)' % cls

class B(A):
	def meth(self):
		self.__sup.meth()                 # super().meth()
		print 'B.meth(%s)' % self
	@classmethod
	def clsmeth(cls):
		cls.__sup.clsmeth()              # super().clsmeth()
		print 'B.clsmeth(%s)' % cls

class C(A):
	def meth(self):
		self.__sup.meth()
		print 'C.meth(%s)' % self
	@classmethod
	def clsmeth(cls):
		cls.__sup.clsmeth()
		print 'C.clsmeth(%s)' % cls

class D(B, C):
	def meth(self):
		self.__sup.meth()
		print 'D.meth(%s)' % self
	@classmethod
	def clsmeth(cls):
		cls.__sup.clsmeth()
		print 'D.clsmeth(%s)' % cls

d = D()
d.meth()
d.clsmeth()

History