From d8a7620ae8b971a85f87d095d78ba95b6c5bba96 Mon Sep 17 00:00:00 2001 From: dot Date: Sat, 10 Oct 2026 22:20:47 +0900 Subject: [PATCH] Preserve Expat qualified names without namespace expansion Retain raw element and attribute prefixes when namespace_separator is None. Keep expanded names and parser configuration unchanged, with regression coverage in the pyexpat snippet. Assisted-by: OpenAI Codex:model identifier unavailable --- crates/stdlib/src/pyexpat.rs | 4 ++++ extra_tests/snippets/stdlib_pyexpat.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 extra_tests/snippets/stdlib_pyexpat.py diff --git a/crates/stdlib/src/pyexpat.rs b/crates/stdlib/src/pyexpat.rs index 5a516dd7821..724fdb75926 100644 --- a/crates/stdlib/src/pyexpat.rs +++ b/crates/stdlib/src/pyexpat.rs @@ -1051,6 +1051,10 @@ mod _pyexpat { fn make_name(&self, name: &xml::name::OwnedName) -> String { match (&self.namespace_separator, &name.namespace) { (Some(sep), Some(ns)) => format!("{}{}{}", ns, sep, name.local_name), + (None, _) => match &name.prefix { + Some(prefix) => format!("{prefix}:{}", name.local_name), + None => name.local_name.clone(), + }, _ => name.local_name.clone(), } } diff --git a/extra_tests/snippets/stdlib_pyexpat.py b/extra_tests/snippets/stdlib_pyexpat.py new file mode 100644 index 00000000000..e8e2652d3db --- /dev/null +++ b/extra_tests/snippets/stdlib_pyexpat.py @@ -0,0 +1,23 @@ +from xml.parsers import expat + +# Without namespace expansion, element and attribute names retain prefixes. +for separator, expected_name, expected_attribute in ( + (None, "p:x", "p:a"), + ("!", "urn:p!x", "urn:p!a"), +): + for ordered in (False, True): + parser = expat.ParserCreate(namespace_separator=separator) + parser.ordered_attributes = ordered + starts = [] + ends = [] + parser.StartElementHandler = lambda name, attrs: starts.append((name, attrs)) + parser.EndElementHandler = ends.append + parser.Parse('', True) + assert [name for name, attrs in starts] == ["r", expected_name] + assert ends == [expected_name, "r"] + expected_attributes = ( + [expected_attribute, "v", "a", "u"] + if ordered + else {expected_attribute: "v", "a": "u"} + ) + assert starts[1][1] == expected_attributes