From b0cb14ae5e9e3bd3ef8075bd289fceb361261ffe Mon Sep 17 00:00:00 2001 From: Stefan Zetzsche Date: Sun, 22 Feb 2026 14:57:35 +0000 Subject: [PATCH 1/3] gh-XXXXX: Fix xml.dom.pulldom dropping events produced by parser.close() getEvent() returned None immediately after parser.close() without checking if close() generated new SAX events, silently dropping trailing events like END_ELEMENT. --- Lib/xml/dom/pulldom.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/xml/dom/pulldom.py b/Lib/xml/dom/pulldom.py index 913141cd7ef3ce..a4607150213c13 100644 --- a/Lib/xml/dom/pulldom.py +++ b/Lib/xml/dom/pulldom.py @@ -249,6 +249,8 @@ def getEvent(self): buf = self.stream.read(self.bufsize) if not buf: self.parser.close() + if self.pulldom.firstEvent[1]: + break return None self.parser.feed(buf) rc = self.pulldom.firstEvent[1][0] From 2dff747d5feae803d51b625d26928e317ce22e61 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 15:36:51 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/2026-02-26-15-36-50.gh-issue-145259._SeM5N.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-02-26-15-36-50.gh-issue-145259._SeM5N.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-26-15-36-50.gh-issue-145259._SeM5N.rst b/Misc/NEWS.d/next/Library/2026-02-26-15-36-50.gh-issue-145259._SeM5N.rst new file mode 100644 index 00000000000000..1f12f57de75fa7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-26-15-36-50.gh-issue-145259._SeM5N.rst @@ -0,0 +1,4 @@ +Fix :class:`xml.dom.pulldom.DOMEventStream` silently dropping SAX events +produced by ``parser.close()`` at end-of-stream. When ``bufsize`` caused the +final tag to be split across reads, ``END_ELEMENT`` and other trailing events +were lost. From 8bcb96fe9ab5f481a62c50674715406f03643088 Mon Sep 17 00:00:00 2001 From: Stefan Zetzsche Date: Thu, 26 Feb 2026 15:50:25 +0000 Subject: [PATCH 3/3] Update test_pulldom for events now correctly delivered by parser.close() - Remove @expectedFailure from test_end_document since END_DOCUMENT events are now correctly delivered - Update test_expandItem to consume remaining events (END_ELEMENT, END_DOCUMENT) that are now properly emitted --- Lib/test/test_pulldom.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_pulldom.py b/Lib/test/test_pulldom.py index 3c8ed251acaa4d..0a53e4b2de0dbc 100644 --- a/Lib/test/test_pulldom.py +++ b/Lib/test/test_pulldom.py @@ -128,8 +128,13 @@ def test_expandItem(self): next(items) # Skip character data evt, node = next(items) self.assertEqual(node.tagName, "html") - with self.assertRaises(StopIteration): - next(items) + # Consume any remaining events (e.g. END_ELEMENT, END_DOCUMENT) + # that are now correctly delivered after the fix for parser.close() + remaining = list(items) + self.assertTrue( + any(evt == pulldom.END_DOCUMENT for evt, _ in remaining), + "Expected END_DOCUMENT in remaining events" + ) items.clear() self.assertIsNone(items.parser) self.assertIsNone(items.stream) @@ -144,9 +149,8 @@ def test_comment(self): else: self.fail("No comment was encountered") - @unittest.expectedFailure def test_end_document(self): - """PullDOM does not receive "end-document" events.""" + """PullDOM receives end-document events.""" items = pulldom.parseString(SMALL_SAMPLE) # Read all of the nodes up to and including : for evt, node in items: