Anthony Pfrunder wrote:
I'll submit them again but basically this is how to patch it: * For all creation DOM methods (clone, createXX ...) you need to add some hidden magical methods to stop weird errors from occuring. Here is how:
# This makes the aquisition path point to the current containing # document. These attributes doesn't exist after a creation call hence, # aquisition doesn't work properly.
def XMLpatch(self, p): p.aq_acquire = self.aq_acquire p.aq_base = self.aq_base return p
Then, for each creation call wrap it like such:
def createTextNode(self, data): return self.XMLpatch(Document.createTextNode(self, data))
here, Document is an XML document and data is the actual content of the Text Node (I think).
Hmm. I'd like to know more about what sort of weird errors this patch fixes. (Ideally I like to see a snippet of code which demonstrates the problem.) In general, hacking an object's 'aq_acquire' method and 'aq_base' attribute is not a good idea. In general the right thing to do is to wrap an object with an acquisition wrapper so that it has the correct acquisition context. That said, I've been talking with Martijn Faassen about some ways in which the XML Document doesn't work well with the DOM API because of acquisition. The problem is that the DOM seems to assume that arguments to methods are changed. For example, foo.removeChild(bar) # does not actually change bar's parent is assumed to change bar, not just foo. This doesn't work with XML Document since it uses acquisition to keep track of parent nodes. Since bar is an acquisition wrapper (which is immutable) we cannot change its parent. Note however, that most DOM methods like this return their arguments so you can get the changed bar as the return value of this method. bar=foo.removeChild(bar) # returns correctly wrapped bar It's fairly easy to work around these problems, but still it would be nice to have a more robust solution, since this sort of gotcha is subtle, and likely to trip up folks. It may be that using acquisition is not the right solution for XMLDocument Nodes to keep track of their parents. I'm open to suggestions (and patches). -Amos -- Amos Latteier mailto:amos@digicool.com Digital Creations http://www.digicool.com
[Anthony's patches to XMLDocument creation functions snipped] Ah, I had seen these and discussed them with Amos, but I just wasn't sure if *you* had. :) Amos Latteier wrote:
Hmm. I'd like to know more about what sort of weird errors this patch fixes. (Ideally I like to see a snippet of code which demonstrates the problem.)
I'm curious too. I could try them out sometime with my XMLWidgets/ZAML system, I suppose.
In general, hacking an object's 'aq_acquire' method and 'aq_base' attribute is not a good idea. In general the right thing to do is to wrap an object with an acquisition wrapper so that it has the correct acquisition context.
That said, I've been talking with Martijn Faassen about some ways in which the XML Document doesn't work well with the DOM API because of acquisition.
The problem is that the DOM seems to assume that arguments to methods are changed.
[snip]
Note however, that most DOM methods like this return their arguments so you can get the changed bar as the return value of this method.
bar=foo.removeChild(bar) # returns correctly wrapped bar
It's fairly easy to work around these problems, but still it would be nice to have a more robust solution, since this sort of gotcha is subtle, and likely to trip up folks.
As I mentioned to Amos, the problems can be triggered in more subtle ways too: For instance: # temporarily store reference to first child of node temp = node.getFirstChild() # remove all child nodes of node for child in node.getChildNodes(): node.removeChild(child) # now try to add temp again node.appendChild(temp) One can work around this one too, but I just wanted to point out it can be more difficult than just using the return value. I'd be nice if Anthony had some data on how his patches behave under these circumstances.
It may be that using acquisition is not the right solution for XMLDocument Nodes to keep track of their parents. I'm open to suggestions (and patches).
Still thinking about this one. :) Regards, Martijn
Hi, I haven't have a chance to try Amos' patch yet (very busy atm but always time for email ;) but I'm wondering if there is a developers guide or something which describes all the acquisition and _/__ attributes and what they are used for (apart from the source). I'm guessing that Element().__ofF__(self) returns the element with an aquisition path pointing to the object referred to by self?? The errors that prompted me to add aq_aquire and aq_base were in the following (general situation): Create an XML Document -> class XMLManager(XMLDocument) x = XMLManager() Create a node --> z = x.createTextNode(data) Add new node to ANOTHER node within same Document x.appendChild(z) Now, if it were not wrapped attribute errors complaining about aq_* would be triggered upon accessing attributes of the new node and aquired methods would also trigger aq_* attribute missing errors. I added them to all "creation" methods and it worked properly henceforth! I can paste a full traceback but it is rather large due to recursive calls I make within the VisualZope system. Cheers, Anthony Pfrunder
participants (3)
-
Amos Latteier -
Anthony Pfrunder -
Martijn Faassen