summaryrefslogtreecommitdiff
path: root/django/utils/functional.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/utils/functional.py')
-rw-r--r--django/utils/functional.py61
1 files changed, 61 insertions, 0 deletions
diff --git a/django/utils/functional.py b/django/utils/functional.py
index f3b0598763..2b3ca8293e 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -2,3 +2,64 @@ def curry(*args, **kwargs):
def _curried(*moreargs, **morekwargs):
return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.items()))
return _curried
+
+def lazy(func, *resultclasses):
+
+ """
+ lazy turns any callable passed in into a lazy evaluated callable.
+ you need to give result classes or types - at least one is needed
+ so that the automatic forcing of the lazy evaluation code is
+ triggered. Results are not memoized - the function is evaluated
+ on every access.
+ """
+
+ class __proxy__:
+
+ """
+ This inner class encapsulates the code that should be evaluated
+ lazyly. On calling of one of the magic methods it will force
+ the evaluation and store the result - afterwards the result
+ is delivered directly. So the result is memoized.
+ """
+
+ def __init__(self, args, kw):
+ self.__func = func
+ self.__args = args
+ self.__kw = kw
+ self.__dispatch = {}
+ for resultclass in resultclasses:
+ self.__dispatch[resultclass] = {}
+ for (k, v) in resultclass.__dict__.items():
+ setattr(self, k, self.__promise__(resultclass, k, v))
+
+ def __promise__(self, klass, funcname, func):
+
+ """
+ This function builds a wrapper around some magic method and
+ registers that magic method for the given type and methodname.
+ """
+
+ def __wrapper__(*args, **kw):
+ """
+ This wrapper function automatically triggers the evaluation of
+ a lazy value. It then applies the given magic method of the
+ result type.
+ """
+ res = self.__func(*self.__args, **self.__kw)
+ return self.__dispatch[type(res)][funcname](res, *args, **kw)
+
+ if not self.__dispatch.has_key(klass):
+ self.__dispatch[klass] = {}
+ self.__dispatch[klass][funcname] = func
+ return __wrapper__
+
+ def __wrapper__(*args, **kw):
+ """
+ This wrapper function just creates the proxy object that is returned
+ instead of the actual value.
+ """
+ return __proxy__(args, kw)
+
+ return __wrapper__
+
+