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.

Reply via email to