[PEAK] dispatch: around generic function with next_method (bug)
Radek Kanovsky
rk at dat.cz
Mon Jan 17 13:42:06 EST 2005
On Mon, Jan 17, 2005 at 11:42:49AM -0500, Phillip J. Eby wrote:
> It's method_chain() that's broken, it should be able to safely chain method
> chains, but I didn't write a test that exercised the case where a callable
> is a chain with a 'next_method'. I've added a test case now and fixed it.
>
> Thanks for all the useful bug reports; I haven't made any real use of
> before/after/around stuff yet myself, just the tests.
I discovered bug during experiments with my TemplateFunction. It was
rather hard as I blamed myself formerly :-) Purpose of TemplateFunction
could be obvious from small example:
# template function parametrized by three parameters
# (parameters do not correspond to function arguments)
tf = TemplateFunction(['p1','p2','p3'])
[tf.t_when('p1 in object')]
def whenDefault (a1, a2) :
print 'whenDefault'
[tf.t_when('p1 in int')]
def whenInt (next_method, a1, a2) :
print 'whenInt'
next_method(a1, a2)
[tf.t_around('p2 in object')]
def aroundDefault (next_method, a1, a2) :
print 'aroundDefault'
next_method(a1, a2)
# create callable function for given parameters
cf = tf[1,'a', None]
# use compiled function many times
>>> cf(1,1)
aroundDefault
whenInt
whenDefault
I am not sure about syntax, names and all of its usability nevertheless
the first draft is here:
from peak.core import *
from dispatch.functions import GenericFunction, Dispatcher
from protocols.advice import add_assignment_advisor, getFrameInfo
import sys
class TemplateFunction (Dispatcher) :
def __init__ (self, params) :
Dispatcher.__init__(self, params)
combine = GenericFunction.combine.im_func
def _decorate(self, cond, qual) :
frame = sys._getframe(2)
cond = self.parseRule(cond, frame=frame) or cond
def registerMethod(frm, name, value, old_locals) :
func = qual,value
kind,module,locals_,globals_ = getFrameInfo(frm)
if kind=='class':
raise NotImplementedError
else:
self[cond] = func
#if old_locals.get(name) in (self,self.delegate):
# return self.delegate
return value
return add_assignment_advisor(registerMethod,frame=frame)
def t_when (self, cond) :
return self._decorate(cond, 'primary')
def t_before (self, cond) :
return self._decorate(cond, 'before')
def t_after (self, cond) :
return self._decorate(cond, 'after')
def t_around (self, cond) :
return self._decorate(cond, 'around')
RadekK
More information about the PEAK
mailing list