Opened 17 years ago
Closed 17 years ago
#5701 closed (fixed)
Fix naive introspection when using Django decorators
Reported by: | Jeremy Dunck | Owned by: | Gary Wilson |
---|---|---|---|
Component: | Uncategorized | Version: | dev |
Severity: | Keywords: | decorators views | |
Cc: | simon@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
It's fairly well-known that decorators are useful, but raise some issues.
Example:
def decorate(f): def wrap(*args, **kwargs): print "called" return f(*args, **kwargs) return wrap @decorate def add_to(augend, addend): "Adds stuff" return augend + addend
Introspecting add_to, undecorated, would have a __name__
of 'add_to'
and __doc__
of 'Adds stuff'.
After decorating, add_to.__name__
becomes 'wrap' and __doc__
becomes None.
================
In Python 2.5+, there's functools.wraps
, which takes care of the
problem of introspection on decorated functions by copying attributes
from the wrapped function.
http://docs.python.org/lib/module-functools.html
Django already includes curry
, which is roughly the same as
functools.partial
, so it's pretty easy to implement functools.wraps
.
The attached patch implements django.utils.functional.wraps
, updates all Django decorators to use it, and includes tests to verify that the fixing-up works.
Attachments (2)
Change History (13)
by , 17 years ago
Attachment: | dj-functools-decorators.diff added |
---|
comment:1 by , 17 years ago
Description: | modified (diff) |
---|
comment:2 by , 17 years ago
Description: | modified (diff) |
---|---|
Triage Stage: | Unreviewed → Accepted |
fixed description formatting.
comment:3 by , 17 years ago
Owner: | changed from | to
---|
comment:5 by , 17 years ago
comment:6 by , 17 years ago
A few questions that need to be asked before this gets checked in:
- Does it work against Python 2.3?
- Do we have explicit permission from the PSF to include that code?
- If so, who?
- Is there any potential backwards-incompatible behavior here?
If the answers to these questions are "yes", "yes", "<some name>", and "no", we'll need to stuff the PSF license at the top of the file.
follow-up: 10 comment:7 by , 17 years ago
Yes, it works in Python 2.3. Only thing is that Python 2.3 doesn't allow assignment to the __name__
attribute, but I have modified the functools code slightly to use a try-except clause around a setattr()
call so that it won't fail. In the tests, the __name__
test is also skipped if running version 2.3 or earlier.
I have emailed the PSF for permission, will note their response when it comes.
AFAIK, the only backwards-incompatible behavior here would be that wrapped functions now look like the wrapped function instead of the wrapper function.
by , 17 years ago
comment:8 by , 17 years ago
A few serializers_regress
tests seem to be failing with python 2.3 and postgresql_psycopg2
backend, but it looks like that is not related as I'm getting the same failures without the patch.
comment:9 by , 17 years ago
Cc: | added |
---|
comment:10 by , 17 years ago
Replying to gwilson:
I have emailed the PSF for permission, will note their response when it comes.
FYI, in the response I got back from Stephan Deibel with the PSF he said that he doesn't believe we need the permission of the PSF as long as we meet the license requirements. He also suggested that we put the Python license in the main LICENSE file (or reference it from the main LICENSE file) so that anyone looking for legal details would see it there.
I went ahead and put the license in the same file as the code as Jacob requested above. Jacob, feel free to move it if you so desire.
comment:11 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
(In [7153]) Fixed #5701 -- Fixed decorators to take the name, attributes, and docstring of the function they decorate by adding a modified version of the functools.wraps
function from Python 2.5. wraps
has been altered to work with Django's curry
function and with Python 2.3, which doesn't allow assignment of a function's __name__
attribute. This fixes severaly annoyances, such as the online documentation for template filters served by the admin app. This change is backwards incompatible if, for some reason, you were relying on the name of a Django decorator instead of the function it decorates.
patch against 6454