"""This module implements general mixin classes for containers and groups"""
import logging
# Local variables
log = logging.getLogger(__name__)
# -----------------------------------------------------------------------------
[docs]class ForwardAttrsMixin:
"""This Mixin class forwards all calls to unavailable attributes to a
certain other attribute, specified by ``FORWARD_ATTR_TO`` class variable.
"""
# The name of the existing attribute to forward to. For None, this behaves
# as if no forwarding would occur, i.e. as if __getattr__ was not called.
FORWARD_ATTR_TO = None
# If set, the only attributes to be forwarded
FORWARD_ATTR_ONLY = None
# Attributes to _not_ forward. Evaluated after ``FORWARD_ATTR_ONLY``
FORWARD_ATTR_EXCLUDE = ()
[docs] def __getattr__(self, attr_name: str):
"""Forward attributes that were not available in this class to some
other attribute of the group or container.
Args:
attr_name (str): The name of the attribute that was tried to be
accessed but was not available in ``self``.
Returns:
The attribute ``attr_name`` of getattr(self, self.FORWARD_ATTR_TO)
"""
if self.FORWARD_ATTR_TO is None:
raise AttributeError(attr_name)
if ( self.FORWARD_ATTR_ONLY is not None
and attr_name not in self.FORWARD_ATTR_ONLY):
raise AttributeError(attr_name)
if attr_name in self.FORWARD_ATTR_EXCLUDE:
raise AttributeError(attr_name)
# Invoke the pre-hook
self._forward_attr_pre_hook(attr_name)
# Get the attribute
a = getattr(self._forward_attr_get_forwarding_target(), attr_name)
# Pass it through the post-hook
return self._forward_attr_post_hook(a)
[docs] def _forward_attr_pre_hook(self, attr_name: str=None):
"""Invoked before attribute forwarding occurs"""
pass
[docs] def _forward_attr_get_forwarding_target(self):
"""Get the object that the attribute call is to be forwarded to"""
return getattr(self, self.FORWARD_ATTR_TO)
[docs] def _forward_attr_post_hook(self, attr):
"""Invoked before attribute forwarding occurs"""
return attr
[docs]class ForwardAttrsToDataMixin(ForwardAttrsMixin):
"""This Mixin class forwards all calls to unavailable attributes to the
``data`` attribute (a property) and thus allows to replace all behaviour
that is not implemented in the group or container with that of the stored
data.
"""
FORWARD_ATTR_TO = 'data'