[PEAK] dispatch -- chaining decorators
Phillip J. Eby
pje at telecommunity.com
Fri Dec 9 15:29:22 EST 2005
At 08:31 PM 12/9/2005 +0100, Simon Belak wrote:
>Hi,
>
>I have a decorator I would like to use along-side generic functions but I
>am having some trouble getting it to play along:
>
>
>def unpickle(arg_name):
> def __entangle(func):
> pickle_pos = list(func.func_code.co_varnames).index(arg_name)
> assert pickle_pos < func.func_code.co_argcount
> def __func(*args, **kwargs):
> return func(*args[:pickle_pos] +
> (load(args[pickle_pos]),)
> + args[pickle_pos+1:],
> **kwargs)
> return __func
> return __entangle
>
>
>When I apply this decorator on an "around" function:
>
>
>@unpickle("form")
>@view.around("is_pickle(form)")
>def unpickle_form(next_method, form, context):
> next_method(form, context)
>
>
>one of two things happen depending on order in which decorators were
>applied. Either argument position gets wrongly calculated (around,
>unpickle) or my decorator does not get called at all (unpickle, around).
>
>I am guessing that in the first case next_method the causing me troubles,
>but what about the second case? Any good wraparounds?
You want to use around+unpickle, because you want the unpickling to apply
to the individual method, in the individual case. The problem you're
having is that __func doesn't have a 'next_method' argument, so the generic
function doesn't pass it one, throwing off the argument order.
A trivial fix would be for __entangle to check 'func' for a next_method
argument, and to define a variant def __func(next_method, *args, ...) in
that case.
(Meanwhile, note that if you have a bunch of
around("something(some_param)") cases, you're likely going to end up with
method ambiguities.)
>On a not-so-related note, can generic functions be overused?
Maybe. I haven't encountered such a situation yet, myself. In my
experience they mainly save me from writing a bunch *more* stuff, or
replace a bunch of stuff I already had, with *less*. So, it seems like
overuse of generic functions would mean you'd have no code at all left, and
so it's hard to see how that would be a *bad* thing, actually. :)
> I am currently writing a framework and just realised that nearly all
> exposed functions have become generic. To me it seems that this allows
> perfect flexibility and modularity as the user can plug in his code
> almost anywhere. But still I cannot completely silent a voice in the back
> of my mind screaming "Danger of cool things!".
I can't know without understanding your framework if that's the case. But
if generic functions aren't reducing the *number* of operations you have,
then I would be concerned. Note that peak.security.rules uses two generic
functions and three classes in order to implement a fairly sophisticated
ACL framework. If your framework isn't dissolving into a surprisingly
small number of simple generic functions, I'd say you're right to worry,
because it means you haven't assimilated them yet, and therefore might well
be "overusing" them. But if they're *dissolving* the framework, then you
have assimilated them (or they've assimilated you), and everything's fine.
(I say "dissolving" because peak.security.rules is technically a framework,
and yet it's so lightweight there doesn't seem to be any "framework" left;
it looks and smells more like a library than a framework, and that's
definitely the place you want to get to.)
More information about the PEAK
mailing list