[lxml-dev] Losing namespace information after deepcopy()

Hello! This is new since 1.0: after deepcopying certain structures, namespace information gets lost. Attached is a small test case, if you run it you'll see that the 't' namespace is not displayed in a string representation of a copy of the node with the t:foo attribute. I'm really clueless what could cause this... Hope the snippet helps. Cheers, Guido P.S. Thanks for the file issue fixes, works like a charm now.

Hi Johnny, Johnny deBris wrote:
Thanks for the report and the test case, I can reproduce this. It looks like copying fake root documents lets us loose namespace information. I had changed the deepcopy method in 1.0 to use fake root documents to avoid creating new documents and get a 'more complete' copy of the original. Well, more data on one side, loss of information on the other. I also found that deepcopy did not previously copy the tail of an element. This is now ET compatible. Both bugs are fixed in the current trunk and the 1.0 branch. Deep copying now uses this function throughout lxml: ------------------------------- cdef xmlDoc* _copyDocRoot(xmlDoc* c_doc, xmlNode* c_new_root): "Recursively copy the document and make c_new_root the new root node." cdef xmlDoc* result cdef xmlNode* c_node result = tree.xmlCopyDoc(c_doc, 2) # non recursive, but with ns __GLOBAL_PARSER_CONTEXT._initDocDict(result) c_node = tree.xmlDocCopyNode(c_new_root, result, 1) # recursive tree.xmlDocSetRootElement(result, c_node) if c_new_root.parent is not <xmlNode*>c_doc: # do not copy the tail for the root node - done automatically _copyTail(c_new_root.next, c_node) if c_doc.URL is not NULL: # handle a bug in older libxml2 versions if result.URL is not NULL: tree.xmlFree(result.URL) result.URL = tree.xmlStrdup(c_doc.URL) return result ------------------------------- Regards, Stefan

Hi again, Stefan Behnel wrote:
Another simplification, another stupid bug fix for the last implementation: ------------------------------- cdef xmlDoc* _copyDocRoot(xmlDoc* c_doc, xmlNode* c_new_root): "Recursively copy the document and make c_new_root the new root node." cdef xmlDoc* result cdef xmlNode* c_node result = tree.xmlCopyDoc(c_doc, 0) # non recursive __GLOBAL_PARSER_CONTEXT._initDocDict(result) c_node = tree.xmlDocCopyNode(c_new_root, result, 1) # recursive tree.xmlDocSetRootElement(result, c_node) _copyTail(c_new_root.next, c_node) if c_doc.URL is not NULL: # handle a bug in older libxml2 versions if result.URL is not NULL: tree.xmlFree(result.URL) result.URL = tree.xmlStrdup(c_doc.URL) return result ------------------------------- Late at night is not the best time to get bugs fixed ... Anyway, this works now as expected. Stefan

Stefan Behnel wrote:
Late at night is not the best time to get bugs fixed ...
No, late at night should be reserved for working out vague ideas that you throw away later... ;)
Anyway, this works now as expected.
My tests are happy again, and so am I! Great! Thanks again! Cheers, Guido
participants (2)
-
Johnny deBris
-
Stefan Behnel