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",),
+]