On Thu, Jun 21, 2012 at 06:59:03AM -0700, Max Avanov 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, ...))
Woo-hoo! Looks like this thread just went another time around the racetrack!
Go a few messages back and Chris says:
"lack of framework-based multiple decorator support just hasn't
been a real pressing issue for anyone, especially given the linked
recipe. If we're lucky, someone for whom it seems to be a pressing
issue can help provide a patch that integrates the linked recipe into
the config with docs and tests."
Which looks to me to be exactly what you want above. So, if this is a
pressing issue for you, please "help provide a patch that integrates the
linked recipe into the config with docs and tests."
>
>
> 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.
>
--
Brian Sutherland
--
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.