Hello community,

here is the log from the commit of package python-Twisted for 
openSUSE:Leap:15.2 checked in at 2020-04-08 12:47:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-Twisted (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.python-Twisted.new.3248 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Twisted"

Wed Apr  8 12:47:56 2020 rev:19 rq:788619 version:19.10.0

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-Twisted/python-Twisted.changes  
2020-01-15 15:46:25.723357127 +0100
+++ 
/work/SRC/openSUSE:Leap:15.2/.python-Twisted.new.3248/python-Twisted.changes    
    2020-04-08 12:47:57.326329510 +0200
@@ -1,0 +2,36 @@
+Wed Dec  4 05:01:47 UTC 2019 - Steve Kowalik <[email protected]>
+
+- Update to 19.10.0 bsc#1162424:
+  * twisted.trial.successResultOf, twisted.trial.failureResultOf, and 
twisted.trial.assertNoResult accept coroutines as well as Deferreds. (#9006)
+  * Fixed circular import in twisted.trial.reporter, introduced in Twisted 
16.0.0. (#8267)
+  * The POP3 server implemented by twisted.mail.pop3 now accepts passwords 
that contain spaces. (#9100)
+  * Incoming HTTP/2 connections will now not time out if they persist for 
longer than one minute. (#9653)
+  * twisted.conch.ssh.keys now correctly writes the "iqmp" parameter in 
serialized RSA private keys as q^-1 mod p rather than p^-1 mod q. (#9681)
+  * twisted.web.server.Request will now use 
twisted.web.server.Site.getContentFile, if it exists, to get a file into which 
to write request content. If getContentFile is not provided by the site, it 
will fall back to the previous behavior of using io.BytesIO for small requests 
and tempfile.TemporaryFile for large ones. (#9655)
+  * twisted.web.client.FileBodyProducer will now stop producing when the 
Deferred returned by FileBodyProducer.startProducing is cancelled. (#9547)
+  * The HTTP/2 server implementation now enforces TCP flow control on control 
frame messages and times out clients that send invalid data without reading 
responses. This closes CVE-2019-9512 (Ping Flood), CVE-2019-9514 (Reset Flood), 
and CVE-2019-9515 (Settings Flood). Thanks to Jonathan Looney and Piotr Sikora. 
(#9694)
+- Add python-38-xml-namespace.patch to fix dictionary mutation under Python 3.8
+- Add python-38-hmac-digestmod.patch to add digestmod parameter where required
+- Add python-38-no-cgi-parseqs.patch to no longer import parse_qs from cgi
+
+-------------------------------------------------------------------
+Sat Sep 14 15:29:06 UTC 2019 - John Vandenberg <[email protected]>
+
+- Remove mailmail when only building Python 3 flavour
+
+-------------------------------------------------------------------
+Fri Sep 13 13:09:16 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 19.7.0:
+  * The callable argument to twisted.internet.task.deferLater() is no longer 
required. (#9577)
+  * twisted.internet.utils.getProcessOutputAndValue now accepts stdinBytes to 
write to the child process's standard input. (#9607)
+  * Add new twisted.logger.capturedLogs context manager for capturing observed 
log events in tests. (#9617)
+  * twisted.internet.base.PluggableResolverMixin, which implements the 
pluggable resolver interfaces for easier re-use in other reactors, has been 
factored out of ReactorBase. (#9632)
+  * The PyPI page for Twisted has been enhanced to include more information 
and useful links. (#9648)
+- Refresh patch:
+  * skip_MultiCast.patch
+- Remove merged patch hyperlink.patch
+- Remove patch 0001-Prevent-CRLF-injections-described-in-CVE-2019-12387.patch
+- Remove patch PR-1147.patch
+
+-------------------------------------------------------------------
@@ -14,0 +51,96 @@
+
+-------------------------------------------------------------------
+Wed Jun 12 05:55:44 UTC 2019 - Thomas Bechtold <[email protected]>
+
+- update to 19.2.1 (bsc#1137825, CVE-2019-12387):
+  * Prevent CRLF injections described in CVE-2019-12387
+
+-------------------------------------------------------------------
+Wed May 22 09:59:19 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 19.2.0:
+  * twisted.internet.ssl.CertificateOptions now uses 32 random bytes instead 
of an MD5 hash for the ssl session identifier context. (#9463)
+  * DeferredLock and DeferredSemaphore can be used as asynchronous context 
managers on Python 3.5+. (#9546)
+  * t.i.b.BaseConnector has custom __repr__ (#9548)
+  * twisted.internet.ssl.optionsForClientTLS now supports validating IP 
addresses from the certificate subjectAltName (#9585)
+  * Twisted's minimum Cryptography requirement is now 2.5. (#9592)
+  * twisted.conch.ssh.keys can now read private keys in the new 
"openssh-key-v1" format, introduced in OpenSSH 6.5 and made the default in 
OpenSSH 7.8. (#9515)
+  * twisted.web.client.HostnameCachingHTTPSPolicy was added as a new 
contextFactory option. The policy caches a specified number of 
twisted.internet.interfaces.IOpenSSLClientConnectionCreator instances to to 
avoid the cost of instantiating a connection creator for multiple requests to 
the same host. (#9138)
+- Remove merged patches:
+  * openssl-errormsg.aptch
+  * openssl111.patch
+- Add patch to tests for new hyperlink:
+  * hyperlink.patch
+
+-------------------------------------------------------------------
+Mon Feb 18 11:24:53 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Add another patch for openssl 1.1.1 (from upstream git):
+  * openssl-errormsg.aptch
+
+-------------------------------------------------------------------
+Thu Jan 24 16:09:14 UTC 2019 - [email protected]
+
+- test-mktime-invalid-tm_isdst.patch: don't pass invalid tm_isdst value to
+  mktime (see also bpo-15750)
+
+-------------------------------------------------------------------
+Thu Nov  8 10:28:09 CET 2018 - [email protected]
+
+- Add no-pygtkcompat.patch to avoid dependency on Gtk (boo#1110669)
+
+-------------------------------------------------------------------
+Thu Nov  1 09:21:03 UTC 2018 - Tomáš Chvátal <[email protected]>
+
+- Version update to 18.9.0:
+  * Fixes for the 3.7 python
+- Remove merged python37.patch
+- Add patch openssl111.patch which fixes tests with new pyOpenssl
+  * Asserts changed behaviour
+
+-------------------------------------------------------------------
+Mon Oct 22 08:48:37 UTC 2018 - Tomáš Chvátal <[email protected]>
+
+- Do not write bytecode stuff when running the tests
+
+-------------------------------------------------------------------
+Fri Oct 19 13:27:25 UTC 2018 - Matěj Cepl <[email protected]>
+
+- Add BuildRequires python-tz, which seems to be required to test suite
+  to pass.
+- Also, add skip_MultiCast.patch to skip tests requiring full
+  netrworking stack.
+
+-------------------------------------------------------------------
+Fri Oct 12 09:06:36 UTC 2018 - [email protected]
+
+- Add missing Requires.
+
+-------------------------------------------------------------------
+Thu Oct 11 08:32:44 UTC 2018 - Tomáš Chvátal <[email protected]>
+
+- Fix the dependencies to match up upstream setup.py
+- Run the tests
+- Add patch to build with python3.7:
+  * python37.patch
+- Add missing dependency on pyamcrest
+- Remove unused patch lp1102685.diff
+
+-------------------------------------------------------------------
+Tue Jul 17 19:42:41 UTC 2018 - [email protected]
+
+- update to 18.7.0:
+  for full list of changes please see
+  https://github.com/twisted/twisted/blob/twisted-18.7.0/NEWS.rst
+
+-------------------------------------------------------------------
+Tue May 29 19:22:32 UTC 2018 - [email protected]
+
+- Add python-service_identity Recommends.
+
+-------------------------------------------------------------------
+Fri May 18 16:59:15 UTC 2018 - [email protected]
+
+- update to 18.4.0
+  For full list of changes please see:
+  https://github.com/twisted/twisted/blob/twisted-18.4.0/NEWS.rst

Old:
----
  0001-Prevent-CRLF-injections-described-in-CVE-2019-12387.patch
  PR-1147.patch
  Twisted-17.9.0.tar.bz2
  lp1102685.diff

New:
----
  Twisted-19.10.0.tar.bz2
  no-pygtkcompat.patch
  python-38-hmac-digestmod.patch
  python-38-no-cgi-parseqs.patch
  python-38-xml-namespace.patch
  skip_MultiCast.patch
  test-mktime-invalid-tm_isdst.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Twisted.spec ++++++
--- /var/tmp/diff_new_pack.CfHHCU/_old  2020-04-08 12:47:57.994329847 +0200
+++ /var/tmp/diff_new_pack.CfHHCU/_new  2020-04-08 12:47:57.994329847 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-Twisted
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,7 +12,7 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
@@ -20,40 +20,59 @@
 %define oldpython python
 %define modname Twisted
 Name:           python-Twisted
-Version:        17.9.0
+Version:        19.10.0
 Release:        0
 Summary:        An asynchronous networking framework written in Python
 License:        MIT
 Group:          Development/Languages/Python
-Url:            http://twistedmatrix.com/
+URL:            http://twistedmatrix.com/
 Source:         
https://files.pythonhosted.org/packages/source/T/Twisted/%{modname}-%{version}.tar.bz2
-# PATCH-FIX-UPSTREAM -- https://twistedmatrix.com/trac/ticket/6280
-Patch0:         lp1102685.diff
-# PATCH-FIX-UPSTREAM 
0001-Prevent-CRLF-injections-described-in-CVE-2019-12387.patch -- 
https://github.com/twisted/twisted/commit/6c61fc4503ae39ab8ecee52d10f10ee2c371d7e2
-Patch1:         0001-Prevent-CRLF-injections-described-in-CVE-2019-12387.patch
-# PATCH-FIX-UPSTREAM PR-1147.patch -- 
https://github.com/twisted/twisted/pull/1147
-Patch2:         PR-1147.patch
-BuildRequires:  %{python_module constantly}
+Patch1:         skip_MultiCast.patch
+Patch2:         no-pygtkcompat.patch
+Patch3:         test-mktime-invalid-tm_isdst.patch
+Patch4:         python-38-xml-namespace.patch
+Patch5:         python-38-hmac-digestmod.patch
+Patch6:         python-38-no-cgi-parseqs.patch
+BuildRequires:  %{python_module Automat >= 0.3.0}
+BuildRequires:  %{python_module PyHamcrest >= 1.9.0}
+BuildRequires:  %{python_module appdirs >= 1.4.0}
+BuildRequires:  %{python_module attrs >= 17.4.0}
+BuildRequires:  %{python_module bcrypt >= 3.0.0}
+BuildRequires:  %{python_module constantly >= 15.1}
+BuildRequires:  %{python_module cryptography >= 2.5}
 BuildRequires:  %{python_module devel}
-BuildRequires:  %{python_module hyperlink}
-BuildRequires:  %{python_module incremental}
-BuildRequires:  %{python_module pyOpenSSL}
+BuildRequires:  %{python_module h2 >= 3.0}
+BuildRequires:  %{python_module hyperlink >= 17.1.1}
+BuildRequires:  %{python_module idna >= 0.6}
+BuildRequires:  %{python_module incremental >= 16.10.1}
+BuildRequires:  %{python_module pyOpenSSL >= 16.0.0}
+BuildRequires:  %{python_module pyasn1}
+BuildRequires:  %{python_module pyserial >= 3.0}
 BuildRequires:  %{python_module pyserial}
 BuildRequires:  %{python_module pytest}
+BuildRequires:  %{python_module python-subunit}
+BuildRequires:  %{python_module pytz}
+BuildRequires:  %{python_module service_identity >= 18.1.0}
 BuildRequires:  %{python_module setuptools}
-BuildRequires:  %{python_module zope.interface}
+BuildRequires:  %{python_module zope.interface >= 4.4.2}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       python-Automat
-Requires:       python-constantly
-Requires:       python-hyperlink
-Requires:       python-incremental
-Requires:       python-pyOpenSSL
+Requires:       python-Automat >= 0.3.0
+Requires:       python-PyHamcrest >= 1.9.0
+Requires:       python-appdirs >= 1.4.0
+Requires:       python-attrs >= 17.4.0
+Requires:       python-bcrypt >= 3.0.0
+Requires:       python-constantly >= 15.1
+Requires:       python-cryptography >= 2.5
+Requires:       python-h2 >= 3.0
+Requires:       python-hyperlink >= 17.1.1
+Requires:       python-idna >= 0.6
+Requires:       python-incremental >= 16.10.1
+Requires:       python-pyOpenSSL >= 16.0.0
 Requires:       python-pyasn1
-Requires:       python-pycrypto
-Requires:       python-pyserial
-Requires:       python-zope.interface
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+Requires:       python-pyserial >= 3.0
+Requires:       python-service_identity >= 18.1.0
+Requires:       python-zope.interface >= 4.4.2
 %ifpython2
 Provides:       %{oldpython}-twisted = %{version}
 Obsoletes:      %{oldpython}-twisted < %{version}
@@ -96,10 +115,7 @@
 
 %prep
 %setup -q -n %{modname}-%{version}
-#%%patch0 -p1
-%patch1 -p1
-%patch2 -p1
-#sed -i "1d" twisted/{mail/test/pop3testserver,trial/test/scripttest}.py
+%autopatch -p1
 
 %build
 %python_build
@@ -111,7 +127,7 @@
 install -m0644 docs/*/man/*.1 %{buildroot}%{_mandir}/man1/ # Install man pages
 find docs -type f -print0 | xargs -0 chmod a-x # Fix doc-file dependency by 
removing x flags
 #sed -i "s/\r//" 
docs/core/howto/listings/udp/{MulticastClient,MulticastServer}.py
-%fdupes %{buildroot}%{_prefix}
+%python_expand %fdupes %{buildroot}%{$python_sitearch}
 
 # Prepare for update-alternatives usage
 for p in twistd cftp ckeygen conch pyhtmlizer tkconch trial ; do
@@ -124,16 +140,25 @@
 %python_clone %{buildroot}%{_bindir}/mailmail
 %python_clone %{buildroot}%{_mandir}/man1/mailmail.1
 %endif
+%if ! 0%{?have_python2} || 0%{?skip_python2}
+rm %{buildroot}%{_bindir}/mailmail %{buildroot}%{_mandir}/man1/mailmail.1
+%endif
+
 # no manpage for twist yet:
 %python_clone %{buildroot}%{_bindir}/twist
 
+%check
+export LANG=en_US.UTF-8
+export PATH=%{buildroot}%{_bindir}:$PATH
+export PYTHONDONTWRITEBYTECODE=1
+%python_expand PYTHONPATH=%{buildroot}%{$python_sitearch} $python -m 
twisted.trial twisted
+
 %files -n %{name}-doc
-%defattr(-,root,root,-)
 %doc docs/*
 
 %files %{python_files}
-%defattr(-,root,root,-)
-%doc LICENSE NEWS.rst README.rst
+%license LICENSE
+%doc NEWS.rst README.rst
 %{_bindir}/*-%{python_bin_suffix}
 %{_mandir}/man1/*-%{python_bin_suffix}.1%{?ext_man}
 %python3_only %{_bindir}/twistd
@@ -150,7 +175,7 @@
 %python3_only %{_mandir}/man1/cftp.1%{?ext_man}
 %python3_only %{_mandir}/man1/ckeygen.1%{?ext_man}
 %python3_only %{_mandir}/man1/conch.1%{?ext_man}
-%python3_only %{_mandir}/man1/mailmail.1%{?ext_man}
+%python2_only %{_mandir}/man1/mailmail.1%{?ext_man}
 %python3_only %{_mandir}/man1/pyhtmlizer.1%{?ext_man}
 %python3_only %{_mandir}/man1/tkconch.1%{?ext_man}
 %python3_only %{_mandir}/man1/trial.1%{?ext_man}

++++++ Twisted-17.9.0.tar.bz2 -> Twisted-19.10.0.tar.bz2 ++++++
++++ 57844 lines of diff (skipped)

++++++ no-pygtkcompat.patch ++++++
diff -ur Twisted-18.7.0.orig/src/twisted/internet/gireactor.py 
Twisted-18.7.0/src/twisted/internet/gireactor.py
--- Twisted-18.7.0.orig/src/twisted/internet/gireactor.py       2018-03-26 
10:19:31.000000000 +0200
+++ Twisted-18.7.0/src/twisted/internet/gireactor.py    2018-10-04 
01:41:32.547220235 +0200
@@ -75,8 +75,12 @@
     # Newer version of gi, so we can try to initialize compatibility layer; if
     # real pygtk was already imported we'll get ImportError at this point
     # rather than segfault, so unconditional import is fine.
-    import gi.pygtkcompat
-    gi.pygtkcompat.enable()
+    try:
+        import gi.pygtkcompat
+    except ImportError:
+        pass # This is probably Python 3, with pygtkcompat removed
+    else:
+        gi.pygtkcompat.enable()
     # At this point importing gobject will get you gi version, and importing
     # e.g. gtk will either fail in non-segfaulty way or use gi version if user
     # does gi.pygtkcompat.enable_gtk(). So, no need to prevent imports of
++++++ python-38-hmac-digestmod.patch ++++++
Index: Twisted-19.10.0/src/twisted/cred/credentials.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/cred/credentials.py
+++ Twisted-19.10.0/src/twisted/cred/credentials.py
@@ -439,7 +439,8 @@ class CramMD5Credentials(object):
 
 
     def checkPassword(self, password):
-        verify = hexlify(hmac.HMAC(password, self.challenge).digest())
+        verify = hexlify(
+            hmac.HMAC(password, self.challenge, digestmod=md5).digest())
         return verify == self.response
 
 
Index: Twisted-19.10.0/src/twisted/cred/test/test_cramauth.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/cred/test/test_cramauth.py
+++ Twisted-19.10.0/src/twisted/cred/test/test_cramauth.py
@@ -7,6 +7,7 @@ Tests for L{twisted.cred}'s implementati
 
 from __future__ import division, absolute_import
 
+from hashlib import md5
 from hmac import HMAC
 from binascii import hexlify
 
@@ -39,7 +40,7 @@ class CramMD5CredentialsTests(TestCase):
         """
         c = CramMD5Credentials()
         chal = c.getChallenge()
-        c.response = hexlify(HMAC(b'secret', chal).digest())
+        c.response = hexlify(HMAC(b'secret', chal, digestmod=md5).digest())
         self.assertTrue(c.checkPassword(b'secret'))
 
 
@@ -61,7 +62,8 @@ class CramMD5CredentialsTests(TestCase):
         """
         c = CramMD5Credentials()
         chal = c.getChallenge()
-        c.response = hexlify(HMAC(b'thewrongsecret', chal).digest())
+        c.response = hexlify(
+            HMAC(b'thewrongsecret', chal, digestmod=md5).digest())
         self.assertFalse(c.checkPassword(b'secret'))
 
 
@@ -75,7 +77,7 @@ class CramMD5CredentialsTests(TestCase):
         chal = c.getChallenge()
         c.setResponse(b" ".join(
             (b"squirrel",
-             hexlify(HMAC(b'supersecret', chal).digest()))))
+             hexlify(HMAC(b'supersecret', chal, digestmod=md5).digest()))))
         self.assertTrue(c.checkPassword(b'supersecret'))
         self.assertEqual(c.username, b"squirrel")
 
Index: Twisted-19.10.0/src/twisted/mail/_cred.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/mail/_cred.py
+++ Twisted-19.10.0/src/twisted/mail/_cred.py
@@ -7,6 +7,7 @@ Credential managers for L{twisted.mail}.
 
 from __future__ import absolute_import, division
 
+from hashlib import md5
 import hmac
 
 from zope.interface import implementer
@@ -28,7 +29,8 @@ class CramMD5ClientAuthenticator:
 
 
     def challengeResponse(self, secret, chal):
-        response = hmac.HMAC(secret, chal).hexdigest().encode('ascii')
+        response = hmac.HMAC(
+            secret, chal, digestmod=md5).hexdigest().encode('ascii')
         return self.user + b' ' + response
 
 
Index: Twisted-19.10.0/src/twisted/mail/test/test_pop3.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/mail/test/test_pop3.py
+++ Twisted-19.10.0/src/twisted/mail/test/test_pop3.py
@@ -12,6 +12,7 @@ import base64
 import itertools
 
 from collections import OrderedDict
+from hashlib import md5
 from io import BytesIO
 
 from zope.interface import implementer
@@ -1097,7 +1098,8 @@ class SASLTests(unittest.TestCase):
         p.lineReceived(b"AUTH CRAM-MD5")
         chal = s.getvalue().splitlines()[-1][2:]
         chal = base64.decodestring(chal)
-        response = hmac.HMAC(b'testpassword', chal).hexdigest().encode("ascii")
+        response = hmac.HMAC(
+            b'testpassword', chal, digestmod=md5).hexdigest().encode("ascii")
 
         p.lineReceived(
             base64.encodestring(b'testuser ' + response).rstrip(b'\n'))
++++++ python-38-no-cgi-parseqs.patch ++++++
Index: Twisted-19.10.0/src/twisted/web/test/test_http.py
===================================================================
--- Twisted-19.10.0.orig/src/twisted/web/test/test_http.py
+++ Twisted-19.10.0/src/twisted/web/test/test_http.py
@@ -9,15 +9,14 @@ from __future__ import absolute_import,
 
 import base64
 import calendar
-import cgi
 import random
 
 import hamcrest
 
 try:
-    from urlparse import urlparse, urlunsplit, clear_cache
+    from urlparse import urlparse, urlunsplit, clear_cache, parse_qs
 except ImportError:
-    from urllib.parse import urlparse, urlunsplit, clear_cache
+    from urllib.parse import urlparse, urlunsplit, clear_cache, parse_qs
 
 from io import BytesIO
 from itertools import cycle
@@ -2156,15 +2155,15 @@ Hello,
 class QueryArgumentsTests(unittest.TestCase):
     def testParseqs(self):
         self.assertEqual(
-            cgi.parse_qs(b"a=b&d=c;+=f"),
+            parse_qs(b"a=b&d=c;+=f"),
             http.parse_qs(b"a=b&d=c;+=f"))
         self.assertRaises(
             ValueError, http.parse_qs, b"blah", strict_parsing=True)
         self.assertEqual(
-            cgi.parse_qs(b"a=&b=c", keep_blank_values=1),
+            parse_qs(b"a=&b=c", keep_blank_values=1),
             http.parse_qs(b"a=&b=c", keep_blank_values=1))
         self.assertEqual(
-            cgi.parse_qs(b"a=&b=c"),
+            parse_qs(b"a=&b=c"),
             http.parse_qs(b"a=&b=c"))
 
 
++++++ python-38-xml-namespace.patch ++++++
>From e42ba68b39f0ae98f1ea89a38a9317f2966c7d0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Poisson?= <[email protected]>
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)
++++++ skip_MultiCast.patch ++++++
Index: Twisted-19.7.0/src/twisted/test/test_udp.py
===================================================================
--- Twisted-19.7.0.orig/src/twisted/test/test_udp.py
+++ Twisted-19.7.0/src/twisted/test/test_udp.py
@@ -514,6 +514,7 @@ class MulticastTests(unittest.TestCase):
         skip = "Does not work on Azure Pipelines"
 
     def setUp(self):
+        raise unittest.SkipTest("Multicast networking doesn't work with OBS")
         self.server = Server()
         self.client = Client()
         # multicast won't work if we listen over loopback, apparently
++++++ test-mktime-invalid-tm_isdst.patch ++++++
Index: Twisted-18.9.0/src/twisted/test/test_log.py
===================================================================
--- Twisted-18.9.0.orig/src/twisted/test/test_log.py
+++ Twisted-18.9.0/src/twisted/test/test_log.py
@@ -456,13 +456,13 @@ class FileObserverTests(LogPublisherTest
 
             # Compute a POSIX timestamp for a certain date and time that is
             # known to occur at a time when daylight saving time is in effect.
-            localDaylightTuple = (2006, 6, 30, 0, 0, 0, 4, 181, 1)
+            localDaylightTuple = (2006, 6, 30, 0, 0, 0, 4, 181, -1)
             daylight = time.mktime(localDaylightTuple)
 
             # Compute a POSIX timestamp for a certain date and time that is
             # known to occur at a time when daylight saving time is not in
             # effect.
-            localStandardTuple = (2007, 1, 31, 0, 0, 0, 2, 31, 0)
+            localStandardTuple = (2007, 1, 31, 0, 0, 0, 2, 31, -1)
             standard = time.mktime(localStandardTuple)
 
             self.assertEqual(

Reply via email to