Source code for dantro.mixins.general

"""This module implements general mixin classes for containers and groups"""

import logging
from typing import Sequence

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. By including naive ``__getstate__`` and ``__setstate__`` methods, classes that include this mixin remain pickleable. """ FORWARD_ATTR_TO: str = None """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_ONLY: Sequence[str] = None """If set, the only attributes to be forwarded""" FORWARD_ATTR_EXCLUDE: Sequence[str] = () """Attributes to *not* forward. Evaluated after ``FORWARD_ATTR_ONLY``"""
[docs] def __getstate__(self) -> dict: """Returns the object's ``__dict__``""" return self.__dict__
[docs] def __setstate__(self, d: dict): """Sets the object's ``__dict__`` to the given one""" self.__dict__ = d
[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 most behaviour that is not implemented in the group or container with that of the underlying data. """ FORWARD_ATTR_TO = "data"