# HG changeset patch # User Thierry Florac # Date 1516977056 -3600 # Node ID 5b80ba4fba8ef02d613d8006a0b6071aa3f1113d # Parent 0fcad7725bdc134197c36f6094203debd4e66178 Added 'inherit' interface and module to handle inheritance diff -r 0fcad7725bdc -r 5b80ba4fba8e src/pyams_utils/inherit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/inherit.py Fri Jan 26 15:30:56 2018 +0100 @@ -0,0 +1,87 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_utils.interfaces.inherit import IInheritInfo + +# import packages +from pyams_utils.traversing import get_parent +from pyams_utils.zodb import volatile_property +from zope.interface import implementer, Interface +from zope.location import Location +from zope.schema.fieldproperty import FieldProperty + + +@implementer(IInheritInfo) +class BaseInheritInfo(Location): + """Base inherit class""" + + adapted_interface = Interface + target_interface = Interface + + _inherit = FieldProperty(IInheritInfo['inherit']) + + @volatile_property + def parent(self): + return get_parent(self.__parent__, self.target_interface, allow_context=False) + + @property + def can_inherit(self): + return self.target_interface.providedBy(self.parent) + + @property + def inherit(self): + return self._inherit if self.can_inherit else False + + @inherit.setter + def inherit(self, value): + if self.can_inherit: + self._inherit = value + del self.parent + + @property + def no_inherit(self): + return not bool(self.inherit) + + @no_inherit.setter + def no_inherit(self, value): + self.inherit = not bool(value) + + +class InheritedFieldProperty(object): + """Inherited field property""" + + def __init__(self, field, name=None): + if name is None: + name = field.__name__ + + self.__field = field + self.__name = name + + def __get__(self, inst, klass): + if inst is None: + return self + inherit_info = IInheritInfo(inst) + if inherit_info.inherit: + return getattr(inherit_info.adapted_interface(inherit_info.parent), self.__name) + else: + return getattr(inst, '_{0}'.format(self.__name)) + + def __set__(self, inst, value): + inherit_info = IInheritInfo(inst) + if not (inherit_info.can_inherit and inherit_info.inherit): + setattr(inst, '_{0}'.format(self.__name), value) diff -r 0fcad7725bdc -r 5b80ba4fba8e src/pyams_utils/interfaces/inherit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/interfaces/inherit.py Fri Jan 26 15:30:56 2018 +0100 @@ -0,0 +1,44 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +# import standard library + +# import interfaces +from pyramid.interfaces import ILocation + +# import packages +from zope.interface import Attribute +from zope.schema import Bool + +from pyams_utils import _ + + +class IInheritInfo(ILocation): + """Inheritance info""" + + adapted_interface = Attribute("Context or parent adapted interface") + + target_interface = Attribute("Parent target interface") + + parent = Attribute("First parent supporting target interface") + + can_inherit = Attribute("Can inherit from parent?") + + inherit = Bool(title=_("Inherit from parent?"), + required=False, + default=True) + + no_inherit = Bool(title=_("Don't inherit from parent?"), + required=False, + default=False)