[z3-five] Does Five support Local Utilities?

Chris Withers chris at simplistix.co.uk
Tue Sep 19 11:43:03 CEST 2006


Philipp von Weitershausen wrote:
>> def setInput(self,name):
>>   input = getUtility(IInput,name)
>>   if IConfigurableComponent.providedBy(input):
>>       input = deepcopy(input)
>>   self.input = input
>>
>> ...in order to be able to configure the input for that particular 
>> Twiddler instance, without that configuration affection the use of the 
>> input in all instances that use it.
>>
>> I don't know how evil the above it, would be interested on people's 
>> views...
> 
> I don't understand the pseudo code above. What's your goal?

Hmm, IInput is a bad example here, lets switch to IOutput... The same 
code above applies, just replace "Input" with "Output"

There are true global utilities that require no configuration that 
implement IOutput, such as the default output renderer which takes the 
Twiddler DOM and turns it into a lump of text:

from twiddler.interfaces import IOutput
from *somewhere* import _render
def Default(root,*args,**kw):
     output = []
     _render(output, root._root, {})
     return u''.join(output)
directlyProvides(Default,IOutput)

This is easy enough to expose through the following zcml:

<utility provides="twiddler.interfaces.IOutput"
          component="twiddler.output.default.Default"
          name="Default"/>

However, I was hoping to use something like utilities for objects that 
implement the same interface but which require configuration. For 
example, Twiddler has an output renderer that returns an 
email.MIMEMultiPart-ish object which also has a send method:

class Email:

     implements(IOutput)

     def __init__(self,
                  smtp_host='localhost',
                  smtp_port='25',
                  mfrom=None,
                  mto=None,...etc...)
         # do stuff
         pass


     def __call__(self,root,*args,**kw):
         # gubbinz goes here
         return MTMultipart(self,
                            values['mfrom'],
                            values['mto'],
                            **multipart_kw)

As you can see, this has configuration that is likely to be specific to 
the individual Twiddler: who the email is to, what smtp server to use, 
etc. Of course, you *might* want to share this between several twiddlers 
if, for example, you're sending several different mails but that all 
share the same From address and use the same smtp server.

I currently have this registered using the following zcml:

<utility provides="twiddler.interfaces.IOutput"
          factory="twiddler.output.emailer.Email"
          name="Emailer"/>

...which, given what you've told me previously, is why I have the 
deepcopy in the Twiddler.setInput pseudocode above. The logic is roughly 
"if the input/output/whatever if configurable, then copy it and store 
the copy, otherwise just store a reference to the global utility"...

Is that evil?

Chris

-- 
Simplistix - Content Management, Zope & Python Consulting
            - http://www.simplistix.co.uk


More information about the z3-five mailing list