summaryrefslogtreecommitdiff
path: root/src/lxml
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2019-04-22 08:59:50 +0200
committerStefan Behnel <stefan_ml@behnel.de>2019-04-22 08:59:50 +0200
commit260ea114cecfafcf848bfec11f75336c57e555d4 (patch)
tree270867fd26fc005f1c9a420354ef3f6d80fa4743 /src/lxml
parenta15e6466ab369c86d805046f33fdb511c5427824 (diff)
downloadpython-lxml-260ea114cecfafcf848bfec11f75336c57e555d4.tar.gz
Fix end-ns reporting in pull parser when start-ns events are not requested.
Diffstat (limited to 'src/lxml')
-rw-r--r--src/lxml/saxparser.pxi18
-rw-r--r--src/lxml/tests/test_elementtree.py44
2 files changed, 54 insertions, 8 deletions
diff --git a/src/lxml/saxparser.pxi b/src/lxml/saxparser.pxi
index b7d8a409..75d4e633 100644
--- a/src/lxml/saxparser.pxi
+++ b/src/lxml/saxparser.pxi
@@ -282,13 +282,16 @@ cdef void _handleSaxStart(
if c_ctxt._private is NULL or c_ctxt.disableSAX:
return
context = <_SaxParserContext>c_ctxt._private
+ cdef int event_filter = context._event_filter
try:
if (c_nb_namespaces and
- context._event_filter & PARSE_EVENT_FILTER_START_NS):
+ event_filter & (PARSE_EVENT_FILTER_START_NS |
+ PARSE_EVENT_FILTER_END_NS)):
declared_namespaces = _build_prefix_uri_list(
context, c_nb_namespaces, c_namespaces)
- for prefix_uri_tuple in declared_namespaces:
- context.events_iterator._events.append(("start-ns", prefix_uri_tuple))
+ if event_filter & PARSE_EVENT_FILTER_START_NS:
+ for prefix_uri_tuple in declared_namespaces:
+ context.events_iterator._events.append(("start-ns", prefix_uri_tuple))
else:
declared_namespaces = None
@@ -298,12 +301,11 @@ cdef void _handleSaxStart(
if c_ctxt.html:
_fixHtmlDictNodeNames(c_ctxt.dict, c_ctxt.node)
- if context._event_filter & PARSE_EVENT_FILTER_END_NS:
+ if event_filter & PARSE_EVENT_FILTER_END_NS:
context._ns_stack.append(declared_namespaces)
- if context._event_filter & (PARSE_EVENT_FILTER_END |
- PARSE_EVENT_FILTER_START):
- _pushSaxStartEvent(context, c_ctxt, c_namespace,
- c_localname, None)
+ if event_filter & (PARSE_EVENT_FILTER_END |
+ PARSE_EVENT_FILTER_START):
+ _pushSaxStartEvent(context, c_ctxt, c_namespace, c_localname, None)
except:
context._handleSaxException(c_ctxt)
finally:
diff --git a/src/lxml/tests/test_elementtree.py b/src/lxml/tests/test_elementtree.py
index 55fa52d9..77e59225 100644
--- a/src/lxml/tests/test_elementtree.py
+++ b/src/lxml/tests/test_elementtree.py
@@ -3078,6 +3078,32 @@ class _ETreeTestCaseBase(HelperTestCase):
'value',
root[0].get(attr_name))
+ def test_iterparse_only_end_ns(self):
+ iterparse = self.etree.iterparse
+ f = BytesIO('<a xmlns="http://ns1/"><b><c xmlns="http://ns2/"/></b></a>')
+
+ attr_name = '{http://testns/}bla'
+ events = []
+ iterator = iterparse(f, events=('start','end','start-ns','end-ns'))
+ for event, elem in iterator:
+ events.append(event)
+ if event == 'start':
+ if elem.tag != '{http://ns1/}a':
+ elem.set(attr_name, 'value')
+
+ self.assertEqual(
+ ['start-ns', 'start', 'start', 'start-ns', 'start',
+ 'end', 'end-ns', 'end', 'end', 'end-ns'],
+ events)
+
+ root = iterator.root
+ self.assertEqual(
+ None,
+ root.get(attr_name))
+ self.assertEqual(
+ 'value',
+ root[0].get(attr_name))
+
def test_iterparse_getiterator(self):
iterparse = self.etree.iterparse
f = BytesIO('<a><b><d/></b><c/></a>')
@@ -4437,6 +4463,24 @@ class _XMLPullParserTest(unittest.TestCase):
self.assertEqual(list(parser.read_events()), [('end-ns', None)])
parser.close()
+ def test_ns_events_end_ns_only(self):
+ parser = self.etree.XMLPullParser(events=['end-ns'])
+ self._feed(parser, "<!-- comment -->\n")
+ self._feed(parser, "<root xmlns='namespace' xmlns:a='abc' xmlns:b='xyz'>\n")
+ self.assertEqual(list(parser.read_events()), [])
+ self._feed(parser, "<a:element key='value'>text</a:element")
+ self._feed(parser, ">\n")
+ self._feed(parser, "<b:element>text</b:element>tail\n")
+ self._feed(parser, "<empty-element/>\n")
+ self.assertEqual(list(parser.read_events()), [])
+ self._feed(parser, "</root>\n")
+ self.assertEqual(list(parser.read_events()), [
+ ('end-ns', None),
+ ('end-ns', None),
+ ('end-ns', None),
+ ])
+ parser.close()
+
@et_needs_pyversion(3,8)
def test_ns_events_start(self):
parser = self.etree.XMLPullParser(events=('start-ns', 'start', 'end'))