diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1,5 +1,6 @@ # test for xml.dom.minidom +import copy import pickle from test.support import findfile import unittest @@ -1481,6 +1482,43 @@ class MinidomTest(unittest.TestCase): self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) + def assert_recursive_equal(self, doc, doc2): + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.assertEqual(n1.nodeType, n2.nodeType) + self.assertEqual(len(n1.childNodes), len(n2.childNodes)) + self.assertEqual(n1.nodeName, n2.nodeName) + self.assertFalse(n1.isSameNode(n2)) + self.assertFalse(n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.assertEqual(len(n1.entities), len(n2.entities)) + self.assertEqual(len(n1.notations), len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.assertEqual(no1.name, no2.name) + self.assertEqual(no1.publicId, no2.publicId) + self.assertEqual(no1.systemId, no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.assertEqual(e1.notationName, e2.notationName) + self.assertEqual(e1.publicId, e2.publicId) + self.assertEqual(e1.systemId, e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.assertTrue(n1.ownerDocument.isSameNode(doc)) + self.assertTrue(n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) + def testPickledDocument(self): doc = parseString("\n" "\n" + "\n" + " \n" + "]> text\n" + " ") + doc2 = copy.deepcopy(doc) + self.assert_recursive_equal(doc, doc2) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() diff --git a/Lib/test/test_xml_dom_minicompat.py b/Lib/test/test_xml_dom_minicompat.py --- a/Lib/test/test_xml_dom_minicompat.py +++ b/Lib/test/test_xml_dom_minicompat.py @@ -1,5 +1,6 @@ # Tests for xml.dom.minicompat +import copy import pickle import unittest @@ -89,6 +90,7 @@ class NodeListTestCase(unittest.TestCase node_list = NodeList() pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) # Non-empty NodeList. @@ -96,7 +98,42 @@ class NodeListTestCase(unittest.TestCase node_list.append(2) pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) + def test_nodelist_copy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIs(x, y) + + + def test_nodelist_deepcopy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIsNot(x, y) + self.assertEqual(x, y) + if __name__ == '__main__': unittest.main() diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -65,9 +65,13 @@ class NodeList(list): doc="The number of nodes in the NodeList.") def __getstate__(self): - return list(self) + return None def __setstate__(self, state): + import warning + warning.warn("NodeList.__setstate__ is deprecated", + DeprecationWarning, + stacklevel=2) self[:] = state