File python-38-xml-namespace.patch of Package python-Twisted.25323
From e42ba68b39f0ae98f1ea89a38a9317f2966c7d0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Poisson?= <goffi@goffi.org>
Date: Sun, 17 Nov 2019 19:48:53 +0100
Subject: [PATCH] Fix parsing of namespaced attributes with Python 3.8 in
twisted.words.xish.domish.ExpatElementStream
---
src/twisted/words/newsfragments/9730.bugfix | 1 +
src/twisted/words/test/test_domish.py | 16 ++++++++++++++++
src/twisted/words/xish/domish.py | 11 +++++++++--
3 files changed, 26 insertions(+), 2 deletions(-)
create mode 100644 src/twisted/words/newsfragments/9730.bugfix
diff --git a/src/twisted/words/newsfragments/9730.bugfix b/src/twisted/words/newsfragments/9730.bugfix
new file mode 100644
index 00000000000..5c91305c8f7
--- /dev/null
+++ b/src/twisted/words/newsfragments/9730.bugfix
@@ -0,0 +1 @@
+Fixed parsing of streams with Python 3.8 when there are spaces in namespaces or namespaced attributes in twisted.words.xish.domish.ExpatElementStream
diff --git a/src/twisted/words/test/test_domish.py b/src/twisted/words/test/test_domish.py
index a8f8fa76b63..5a691270443 100644
--- a/src/twisted/words/test/test_domish.py
+++ b/src/twisted/words/test/test_domish.py
@@ -350,6 +350,22 @@ def test_namespaceWithWhitespace(self):
self.elements[0].attributes, {(" bar baz ", "baz"): "quux"})
+ def test_attributesWithNamespaces(self):
+ """
+ Attributes with namespace are parsed correctly (#9730 regression test).
+ """
+
+ xml = b"""<root xmlns:test='http://example.org' xml:lang='en'>
+ <test:test>test</test:test>
+ </root>"""
+
+ # with Python 3.8 and without #9730 fix, the following error would
+ # happen at next line:
+ # ``RuntimeError: dictionary keys changed during iteration``
+ self.stream.parse(xml)
+ self.assertEqual(self.elements[0].uri, "http://example.org")
+
+
def testChildPrefix(self):
xml = b"<root xmlns='testns' xmlns:foo='testns2'><foo:child/></root>"
diff --git a/src/twisted/words/xish/domish.py b/src/twisted/words/xish/domish.py
index 2063c410a3c..30e47458f82 100644
--- a/src/twisted/words/xish/domish.py
+++ b/src/twisted/words/xish/domish.py
@@ -807,11 +807,18 @@ def _onStartElement(self, name, attrs):
qname = ('', name)
# Process attributes
+ new_attrs = {}
+ to_delete = []
for k, v in attrs.items():
if " " in k:
aqname = k.rsplit(" ", 1)
- attrs[(aqname[0], aqname[1])] = v
- del attrs[k]
+ new_attrs[(aqname[0], aqname[1])] = v
+ to_delete.append(k)
+
+ attrs.update(new_attrs)
+
+ for k in to_delete:
+ del attrs[k]
# Construct the new element
e = Element(qname, self.defaultNsStack[-1], attrs, self.localPrefixes)