Source code for auromat.util.decorators

# Copyright European Space Agency, 2013

from functools import wraps

[docs]def lazy_property(fn): """ Caches the result of a property. """ attr_name = '_lazy_' + fn.__name__ @property @wraps(fn) def _lazyprop(self): if not hasattr(self, attr_name): setattr(self, attr_name, fn(self)) return getattr(self, attr_name) return _lazyprop
[docs]def inherit_docs(cls): """ Inherits docstrings from base classes for all overridden methods and properties in `cls` which lack a docstring. """ # see https://stackoverflow.com/a/23964187 for name in dir(cls): func = getattr(cls, name) if func.__doc__: continue for parent in cls.mro()[1:]: if not hasattr(parent, name): continue doc = getattr(parent, name).__doc__ if not doc: continue try: # __doc__'s of properties are read-only. # The work-around below wraps the property into a new property. if isinstance(func, property): # We don't want to introduce new properties, therefore check # if cls owns it or search where it's coming from. # With that approach (using dir(cls) instead of var(cls)) # we also handle the mix-in class case. wrapped = property(func.fget, func.fset, func.fdel, doc) clss = list(filter(lambda c: name in vars(c).keys() and not getattr(c, name).__doc__, cls.mro())) setattr(clss[0], name, wrapped) else: try: func = func.__func__ # for instancemethod's except: pass func.__doc__ = doc except: # some __doc__'s are not writable pass break return cls