From aff84f751da7f4605cbcb33a63f9509a6e3ae659 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Tue, 8 Oct 2002 19:49:36 +0000 Subject: [PATCH] Fix some code that was added to the r22-maint branch to allow it to work with arbitrary versions of Expat. Not applicable to Python 2.3, which will incorporate an Expat that does not need this crutch. --- Lib/test/output/test_sax | 5 ++- Lib/test/test_sax.py | 64 ++++++++++++++++++++++++++++++++++++++ Lib/xml/sax/expatreader.py | 26 ++++++++++++---- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/Lib/test/output/test_sax b/Lib/test/output/test_sax index 8aa5a77c2f97..704b5fe8452e 100644 --- a/Lib/test/output/test_sax +++ b/Lib/test/output/test_sax @@ -21,6 +21,9 @@ Passed test_expat_locator_noinfo Passed test_expat_locator_withinfo Passed test_expat_nsattrs_empty Passed test_expat_nsattrs_wattr +Passed test_expat_nsdecl_pair_diff +Passed test_expat_nsdecl_pair_same +Passed test_expat_nsdecl_single Passed test_filter_basic Passed test_make_parser Passed test_make_parser2 @@ -36,4 +39,4 @@ Passed test_xmlgen_content_escape Passed test_xmlgen_ignorable Passed test_xmlgen_ns Passed test_xmlgen_pi -37 tests, 0 failures +40 tests, 0 failures diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index 2a824950666b..7c9a21a4d710 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -348,6 +348,70 @@ def test_expat_nsattrs_wattr(): attrs.getValue((ns_uri, "attr")) == "val" and \ attrs[(ns_uri, "attr")] == "val" +class ElemGatherer(ContentHandler): + def __init__(self): + self.events = [] + def startElementNS(self, pair, qname, attrs): + self.events.append(('start', pair, qname)) + def endElementNS(self, pair, qname): + self.events.append(('end', pair, qname)) + +def check_expat_nsdecl(text, expected): + parser = create_parser(1) + handler = ElemGatherer() + parser.setContentHandler(handler) + parser.feed(text) + parser.close() + if verbose and handler.events != expected: + from pprint import pprint + print "Expected:" + pprint(expected) + print "Received:" + pprint(handler.events) + return handler.events == expected + +def test_expat_nsdecl_single(): + return check_expat_nsdecl( + "", [ + ("start", ("http://xml.python.org/", "abc"), "abc"), + ("end", ("http://xml.python.org/", "abc"), "abc"), + ]) + +def test_expat_nsdecl_pair_same(): + # XXX This shows where xml.sax.expatreader can use the wrong + # prefix when more than one is in scope for a particular URI. + # We still want to exercise this code since previous versions got + # the namespace handling wrong in more severe ways (exceptions + # that should not have happened). + return check_expat_nsdecl( + "" + "" + "" + "", [ + ("start", ("http://xml.python.org/", "abc"), "foo:abc"), + ("start", ("http://xml.python.org/", "def"), "foo:def"), + ("end", ("http://xml.python.org/", "def"), "foo:def"), + ("start", ("http://xml.python.org/", "ghi"), "foo:ghi"), + ("end", ("http://xml.python.org/", "ghi"), "foo:ghi"), + ("end", ("http://xml.python.org/", "abc"), "foo:abc"), + ]) + +def test_expat_nsdecl_pair_diff(): + return check_expat_nsdecl( + "" + "" + "" + "", [ + ("start", ("http://xml.python.org/1", "abc"), "abc"), + ("start", ("http://xml.python.org/2", "def"), "foo:def"), + ("end", ("http://xml.python.org/2", "def"), "foo:def"), + ("start", ("http://xml.python.org/1", "ghi"), "ghi"), + ("end", ("http://xml.python.org/1", "ghi"), "ghi"), + ("end", ("http://xml.python.org/1", "abc"), "abc"), + ]) + # ===== InputSource support xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read() diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py index 4b81b99fbf65..b919de3c0d34 100644 --- a/Lib/xml/sax/expatreader.py +++ b/Lib/xml/sax/expatreader.py @@ -224,8 +224,14 @@ class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator): pair = string.split(name) if len(pair) == 1: pair = (None, name) + qname = name else: pair = tuple(pair) + qname = pair[1] + if self._ns_stack: + prefix = self._ns_stack[-1][pair[0]][-1] + if prefix: + qname = "%s:%s" % (prefix, pair[1]) newattrs = {} qnames = {} @@ -233,27 +239,33 @@ class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator): apair = string.split(aname) if len(apair) == 1: apair = (None, aname) - qname = aname + aqname = aname else: apair = tuple(apair) # XXX need to guess the prefix prefix = self._ns_stack[-1][apair[0]][-1] - qname = "%s:%s" % (prefix, apair[1]) + aqname = "%s:%s" % (prefix, apair[1]) newattrs[apair] = value - qnames[apair] = qname + qnames[apair] = aqname - self._cont_handler.startElementNS(pair, None, + self._cont_handler.startElementNS(pair, qname, AttributesNSImpl(newattrs, qnames)) def end_element_ns(self, name): pair = string.split(name) if len(pair) == 1: pair = (None, name) + qname = name else: pair = tuple(pair) + qname = pair[1] + if self._ns_stack: + prefix = self._ns_stack[-1][pair[0]][-1] + if prefix: + qname = "%s:%s" % (prefix, pair[1]) - self._cont_handler.endElementNS(pair, None) + self._cont_handler.endElementNS(pair, qname) # this is not used (call directly to ContentHandler) def processing_instruction(self, target, data): @@ -265,11 +277,13 @@ class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator): def start_namespace_decl(self, prefix, uri): if self._ns_stack: - d = self._ns_stack.copy() + d = self._ns_stack[-1].copy() if d.has_key(uri): L = d[uri][:] d[uri] = L L.append(prefix) + else: + d[uri] = [prefix] else: d = {uri: [prefix]} self._ns_stack.append(d) -- 2.47.3