diff options
| author | Iacopo Spalletti <i.spalletti@nephila.it> | 2015-11-07 14:30:20 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-12-12 14:46:48 -0500 |
| commit | d693074d431c50e4801dd6bf52525ce1436358f0 (patch) | |
| tree | ad452646aad45bf9241478f3fc17803d05320cfc /django/utils/functional.py | |
| parent | 93fc23b2d542105f5d129dff2dd2c8895e9abd5d (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.py | 50 |
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() |
