[PEAK] gf.when() doesn't honour Interfaces on instances
(protocols.adviseObject)
Ulrich Eck
ueck at net-labs.de
Thu Dec 2 09:35:46 EST 2004
Hi Phillip,
i played around with GenericFunctions/Dispatch to build a trivial
publishing workflow. The idea for this implementation is based on some
work i did with jim fulton for zope3 worklfow as a prototype.
In this idea, Interfaces represent the object's state and transitions
change some of the Interfaces the object implements.
A StateInterface inherits from a ProcessInterface, CompositeStates are
represented via InterfaceInheritance. There might be some metadata about
the StateConfiguration stored in some Attribute (optionally) or
StickyAdapters.
this is my module that defines the PublishingProcess Interfaces and an
Object that Implements the Process with generic functions:
------------------------------------------------------------
import dispatch, protocols
from dispatch import strategy
import workflow
class CallEvent(object):
def __init__(self, name, args=(), kw={}):
self.name=name
self.args=args
self.kw=kw
def __repr__(self):
args = ",".join(self.args)
kw = ",".join(["=".join(item) for item in self.kw.items()])
if kw:
return "%s(%s,%s)" %(self.name,args,kw)
return "%s(%s)" %(self.name,args)
class IState(protocols.Interface):
"""IState"""
__state_config__ = protocols.Attribute('StateConfig dictionary')
def callMethod(event):
"""Trigger all Transitions that match this CallEvent
usually implemented as generic function.
"""
class IPublishingProcess(IState):
"""A Publishing Process."""
class IPPStatePrivate(IPublishingProcess):
"""Private State."""
class IPPStatePending(IPublishingProcess):
"""Pending State."""
class IPPStatePublished(IPublishingProcess):
"""Published State."""
class PPObject(object):
"""Some object with a State."""
protocols.advise(
instancesProvide=[IPublishingProcess]
)
__state_config__ = None
# callMethod = workflow.callMethodFor(IPublishingProcess) ???
[dispatch.generic(strategy.single_best_method)]
def callMethod(self, event):
"""GenericFunction."""
[callMethod.when("self is IPPStatePrivate and
event.name=='submit'")]
def callMethod_submit(self, event):
print "Submit", event
protocols.adviseObject(self,provides=[IPPStatePending],
doesNotProvide=[IPPStatePrivate])
[callMethod.when("self is IPPStatePending and
event.name=='publish'")]
def callMethod_publish(self, event):
print "Publish", event
protocols.adviseObject(self,provides=[IPPStatePublished],
doesNotProvide=[IPPStatePending])
[callMethod.when("self is IPPStatePublished and
event.name=='retract'")]
def callMethod_retract(self, event):
print "Retract", event
protocols.adviseObject(self,provides=[IPPStatePrivate],
doesNotProvide=[IPPStatePublished])
--------------------------------------------------------------------
and i do the following in my python-prompt, the result is not what i'ld
expect:
Python 2.3.4 (#2, Dec 1 2004, 09:11:25)
[GCC 3.3.5 (Debian 1:3.3.5-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import protocols
>>> import wftest
>>> o = wftest.PPObject()
>>> protocols.adviseObject(o, provides=[wftest.IPPStatePrivate])
>>> wftest.IPPStatePrivate(o)
<wftest.PPObject object at 0x40515ecc>
>>> o.callMethod(wftest.CallEvent('submit'))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 5, in callMethod
File "/usr/lib/python2.3/site-packages/dispatch/functions.py", line
319, in __getitem__
raise NoApplicableMethods
dispatch.interfaces.NoApplicableMethods
it seems, the dispatch.when does some optimization that prevents it from
being able to recognize that the PPObject implements the Interface
needed to match the spec.
am i doing something wrong?
is the behaviour intended?
thanks for your comments
Ulrich
--
Ulrich Eck <ueck at net-labs.de>
net-labs Systemhaus GmbH
More information about the PEAK
mailing list