[lxml-dev] Objectify nodes can't have real attributes

Stefan Behnel stefan_ml at behnel.de
Fri Feb 16 08:22:34 CET 2007


Hi Tres,

sorry, big confusion. Was late yesterday.

Tres Seaver wrote:
> Stefan Behnel wrote:
>> Tres Seaver wrote:
>>> For a project I'm currently working on, I want to create nodes by
>>> parsing an XML document, and then bind a Zope3 interface to the node, in
>>> order to allow for compmonent lookup.  With classic elementtree nodes,
>>> and with lxml.etree nodes, I can.  However, the nodes produced by
>>> lxml.objectify don't allow this.
>>
>> I never used zope.interfaces, so maybe I'm not the right person to try an
>> answer here, but the problem is that lxml.objectify has to do all sorts of
>> tricks to make an element look like a list and the like. Just like
>> zope.interfaces does all sorts of tricks (metaclasses and the like) to allow
>> things like "implements()" in a class body. Both don't seem to work that well
>> together...
> 
>> The main problem is that assignments to __provides__ end up in the child
>> lookup machinery of ObjectifiedElement's __getattr__. Maybe you could try to
>> override __getattr__ and intercept the assignment?
> 
> Do you mean '__setattr__' here?

Mainly, yes. Note that that usually does the same thing as __getattr__ first,
that got me confused.


>> Anyway, here is a pretty hackish third trick that updates the interfaces
>> provided by an object once you used "implements()" to assign a first one.
[...]
> I'm afraid that is mutating the class-level value, set by the
> 'implements()' call.  I need to override this on an instance level.  I
> may be out of luck, due to the fact that objectify overrides both
> '__setattr__' and '__dict__'.

True. It has to, though.


>> Properties/descriptors should make a
>> difference here, but zope.interfaces already uses them in a couple of
>> places, so they may be hard to apply.
>
> I can't see how I could use a property / descriptor here

Again, my fault. I only saw my own comment in __setattr__ now that says
"properties are looked up /after/ __setattr__" ... ;o)

We might consider special casing "__*" names in general and handle them
ourselves, but object.__?etattr__() will not work straight away as we are
dealing with C classes (builtins) here that do not support things like
__dict__ by themselves.

I'm not sure how we could support this, especially, since we are only dealing
with element proxies here. You will loose the information about supported
interfaces whenever the element object is garbage collected. So, this will
only make any sense if you take care yourself that proxies are kept alive.

So, this one is rather tricky and at the same time error prone as it will not
work without extra care by the user. It might be useful for other
applications, too - I'm just not sure it's worth going into too much trouble.

Stefan




More information about the lxml-dev mailing list