<gh_stars>0
from __future__ import absolute_import, division, print_function


class DBCache(object):
    """A helper class with useful functions to manage caching of database
    requests.
    Subclasses must implement reload() which should store data to be cached
    in self._data. Cached data should be accessed as self._data. On first
    uncached access reload() is called."""

    def load(self):
        """Ensure data is loaded from the database."""
        if not self.cached:
            self.reload()

    def reload(self):
        """Force update from the database."""
        raise NotImplementedError()

    @property
    def _data(self):
        """Internal caching logic so that information is only read once from the
        database, and only when required."""
        if not hasattr(self, "_data_cache"):
            self.reload()
        return getattr(self, "_data_cache")

    @_data.setter
    def _data(self, value):
        setattr(self, "_data_cache", value)

    @property
    def cached(self):
        return hasattr(self, "_data_cache")


class EncapsulatedValue(object):
    """A helper class encapsulating another object and mostly behaving as that
    object. The property .value allows access to the original object.
    A list of magic methods is implemented to allow meaningful comparisons.
    """

    def __init__(self, value):
        """Encapsulate an object."""
        self._value = value

    @property
    def value(self):
        """Provide read-only access to the encapsulated object"""
        return self._value

    def __getattr__(self, item):
        """Any undefined attribute access is passed to the encapsulated object."""
        return self._value.__getattr__(item)

    def __getitem__(self, item):
        """Default item getter for iteration."""
        return self._value.__getitem__(item)

    def __str__(self):
        """String coercion"""
        return self._value.__str__()

    def __eq__(self, other):
        """Equality operator (==)"""
        return self._value == other

    def __ne__(self, other):
        """Not-equals operator (!=)"""
        return self._value != other

    def __lt__(self, other):
        """Less-than operator (<)"""
        return self._value < other

    def __le__(self, other):
        """Less-than-or-equals operator (<=)"""
        return self._value <= other

    def __gt__(self, other):
        """Greater-than operator (>)"""
        return self._value > other

    def __ge__(self, other):
        """Greater-than-or-equals operator (>=)"""
        return self._value >= other

    def __bool__(self):
        """Python 3: value when used in bool() context."""
        return bool(self._value)

    def __nonzero__(self):
        """Python 2: value when used in bool() context."""
        return bool(self._value)

    def __hash__(self):
        """Pass on the hash value of the inner object."""
        return hash(self._value)


def add_properties(objectclass, property_list):
    """Generate class properties for a model that provide read-only access
    to elements from the internal ._data data structure.

    :param objectclass: The class to which properties should be added
    :param property_list: A list of property name + data structure key
                          + optional docstring tuples. Property names
                          then read from the given data structure keys.
    """
    for prop_item in property_list:
        key = prop_item[0]
        internalkey = prop_item[1]

        def model_attribute(self, k=internalkey):
            return self._data[k]

        if len(prop_item) > 2:
            model_attribute.__doc__ = prop_item[2]
        setattr(objectclass, key, property(model_attribute))

from __future__ import absolute_import, division, print_function


class DBCache(object):
    """A helper class with useful functions to manage caching of database
    requests.
    Subclasses must implement reload() which should store data to be cached
    in self._data. Cached data should be accessed as self._data. On first
    uncached access reload() is called."""

    def load(self):
        """Ensure data is loaded from the database."""
        if not self.cached:
            self.reload()

    def reload(self):
        """Force update from the database."""
        raise NotImplementedError()

    @property
    def _data(self):
        """Internal caching logic so that information is only read once from the
        database, and only when required."""
        if not hasattr(self, "_data_cache"):
            self.reload()
        return getattr(self, "_data_cache")

    @_data.setter
    def _data(self, value):
        setattr(self, "_data_cache", value)

    @property
    def cached(self):
        return hasattr(self, "_data_cache")


class EncapsulatedValue(object):
    """A helper class encapsulating another object and mostly behaving as that
    object. The property .value allows access to the original object.
    A list of magic methods is implemented to allow meaningful comparisons.
    """

    def __init__(self, value):
        """Encapsulate an object."""
        self._value = value

    @property
    def value(self):
        """Provide read-only access to the encapsulated object"""
        return self._value

    def __getattr__(self, item):
        """Any undefined attribute access is passed to the encapsulated object."""
        return self._value.__getattr__(item)

    def __getitem__(self, item):
        """Default item getter for iteration."""
        return self._value.__getitem__(item)

    def __str__(self):
        """String coercion"""
        return self._value.__str__()

    def __eq__(self, other):
        """Equality operator (==)"""
        return self._value == other

    def __ne__(self, other):
        """Not-equals operator (!=)"""
        return self._value != other

    def __lt__(self, other):
        """Less-than operator (<)"""
        return self._value < other

    def __le__(self, other):
        """Less-than-or-equals operator (<=)"""
        return self._value <= other

    def __gt__(self, other):
        """Greater-than operator (>)"""
        return self._value > other

    def __ge__(self, other):
        """Greater-than-or-equals operator (>=)"""
        return self._value >= other

    def __bool__(self):
        """Python 3: value when used in bool() context."""
        return bool(self._value)

    def __nonzero__(self):
        """Python 2: value when used in bool() context."""
        return bool(self._value)

    def __hash__(self):
        """Pass on the hash value of the inner object."""
        return hash(self._value)


def add_properties(objectclass, property_list):
    """Generate class properties for a model that provide read-only access
    to elements from the internal ._data data structure.

    :param objectclass: The class to which properties should be added
    :param property_list: A list of property name + data structure key
                          + optional docstring tuples. Property names
                          then read from the given data structure keys.
    """
    for prop_item in property_list:
        key = prop_item[0]
        internalkey = prop_item[1]

        def model_attribute(self, k=internalkey):
            return self._data[k]

        if len(prop_item) > 2:
            model_attribute.__doc__ = prop_item[2]
        setattr(objectclass, key, property(model_attribute))
A helper class with useful functions to manage caching of database     requests.     Subclasses must implement reload() which should store data to be cached     in self._data. Cached data should be accessed as self._data. On first     uncached access reload() is called. Ensure data is loaded from the database. Force update from the database. Internal caching logic so that information is only read once from the         database, and only when required. A helper class encapsulating another object and mostly behaving as that     object. The property .value allows access to the original object.     A list of magic methods is implemented to allow meaningful comparisons. Encapsulate an object. Provide read-only access to the encapsulated object Any undefined attribute access is passed to the encapsulated object. Default item getter for iteration. String coercion Equality operator (==) Not-equals operator (!=) Less-than operator (<) Less-than-or-equals operator (<=) Greater-than operator (>) Greater-than-or-equals operator (>=) Python 3: value when used in bool() context. Python 2: value when used in bool() context. Pass on the hash value of the inner object. Generate class properties for a model that provide read-only access     to elements from the internal ._data data structure.      :param objectclass: The class to which properties should be added     :param property_list: A list of property name + data structure key                           + optional docstring tuples. Property names                           then read from the given data structure keys.