[Twisted-Python] Question about plugins tutorial

I've been reading through the tutorial section on Twisted Plugins at: http://twistedmatrix.com/projects/core/documentation/howto/plugin.html I have a question about this code (the actual plugin from the tutorial) from twisted.plugin import IPlugin from matsim import imatsim class SimpleMaterial(object): implements(IPlugin, imatsim.IMaterial) def __init__(self, yieldStressFactor, dielectricConstant): self._yieldStressFactor = yieldStressFactor self.dielectricConstant = dielectricConstant def yieldStress(self, temperature): return self._yieldStressFactor * temperature steelPlate = SimpleMaterial(2.06842719e11, 2.7 + 0.2j) brassPlate = SimpleMaterial(1.03421359e11, 1.4 + 0.5j) The tutorial implies, but does not say directly, that plug-ins should not just define a class that implements IPlugin and your interface, but instantiate an object. This code (also from the example) iterates over returned plugins (actually according to the example, the objects steelPlate and brassPlate). def displayAllKnownMaterials(): for material in getPlugins(imatsim.IMaterial): displayMaterial(material) If my understanding is correct, then # plugin class Foo(object): implements(IPlugin, imyplugins.IMyPlugIn) def fooStuff(self): # do foo stuff # end plugin #call plugin from app for n in getPlugins(imyplugins.IMyPlugIn): n.fooStuff() Won't work. I'd need to do this # plugin class Foo(object): implements(IPlugin, imyplugins.IMyPlugIn) def fooStuff(self): # do foo stuff f = Foo() # end plugin #call plugin from app for n in getPlugins(imyplugins.IMyPlugIn): n.fooStuff() But I'm looking at the Plugins as a way to abstract multiple back-end actions taken in response to data recieved by a number of asynchronous events (off of LineReciever and XML-RPC). The plug-in is going to need to keep some intermediate state data in some cases, which won't work if they all get the same object. So I was thinking of something along these lines: # plugin class Foo(object): implements(IPlugin, imyplugins.IMyPlugIn) def fooStuff(self): # do foo stuff def fooFactory(self): return Foo() f = Foo() # end plugin #call plugin from app for n in getPlugins(imyplugins.IMyPlugIn): o = n.fooFactory() o.fooStuff() Does this make sense? Is there a better way in the twisted framework to handle this?

On 4/4/07, Brian Costlow <brian.costlow@gmail.com> wrote:
But I'm looking at the Plugins as a way to abstract multiple back-end actions taken in response to data recieved by a number of asynchronous events (off of LineReciever and XML-RPC). The plug-in is going to need to keep some intermediate state data in some cases, which won't work if they all get the same object. So I was thinking of something along these lines:
# plugin class Foo(object): implements(IPlugin, imyplugins.IMyPlugIn)
def fooStuff(self): # do foo stuff
def fooFactory(self): return Foo()
f = Foo() # end plugin
#call plugin from app for n in getPlugins(imyplugins.IMyPlugIn): o = n.fooFactory() o.fooStuff()
Does this make sense? Is there a better way in the twisted framework to handle this?
Yep: making your plugins factories is a common pattern. There's also often a conditional checking something about 'n' before calling the fooFactory on it (for example, is it the one the user requested by name? etc) -- Christopher Armstrong International Man of Twistery http://radix.twistedmatrix.com/ http://twistedmatrix.com/ http://canonical.com/

On Wed, 2007-04-04 at 10:37 -0400, Brian Costlow wrote:
But I'm looking at the Plugins as a way to abstract multiple back-end actions taken in response to data recieved by a number of asynchronous events (off of LineReciever and XML-RPC).
This is only useful if you need to plug-in new actions, either by 3rd parties or as a configuration measure. If the actions are fixed, an easier way to do it is command dispatch to appropriately named methods, like the way XML-RPC dispatches a "foobar" command to the method xmlrpc_foobar, or to appropriate command-handling objects.

* Brian Costlow <brian.costlow@gmail.com> [2007-04-04 10:37:20 -0400]:
# plugin class Foo(object): implements(IPlugin, imyplugins.IMyPlugIn)
def fooStuff(self): # do foo stuff
def fooFactory(self): return Foo()
f = Foo() # end plugin
#call plugin from app for n in getPlugins(imyplugins.IMyPlugIn): o = n.fooFactory() o.fooStuff()
Does this make sense? Is there a better way in the twisted framework to handle this?
The other replies to your posts raise some good points, but I would just like to point out that classes themselves can be used as plugins. For example: class Foo(object): classProvides(IPlugin, IMyPlugin): def fooStuff(self): """Does foo stuff.""" for cls in getPlugins(IMyPlugin): o = cls() o.fooStuff() -- mithrandi, i Ainil en-Balandor, a faer Ambar
participants (4)
-
Brian Costlow
-
Christopher Armstrong
-
Itamar Shtull-Trauring
-
Tristan Seligmann