Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#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)

django.tb (6.3 KB ) - added by Torsten Bronger 6 years ago.
Taceback when using @mark_safe with a template filter function.

Download all attachments as: .zip

Change History (9)

by Torsten Bronger, 6 years ago

Attachment: django.tb added

Taceback when using @mark_safe with a template filter function.

comment:1 by Tim Graham, 6 years ago

Component: UncategorizedTemplate system
Severity: NormalRelease 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: UnreviewedAccepted
Type: UncategorizedBug

comment:2 by oliver, 6 years ago

Owner: changed from nobody to oliver
Status: newassigned

in reply to:  2 comment:3 by Ryan Rubin, 6 years ago

Replying to oliver:
I'm happy to work on this if you need to relinquish it.

comment:4 by Ryan Rubin, 6 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 Tim Graham, 6 years ago

Has patch: set
Triage Stage: AcceptedReady for checkin

comment:6 by Tim Graham <timograham@…>, 6 years ago

Resolution: fixed
Status: assignedclosed

In a8d12bc2:

Fixed #29400 -- Fixed crash in custom template filters that use decorated functions.

Regression in 620e9dd31a2146d70de740f96a8cb9a6db054fc7.

comment:7 by Tim Graham <timograham@…>, 6 years ago

In 6b91152:

[2.1.x] Fixed #29400 -- Fixed crash in custom template filters that use decorated functions.

Regression in 620e9dd31a2146d70de740f96a8cb9a6db054fc7.

Backport of a8d12bc28069d56e0306770ab9c73738293663f7 from master

comment:8 by Tim Graham <timograham@…>, 6 years ago

In c2a1af88:

[2.0.x] Fixed #29400 -- Fixed crash in custom template filters that use decorated functions.

Regression in 620e9dd31a2146d70de740f96a8cb9a6db054fc7.

Backport of a8d12bc28069d56e0306770ab9c73738293663f7 from master

Note: See TracTickets for help on using tickets.
Back to Top