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

Tres Seaver tseaver at palladion.com
Fri Feb 16 18:03:48 CET 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stefan Behnel wrote:
> 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.

The bigger difference for my case is the Python calls '__getattr__' as a
*fallback*, but calls '__setattr__' *every time*.  Without a "real"
__dict__ to put my "special" attributes in, I can't even override
'__setattr__'.

>>> 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.

If the node would at least honor slot assignment, that would be enough,
I think.

> 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.

For my case, the node object only has to stay around for the duration of
an HTTP request, which it will do, because it is the "published" object.
 I have code in hand which "stamps" the interface onto the node whenever
it is used in this way, so I should be OK.

> 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.

I've punted for now, and am using the objectify nodes from within a
Zope3 view on the "container" object.



Tres.
- --
===================================================================
Tres Seaver          +1 540-429-0999          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF1eP0+gerLs4ltQ4RAqQ2AJ0VgH8u9qydsqQOEhiVJzpIBDZMOgCeI842
+T5vZ+ctRfJFrigpSm4vJxs=
=O8y+
-----END PGP SIGNATURE-----



More information about the lxml-dev mailing list