summaryrefslogtreecommitdiff
path: root/alot/utils
diff options
context:
space:
mode:
authorPatrick Totzke <patricktotzke@gmail.com>2017-06-15 10:08:18 +0100
committerPatrick Totzke <patricktotzke@gmail.com>2017-06-15 11:01:48 +0100
commit36e9d2948190891df7407f5fb98f0cf181f659d0 (patch)
tree3024e52e86659f6e4929cf2ca524d797038ebbb8 /alot/utils
parentcc140e518be6f97ca7856d5121e4246c495af29b (diff)
conservative lookup of sub-completers
via cached properties
Diffstat (limited to 'alot/utils')
-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