[lxml-dev] Issues with objectify.ObjectifiedElement: assignment, attribute handling, and documentation

jholg at gmx.de jholg at gmx.de
Mon Oct 8 09:59:01 CEST 2007


Hi Michael,

> My main problem is that assigning a new value to an
> objectify.DataElement destroys the existing attribute list.  My current
> workaround is to retrieve the attributes with the items() call, assign
> the new value, and then reapply attributes with set() method for each
> pair in the items dict.  I dug through the API documentation and I did
> not see a way around this issue.  Am I missing something here?

objectify maps element data to simple python builtins, so it treats them as immutable, i.e. you cannot modify element.text. This is intentional and not going to change (I hope :)

With 2.0alpha, you could however do this to keep your attributes:

>>> msg.a = 12345
>>> msg.a.set("foo", "bar")
>>> print objectify.dump(msg)
msg = None [ObjectifiedElement]
    a = 12345 [IntElement]
      * py:pytype = 'int'
      * foo = 'bar'
>>> msg.a = objectify.DataElement("changeMe", attrib=dict(msg.a.attrib))
>>> print objectify.dump(msg)
msg = None [ObjectifiedElement]
    a = 'changeMe' [StringElement]
      * py:pytype = 'str'
      * foo = 'bar'
>>>

Note that the foo attribute remains intact, whilst the py:pytype gets corrected to s.th. that fits the element value.

> I thought about subclassing DataElement and then I scanned the SVN
> development change list.  I saw some discussion about preserving _pytype
> or _xsi attributes, but does this include ALL attributes?  If so, I will
> proceed with a build from the latest SVN copy.  How stable are dev
> versions?  Are there automated acceptance tests (unittest) that gate the
> check in?  I may just use my workaround until 1.3.5 arrives.

Generally I'd say the dev versions are still very stable with regard to robustness, but of course feature-wise they can be in flux.

> Another issue I noticed is that if I specify _xsi='int', the _pytype
> attribute will be 'long' instead of 'integer', so I am forced to use
> _pytype='integer' for all integer data elements.  Also, if you run
> objectify.annonate(), the integer becomes a long type again.  Annotate
> should look to the _xsi or even pyval type.  Has this been fixed?  This
> is not really an issue for me, since I always keep the list annotated.

Please try 2.0alpha, the behaviour with regard to py:pytype/xsi:type has been tweaked a little, and some parts now behave more "natural". There's also now a triplet of annotation functions (pyannotate, xsiannotate, annotate) that give you fine-grained control of annotation. The most prominent change is that you get auto-pytypification now:

>>> msg.a = 999
>>> print objectify.dump(msg)
msg = None [ObjectifiedElement]
    a = 999 [IntElement]
      * py:pytype = 'int'
>>>

Here, the actual Python type of the RVAL of the assignment gets taken into account now.

Regarding your example, explicitly setting _xsi="int" gives

>>> msg.a = objectify.DataElement(8, _xsi="int")
>>> print objectify.dump(msg)
msg = None [ObjectifiedElement]
    a = 8 [IntElement]
      * py:pytype = 'int'
      * xsi:type = 'xsd:int'
>>>

I do think it's just the same with 1.3, so I think you might have mixed s.th. up here.
However, specifying _xsi="integer" will result in:

>>> msg.a = objectify.DataElement(8, _xsi="integer")
>>> print objectify.dump(msg)
msg = None [ObjectifiedElement]
    a = 8L [LongElement]
      * py:pytype = 'long'
      * xsi:type = 'xsd:integer'
>>>

This is due to the XML Schema type system, where an XML Schema integer is
not restricted to 32 bits, like a Python int (still is), see
 
http://www.w3.org/TR/xmlschema-2/

Holger
-- 
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail


More information about the lxml-dev mailing list