diff --git a/Lib/test/test_xml_expatreader.py b/Lib/test/test_xml_expatreader.py new file mode 100644 index 00000000000000..e73e8347fcb411 --- /dev/null +++ b/Lib/test/test_xml_expatreader.py @@ -0,0 +1,24 @@ +import unittest + +from xml.sax.expatreader import create_parser +from xml.sax import handler + + +class feature_namespace_prefixes(unittest.TestCase): + def setUp(self): + self.parser = create_parser() + self.parser.setFeature(handler.feature_namespaces, 1) + self.parser.setFeature(handler.feature_namespace_prefixes, 1) + + def test_prefix_given(self): + class Handler(handler.ContentHandler): + def startElementNS(self, name, qname, attrs): + self.qname = qname + + h = Handler() + + self.parser.setContentHandler(h) + self.parser.feed("") + self.parser.close() + print("self.assertEqual") + self.assertFalse(h.qname is None) diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py index ba3c1e98517429..78b79df21ca079 100644 --- a/Lib/xml/sax/expatreader.py +++ b/Lib/xml/sax/expatreader.py @@ -91,6 +91,7 @@ def __init__(self, namespaceHandling=0, bufsize=2**16-20): self._entity_stack = [] self._external_ges = 0 self._interning = None + self._namespace_prefixes = 1 # XMLReader methods @@ -126,8 +127,9 @@ def getFeature(self, name): return self._namespaces elif name == feature_string_interning: return self._interning is not None - elif name in (feature_validation, feature_external_pes, - feature_namespace_prefixes): + elif name == feature_namespace_prefixes: + return self._namespace_prefixes + elif name in (feature_validation, feature_external_pes): return 0 elif name == feature_external_ges: return self._external_ges @@ -147,6 +149,8 @@ def setFeature(self, name, state): self._interning = {} else: self._interning = None + elif name == feature_namespace_prefixes: + self._namespace_prefixes = state elif name == feature_validation: if state: raise SAXNotSupportedException( @@ -155,10 +159,6 @@ def setFeature(self, name, state): if state: raise SAXNotSupportedException( "expat does not read external parameter entities") - elif name == feature_namespace_prefixes: - if state: - raise SAXNotSupportedException( - "expat does not report namespace prefixes") else: raise SAXNotRecognizedException( "Feature '%s' not recognized" % name) @@ -347,11 +347,14 @@ def start_element_ns(self, name, attrs): pair = name.split() if len(pair) == 1: # no namespace + elem_qname = name pair = (None, name) elif len(pair) == 3: + elem_qname = "%s:%s" % (pair[2], pair[1]) pair = pair[0], pair[1] else: # default namespace + elem_qname = pair[1] pair = tuple(pair) newattrs = {} @@ -374,7 +377,7 @@ def start_element_ns(self, name, attrs): newattrs[apair] = value qnames[apair] = qname - self._cont_handler.startElementNS(pair, None, + self._cont_handler.startElementNS(pair, elem_qname, AttributesNSImpl(newattrs, qnames)) def end_element_ns(self, name): diff --git a/Misc/NEWS.d/next/Library/2024-04-26-14-21-04.gh-issue-54873.vf2bfp.rst b/Misc/NEWS.d/next/Library/2024-04-26-14-21-04.gh-issue-54873.vf2bfp.rst new file mode 100644 index 00000000000000..92c90c19b85dba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-04-26-14-21-04.gh-issue-54873.vf2bfp.rst @@ -0,0 +1,2 @@ +Backported namespaces prefixes support for xml.sax.expatreader from PyXml +(0.8.4)