[Twisted-Python] config interface

Glyph Lefkowitz glyph at twistedmatrix.com
Wed Apr 11 07:31:32 EDT 2001

On Sunday 08 April 2001 20:04, you wrote:
> configurable objects are organized in a tree. Every object defines these
> methods:

>     #ContainableTypes should return a list of classes that
>     #it can hold.
>     def configContainableTypes(self): pass

This seems fine...

>     #Type should return the type of the current object
>     def configType(self): pass

I don't think this is necessary though.  Can't you just use the Python class?

>     #GetContents should return a dict of children of this object. {"name":
> obj} def configGetChildren(self): pass

Seems like a list of tuples (.items() style) might be more appropriate than a 
dict, considering that this really isn't mutable.

>     #AddItem should add a child to this object
>     def configAddItem(self, id, item): pass

Also fine...

>     #RemoveItem should remove a child from this object.
>     def configRemoveItem(self, id): pass

> I'd like to change this API somewhat to allow different paramaters to add
> and remove item methods. Not all objects need ids to add an object, and
> it's not natural for some objects to represent their contents as a dict
> (selectors, for instance). I was thinking about a solution similar to the
> improper-state trick that glyph described to me, only it would just look at
> the arguments that a method needs rather than a constructor of a class.

That trick is a necessary addition to the API in any case -- these functions 
aren't enough.  However, you might want to have ConfigurableDictionary, 
ConfigurableItem, and ConfigurableSequence types which have different ideas 
about how things get added to them.

In order for new configurable things to be instantiatable, you'll need API 
additions like:

def configGetRequiredInitArgs(self)

This returns a 2-tuple of a sequence and a hash.  The first sequence is a 
list of types/classes of the required arguments, in order, and the second is 
a hash of name:type/class of optional argument.

These arguments get filled in by your configuration interface code, and 
passed to:

def configCheckInitArgs(self, args, kw)

This to separate preconditions of the init from the init itself -- if this 
indicates there's something wrong with the arguments (for example, an integer 
is outside of its acceptable range) then this message can be displayed to the 
user for them to try again.

def configDoInit(self, args, kw)

This will most likely be a passthru to self.__init__, probably frequently 
enough to make that the default implementation, but since 
configGetRequiredInitArgs may want to do some pre-initialization, things 
could be different.

Note that if something returned by configGetRequiredInitArgs is a class, that 
class be configurable as well -- that, and your interface may need to be 
somewhat recursive in order to allow you to pass configurable elements to the 
initializers of other configurable elements... I'd recommend trying to get 
something work only supporting basic types at first.

Also, what are you planning on doing for configuring an object's attributes?  
It seems like that should behave differently from configuring the objects it 

                      ______      __   __  _____  _     _
                     |  ____ |      \_/   |_____] |_____|
                     |_____| |_____  |    |       |     |
                     @ t w i s t e d m a t r i x  . c o m

More information about the Twisted-Python mailing list