from __future__ import print_function class Base(object): @property def prop(self): return 123 @prop.setter def prop(self, val): print(val) class Mixin(object): def __init__(self, super): self.super = super @property def prop(self): return self.super(Mixin, self).prop @prop.setter def prop(self, val): self.super(Mixin, self).prop = val class Final(Mixin, Base): pass class mysuper(object): def __init__(self, base, inst): self.__base = base self.__inst = inst def __getattr__(self, name): s = super(self.__base, self.__inst) return getattr(s, name) def __setattr__(self, name, val): if name.startswith('_mysuper'): object.__setattr__(self, name, val) else: cs = super(self.__base, type(self.__inst)) #XXX: could have a fallback to put into __dict__ here # instead of failing, needs discussion prop = getattr(cs, name) prop.__set__(self.__inst, val) if __name__ == '__main__': print('builtin super') inst = Final(super) print(inst.prop) # works try: inst.prop = 123 # fails except AttributeError: print("fail") print('extended super') inst = Final(mysuper) print(inst.prop) # works inst.prop = 234 # works