[Dev] XML for CPIA

Phillip J. Eby pje at telecommunity.com
Wed Aug 10 14:06:48 PDT 2005


At 01:36 PM 8/10/2005 -0700, Alec Flett wrote:
>Phillip J. Eby wrote:
>>I would imagine that if we were using Python to create items in the first 
>>place, the evolutionary pressure would've been towards providing simpler 
>>constructors or utility functions as part of the CPIA API, because those 
>>could be done by just writing new methods or functions, not by needing to 
>>change an XML format.
>now we're getting somewhere. I'd like to hear some suggestions about how 
>this could be done though. I mean is there a smarter way to use .update() 
>by fixing up the constructors? I thought .update() worked by constructing 
>the object, and then assigning attributes - but maybe what you're saying 
>is the arguments to .update() go directly to the constructor?

Only for new item creation; otherwise they are set as attributes.  This 
doesn't mean you can't tweak the process.  I was mainly thinking that for 
specialty constructors you'd define classmethods or functions that then 
call down to update() as needed, and possibly do postprocessing on the 
arguments (e.g. to set up a hierarchy).


>If that's the case then yeah, this does get a little simpler.... but 
>honestly, I'm still skeptical.
>
>The things that are rubbing me the wrong way with .update() and CPIA are:
>1) childrenBlocks & hierarchy - I want a system where the hierarchy is implied
>1a) A "nice to have" would be making the repository child relationship 
>match the childrenBlocks hierarchy - this is extraordinarily painful with 
>python at the moment and requires lots of temporaries.
>2) itsName vs. blockName - I should not have to declare them seperately.

For these you'll have to talk to a CPIA person.

>3) anonymous block names/itsname/etc - for instance menu separators don't 
>need itsName but .update() requires them to be consistently findable with 
>the same name.

If you're using a hierarchy, you could certainly delete those children and 
recreate them.


>4) Having to repeatedly pass in 'parcel' as the first parameter of every 
>single update() call.

In Python 2.5, the 'with' statement will let us fix this syntactically, but 
we could perhaps have a 'setCurrentParcel()' API in the meantime.  Or set 
"p=parcel" at the top of your installParcel() and just type 'p,' as the 
first parameter.  :)


>You can fix ALL of these problems with a declarative syntax and a 
>processor for that syntax.

And whatever you were able to implement to do those things would also be 
usable as a declarative syntax in Python, with basically the same amount of 
code.


>(2) could be solved by CPIA eliminating blockName and falling back to the 
>repository name - but I think we'd have to stop copying blocks to 
>//userdata to solve that problem.
>
>An alternative that I was debating was some sort of big hierarchical 
>list/dict system directly in python like:
>
>[Menu, { blockName='FileMenu', title=_('File') },
>  [NewMenu, { blockName='NewMenu', title=_('New...'), ...},
>    [MenuItem, {blockName="NewMessageItem", ..}],
>    [MenuItem, {blockName="NewNoteItem", ...}]
>  ]
>]

from somewhere.cpia_templates import Menu, MenuItem

Menu("FileMenu", _('File'), [
     Menu("NewMenu", _('New...'), [
         MenuItem("NewMessageItem", _("Message"), ...),
         MenuItem("NewNoteItem",    _("Note"), ...),
     ])
]).install(parcel)


where the translation is something like:

     class template(object):
         child_attrs = ()
         target_class = None

         def __init__(self, itsName, **attrs):
             self.attrs = attrs
             self.itsName = itsName

         def install(parent,name=None):
             if name is None: name=self.itsName
             me = target_class.update(parent,name)  # make parent exist
             attrs = self.attrs.copy()
             for attr in self.child_attrs:
                 if attr in attrs:
                     attrs[attr] = [
                         t.install(me) for t in attrs[attr]
                     ]
             return target_class.update(parent,name,**attrs)

     class Menu(template):
         child_attrs = ('childrenBlocks',)
         target_class = blocks.Menu

         def __init__(self, itsName, title, ..., **attrs):
             super(Menu,self).__init__(itsName, title=title, ..., **attrs)

You'll notice that this relatively simple arrangement can takes care of all 
your requests except item #3, which I'd need to think about a little more 
before proposing a solution.

Also, although I've written this as a set of template classes, this could 
be hacked a little so there's only one template class, and everything else 
is a factory method on the target classes.


>But this is basically xml-translated-into-lists-and-dicts and seemed a 
>little silly - I mean when writing it its harder to figure out the correct 
>syntax, brace balancing, and so forth.. furthermore you'd STILL have to 
>write some sort of processor for this datastructure. Since there are tools 
>to do this for you with XML (emacs, eclipse, you name it) it just makes 
>more sense to me to do this in XML
>
>If you have another specific suggestion for improving cpia's API to make 
>this cleaner, I'm all ears.



More information about the Dev mailing list