diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 5a5404d10..c6b52ce33 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -553,7 +553,6 @@ class MinidomTest(unittest.TestCase): self.assertEqual(str(node), repr(node)) dom.unlink() - @unittest.expectedFailure # TODO: RUSTPYTHON def testWriteXML(self): str = '' dom = parseString(str) @@ -601,7 +600,6 @@ class MinidomTest(unittest.TestCase): 'lflf=" " ' 'ws=" "/>') - @unittest.expectedFailure # TODO: RUSTPYTHON def testAltNewline(self): str = '\n\n' dom = parseString(str) @@ -705,7 +703,6 @@ class MinidomTest(unittest.TestCase): def testAttrListKeysNS(self): pass - @unittest.expectedFailure # TODO: RUSTPYTHON def testRemoveNamedItem(self): doc = parseString("") e = doc.documentElement @@ -715,7 +712,6 @@ class MinidomTest(unittest.TestCase): self.assertTrue(a1.isSameNode(a2)) self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItem, "a") - @unittest.expectedFailure # TODO: RUSTPYTHON def testRemoveNamedItemNS(self): doc = parseString("") e = doc.documentElement @@ -788,7 +784,6 @@ class MinidomTest(unittest.TestCase): root.setAttribute("added", "VALUE") return dom, clone - @unittest.expectedFailure # TODO: RUSTPYTHON def testCloneElementShallow(self): dom, clone = self._setupCloneElement(0) self.assertEqual(len(clone.childNodes), 0) @@ -940,11 +935,9 @@ class MinidomTest(unittest.TestCase): self.confirm(clone.specified, testName + ": cloned attribute must have specified == True") - @unittest.expectedFailure # TODO: RUSTPYTHON def testCloneAttributeShallow(self): self.check_clone_attribute(0, "testCloneAttributeShallow") - @unittest.expectedFailure # TODO: RUSTPYTHON def testCloneAttributeDeep(self): self.check_clone_attribute(1, "testCloneAttributeDeep") @@ -1336,7 +1329,6 @@ class MinidomTest(unittest.TestCase): self.assertRaises(xml.dom.WrongDocumentErr, doc2.renameNode, node, xml.dom.EMPTY_NAMESPACE, "foo") - @unittest.expectedFailure # TODO: RUSTPYTHON def testRenameAttribute(self): doc = parseString("") elem = doc.documentElement @@ -1541,7 +1533,6 @@ class MinidomTest(unittest.TestCase): self.confirm(text is None and len(elem.childNodes) == 2) - @unittest.expectedFailure # TODO: RUSTPYTHON def testSchemaType(self): doc = parseString( "") e = doc.documentElement @@ -1607,7 +1597,6 @@ class MinidomTest(unittest.TestCase): self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) - @unittest.expectedFailure # TODO: RUSTPYTHON def testSetIdAttributeNS(self): NS1 = "http://xml.python.org/ns1" NS2 = "http://xml.python.org/ns2" @@ -1644,7 +1633,6 @@ class MinidomTest(unittest.TestCase): self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) - @unittest.expectedFailure # TODO: RUSTPYTHON def testSetIdAttributeNode(self): NS1 = "http://xml.python.org/ns1" NS2 = "http://xml.python.org/ns2" @@ -1766,7 +1754,6 @@ class MinidomTest(unittest.TestCase): pi = doc.createProcessingInstruction("y", "z") pi.nodeValue = "crash" - @unittest.expectedFailure # TODO: RUSTPYTHON def test_minidom_attribute_order(self): xml_str = '' doc = parseString(xml_str) @@ -1774,13 +1761,11 @@ class MinidomTest(unittest.TestCase): doc.writexml(output) self.assertEqual(output.getvalue(), xml_str) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_toxml_with_attributes_ordered(self): xml_str = '' doc = parseString(xml_str) self.assertEqual(doc.toxml(), xml_str) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_toprettyxml_with_attributes_ordered(self): xml_str = '' doc = parseString(xml_str) diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 85db8e14c..cb9ae24cc 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -2355,7 +2355,6 @@ class ArgsTestCase(BaseTestCase): self.check_executed_tests(output, testname, stats=1, parallel=True) self.assertNotIn('SPAM SPAM SPAM', output) - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType' def test_xml(self): code = textwrap.dedent(r""" import unittest diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 18a845fe2..2b0777c1d 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -392,7 +392,6 @@ class ElementTreeTest(unittest.TestCase): self.serialize_check(ET.XML(""), 'hello') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_file_init(self): stringfile = io.BytesIO(SAMPLE_XML.encode("utf-8")) tree = ET.ElementTree(file=stringfile) @@ -508,7 +507,6 @@ class ElementTreeTest(unittest.TestCase): elem[:] = tuple([subelem]) self.serialize_check(elem, '') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_parsefile(self): # Test parsing from file. @@ -688,7 +686,6 @@ class ElementTreeTest(unittest.TestCase): parser2 = ET.XMLParser() self.assertIsInstance(parser2.target, ET.TreeBuilder) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_children(self): # Test Element children iteration @@ -1091,7 +1088,6 @@ class ElementTreeTest(unittest.TestCase): self.assertEqual(str(cm.exception), 'undefined entity &entity;: line 4, column 10') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_namespace(self): # Test namespace issues. @@ -1335,7 +1331,6 @@ class ElementTreeTest(unittest.TestCase): class IterparseTest(unittest.TestCase): # Test iterparse interface. - @unittest.expectedFailure # TODO: RUSTPYTHON def test_basic(self): iterparse = ET.iterparse @@ -1361,7 +1356,6 @@ class IterparseTest(unittest.TestCase): ]) it.close() - @unittest.expectedFailure # TODO: RUSTPYTHON def test_external_file(self): with open(SIMPLE_XMLFILE, 'rb') as source: it = ET.iterparse(source) @@ -1374,7 +1368,6 @@ class IterparseTest(unittest.TestCase): ]) self.assertEqual(it.root.tag, 'root') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_events(self): iterparse = ET.iterparse @@ -1475,7 +1468,6 @@ class IterparseTest(unittest.TestCase): with self.assertRaises(FileNotFoundError): ET.iterparse("nonexistent") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_resource_warnings_not_exhausted(self): # Not exhausting the iterator still closes the underlying file (bpo-43292) it = ET.iterparse(SIMPLE_XMLFILE) @@ -1514,7 +1506,6 @@ class IterparseTest(unittest.TestCase): del it gc_collect() - @unittest.expectedFailure # TODO: RUSTPYTHON def test_close_not_exhausted(self): iterparse = ET.iterparse @@ -2041,7 +2032,6 @@ class XIncludeTest(unittest.TestCase): else: return None - @unittest.expectedFailure # TODO: RUSTPYTHON def test_xinclude_default(self): from xml.etree import ElementInclude doc = self.xinclude_loader('default.xml') @@ -2056,7 +2046,6 @@ class XIncludeTest(unittest.TestCase): '\n' '') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_xinclude(self): from xml.etree import ElementInclude @@ -2121,7 +2110,6 @@ class XIncludeTest(unittest.TestCase): ' \n' '') # C5 - @unittest.expectedFailure # TODO: RUSTPYTHON def test_xinclude_repeated(self): from xml.etree import ElementInclude @@ -2129,7 +2117,6 @@ class XIncludeTest(unittest.TestCase): ElementInclude.include(document, self.xinclude_loader) self.assertEqual(1+4*2, len(document.findall(".//p"))) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_xinclude_failures(self): from xml.etree import ElementInclude @@ -2234,7 +2221,6 @@ class BugsTest(unittest.TestCase): elem.set("123", 123) check(elem) # attribute value - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bug_xmltoolkit25(self): # typo in ElementTree.findtext @@ -2258,7 +2244,6 @@ class BugsTest(unittest.TestCase): ET.dump(tree) self.assertEqual(stdout.getvalue(), '
\n') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bug_xmltoolkit39(self): # non-ascii element and attribute names doesn't work @@ -2345,7 +2330,6 @@ class BugsTest(unittest.TestCase): xmltoolkit63() self.assertEqual(sys.getrefcount(None), count) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bug_200708_newline(self): # Preserve newlines in attributes. @@ -2461,7 +2445,6 @@ class BugsTest(unittest.TestCase): b"\n" b'tãg') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_issue6565(self): elem = ET.XML("") self.assertEqual(summarize_list(elem), ['tag']) @@ -2533,7 +2516,6 @@ class BugsTest(unittest.TestCase): root = ET.XML(xml) self.assertEqual(root.get('b'), text.decode('utf-8')) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_expat224_utf8_bug(self): # bpo-31170: Expat 2.2.3 had a bug in its UTF-8 decoder. # Check that Expat 2.2.4 fixed the bug. @@ -3355,7 +3337,6 @@ class ElementTreeTypeTest(unittest.TestCase): class ElementFindTest(unittest.TestCase): - @unittest.expectedFailure # TODO: RUSTPYTHON def test_find_simple(self): e = ET.XML(SAMPLE_XML) self.assertEqual(e.find('tag').tag, 'tag') @@ -3379,7 +3360,6 @@ class ElementFindTest(unittest.TestCase): # Issue #16922 self.assertEqual(ET.XML('').findtext('empty'), '') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_find_xpath(self): LINEAR_XML = ''' @@ -3402,7 +3382,6 @@ class ElementFindTest(unittest.TestCase): self.assertRaisesRegex(SyntaxError, 'XPath', e.find, './tag[last()-0]') self.assertRaisesRegex(SyntaxError, 'XPath', e.find, './tag[last()+1]') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_findall(self): e = ET.XML(SAMPLE_XML) e[2] = ET.XML(SAMPLE_SECTION) @@ -3591,7 +3570,6 @@ class ElementFindTest(unittest.TestCase): with self.assertRaisesRegex(SyntaxError, 'cannot use absolute path'): e.findall('/tag') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_find_through_ElementTree(self): e = ET.XML(SAMPLE_XML) self.assertEqual(ET.ElementTree(e).find('tag').tag, 'tag') @@ -4576,7 +4554,6 @@ class NoAcceleratorTest(unittest.TestCase): # -------------------------------------------------------------------- class BoolTest(unittest.TestCase): - @unittest.expectedFailure # TODO: RUSTPYTHON def test_warning(self): e = ET.fromstring('
') msg = ( diff --git a/crates/stdlib/src/pyexpat.rs b/crates/stdlib/src/pyexpat.rs index f690abade..9b55bbb22 100644 --- a/crates/stdlib/src/pyexpat.rs +++ b/crates/stdlib/src/pyexpat.rs @@ -43,7 +43,8 @@ macro_rules! create_bool_property { #[pymodule(name = "pyexpat")] mod _pyexpat { use crate::vm::{ - Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, + VirtualMachine, builtins::{PyBytesRef, PyException, PyModule, PyStr, PyStrRef, PyType, PyUtf8StrRef}, extend_module, function::{ArgBytesLike, ArgPrimitiveIndex, Either, IntoFuncArgs, OptionalArg}, @@ -355,19 +356,30 @@ mod _pyexpat { XmlEvent::StartElement { name, attributes, .. } => { - let dict = vm.ctx.new_dict(); - for attribute in attributes { - let attr_name = self.make_name(&attribute.name); - dict.set_item( - attr_name.as_str(), - vm.ctx.new_str(attribute.value).into(), - vm, - ) - .unwrap(); - } + let ordered = self.ordered_attributes.read().is(&vm.ctx.true_value); + // Build the container. + let attrs: PyObjectRef = if ordered { + let mut items = Vec::with_capacity(attributes.len() * 2); + for attribute in attributes { + items.push(vm.ctx.new_str(self.make_name(&attribute.name)).into()); + items.push(vm.ctx.new_str(attribute.value).into()); + } + vm.ctx.new_list(items).into() + } else { + let dict = vm.ctx.new_dict(); + for attribute in attributes { + dict.set_item( + self.make_name(&attribute.name).as_str(), + vm.ctx.new_str(attribute.value).into(), + vm, + ) + .unwrap(); + } + dict.into() + }; let name_str = PyStr::from(self.make_name(&name)).into_ref(&vm.ctx); - invoke_handler(vm, &self.start_element, (name_str, dict)); + invoke_handler(vm, &self.start_element, (name_str, attrs)); } XmlEvent::EndElement { name, .. } => { let name_str = PyStr::from(self.make_name(&name)).into_ref(&vm.ctx);