Source code for pynion.decorators.extendable

# -*-
#
# @author: jaumebonet
# @email:  jaume.bonet@gmail.com
# @url:    jaumebonet.github.io
#
# @date:   2016-01-29 17:03:51
#
# @last modified by:   jaumebonet
# @last modified time: 2016-01-29 17:51:38
#
# -*-


class RepeatedExtendedAttributeException(Exception):
    pass


class ProtectedExtendedAttributeException(Exception):
    pass


class UndeclaredProtectedAttributeException(Exception):
    pass


[docs]def extendable(original_class): """The **extendable** class decorators provides the methods to allow the controlled addition and retrieval of attributes to the class. The recipie for overwritting the __init__ method is adapted from http://stackoverflow.com/a/682242/2806632 """ orig_init = original_class.__init__ # copy original __init__ def _check_W_attribute(self, attribute): if self._ext[attribute] is None: return True if attribute not in self._ext_protected: return True return False def _check_D_attribute(self, attribute, force): if force: return True if attribute not in self._ext_protected: return True return False def declare_attribute(self, attribute, protected = False): if attribute not in self._ext: self._ext[attribute] = None if protected: self._ext_protected.add(attribute) else: raise RepeatedExtendedAttributeException def set_attribute(self, attribute, value): if attribute in self._ext: if self._check_W_attribute(attribute): self._ext[attribute] = value else: raise ProtectedExtendedAttributeException else: raise UndeclaredProtectedAttributeException def get_attribute(self, attribute): if attribute in self._ext: return self._ext[attribute] else: raise UndeclaredProtectedAttributeException def del_attribute(self, attribute, force = False): if attribute in self._ext: if self._check_D_attribute(attribute, force): del(self._ext[attribute]) self._ext_protected.discard(attribute) else: raise ProtectedExtendedAttributeException else: raise UndeclaredProtectedAttributeException def __init__(self, *args, **kws): # new __init__ orig_init(self, *args, **kws) # call the original __init__ self._ext = {} self._ext_protected = set() original_class.__init__ = __init__ # set new __init__ original_class._check_W_attribute = _check_W_attribute original_class._check_D_attribute = _check_D_attribute original_class.declare_attribute = declare_attribute original_class.set_attribute = set_attribute original_class.get_attribute = get_attribute original_class.del_attribute = del_attribute return original_class