On 12/14/10 11:24 AM, Chris McDonough wrote:
On Tue, 2010-12-14 at 10:36 -0800, Rob Miller wrote:
On 12/14/10 9:25 AM, Chris McDonough wrote:
In trying to think this through I've come up w/ a couple of ideas:

- I could write my own set of action decorators that implement the
desired functionality in addition to marking the wrapped functions as
exposed actions.  This would essentially be the same thing as stacking
multiple decorators around each of the functions, except that it avoids
having to stack multiple decorators around each of the functions.  ;)

- I could override the router itself, to allow me to keep the wrapped
functionality closer to the WSGI level.  Pyramid doesn't really provide
any hooks for this, however.  It'd be easy enough to change Pyramid to
fetch the router by interface rather than by class, making it possible
to supply an alternate router implementation, but there's a lot of code
in that __call__ method; I'm not terribly fond of copy/pasting large
blocks of code only to add a handful of additional lines to the middle
somewhere.

Does anyone have any other suggestions?  Opinions on the suggestions
I've made?  Has anybody out there thought about how to handle this
pattern in a Pyramid upgrade?

This is probably not a 100% solution, but have you seen
http://docs.pylonshq.com/pyramid/dev/narr/hooks.html#using-finished-callbacks ?

Yeah, I saw both the response and the finished callbacks, and am already
using them for other purposes.  But, as you said, they don't handle all
of the cases, especially not those where try: excepts are put around the
entire WSGIController.__call__ invocation.

Right now I'm leaning towards using a custom @action decorator.  This
decorator would call a method on the handler that would wrap the view
callable before adding the view callable to the registry.  I'll let you
know how it turns out.

I'd probably do it the other way around:

@view_config(...)
@mydecorator(...)
def aview(request):
     ...

or

class AHandler(object):
     def __init__(self, request):
         self.request = request

     @action(....)
     @mydecorator(...)
     def aview(self):

Both cases would add the *decorated* function / method to the registry,
which is probably what you want (the @action and @view_config
dectorators just attach attributes to the function / method, they don't
actually wrap the callable when it is called).

Yeah, that's essentially what I meant, sorry for being unclear. I'm thinking a bit more syntactic sugar, though, something along the lines of:

class AHandler(object):
    def __init__(self, request):
        self.request = request

    @classmethod
    def _action_wrapper(klass, wrapped):
        def action_method_wrapper(self, *args, **kw):
            <do stuff>
            ret = wrapped(self, *args, **kw)
            <do more stuff>
            return ret
        return action_method_wrapper

    @myaction(...)
    def aview(self):
        <regular view code>

Then the myaction decorator would call AHandler._action_wrapper(aview) to generate a wrapped view callable, which would then finally be registered. This is only half-baked; I'm not even sure I can _get_ to the AHandler class from within the myaction decorator yet, but if I can then this would let me mirror the existing controller class hierarchy with a set of handler classes, moving the code from the older __call__ methods to the newer _action_wrapper class methods w/o too much of a conceptual leap.

does this seem like it would work?

-r

--
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to pylons-disc...@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-discuss+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to