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 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