#29400 closed Bug (fixed)
mark_safe() doesn't work as a decorator for template filters and tags
| Reported by: | Torsten Bronger | Owned by: | oliver | 
|---|---|---|---|
| Component: | Template system | Version: | 2.0 | 
| Severity: | Release blocker | Keywords: | |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description
With Django 1.11, I had the following pattern frequently in my code:
@register.filter
@mark_safe
def myfilter(value):
    ...
Smilarly for tags.  This has worked in Django 1.11, however, with Django 2.0, this leads to the TemplateError saying that "myfilter requires 0 arguments, 1 provided".  For tags, it results in an IndexError because the "params" list when processing the tag is empty.
If I make @mark_safe the outmost (i.e. first) decorator, no exception occurs – but the output is escaped HTML instead of passed-through HTML.
Attachments (1)
Change History (9)
by , 7 years ago
comment:1 by , 7 years ago
| Component: | Uncategorized → Template system | 
|---|---|
| Severity: | Normal → Release blocker | 
| Summary: | mark_safe does not work as a decorator for filters and tags (regression) → mark_safe() doesn't work as a decorator for template filters and tags | 
| Triage Stage: | Unreviewed → Accepted | 
| Type: | Uncategorized → Bug | 
Bisected to 620e9dd31a2146d70de740f96a8cb9a6db054fc7.
follow-up: 3 comment:2 by , 7 years ago
| Owner: | changed from to | 
|---|---|
| Status: | new → assigned | 
comment:3 by , 7 years ago
Replying to oliver:
I'm happy to work on this if you need to relinquish it.
comment:4 by , 7 years ago
I went ahead and took a look, since it was 10 days past claimed. I was unable to reproduce for any tags, but I did for filters. As of the bisected commit, inspect.getfullargspec is being passed the function, but if that function is decorated, inspect.getfullargspec does not read __wrapped__ attributes as of Python 3.4: https://docs.python.org/3/library/inspect.html#inspect.getfullargspec
The function is checked for a _decorated_function attribute, but that's not always present. inspect.unwrap will get the original function for the call to inspect.getfullargspec, though. I've opened a PR here: https://github.com/django/django/pull/9979
comment:5 by , 7 years ago
| Has patch: | set | 
|---|---|
| Triage Stage: | Accepted → Ready for checkin | 
Taceback when using @mark_safe with a template filter function.