Simplified @stringfilter decorator and Library with unwrap().

Nowadays we can use inspect.unwrap() to retrieve the innermost function
object when needed, and most of the uses of _decorated_function were to
access the original __name__ which is not needed because
@functools.wraps sets that attribute correctly.
This commit is contained in:
Baptiste Mispelon 2022-01-10 08:31:43 +01:00 committed by GitHub
parent 3430093a46
commit 3d7ac6420c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 20 deletions

View File

@ -4,6 +4,7 @@ import re
import types import types
from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation
from functools import wraps from functools import wraps
from inspect import unwrap
from operator import itemgetter from operator import itemgetter
from pprint import pformat from pprint import pformat
from urllib.parse import quote from urllib.parse import quote
@ -37,20 +38,15 @@ def stringfilter(func):
Decorator for filters which should only receive strings. The object Decorator for filters which should only receive strings. The object
passed as the first positional argument will be converted to a string. passed as the first positional argument will be converted to a string.
""" """
def _dec(*args, **kwargs): @wraps(func)
args = list(args) def _dec(first, *args, **kwargs):
args[0] = str(args[0]) first = str(first)
if (isinstance(args[0], SafeData) and result = func(first, *args, **kwargs)
getattr(_dec._decorated_function, 'is_safe', False)): if isinstance(first, SafeData) and getattr(unwrap(func), 'is_safe', False):
return mark_safe(func(*args, **kwargs)) result = mark_safe(result)
return func(*args, **kwargs) return result
# Include a reference to the real function (used to check original return _dec
# arguments by the template parser, and to bear the 'is_safe' attribute
# when multiple decorators are applied).
_dec._decorated_function = getattr(func, '_decorated_function', func)
return wraps(func)(_dec)
################### ###################

View File

@ -48,7 +48,7 @@ class Library:
) )
def tag_function(self, func): def tag_function(self, func):
self.tags[getattr(func, "_decorated_function", func).__name__] = func self.tags[func.__name__] = func
return func return func
def filter(self, name=None, filter_func=None, **flags): def filter(self, name=None, filter_func=None, **flags):
@ -83,8 +83,7 @@ class Library:
setattr(filter_func, attr, value) setattr(filter_func, attr, value)
# set the flag on the innermost decorated function # set the flag on the innermost decorated function
# for decorators that need it, e.g. stringfilter # for decorators that need it, e.g. stringfilter
if hasattr(filter_func, "_decorated_function"): setattr(unwrap(filter_func), attr, value)
setattr(filter_func._decorated_function, attr, value)
filter_func._filter_name = name filter_func._filter_name = name
return filter_func return filter_func
else: else:
@ -94,8 +93,7 @@ class Library:
) )
def filter_function(self, func, **flags): def filter_function(self, func, **flags):
name = getattr(func, "_decorated_function", func).__name__ return self.filter(func.__name__, func, **flags)
return self.filter(name, func, **flags)
def simple_tag(self, func=None, takes_context=None, name=None): def simple_tag(self, func=None, takes_context=None, name=None):
""" """
@ -107,7 +105,7 @@ class Library:
""" """
def dec(func): def dec(func):
params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(unwrap(func)) params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(unwrap(func))
function_name = (name or getattr(func, '_decorated_function', func).__name__) function_name = (name or func.__name__)
@functools.wraps(func) @functools.wraps(func)
def compile_func(parser, token): def compile_func(parser, token):
@ -144,7 +142,7 @@ class Library:
""" """
def dec(func): def dec(func):
params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(unwrap(func)) params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(unwrap(func))
function_name = (name or getattr(func, '_decorated_function', func).__name__) function_name = name or func.__name__
@functools.wraps(func) @functools.wraps(func)
def compile_func(parser, token): def compile_func(parser, token):