"Inherit descriptors, run validations" traceMe = False def trace(*args): if traceMe: print('[' + ' '.join(map(str, args)) + ']') class BuiltinsMixin: class ProxyDesc: # Define descriptor def __init__(self, attrname): self.attrname = attrname def __get__(self, instance, owner): return instance.__getattr__(self.attrname) # Run validations builtins = ['add', 'str', 'getitem', 'call'] # Plus any others for attr in builtins: exec(f'__{attr}__ = ProxyDesc("__{attr}__")') # Make descriptors def accessControl(failIf): def onDecorator(aClass): class onInstance(BuiltinsMixin): # Inherit descriptors def __init__(self, *args, **kargs): self.__wrapped = aClass(*args, **kargs) def __getattr__(self, attr): trace('get:', attr) if failIf(attr): raise TypeError('private attribute fetch, ' + attr) else: return getattr(self.__wrapped, attr) def __setattr__(self, attr, value): trace('set:', attr, value) if attr == '_onInstance__wrapped': self.__dict__[attr] = value elif failIf(attr): raise TypeError('private attribute change, ' + attr) else: setattr(self.__wrapped, attr, value) return onInstance return onDecorator def Private(*attributes): return accessControl(failIf=(lambda attr: attr in attributes)) def Public(*attributes): return accessControl(failIf=(lambda attr: attr not in attributes))