diff options
author | Olli Pottonen <olli.pottonen@iki.fi> | 2015-02-18 16:53:41 +1000 |
---|---|---|
committer | Olli Pottonen <olli.pottonen@iki.fi> | 2015-02-18 16:51:43 +1000 |
commit | fdd2f237fb1945fde323b9e8987d7c28a769a4d0 (patch) | |
tree | 12d59cd52fff0d3e2d108807fd6e20f68e7d4df0 /src/lxml | |
parent | 6095a09e3f9d8e44d111c36aa813aea23885ec9a (diff) | |
download | python-lxml-fdd2f237fb1945fde323b9e8987d7c28a769a4d0.tar.gz |
Make _ElementTree.deepcopy() properly handle comments/PI's before doctype.
Diffstat (limited to 'src/lxml')
-rw-r--r-- | src/lxml/apihelpers.pxi | 18 | ||||
-rw-r--r-- | src/lxml/lxml.etree.pyx | 6 | ||||
-rw-r--r-- | src/lxml/tests/test_etree.py | 11 |
3 files changed, 24 insertions, 11 deletions
diff --git a/src/lxml/apihelpers.pxi b/src/lxml/apihelpers.pxi index 0492b0be..c529384a 100644 --- a/src/lxml/apihelpers.pxi +++ b/src/lxml/apihelpers.pxi @@ -1069,13 +1069,21 @@ cdef int _copyNonElementSiblings(xmlNode* c_node, xmlNode* c_target) except -1: cdef xmlNode* c_copy cdef xmlNode* c_sibling = c_node while c_sibling.prev != NULL and \ - (c_sibling.prev.type == tree.XML_PI_NODE or \ - c_sibling.prev.type == tree.XML_COMMENT_NODE): + (c_sibling.prev.type == tree.XML_PI_NODE or + c_sibling.prev.type == tree.XML_COMMENT_NODE or + c_sibling.prev.type == tree.XML_DTD_NODE): c_sibling = c_sibling.prev while c_sibling != c_node: - c_copy = tree.xmlDocCopyNode(c_sibling, c_target.doc, 1) - if c_copy is NULL: - raise MemoryError() + if c_sibling.type == tree.XML_DTD_NODE: + c_copy = <xmlNode*>_copyDtd(<tree.xmlDtd*>c_sibling) + if c_sibling == <xmlNode*>c_node.doc.intSubset: + c_target.doc.intSubset = <tree.xmlDtd*>c_copy + else: # c_sibling == c_node.doc.extSubset + c_target.doc.extSubset = <tree.xmlDtd*>c_copy + else: + c_copy = tree.xmlDocCopyNode(c_sibling, c_target.doc, 1) + if c_copy is NULL: + raise MemoryError() tree.xmlAddPrevSibling(c_target, c_copy) c_sibling = c_sibling.next while c_sibling.next != NULL and \ diff --git a/src/lxml/lxml.etree.pyx b/src/lxml/lxml.etree.pyx index d5f43f67..74e7e93a 100644 --- a/src/lxml/lxml.etree.pyx +++ b/src/lxml/lxml.etree.pyx @@ -1903,12 +1903,6 @@ cdef public class _ElementTree [ type LxmlElementTreeType, assert root is not None _assertValidNode(root) _copyNonElementSiblings(self._context_node._c_node, root._c_node) - doc = root._doc - c_doc = self._context_node._doc._c_doc - if c_doc.intSubset is not NULL and doc._c_doc.intSubset is NULL: - doc._c_doc.intSubset = _copyDtd(c_doc.intSubset) - if c_doc.extSubset is not NULL and not doc._c_doc.extSubset is NULL: - doc._c_doc.extSubset = _copyDtd(c_doc.extSubset) return _elementTreeFactory(None, root) elif self._doc is not None: _assertValidDoc(self._doc) diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py index 25ad998b..8131881e 100644 --- a/src/lxml/tests/test_etree.py +++ b/src/lxml/tests/test_etree.py @@ -576,6 +576,17 @@ class ETreeOnlyTestCase(HelperTestCase): self.assertEqual(_bytes("<test/>"), tostring(root2)) + def test_deepcopy_pi_dtd(self): + XML = self.etree.XML + tostring = self.etree.tostring + xml = _bytes('<!-- comment --><!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') + root = XML(xml) + tree1 = self.etree.ElementTree(root) + self.assertEqual(xml, tostring(tree1)) + + tree2 = copy.deepcopy(tree1) + self.assertEqual(xml, tostring(tree2)) + def test_parse_remove_comments(self): fromstring = self.etree.fromstring tostring = self.etree.tostring |