summaryrefslogtreecommitdiff
path: root/django/utils/functional.py
diff options
context:
space:
mode:
authorIacopo Spalletti <i.spalletti@nephila.it>2015-11-07 14:30:20 +0100
committerTim Graham <timograham@gmail.com>2015-12-12 14:46:48 -0500
commitd693074d431c50e4801dd6bf52525ce1436358f0 (patch)
treead452646aad45bf9241478f3fc17803d05320cfc /django/utils/functional.py
parent93fc23b2d542105f5d129dff2dd2c8895e9abd5d (diff)
Fixed #20223 -- Added keep_lazy() as a replacement for allow_lazy().
Thanks to bmispelon and uruz for the initial patch.
Diffstat (limited to 'django/utils/functional.py')
-rw-r--r--django/utils/functional.py50
1 files changed, 40 insertions, 10 deletions
diff --git a/django/utils/functional.py b/django/utils/functional.py
index 7b566e429f..2830cc47ab 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -1,8 +1,10 @@
import copy
import operator
+import warnings
from functools import total_ordering, wraps
from django.utils import six
+from django.utils.deprecation import RemovedInDjango20Warning
# You can't trivially replace this with `functools.partial` because this binds
@@ -176,24 +178,52 @@ def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses):
return lazy(func, *resultclasses)(*args, **kwargs)
+def lazystr(text):
+ """
+ Shortcut for the common case of a lazy callable that returns str.
+ """
+ from django.utils.encoding import force_text # Avoid circular import
+ return lazy(force_text, six.text_type)(text)
+
+
def allow_lazy(func, *resultclasses):
+ warnings.warn(
+ "django.utils.functional.allow_lazy() is deprecated in favor of "
+ "django.utils.functional.keep_lazy()",
+ RemovedInDjango20Warning, 2)
+ return keep_lazy(*resultclasses)(func)
+
+
+def keep_lazy(*resultclasses):
"""
A decorator that allows a function to be called with one or more lazy
arguments. If none of the args are lazy, the function is evaluated
immediately, otherwise a __proxy__ is returned that will evaluate the
function when needed.
"""
- lazy_func = lazy(func, *resultclasses)
+ if not resultclasses:
+ raise TypeError("You must pass at least one argument to keep_lazy().")
- @wraps(func)
- def wrapper(*args, **kwargs):
- for arg in list(args) + list(kwargs.values()):
- if isinstance(arg, Promise):
- break
- else:
- return func(*args, **kwargs)
- return lazy_func(*args, **kwargs)
- return wrapper
+ def decorator(func):
+ lazy_func = lazy(func, *resultclasses)
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ for arg in list(args) + list(six.itervalues(kwargs)):
+ if isinstance(arg, Promise):
+ break
+ else:
+ return func(*args, **kwargs)
+ return lazy_func(*args, **kwargs)
+ return wrapper
+ return decorator
+
+
+def keep_lazy_text(func):
+ """
+ A decorator for functions that accept lazy arguments and return text.
+ """
+ return keep_lazy(six.text_type)(func)
empty = object()