summaryrefslogtreecommitdiff
path: root/alot/utils/cached_property.py
diff options
context:
space:
mode:
Diffstat (limited to 'alot/utils/cached_property.py')
-rw-r--r--alot/utils/cached_property.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/alot/utils/cached_property.py b/alot/utils/cached_property.py
new file mode 100644
index 00000000..95ca954b
--- /dev/null
+++ b/alot/utils/cached_property.py
@@ -0,0 +1,43 @@
+# werkzeug.utils.cached_property
+
+_missing = object()
+
+class cached_property(object):
+ """A decorator that converts a function into a lazy property. The
+ function wrapped is called the first time to retrieve the result
+ and then that calculated result is used the next time you access
+ the value::
+
+ class Foo(object):
+
+ @cached_property
+ def foo(self):
+ # calculate something important here
+ return 42
+
+ The class has to have a `__dict__` in order for this property to
+ work.
+ """
+
+ # implementation detail: this property is implemented as non-data
+ # descriptor. non-data descriptors are only invoked if there is
+ # no entry with the same name in the instance's __dict__.
+ # this allows us to completely get rid of the access function call
+ # overhead. If one choses to invoke __get__ by hand the property
+ # will still work as expected because the lookup logic is replicated
+ # in __get__ for manual invocation.
+
+ def __init__(self, func, name=None, doc=None):
+ self.__name__ = name or func.__name__
+ self.__module__ = func.__module__
+ self.__doc__ = doc or func.__doc__
+ self.func = func
+
+ def __get__(self, obj, type=None):
+ if obj is None:
+ return self
+ value = obj.__dict__.get(self.__name__, _missing)
+ if value is _missing:
+ value = self.func(obj)
+ obj.__dict__[self.__name__] = value
+ return value