File: LP6E/Chapter39/access_builtins_mixin_desc.py
"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))