Marek,
You're right this class based decorator works, except for the first
problem mentioned, that is, 'unexpected keyword argument
`start_response`'. It works with or without the 'self' param, that
ends up being the controller instance when decorating a Pylons
action. This decorator will work fine on methods that are not Pylons
actions.
class deco(object):
def __init__(self, option):
print '__init__', option
self.option = option
def __call__(self, func):
print '__call__: decorating', func.func_name
def newfunc(self, *args, **kwargs):
print 'newfunc', self, args, kwargs.keys()
# passing in kwargs here throws exception
return func(self, *args, **kwargs)
return newfunc
.....
@deco('myoption')
def action(self):
return 'action result'
I can avoid the 'unexpected kwarg `start_response`' error by using the
decorator module to wrap a function based decorator. I believe the
decorator module somehow does the magic of preserving the function
signature so it does not throw the kwarg error. For now, I guess I
will go with this. I would like to figure out how to apply the
decorator module to the class based decorator as well.
def factory(option):
def deco(func, self, *args, **kwargs):
print 'deco decorating ', func.func_name, self, args,
kwargs.keys()
return func(self, *args, **kwargs)
return decorator(deco)
Thanks,
Chris
On Feb 10, 10:34 am, "Marek Stępniowski" <[EMAIL PROTECTED]>
wrote:
> 09-02-08, Chris <[EMAIL PROTECTED]> napisał(a):
>
>
>
>
>
> (cut!)
> > I think you get the AssertionError because the authorize function
> > accepts arguments. In that case, I believe it is called a decorator
> > factory and you need to call it like @authorize() with parenthesis.
> > But obviously, I'm not an expert :)
>
> > One other question/comment, it seems a class based decorator is not
> > doable on a controller method.
>
> > class deco(object):
> > def __init__(self, func):
> > self.func = func
> > def __call__(self, *args, **kwargs):
> > return self.func(*args, **kwargs)
>
> > @deco
> > def myaction(self):
> > return 'results'
>
> > This results in:
> > <type 'exceptions.NotImplementedError'>: Action u'myaction' is not
> > implemented
>
> > THis happens because _dispatch_call in pylons.controllers.core, check
> > the type of the func and expects it to be of type 'instancemethod'.
> > But a class based decorator will be of some 'class' type, even though
> > it is still callable. Expected, bug?
>
> I didn't test it, but in your example above class deco seems to be a
> decorator factory
> (because __call__ is an instance method, not a class method, and
> calling a class always returns a new instance of this class).
> So you should probably call it like this:
>
> class deco(object):
> def __init__(self, func):
> self.func = func
> def __call__(self, *args, **kwargs):
> return self.func(*args, **kwargs)
>
> @deco()
> def myaction(self):
> return 'results'
>
> As I said, I haven't tested it :-)
>
> --
> Marek Stępniowski
> email: [EMAIL PROTECTED] || [EMAIL PROTECTED]
> gg: 5354504
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---