Django

Code

Ticket #5701 (closed: fixed)

Opened 9 months ago

Last modified 4 months ago

Fix naive introspection when using Django decorators

Reported by: jdunck Assigned to: gwilson
Milestone: Component: Uncategorized
Version: SVN Keywords: decorators views
Cc: simon@akoha.org Triage Stage: Accepted
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description (Last modified by gwilson)

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

dj-functools-decorators.diff (9.2 kB) - added by jdunck on 10/07/07 23:25:21.
patch against 6454
5701.diff (13.7 kB) - added by gwilson on 12/01/07 17:30:42.

Change History

10/07/07 23:25:21 changed by jdunck

  • attachment dj-functools-decorators.diff added.

patch against 6454

10/07/07 23:25:57 changed by jdunck

  • description changed.

11/18/07 23:45:34 changed by gwilson

  • description changed.
  • stage changed from Unreviewed to Accepted.

fixed description formatting.

11/20/07 00:44:47 changed by gwilson

  • owner changed from nobody to gwilson.

11/20/07 00:46:00 changed by gwilson

#1840 marked as duplicate.

12/01/07 14:07:11 changed by jacob

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 ) 12/01/07 17:29:28 changed by gwilson

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.

12/01/07 17:30:42 changed by gwilson

  • attachment 5701.diff added.

12/01/07 17:33:10 changed by gwilson

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.

12/18/07 10:03:39 changed by Simon Law <simon@akoha.org>

  • cc set to simon@akoha.org.

(in reply to: ↑ 7 ) 02/24/08 23:58:55 changed by gwilson

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.

02/25/08 00:02:35 changed by gwilson

  • status changed from new to closed.
  • resolution set to fixed.

(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.


Add/Change #5701 (Fix naive introspection when using Django decorators)




Change Properties
Action