diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 26fd36635..5a5404d10 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -659,7 +659,6 @@ class MinidomTest(unittest.TestCase): self.assertIsNone(pi.localName) self.assertEqual(pi.namespaceURI, xml.dom.EMPTY_NAMESPACE) - @unittest.expectedFailure # TODO: RUSTPYTHON def testProcessingInstructionRepr(self): dom = parseString('') pi = dom.documentElement.firstChild @@ -957,11 +956,9 @@ class MinidomTest(unittest.TestCase): self.confirm(clone.target == pi.target and clone.data == pi.data) - @unittest.expectedFailure # TODO: RUSTPYTHON def testClonePIShallow(self): self.check_clone_pi(0, "testClonePIShallow") - @unittest.expectedFailure # TODO: RUSTPYTHON def testClonePIDeep(self): self.check_clone_pi(1, "testClonePIDeep") @@ -1219,7 +1216,6 @@ class MinidomTest(unittest.TestCase): self.assertIsNone(node.childNodes[-1].nextSibling, "Final child's .nextSibling should be None") - @unittest.expectedFailure # TODO: RUSTPYTHON def testSiblings(self): doc = parseString("text?") root = doc.documentElement @@ -1792,7 +1788,6 @@ class MinidomTest(unittest.TestCase): '\n' '\n') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_toprettyxml_with_cdata(self): xml_str = ']]>' doc = parseString(xml_str) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 682abc520..e7046b79f 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -560,7 +560,6 @@ class BufferTextTest(unittest.TestCase): ["", "1", "", "", "2", "", "", "345", ""], "buffered text not properly split") - @unittest.expectedFailure # TODO: RUSTPYTHON def test7(self): self.setHandlers(["CommentHandler", "EndElementHandler", "StartElementHandler"]) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 6a75126f2..18a845fe2 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1800,7 +1800,6 @@ class XMLPullParserTest(unittest.TestCase): self._feed(parser, "\n") self.assert_events(parser, [('comment', (ET.Comment, ' text here '))]) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_events_pi(self): parser = ET.XMLPullParser(events=('start', 'pi', 'end')) self._feed(parser, "\n") @@ -3821,7 +3820,6 @@ class TreeBuilderTest(unittest.TestCase): a = parser.close() self.assertEqual(a.text, "texttail") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_late_tail_mix_pi_comments(self): # Issue #37399: The tail of an ignored comment could overwrite the text before it. # Test appending tails to comments/pis. diff --git a/crates/stdlib/src/pyexpat.rs b/crates/stdlib/src/pyexpat.rs index 143d820d6..f690abade 100644 --- a/crates/stdlib/src/pyexpat.rs +++ b/crates/stdlib/src/pyexpat.rs @@ -305,8 +305,9 @@ mod _pyexpat { fn create_config(&self) -> xml::ParserConfig { xml::ParserConfig::new() - .cdata_to_characters(true) + .cdata_to_characters(false) .coalesce_characters(false) + .ignore_comments(false) .whitespace_to_characters(true) } @@ -350,10 +351,10 @@ mod _pyexpat { T: std::io::Read, { for e in parser { - match e { - Ok(XmlEvent::StartElement { + match e? { + XmlEvent::StartElement { name, attributes, .. - }) => { + } => { let dict = vm.ctx.new_dict(); for attribute in attributes { let attr_name = self.make_name(&attribute.name); @@ -368,15 +369,29 @@ mod _pyexpat { let name_str = PyStr::from(self.make_name(&name)).into_ref(&vm.ctx); invoke_handler(vm, &self.start_element, (name_str, dict)); } - Ok(XmlEvent::EndElement { name, .. }) => { + XmlEvent::EndElement { name, .. } => { let name_str = PyStr::from(self.make_name(&name)).into_ref(&vm.ctx); invoke_handler(vm, &self.end_element, (name_str,)); } - Ok(XmlEvent::Characters(chars)) => { + XmlEvent::Characters(chars) => { let str = PyStr::from(chars).into_ref(&vm.ctx); invoke_handler(vm, &self.character_data, (str,)); } - Err(e) => return Err(e), + XmlEvent::ProcessingInstruction { name, data } => { + let name = PyStr::from(name).into_ref(&vm.ctx); + let data = PyStr::from(data.unwrap_or_default()).into_ref(&vm.ctx); + invoke_handler(vm, &self.processing_instruction, (name, data)); + } + XmlEvent::Comment(comment) => { + let comment = PyStr::from(comment).into_ref(&vm.ctx); + invoke_handler(vm, &self.comment, (comment,)); + } + XmlEvent::CData(chars) => { + invoke_handler(vm, &self.start_cdata_section, ()); + let str = PyStr::from(chars).into_ref(&vm.ctx); + invoke_handler(vm, &self.character_data, (str,)); + invoke_handler(vm, &self.end_cdata_section, ()); + } _ => {} } } diff --git a/extra_tests/snippets/stdlib_xml.py b/extra_tests/snippets/stdlib_xml.py index 268cdf45a..34f1a726e 100644 --- a/extra_tests/snippets/stdlib_xml.py +++ b/extra_tests/snippets/stdlib_xml.py @@ -45,3 +45,24 @@ assert handler.events == [ ("end", "child"), ("end", "main"), ] + +events = [] +parser = expat.ParserCreate() +parser.ProcessingInstructionHandler = lambda target, data: events.append( + ("processing-instruction", target, data) +) +parser.CommentHandler = lambda data: events.append(("comment", data)) +parser.StartCdataSectionHandler = lambda: events.append(("start-cdata",)) +parser.CharacterDataHandler = lambda data: events.append(("characters", data)) +parser.EndCdataSectionHandler = lambda: events.append(("end-cdata",)) +parser.Parse( + "", True +) +assert events == [ + ("processing-instruction", "target", "data"), + ("processing-instruction", "empty", ""), + ("comment", "comment"), + ("start-cdata",), + ("characters", "text"), + ("end-cdata",), +]