inability to use decorators on template filters

2 views
Skip to first unread message

Gary Wilson

unread,
Jun 10, 2006, 2:41:00 AM6/10/06
to Django developers
While dealing with http://code.djangoproject.com/ticket/2127, I
realized that unless your decorator takes the same number of arguments
as the filter function, it will fail since
FilterExpression.args_check() (in django/template/__init__.py) is using
inspect.getargspec() to count the number of required arguments.

Problem is that when using a decorator, getargspec() looks at the
decorator's parameters, which usually include *args and **kwargs. The
decorator doesn't always have the same number of arguments as the
function it's decorating.

Honza Král

unread,
Jun 10, 2006, 8:30:34 AM6/10/06
to django-d...@googlegroups.com
I don't understand your question
bacause the number of parameters may differ, that is why you use *args
and **kwargs

Is this what you need?
this decorator works with any function with any number of parameters,
both positional and keyword

In [7]:def decor( function ):
...: def _callit( *args, **kwargs):
...: print "calling function %s" % str(function)
...: return function(*args, **kwargs)
...: return _callit
...:

In [8]:def func( one, two, three, aa=None ):
...: print one, two, three, aa
...:

In [9]:func = decor(func)

In [10]:func(1,2,3)
calling function <function func at 0xb7c6cca4>
1 2 3 None

In [11]:func(1,2,3, aa=6)
calling function <function func at 0xb7c6cca4>
1 2 3 6

HK


--
Honza Král
E-Mail: Honza...@gmail.com
ICQ#: 107471613
Phone: +420 606 678585

Luke Plant

unread,
Jun 10, 2006, 9:10:00 AM6/10/06
to django-d...@googlegroups.com
On Saturday 10 June 2006 13:30, Honza Král wrote:
> I don't understand your question
> bacause the number of parameters may differ, that is why you use
> *args and **kwargs

The problem is that the decorators you demonstrated do not preserve the
signature of the function, so when you do inspect.getargspec you get
different results on your decorated function and undecorated function.
This causes some of the filter code to fail, since it uses getargspec.
A solution is to use a decorator that doesn't change the function
signature (but still allows you to use *args and **kwargs). A module
to help do this is here:

http://www.phyast.pitt.edu/~micheles/python/documentation.html

In a recent ticket I suggested that we use if for all Django's
decorators:

http://code.djangoproject.com/ticket/1840

Luke

--
The probability of someone watching you is proportional to the
stupidity of your action.

Luke Plant || L.Plant.98 (at) cantab.net || http://lukeplant.me.uk/

Reply all
Reply to author
Forward
0 new messages