Don't let the perfect be the enemy of the good. Chris
On Thu, Jun 21, 2012 at 9:59 AM, Max Avanov <[email protected]> wrote: > But I want to. I really do. And view_config doesn't allow me to do so. > You should understand me. I don't want to have extra imports in my project. > I want transparent support from the framework. This example makes sense for > me: > > from pyramid.view import view_config > @view_config(decorator=(decorator1, decorator2, ...)) > > But this is not: > from pyramid.view import view_config > # Why should I do this for each of my view modules? > from somewhere import chain_decorators > > @view_config(decorator=chain_decorators(decorator1, decorator2, ...)) > > > > On Thursday, June 21, 2012 4:21:24 PM UTC+4, Chris McDonough wrote: >> >> On 06/21/2012 07:29 AM, Max Avanov wrote: >> > > No! View callable functions must accept at least a request argument. >> > There will never be something this that will work as a view callable: >> > >> > This is my typo. I was talking about a regular generic view callable. >> > I still don't get how to rewrite these @authenticate_form and @https (as >> > an example) - >> > https://github.com/Pylons/pylons/blob/master/pylons/decorators/secure.py >> > - to be able to do the common: >> > >> > @view_config() >> > @https() >> > @autnenticate_form >> > def view(request) - or - def view(context, request) - or - def >> > view(self) >> > >> > without passing it to view_config >> >> Why you don't want to pass the decorator to view_config via decorator= I >> have no idea, given that dealing with the differences is the entire >> purpose of that machinery and the code to support a chain of decorators >> is entirely boilerplate. >> >> But assuming you didn't, and assuming this isn't an entirely theoretical >> exercise which we're beating to death, you could write a decorator that >> assumed *one* signature which also set __module__, and __doc__ and on >> the function returned from the decorator: >> >> from functools import wraps >> >> def adecorator(wrapped): >> def inner(request): >> print request.url >> return wrapped(request) >> return wraps(wrapped, ('__module__', '__doc__'))(decorator) >> >> @view_config(....) >> @adecorator >> def view(request): >> .... >> >> - C >> >> >> >> > >> > >> > On Thursday, June 21, 2012 2:39:57 AM UTC+4, Chris McDonough wrote: >> > >> > On 06/20/2012 06:13 PM, Max Avanov wrote: >> > > > So I'm lost as to what >> > > you mean by "no other way to get access to request object" >> > > >> > > Because I must >> > > - either to follow the official approach provided by Michael (" a >> > > consistent signature no matter whether the actual view is a >> > method, or a >> > > function >> > > that accepts either (context, request) or just (request)...") >> > with the >> > > consequent @view_config(decorator=...) and the chained code >> > snipped. >> > > - or use the "classic" way: >> > > @decorator1 >> > > @decorator2 >> > > @decoratorN >> > > @view_config >> > > def func() >> > > >> > > For classic way I use the decorator package - >> > > http://micheles.googlecode.com/hg/decorator/documentation.html >> > <http://micheles.googlecode.com/hg/decorator/documentation.html> - >> > But the >> > > classic way allows me only one generic approach to get the >> > request >> > > object - via get_current_request, right? >> > >> > No! View callable functions must accept at least a request argument. >> > There will never be something this that will work as a view >> > callable: >> > >> > def func(): >> > ... >> > >> > It just wont work. A view callable must be: >> > >> > def func(request): >> > ... >> > >> > An alternate view callable signature optionally accepts "(context, >> > request)" but if your code doesn't use that signature for any of >> > your >> > view callables, you won't care. Pyramid view callables can also be >> > methods of classes, but if your code doesn't use view classes, you >> > won't >> > care about that either. >> > >> > If you *do* care about reusing a decorator across all of these view >> > callable conventions, however, you can use the decorator= argument >> > to >> > view_config. The point of the decorator= argument to view_config is >> > to >> > provide genericness by accepting a decorator that can use a single >> > common call signature for a decorator ("(context, request)"). So you >> > can use the following decorator: >> > >> > def adecorator(viewcallable): >> > def inner(context, request): >> > print request.url >> > return viewcallable(context, request) >> > return inner >> > >> > .. against this kind of view configuration ... >> > >> > class AView(object): >> > def __init__(self, request): >> > self.request = request >> > >> > @view_config(decorator=adecorator) >> > def aview(self): >> > return Response('OK') >> > >> > .. or this kind ... >> > >> > @view_config(decorator=adecorator) >> > def aview(request): >> > return Response('OK') >> > >> > ... or this kind ... >> > >> > @view_config(decorator=adecorator) >> > def aview(context, request): >> > return Response('OK') >> > >> > ... or this kind ... >> > >> > @view_config(decorator=adecorator) >> > class AView(object): >> > def __init__(self, request): >> > self.request = request >> > >> > def __call__(self): >> > return Response('OK') >> > >> > ... or this kind ... >> > >> > class AView(object): >> > def __init__(self, context, request): >> > self.context = context >> > self.request = request >> > >> > @view_config(decorator=adecorator) >> > def aview(self): >> > return Response('OK') >> > >> > You get the point. The *same decorator* will work against any view >> > callable you define, even though the place it gets used differs: >> > against a method of a class, against a class object, against a >> > function >> > object, and the associated callable may have different arguments. It >> > will still work in all scenarios. >> > >> > Since a decorator is just a callable that returns a callable, >> > whether >> > you use the package you linked to or not to produce one is >> > irrelevant. >> > Even the "@" syntax is just sugar. Instead of: >> > >> > @decorator1 >> > @decorator2 >> > def func(): >> > ... >> > >> > it could just be: >> > >> > def func(): >> > ... >> > >> > func = decorator2(decorator1(func)) >> > >> > If you're decorating functions or methods that you don't know the >> > argument list for, just make the decorator accept *arg, **kw and >> > pass >> > those along to the wrapped function from your wrapper function >> > defined >> > inside the decorator. That will work for any sort of wrapped >> > function, >> > even those for a view callable. >> > >> > If you mean you want to create some sort of omniscient decorator >> > that >> > can be used for both a view callable *and any other kind of >> > function*, >> > but which in both cases requires a request to.. do something.., >> > then, >> > yes, you could use get_current_request inside the decorator logic. >> > It'd >> > be insane to try to define such a decorator, when you could just >> > create >> > one that expected the decorated function to supply the (context, >> > request) signature, but you could do it. >> > >> > If this all boils down to "why dont you support a sequence rather >> > than a >> > single function as a valid decorator= argument" because you need to >> > mix >> > and match logic in your decorators, please either submit some code >> > that >> > makes it so or use the recipe for chained decorators. >> > >> > - C >> > >> > -- >> > You received this message because you are subscribed to the Google >> > Groups "pylons-discuss" group. >> > To view this discussion on the web visit >> > https://groups.google.com/d/msg/pylons-discuss/-/fhyzewf5dfkJ. >> > 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. >> > -- > You received this message because you are subscribed to the Google Groups > "pylons-discuss" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/pylons-discuss/-/vp2QABR9sV0J. > > 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. -- 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.
