commit 763b1dde4d0e2eca969f55e2a082f08ca1dd1a6e5e84f09301479bce4f146351 Author: Matej Cepl Date: Thu Sep 19 00:29:56 2024 +0000 - Update CVE-2023-52425-libexpat-2.6.0-backport.patch so that it uses features sniffing, not just comparing version number. Include also support-expat-CVE-2022-25236-patched.patch. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python38?expand=0&rev=173 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/98437-sphinx.locale._-as-gettext-in-pyspecific.patch b/98437-sphinx.locale._-as-gettext-in-pyspecific.patch new file mode 100644 index 0000000..439b730 --- /dev/null +++ b/98437-sphinx.locale._-as-gettext-in-pyspecific.patch @@ -0,0 +1,54 @@ +From 5775f51691d7d64fb676586e008b41261ce64ac2 Mon Sep 17 00:00:00 2001 +From: "Matt.Wang" +Date: Wed, 19 Oct 2022 14:49:08 +0800 +Subject: [PATCH 1/2] fix(doc-tools): use sphinx.locale._ as gettext() for + backward-compatibility in pyspecific.py + +[why] spinix 5.3 changed locale.translators from a defaultdict(gettext.NullTranslations) to a dict, which leads to failure of pyspecific.py. Use sphinx.locale._ as gettext to fix the issue. +--- + Doc/tools/extensions/pyspecific.py | 8 ++++---- + Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst | 1 + + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/Doc/tools/extensions/pyspecific.py ++++ b/Doc/tools/extensions/pyspecific.py +@@ -26,7 +26,7 @@ try: + from sphinx.errors import NoUri + except ImportError: + from sphinx.environment import NoUri +-from sphinx.locale import translators ++from sphinx.locale import _ as sphinx_gettext + from sphinx.util import status_iterator, logging + from sphinx.util.nodes import split_explicit_title + from sphinx.writers.text import TextWriter, TextTranslator +@@ -110,7 +110,7 @@ class ImplementationDetail(Directive): + + def run(self): + pnode = nodes.compound(classes=['impl-detail']) +- label = translators['sphinx'].gettext(self.label_text) ++ label = sphinx_gettext(self.label_text) + content = self.content + add_text = nodes.strong(label, label) + if self.arguments: +@@ -179,7 +179,7 @@ class AuditEvent(Directive): + else: + args = [] + +- label = translators['sphinx'].gettext(self._label[min(2, len(args))]) ++ label = sphinx_gettext(self._label[min(2, len(args))]) + text = label.format(name="``{}``".format(name), + args=", ".join("``{}``".format(a) for a in args if a)) + +@@ -357,7 +357,7 @@ class DeprecatedRemoved(Directive): + else: + label = self._removed_label + +- label = translators['sphinx'].gettext(label) ++ label = sphinx_gettext(label) + text = label.format(deprecated=self.arguments[0], removed=self.arguments[1]) + if len(self.arguments) == 3: + inodes, messages = self.state.inline_text(self.arguments[2], +--- /dev/null ++++ b/Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst +@@ -0,0 +1 @@ ++Use sphinx.locale._ as the gettext function in pyspecific.py. diff --git a/99366-patch.dict-can-decorate-async.patch b/99366-patch.dict-can-decorate-async.patch new file mode 100644 index 0000000..96aaadd --- /dev/null +++ b/99366-patch.dict-can-decorate-async.patch @@ -0,0 +1,79 @@ +From c0dea0309b9a0a7cbc87727c9957f0a388fb9b0f Mon Sep 17 00:00:00 2001 +From: Nikita Sobolev +Date: Fri, 11 Nov 2022 11:04:30 +0300 +Subject: [PATCH] gh-98086: Now ``patch.dict`` can decorate async functions + (GH-98095) (cherry picked from commit + 67b4d2772c5124b908f8ed9b13166a79bbeb88d2) + +Co-authored-by: Nikita Sobolev +--- + Lib/unittest/mock.py | 18 ++++++++++ + Lib/unittest/test/testmock/testasync.py | 17 +++++++++ + Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst | 1 + 3 files changed, 36 insertions(+) + create mode 100644 Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst + +--- a/Lib/unittest/mock.py ++++ b/Lib/unittest/mock.py +@@ -1749,6 +1749,12 @@ class _patch_dict(object): + def __call__(self, f): + if isinstance(f, type): + return self.decorate_class(f) ++ if inspect.iscoroutinefunction(f): ++ return self.decorate_async_callable(f) ++ return self.decorate_callable(f) ++ ++ ++ def decorate_callable(self, f): + @wraps(f) + def _inner(*args, **kw): + self._patch_dict() +@@ -1757,6 +1763,18 @@ class _patch_dict(object): + finally: + self._unpatch_dict() + ++ return _inner ++ ++ ++ def decorate_async_callable(self, f): ++ @wraps(f) ++ async def _inner(*args, **kw): ++ self._patch_dict() ++ try: ++ return await f(*args, **kw) ++ finally: ++ self._unpatch_dict() ++ + return _inner + + +--- a/Lib/unittest/test/testmock/testasync.py ++++ b/Lib/unittest/test/testmock/testasync.py +@@ -143,6 +143,23 @@ class AsyncPatchCMTest(unittest.TestCase + + asyncio.run(test_async()) + ++ def test_patch_dict_async_def(self): ++ foo = {'a': 'a'} ++ @patch.dict(foo, {'a': 'b'}) ++ async def test_async(): ++ self.assertEqual(foo['a'], 'b') ++ ++ self.assertTrue(inspect.iscoroutinefunction(test_async)) ++ asyncio.run(test_async()) ++ ++ def test_patch_dict_async_def_context(self): ++ foo = {'a': 'a'} ++ async def test_async(): ++ with patch.dict(foo, {'a': 'b'}): ++ self.assertEqual(foo['a'], 'b') ++ ++ asyncio.run(test_async()) ++ + + class AsyncMockTest(unittest.TestCase): + def test_iscoroutinefunction_default(self): +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst +@@ -0,0 +1 @@ ++Make sure ``patch.dict()`` can be applied on async functions. diff --git a/CVE-2019-5010-null-defer-x509-cert-DOS.patch b/CVE-2019-5010-null-defer-x509-cert-DOS.patch new file mode 100644 index 0000000..3ff39d9 --- /dev/null +++ b/CVE-2019-5010-null-defer-x509-cert-DOS.patch @@ -0,0 +1,57 @@ +From a37f52436f9aa4b9292878b72f3ff1480e2606c3 Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Tue, 15 Jan 2019 23:47:42 +0100 +Subject: [PATCH] bpo-35746: Fix segfault in ssl's cert parser (GH-11569) + +Fix a NULL pointer deref in ssl module. The cert parser did not handle CRL +distribution points with empty DP or URI correctly. A malicious or buggy +certificate can result into segfault. + +Signed-off-by: Christian Heimes + + + +https://bugs.python.org/issue35746 +--- + Lib/test/test_ssl.py | 21 ++++++++++ + Misc/NEWS.d/next/Security/2019-01-15-18-16-05.bpo-35746.nMSd0j.rst | 3 + + 2 files changed, 24 insertions(+) + create mode 100644 Lib/test/talos-2019-0758.pem + create mode 100644 Misc/NEWS.d/next/Security/2019-01-15-18-16-05.bpo-35746.nMSd0j.rst + +--- a/Lib/test/test_ssl.py ++++ b/Lib/test/test_ssl.py +@@ -507,6 +507,27 @@ class BasicSocketTests(unittest.TestCase + } + ) + ++ def test_parse_cert_CVE_2019_5010(self): ++ p = ssl._ssl._test_decode_cert(TALOS_INVALID_CRLDP) ++ if support.verbose: ++ sys.stdout.write("\n" + pprint.pformat(p) + "\n") ++ self.assertEqual( ++ p, ++ { ++ 'issuer': ( ++ (('countryName', 'UK'),), (('commonName', 'cody-ca'),)), ++ 'notAfter': 'Jun 14 18:00:58 2028 GMT', ++ 'notBefore': 'Jun 18 18:00:58 2018 GMT', ++ 'serialNumber': '02', ++ 'subject': ((('countryName', 'UK'),), ++ (('commonName', ++ 'codenomicon-vm-2.test.lal.cisco.com'),)), ++ 'subjectAltName': ( ++ ('DNS', 'codenomicon-vm-2.test.lal.cisco.com'),), ++ 'version': 3 ++ } ++ ) ++ + def test_parse_cert_CVE_2013_4238(self): + p = ssl._ssl._test_decode_cert(NULLBYTECERT) + if support.verbose: +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2019-01-15-18-16-05.bpo-35746.nMSd0j.rst +@@ -0,0 +1,3 @@ ++[CVE-2019-5010] Fix a NULL pointer deref in ssl module. The cert parser did ++not handle CRL distribution points with empty DP or URI correctly. A ++malicious or buggy certificate can result into segfault. diff --git a/CVE-2023-52425-libexpat-2.6.0-backport.patch b/CVE-2023-52425-libexpat-2.6.0-backport.patch new file mode 100644 index 0000000..ffafbe0 --- /dev/null +++ b/CVE-2023-52425-libexpat-2.6.0-backport.patch @@ -0,0 +1,313 @@ +From d7133c7e0f91b14c390aa30a5689c353ef754fb6 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Wed, 7 Feb 2024 15:32:45 +0100 +Subject: [PATCH] Fix etree XMLPullParser tests for Expat >=2.6.0 with reparse + deferral + +Combined with gh#python/cpython!31453 +bpo-46811: Make test suite support Expat >=2.4.5 (GH-31453) + +Curly brackets were never allowed in namespace URIs +according to RFC 3986, and so-called namespace-validating +XML parsers have the right to reject them a invalid URIs. + +libexpat >=2.4.5 has become strcter in that regard due to +related security issues; with ET.XML instantiating a +namespace-aware parser under the hood, this test has no +future in CPython. + +References: +- https://datatracker.ietf.org/doc/html/rfc3968 +- https://www.w3.org/TR/xml-names/ + +Also, test_minidom.py: Support Expat >=2.4.5 +(cherry picked from commit 2cae93832f46b245847bdc252456ddf7742ef45e) + +Co-authored-by: Sebastian Pipping +Fixes: gh#python/cpython#115133 +From-PR: gh#python/cpython!115138 +Patch: CVE-2023-52425-libexpat-2.6.0-backport.patch +--- + Lib/test/support/__init__.py | 15 ++ + Lib/test/test_minidom.py | 22 +-- + Lib/test/test_pyexpat.py | 61 +++++++++- + Lib/test/test_sax.py | 54 ++++++++ + Lib/test/test_xml_etree.py | 13 +- + Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst | 1 + Misc/NEWS.d/next/Tests/2024-02-07-15-49-37.gh-issue-115133.WBajNr.rst | 1 + 7 files changed, 146 insertions(+), 21 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst + create mode 100644 Misc/NEWS.d/next/Tests/2024-02-07-15-49-37.gh-issue-115133.WBajNr.rst + +--- a/Lib/test/support/__init__.py ++++ b/Lib/test/support/__init__.py +@@ -23,6 +23,7 @@ import platform + import re + import shutil + import socket ++import pyexpat + import stat + import struct + import subprocess +@@ -119,9 +120,11 @@ __all__ = [ + "run_with_locale", "swap_item", + "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", + "run_with_tz", "PGO", "missing_compiler_executable", "fd_count", +- "ALWAYS_EQ", "LARGEST", "SMALLEST" ++ "ALWAYS_EQ", "LARGEST", "SMALLEST", ++ "fails_with_expat_2_6_0", "is_expat_2_6_0" + ] + ++ + class Error(Exception): + """Base class for regression test exceptions.""" + +@@ -3411,3 +3414,13 @@ def adjust_int_max_str_digits(max_digits + yield + finally: + sys.set_int_max_str_digits(current) ++ ++ ++@functools.lru_cache(maxsize=32) ++def _is_expat_2_6_0(): ++ return hasattr(pyexpat.ParserCreate(), 'SetReparseDeferralEnabled') ++is_expat_2_6_0 = _is_expat_2_6_0() ++ ++fails_with_expat_2_6_0 = (unittest.expectedFailure ++ if is_expat_2_6_0 ++ else lambda test: test) +--- a/Lib/test/test_minidom.py ++++ b/Lib/test/test_minidom.py +@@ -1149,13 +1149,11 @@ class MinidomTest(unittest.TestCase): + + # Verify that character decoding errors raise exceptions instead + # of crashing +- if pyexpat.version_info >= (2, 4, 5): +- self.assertRaises(ExpatError, parseString, +- b'') +- self.assertRaises(ExpatError, parseString, +- b'Comment \xe7a va ? Tr\xe8s bien ?') +- else: +- self.assertRaises(UnicodeDecodeError, parseString, ++ # It doesn’t make any sense to insist on the exact text of the ++ # error message, or even the exact Exception … it is enough that ++ # the error has been discovered. ++ with self.assertRaises((UnicodeDecodeError, ExpatError)): ++ parseString( + b'Comment \xe7a va ? Tr\xe8s bien ?') + + doc.unlink() +@@ -1601,12 +1599,10 @@ class MinidomTest(unittest.TestCase): + self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE) + + def testExceptionOnSpacesInXMLNSValue(self): +- if pyexpat.version_info >= (2, 4, 5): +- context = self.assertRaisesRegex(ExpatError, 'syntax error') +- else: +- context = self.assertRaisesRegex(ValueError, 'Unsupported syntax') +- +- with context: ++ # It doesn’t make any sense to insist on the exact text of the ++ # error message, or even the exact Exception … it is enough that ++ # the error has been discovered. ++ with self.assertRaises((ExpatError, ValueError)): + parseString('') + + def testDocRemoveChild(self): +--- a/Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -11,7 +11,7 @@ import traceback + from xml.parsers import expat + from xml.parsers.expat import errors + +-from test.support import sortdict ++from test.support import sortdict, is_expat_2_6_0 + + + class SetAttributeTest(unittest.TestCase): +@@ -778,6 +778,65 @@ class ReparseDeferralTest(unittest.TestC + + for chunk in (b''): + parser.Parse(chunk, False) ++ ++ # The key test: Have handlers already fired? Expecting: yes. ++ self.assertEqual(started, ['doc']) ++ ++ ++class ReparseDeferralTest(unittest.TestCase): ++ def test_getter_setter_round_trip(self): ++ if not is_expat_2_6_0: ++ self.skipTest("Linked libexpat doesn't support reparse deferral") ++ ++ parser = expat.ParserCreate() ++ enabled = (expat.version_info >= (2, 6, 0)) ++ ++ self.assertIs(parser.GetReparseDeferralEnabled(), enabled) ++ parser.SetReparseDeferralEnabled(False) ++ self.assertIs(parser.GetReparseDeferralEnabled(), False) ++ parser.SetReparseDeferralEnabled(True) ++ self.assertIs(parser.GetReparseDeferralEnabled(), enabled) ++ ++ def test_reparse_deferral_enabled(self): ++ if not is_expat_2_6_0: ++ self.skipTest("Linked libexpat doesn't support reparse deferral") ++ ++ started = [] ++ ++ def start_element(name, _): ++ started.append(name) ++ ++ parser = expat.ParserCreate() ++ parser.StartElementHandler = start_element ++ self.assertTrue(parser.GetReparseDeferralEnabled()) ++ ++ for chunk in (b''): ++ parser.Parse(chunk, False) ++ ++ # The key test: Have handlers already fired? Expecting: no. ++ self.assertEqual(started, []) ++ ++ parser.Parse(b'', True) ++ ++ self.assertEqual(started, ['doc']) ++ ++ def test_reparse_deferral_disabled(self): ++ if not is_expat_2_6_0: ++ self.skipTest("Linked libexpat doesn't support reparse deferral") ++ ++ started = [] ++ ++ def start_element(name, _): ++ started.append(name) ++ ++ parser = expat.ParserCreate() ++ parser.StartElementHandler = start_element ++ if is_expat_2_6_0: ++ parser.SetReparseDeferralEnabled(False) ++ self.assertFalse(parser.GetReparseDeferralEnabled()) ++ ++ for chunk in (b''): ++ parser.Parse(chunk, False) + + # The key test: Have handlers already fired? Expecting: yes. + self.assertEqual(started, ['doc']) +--- a/Lib/test/test_sax.py ++++ b/Lib/test/test_sax.py +@@ -22,7 +22,7 @@ import pyexpat + import shutil + from urllib.error import URLError + from test import support +-from test.support import findfile, run_unittest, FakePath, TESTFN ++from test.support import findfile, run_unittest, FakePath, TESTFN, is_expat_2_6_0 + + TEST_XMLFILE = findfile("test.xml", subdir="xmltestdata") + TEST_XMLFILE_OUT = findfile("test.xml.out", subdir="xmltestdata") +@@ -1247,6 +1247,58 @@ class ExpatReaderTest(XmlTestBase): + + self.assertFalse(parser._parser.GetReparseDeferralEnabled()) + ++ parser.flush() ++ ++ self.assertFalse(parser._parser.GetReparseDeferralEnabled()) ++ self.assertEqual(result.getvalue(), start + b"") ++ ++ parser.feed("") ++ parser.close() ++ ++ self.assertEqual(result.getvalue(), start + b"") ++ ++ def test_flush_reparse_deferral_enabled(self): ++ if not is_expat_2_6_0: ++ self.skipTest("Linked libexpat doesn't support reparse deferral") ++ ++ result = BytesIO() ++ xmlgen = XMLGenerator(result) ++ parser = create_parser() ++ parser.setContentHandler(xmlgen) ++ ++ for chunk in (""): ++ parser.feed(chunk) ++ ++ self.assertEqual(result.getvalue(), start) # i.e. no elements started ++ self.assertTrue(parser._parser.GetReparseDeferralEnabled()) ++ ++ parser.flush() ++ ++ self.assertTrue(parser._parser.GetReparseDeferralEnabled()) ++ self.assertEqual(result.getvalue(), start + b"") ++ ++ parser.feed("") ++ parser.close() ++ ++ self.assertEqual(result.getvalue(), start + b"") ++ ++ def test_flush_reparse_deferral_disabled(self): ++ if not is_expat_2_6_0: ++ self.skipTest("Linked libexpat doesn't support reparse deferral") ++ ++ result = BytesIO() ++ xmlgen = XMLGenerator(result) ++ parser = create_parser() ++ parser.setContentHandler(xmlgen) ++ ++ for chunk in (""): ++ parser.feed(chunk) ++ ++ parser._parser.SetReparseDeferralEnabled(False) ++ self.assertEqual(result.getvalue(), start) # i.e. no elements started ++ ++ self.assertFalse(parser._parser.GetReparseDeferralEnabled()) ++ + parser.flush() + + self.assertFalse(parser._parser.GetReparseDeferralEnabled()) +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -25,7 +25,8 @@ import weakref + from functools import partial + from itertools import product, islice + from test import support +-from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr ++from test.support import (TESTFN, findfile, import_fresh_module, ++ gc_collect, swap_attr, is_expat_2_6_0, fails_with_expat_2_6_0) + + # pyET is the pure-Python implementation. + # +@@ -1271,6 +1272,7 @@ class XMLPullParserTest(unittest.TestCas + expected) + + def test_simple_xml(self, chunk_size=None, flush=False): ++ expected_events = [] + parser = ET.XMLPullParser() + self.assert_event_tags(parser, []) + self._feed(parser, "\n", chunk_size, flush) +@@ -1280,16 +1282,17 @@ class XMLPullParserTest(unittest.TestCas + chunk_size, flush) + self.assert_event_tags(parser, []) + self._feed(parser, ">\n", chunk_size, flush) +- self.assert_event_tags(parser, [('end', 'element')]) ++ expected_events += [('end', 'element')]) + self._feed(parser, "texttail\n", chunk_size, flush) + self._feed(parser, "\n", chunk_size, flush) +- self.assert_event_tags(parser, [ ++ expected_events += [ + ('end', 'element'), + ('end', 'empty-element'), +- ]) ++ ] + self._feed(parser, "\n", chunk_size, flush) +- self.assert_event_tags(parser, [('end', 'root')]) ++ expected_events += [('end', 'root')] + self.assertIsNone(parser.close()) ++ self.assert_event_tags(parser, expected_events) + + def test_simple_xml_chunk_1(self): + self.test_simple_xml(chunk_size=1, flush=True) +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst +@@ -0,0 +1 @@ ++Make test suite support Expat >=2.4.5 +--- /dev/null ++++ b/Misc/NEWS.d/next/Tests/2024-02-07-15-49-37.gh-issue-115133.WBajNr.rst +@@ -0,0 +1 @@ ++Fix etree XMLPullParser tests for Expat >=2.6.0 with reparse deferral diff --git a/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch b/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch new file mode 100644 index 0000000..6fd5f71 --- /dev/null +++ b/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch @@ -0,0 +1,1742 @@ +From 3ddf7fa83b19463e710b75ae6e8a28831e575f3d Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Wed, 28 Oct 2020 09:26:39 +0100 +Subject: [PATCH] PEP-644: Require OpenSSL 1.1.1 or newer + +- Remove HAVE_X509_VERIFY_PARAM_SET1_HOST check +- Update hashopenssl to require OpenSSL 1.1.1 +- multissltests only OpenSSL > 1.1.0 +- ALPN is always supported +- SNI is always supported +- Remove deprecated NPN code. Python wrappers are no-op. +- ECDH is always supported +- Remove OPENSSL_VERSION_1_1 macro +- Remove locking callbacks +- Drop PY_OPENSSL_1_1_API macro +- Drop HAVE_SSL_CTX_CLEAR_OPTIONS macro +- SSL_CTRL_GET_MAX_PROTO_VERSION is always defined now +- security level is always available now +- get_num_tickets is available with TLS 1.3 +- X509_V_ERR MISMATCH is always available now +- Always set SSL_MODE_RELEASE_BUFFERS +- X509_V_FLAG_TRUSTED_FIRST is always available +- get_ciphers is always supported +- SSL_CTX_set_keylog_callback is always available +- Update Modules/Setup with static link example +- Mention PEP in whatsnew +- Drop 1.0.2 and 1.1.0 from GHA tests +--- + Doc/using/unix.rst | 1 + Lib/ssl.py | 10 + Lib/test/test_ssl.py | 119 -- + Misc/NEWS.d/next/Build/2021-03-30-14-19-39.bpo-43669.lWMUYx.rst | 1 + Modules/Setup | 22 + Modules/_hashopenssl.c | 24 + Modules/_ssl.c | 518 ---------- + Modules/_ssl/debughelpers.c | 4 + Modules/clinic/_hashopenssl.c.h | 4 + Modules/clinic/_ssl.c.h | 85 - + Tools/ssl/multissltests.py | 4 + configure | 9 + configure.ac | 36 + pyconfig.h.in | 3 + setup.py | 19 + 15 files changed, 75 insertions(+), 784 deletions(-) + create mode 100644 Misc/NEWS.d/next/Build/2021-03-30-14-19-39.bpo-43669.lWMUYx.rst + +--- a/Doc/using/unix.rst ++++ b/Doc/using/unix.rst +@@ -113,6 +113,7 @@ For example, on most Linux systems, the + | | embedding the interpreter. | + +-----------------------------------------------+------------------------------------------+ + ++.. _unix_custom_openssl: + + Miscellaneous + ============= +--- a/Lib/ssl.py ++++ b/Lib/ssl.py +@@ -909,15 +909,12 @@ class SSLObject: + """Return the currently selected NPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if NPN is not supported by one + of the peers.""" +- if _ssl.HAS_NPN: +- return self._sslobj.selected_npn_protocol() + + def selected_alpn_protocol(self): + """Return the currently selected ALPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if ALPN is not supported by one + of the peers.""" +- if _ssl.HAS_ALPN: +- return self._sslobj.selected_alpn_protocol() ++ return self._sslobj.selected_alpn_protocol() + + def cipher(self): + """Return the currently selected cipher as a 3-tuple ``(name, +@@ -1159,10 +1156,7 @@ class SSLSocket(socket): + @_sslcopydoc + def selected_npn_protocol(self): + self._checkClosed() +- if self._sslobj is None or not _ssl.HAS_NPN: +- return None +- else: +- return self._sslobj.selected_npn_protocol() ++ return None + + @_sslcopydoc + def selected_alpn_protocol(self): +--- a/Lib/test/test_ssl.py ++++ b/Lib/test/test_ssl.py +@@ -35,7 +35,6 @@ from ssl import TLSVersion, _TLSContentT + PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) + HOST = support.HOST + IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL') +-IS_OPENSSL_1_1_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0) + IS_OPENSSL_1_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 1) + IS_OPENSSL_3_0_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (3, 0, 0) + PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') +@@ -268,18 +267,6 @@ def handle_error(prefix): + if support.verbose: + sys.stdout.write(prefix + exc_format) + +-def can_clear_options(): +- # 0.9.8m or higher +- return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15) +- +-def no_sslv2_implies_sslv3_hello(): +- # 0.9.7h or higher +- return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15) +- +-def have_verify_flags(): +- # 0.9.8 or higher +- return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15) +- + def _have_secp_curves(): + if not ssl.HAS_ECDH: + return False +@@ -370,17 +357,15 @@ class BasicSocketTests(unittest.TestCase + ssl.OP_SINGLE_DH_USE + if ssl.HAS_ECDH: + ssl.OP_SINGLE_ECDH_USE +- if ssl.OPENSSL_VERSION_INFO >= (1, 0): +- ssl.OP_NO_COMPRESSION ++ ssl.OP_NO_COMPRESSION + self.assertIn(ssl.HAS_SNI, {True, False}) + self.assertIn(ssl.HAS_ECDH, {True, False}) + ssl.OP_NO_SSLv2 + ssl.OP_NO_SSLv3 + ssl.OP_NO_TLSv1 + ssl.OP_NO_TLSv1_3 +- if ssl.OPENSSL_VERSION_INFO >= (1, 0, 1): +- ssl.OP_NO_TLSv1_1 +- ssl.OP_NO_TLSv1_2 ++ ssl.OP_NO_TLSv1_1 ++ ssl.OP_NO_TLSv1_2 + self.assertEqual(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv23) + + def test_private_init(self): +@@ -1189,7 +1174,6 @@ class ContextTests(unittest.TestCase): + self.assertNotIn("RC4", name) + self.assertNotIn("3DES", name) + +- @unittest.skipIf(ssl.OPENSSL_VERSION_INFO < (1, 0, 2, 0, 0), 'OpenSSL too old') + def test_get_ciphers(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ctx.set_ciphers('AESGCM') +@@ -1209,15 +1193,11 @@ class ContextTests(unittest.TestCase): + self.assertEqual(default, ctx.options) + ctx.options |= ssl.OP_NO_TLSv1 + self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options) +- if can_clear_options(): +- ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) +- self.assertEqual(default, ctx.options) +- ctx.options = 0 +- # Ubuntu has OP_NO_SSLv3 forced on by default +- self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) +- else: +- with self.assertRaises(ValueError): +- ctx.options = 0 ++ ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) ++ self.assertEqual(default, ctx.options) ++ ctx.options = 0 ++ # Ubuntu has OP_NO_SSLv3 forced on by default ++ self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) + + def test_verify_mode_protocol(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) +@@ -1336,8 +1316,6 @@ class ContextTests(unittest.TestCase): + with self.assertRaises(ValueError): + ctx.maximum_version = ssl.TLSVersion.TLSv1 + +- @unittest.skipUnless(have_verify_flags(), +- "verify_flags need OpenSSL > 0.9.8") + def test_verify_flags(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + # default value +@@ -1810,7 +1788,6 @@ class ContextTests(unittest.TestCase): + obj = ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO()) + self.assertIsInstance(obj, MySSLObject) + +- @unittest.skipUnless(IS_OPENSSL_1_1_1, "Test requires OpenSSL 1.1.1") + def test_num_tickest(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + self.assertEqual(ctx.num_tickets, 2) +@@ -2973,8 +2950,6 @@ class ThreadedTests(unittest.TestCase): + after = ssl.cert_time_to_seconds(cert['notAfter']) + self.assertLess(before, after) + +- @unittest.skipUnless(have_verify_flags(), +- "verify_flags need OpenSSL > 0.9.8") + def test_crl_check(self): + if support.verbose: + sys.stdout.write("\n") +@@ -3878,12 +3853,7 @@ class ThreadedTests(unittest.TestCase): + self.assertIs(s.version(), None) + self.assertIs(s._sslobj, None) + s.connect((HOST, server.port)) +- if IS_OPENSSL_1_1_1 and has_tls_version('TLSv1_3'): +- self.assertEqual(s.version(), 'TLSv1.3') +- elif ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): +- self.assertEqual(s.version(), 'TLSv1.2') +- else: # 0.9.8 to 1.0.1 +- self.assertIn(s.version(), ('TLSv1', 'TLSv1.2')) ++ self.assertEqual(s.version(), 'TLSv1.3') + self.assertIs(s._sslobj, None) + self.assertIs(s.version(), None) + +@@ -3985,8 +3955,6 @@ class ThreadedTests(unittest.TestCase): + # explicitly using the 'ECCdraft' cipher alias. Otherwise, + # our default cipher list should prefer ECDH-based ciphers + # automatically. +- if ssl.OPENSSL_VERSION_INFO < (1, 0, 0): +- context.set_ciphers("ECCdraft:ECDH") + with ThreadedEchoServer(context=context) as server: + with context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) +@@ -4117,15 +4085,11 @@ class ThreadedTests(unittest.TestCase): + server_context.set_ciphers("ECDHE:!eNULL:!aNULL") + server_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + try: +- stats = server_params_test(client_context, server_context, +- chatty=True, connectionchatty=True, +- sni_name=hostname) ++ server_params_test(client_context, server_context, ++ chatty=True, connectionchatty=True, ++ sni_name=hostname) + except ssl.SSLError: +- pass +- else: +- # OpenSSL 1.0.2 does not fail although it should. +- if IS_OPENSSL_1_1_0: +- self.fail("mismatch curve did not fail") ++ self.fail("mismatch curve did not fail") + + def test_selected_alpn_protocol(self): + # selected_alpn_protocol() is None unless ALPN is used. +@@ -4135,7 +4099,6 @@ class ThreadedTests(unittest.TestCase): + sni_name=hostname) + self.assertIs(stats['client_alpn_protocol'], None) + +- @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required") + def test_selected_alpn_protocol_if_server_uses_alpn(self): + # selected_alpn_protocol() is None unless ALPN is used by the client. + client_context, server_context, hostname = testing_context() +@@ -4145,7 +4108,6 @@ class ThreadedTests(unittest.TestCase): + sni_name=hostname) + self.assertIs(stats['client_alpn_protocol'], None) + +- @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test") + def test_alpn_protocols(self): + server_protocols = ['foo', 'bar', 'milkshake'] + protocol_tests = [ +@@ -4168,22 +4130,17 @@ class ThreadedTests(unittest.TestCase): + except ssl.SSLError as e: + stats = e + +- if (expected is None and IS_OPENSSL_1_1_0 +- and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)): +- # OpenSSL 1.1.0 to 1.1.0e raises handshake error +- self.assertIsInstance(stats, ssl.SSLError) +- else: +- msg = "failed trying %s (s) and %s (c).\n" \ +- "was expecting %s, but got %%s from the %%s" \ +- % (str(server_protocols), str(client_protocols), +- str(expected)) +- client_result = stats['client_alpn_protocol'] +- self.assertEqual(client_result, expected, +- msg % (client_result, "client")) +- server_result = stats['server_alpn_protocols'][-1] \ +- if len(stats['server_alpn_protocols']) else 'nothing' +- self.assertEqual(server_result, expected, +- msg % (server_result, "server")) ++ msg = "failed trying %s (s) and %s (c).\n" \ ++ "was expecting %s, but got %%s from the %%s" \ ++ % (str(server_protocols), str(client_protocols), ++ str(expected)) ++ client_result = stats['client_alpn_protocol'] ++ self.assertEqual(client_result, expected, ++ msg % (client_result, "client")) ++ server_result = stats['server_alpn_protocols'][-1] \ ++ if len(stats['server_alpn_protocols']) else 'nothing' ++ self.assertEqual(server_result, expected, ++ msg % (server_result, "server")) + + def test_selected_npn_protocol(self): + # selected_npn_protocol() is None unless NPN is used +@@ -4193,31 +4150,8 @@ class ThreadedTests(unittest.TestCase): + sni_name=hostname) + self.assertIs(stats['client_npn_protocol'], None) + +- @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test") + def test_npn_protocols(self): +- server_protocols = ['http/1.1', 'spdy/2'] +- protocol_tests = [ +- (['http/1.1', 'spdy/2'], 'http/1.1'), +- (['spdy/2', 'http/1.1'], 'http/1.1'), +- (['spdy/2', 'test'], 'spdy/2'), +- (['abc', 'def'], 'abc') +- ] +- for client_protocols, expected in protocol_tests: +- client_context, server_context, hostname = testing_context() +- server_context.set_npn_protocols(server_protocols) +- client_context.set_npn_protocols(client_protocols) +- stats = server_params_test(client_context, server_context, +- chatty=True, connectionchatty=True, +- sni_name=hostname) +- msg = "failed trying %s (s) and %s (c).\n" \ +- "was expecting %s, but got %%s from the %%s" \ +- % (str(server_protocols), str(client_protocols), +- str(expected)) +- client_result = stats['client_npn_protocol'] +- self.assertEqual(client_result, expected, msg % (client_result, "client")) +- server_result = stats['server_npn_protocols'][-1] \ +- if len(stats['server_npn_protocols']) else 'nothing' +- self.assertEqual(server_result, expected, msg % (server_result, "server")) ++ assert not ssl.HAS_NPN + + def sni_contexts(self): + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) +@@ -4387,8 +4321,7 @@ class ThreadedTests(unittest.TestCase): + self.assertGreater(session.time, 0) + self.assertGreater(session.timeout, 0) + self.assertTrue(session.has_ticket) +- if ssl.OPENSSL_VERSION_INFO > (1, 0, 1): +- self.assertGreater(session.ticket_lifetime_hint, 0) ++ self.assertGreater(session.ticket_lifetime_hint, 0) + self.assertFalse(stats['session_reused']) + sess_stat = server_context.session_stats() + self.assertEqual(sess_stat['accept'], 1) +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2021-03-30-14-19-39.bpo-43669.lWMUYx.rst +@@ -0,0 +1 @@ ++Implement :pep:`644`. Python now requires OpenSSL 1.1.1 or newer. +--- a/Modules/Setup ++++ b/Modules/Setup +@@ -206,11 +206,23 @@ _symtable symtablemodule.c + #_socket socketmodule.c + + # Socket module helper for SSL support; you must comment out the other +-# socket line above, and possibly edit the SSL variable: +-#SSL=/usr/local/ssl +-#_ssl _ssl.c \ +-# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ +-# -L$(SSL)/lib -lssl -lcrypto ++# socket line above, and edit the OPENSSL variable: ++# OPENSSL=/path/to/openssl/directory ++# _ssl _ssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -lssl -lcrypto ++#_hashlib _hashopenssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -lcrypto ++ ++# To statically link OpenSSL: ++# _ssl _ssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -l:libssl.a -Wl,--exclude-libs,libssl.a \ ++# -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a ++#_hashlib _hashopenssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a + + # The crypt module is now disabled by default because it breaks builds + # on many systems (where -lcrypt is needed), e.g. Linux (I believe). +--- a/Modules/_hashopenssl.c ++++ b/Modules/_hashopenssl.c +@@ -37,25 +37,14 @@ + # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" + #endif + +-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +-/* OpenSSL < 1.1.0 */ +-#define EVP_MD_CTX_new EVP_MD_CTX_create +-#define EVP_MD_CTX_free EVP_MD_CTX_destroy +-#endif +- + #define MUNCH_SIZE INT_MAX + +-#ifdef NID_sha3_224 ++#define PY_OPENSSL_HAS_SCRYPT 1 + #define PY_OPENSSL_HAS_SHA3 1 +-#endif + +-#if defined(EVP_MD_FLAG_XOF) && defined(NID_shake128) + #define PY_OPENSSL_HAS_SHAKE 1 +-#endif + +-#if defined(NID_blake2b512) && !defined(OPENSSL_NO_BLAKE2) + #define PY_OPENSSL_HAS_BLAKE2 1 +-#endif + + typedef struct { + PyObject_HEAD +@@ -848,8 +837,7 @@ pbkdf2_hmac_impl(PyObject *module, const + return key_obj; + } + +-#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) +-#define PY_SCRYPT 1 ++#ifdef PY_OPENSSL_HAS_SCRYPT + + /* XXX: Parameters salt, n, r and p should be required keyword-only parameters. + They are optional in the Argument Clinic declaration only due to a +@@ -972,7 +960,7 @@ _hashlib_scrypt_impl(PyObject *module, P + } + return key_obj; + } +-#endif ++#endif /* PY_OPENSSL_HAS_SCRYPT */ + + /* Fast HMAC for hmac.digest() + */ +@@ -1116,12 +1104,6 @@ PyInit__hashlib(void) + { + PyObject *m, *openssl_md_meth_names; + +-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +- /* Load all digest algorithms and initialize cpuid */ +- OPENSSL_add_all_algorithms_noconf(); +- ERR_load_crypto_strings(); +-#endif +- + /* TODO build EVP_functions openssl_* entries dynamically based + * on what hashes are supported rather than listing many + * but having some be unsupported. Only init appropriate +--- a/Modules/_ssl.c ++++ b/Modules/_ssl.c +@@ -31,9 +31,9 @@ + #define _PySSL_FIX_ERRNO + + #define PySSL_BEGIN_ALLOW_THREADS_S(save) \ +- do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0) ++ do { (save) = PyEval_SaveThread(); } while(0) + #define PySSL_END_ALLOW_THREADS_S(save) \ +- do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0) ++ do { PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0) + #define PySSL_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save = NULL; \ + PySSL_BEGIN_ALLOW_THREADS_S(_save); +@@ -64,16 +64,6 @@ static PySocketModule_APIObject PySocket + #include "openssl/bio.h" + #include "openssl/dh.h" + +-#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST +-# ifdef LIBRESSL_VERSION_NUMBER +-# error "LibreSSL is missing X509_VERIFY_PARAM_set1_host(), see https://github.com/libressl-portable/portable/issues/381" +-# elif OPENSSL_VERSION_NUMBER > 0x1000200fL +-# define HAVE_X509_VERIFY_PARAM_SET1_HOST +-# else +-# error "libssl is too old and does not support X509_VERIFY_PARAM_set1_host()" +-# endif +-#endif +- + #ifndef OPENSSL_THREADS + # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" + #endif +@@ -144,15 +134,7 @@ static void _PySSLFixErrno(void) { + #include "_ssl_data.h" + #endif + +-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +-# define OPENSSL_VERSION_1_1 1 +-# define PY_OPENSSL_1_1_API 1 +-#endif +- +-/* OpenSSL API 1.1.0+ does not include version methods. Define the methods +- * unless OpenSSL is compiled without the methods. It's the easiest way to +- * make 1.0.2, 1.1.0, 1.1.1, and 3.0.0 happy without deprecation warnings. +- */ ++/* OpenSSL API 1.1.0+ does not include version methods */ + #ifndef OPENSSL_NO_TLS1_METHOD + extern const SSL_METHOD *TLSv1_method(void); + #endif +@@ -163,59 +145,10 @@ extern const SSL_METHOD *TLSv1_1_method( + extern const SSL_METHOD *TLSv1_2_method(void); + #endif + +-/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ +-#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL +-# define PY_OPENSSL_1_1_API 1 +-#endif +- +-#if (OPENSSL_VERSION_NUMBER >= 0x30300000L) && !defined(LIBRESSL_VERSION_NUMBER) +-# define OPENSSL_VERSION_3_3 1 +-#endif +- +-/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f +- * This includes the SSL_set_SSL_CTX() function. +- */ +-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +-# define HAVE_SNI 1 +-#else +-# define HAVE_SNI 0 +-#endif +- +-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +-# define HAVE_ALPN 1 +-#else +-# define HAVE_ALPN 0 +-#endif +- +-/* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped +- * NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility +- * reasons. The check for TLSEXT_TYPE_next_proto_neg works with +- * OpenSSL 1.0.1+ and LibreSSL. +- * OpenSSL 1.1.1-pre1 dropped NPN but still has TLSEXT_TYPE_next_proto_neg. +- */ +-#ifdef OPENSSL_NO_NEXTPROTONEG +-# define HAVE_NPN 0 +-#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +-# define HAVE_NPN 0 +-#elif defined(TLSEXT_TYPE_next_proto_neg) +-# define HAVE_NPN 1 +-#else +-# define HAVE_NPN 0 +-#endif +- +-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +-#define HAVE_OPENSSL_KEYLOG 1 +-#endif +- + #ifndef INVALID_SOCKET /* MS defines this */ + #define INVALID_SOCKET (-1) + #endif + +-/* OpenSSL 1.0.2 and LibreSSL needs extra code for locking */ +-#ifndef OPENSSL_VERSION_1_1 +-#define HAVE_OPENSSL_CRYPTO_LOCK +-#endif +- + /* OpenSSL 1.1+ allows locking X509_STORE, 1.0.2 doesn't. */ + #ifdef OPENSSL_VERSION_1_1 + #define HAVE_OPENSSL_X509_STORE_LOCK +@@ -226,80 +159,8 @@ extern const SSL_METHOD *TLSv1_2_method( + #define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1 + #endif + +-#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2) ++/* OpenSSL 1.1 does not have SSL 2.0 */ + #define OPENSSL_NO_SSL2 +-#endif +- +-#ifndef PY_OPENSSL_1_1_API +-/* OpenSSL 1.1 API shims for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */ +- +-#define TLS_method SSLv23_method +-#define TLS_client_method SSLv23_client_method +-#define TLS_server_method SSLv23_server_method +-#define ASN1_STRING_get0_data ASN1_STRING_data +-#define X509_get0_notBefore X509_get_notBefore +-#define X509_get0_notAfter X509_get_notAfter +-#define OpenSSL_version_num SSLeay +-#define OpenSSL_version SSLeay_version +-#define OPENSSL_VERSION SSLEAY_VERSION +- +-static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +-{ +- return ne->set; +-} +- +-#ifndef OPENSSL_NO_COMP +-/* LCOV_EXCL_START */ +-static int COMP_get_type(const COMP_METHOD *meth) +-{ +- return meth->type; +-} +-/* LCOV_EXCL_STOP */ +-#endif +- +-static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) +-{ +- return ctx->default_passwd_callback; +-} +- +-static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) +-{ +- return ctx->default_passwd_callback_userdata; +-} +- +-static int X509_OBJECT_get_type(X509_OBJECT *x) +-{ +- return x->type; +-} +- +-static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) +-{ +- return x->data.x509; +-} +- +-static int BIO_up_ref(BIO *b) +-{ +- CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); +- return 1; +-} +- +-static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) { +- return store->objs; +-} +- +-static int +-SSL_SESSION_has_ticket(const SSL_SESSION *s) +-{ +- return (s->tlsext_ticklen > 0) ? 1 : 0; +-} +- +-static unsigned long +-SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) +-{ +- return s->tlsext_tick_lifetime_hint; +-} +- +-#endif /* OpenSSL < 1.1.0 or LibreSSL < 2.7.0 */ + + /* Default cipher suites */ + #ifndef PY_SSL_DEFAULT_CIPHERS +@@ -411,24 +272,10 @@ enum py_proto_version { + #endif + }; + +- +-/* serves as a flag to see whether we've initialized the SSL thread support. */ +-/* 0 means no, greater than 0 means yes */ +- +-static unsigned int _ssl_locks_count = 0; +- + /* SSL socket object */ + + #define X509_NAME_MAXLEN 256 + +-/* SSL_CTX_clear_options() and SSL_clear_options() were first added in +- * OpenSSL 0.9.8m but do not appear in some 0.9.9-dev versions such the +- * 0.9.9 from "May 2008" that NetBSD 5.0 uses. */ +-#if OPENSSL_VERSION_NUMBER >= 0x009080dfL && OPENSSL_VERSION_NUMBER != 0x00909000L +-# define HAVE_SSL_CTX_CLEAR_OPTIONS +-#else +-# undef HAVE_SSL_CTX_CLEAR_OPTIONS +-#endif + + /* In case of 'tls-unique' it will be 12 bytes for TLS, 36 bytes for + * older SSL, but let's be safe */ +@@ -438,17 +285,9 @@ static unsigned int _ssl_locks_count = 0 + typedef struct { + PyObject_HEAD + SSL_CTX *ctx; +-#if HAVE_NPN +- unsigned char *npn_protocols; +- int npn_protocols_len; +-#endif +-#if HAVE_ALPN + unsigned char *alpn_protocols; + unsigned int alpn_protocols_len; +-#endif +-#ifndef OPENSSL_NO_TLSEXT + PyObject *set_sni_cb; +-#endif + int check_hostname; + /* OpenSSL has no API to get hostflags from X509_VERIFY_PARAM* struct. + * We have to maintain our own copy. OpenSSL's hostflags default to 0. +@@ -459,10 +298,8 @@ typedef struct { + int post_handshake_auth; + #endif + PyObject *msg_cb; +-#ifdef HAVE_OPENSSL_KEYLOG + PyObject *keylog_filename; + BIO *keylog_bio; +-#endif + } PySSLContext; + + typedef struct { +@@ -669,23 +506,18 @@ fill_and_set_sslerror(PySSLSocket *sslso + } + + switch (verify_code) { +-#ifdef X509_V_ERR_HOSTNAME_MISMATCH +- /* OpenSSL >= 1.0.2, LibreSSL >= 2.5.3 */ + case X509_V_ERR_HOSTNAME_MISMATCH: + verify_obj = PyUnicode_FromFormat( + "Hostname mismatch, certificate is not valid for '%S'.", + sslsock->server_hostname + ); + break; +-#endif +-#ifdef X509_V_ERR_IP_ADDRESS_MISMATCH + case X509_V_ERR_IP_ADDRESS_MISMATCH: + verify_obj = PyUnicode_FromFormat( + "IP address mismatch, certificate is not valid for '%S'.", + sslsock->server_hostname + ); + break; +-#endif + default: + verify_str = X509_verify_cert_error_string(verify_code); + if (verify_str != NULL) { +@@ -2016,7 +1848,6 @@ cipher_to_tuple(const SSL_CIPHER *cipher + return NULL; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10002000UL + static PyObject * + cipher_to_dict(const SSL_CIPHER *cipher) + { +@@ -2025,10 +1856,8 @@ cipher_to_dict(const SSL_CIPHER *cipher) + unsigned long cipher_id; + int alg_bits, strength_bits, len; + char buf[512] = {0}; +-#if OPENSSL_VERSION_1_1 + int aead, nid; + const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL; +-#endif + + /* can be NULL */ + cipher_name = SSL_CIPHER_get_name(cipher); +@@ -2041,7 +1870,6 @@ cipher_to_dict(const SSL_CIPHER *cipher) + buf[len-1] = '\0'; + strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits); + +-#if OPENSSL_VERSION_1_1 + aead = SSL_CIPHER_is_aead(cipher); + nid = SSL_CIPHER_get_cipher_nid(cipher); + skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; +@@ -2051,13 +1879,10 @@ cipher_to_dict(const SSL_CIPHER *cipher) + kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_auth_nid(cipher); + auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; +-#endif + + return Py_BuildValue( + "{sksssssssisi" +-#if OPENSSL_VERSION_1_1 + "sOssssssss" +-#endif + "}", + "id", cipher_id, + "name", cipher_name, +@@ -2065,16 +1890,13 @@ cipher_to_dict(const SSL_CIPHER *cipher) + "description", buf, + "strength_bits", strength_bits, + "alg_bits", alg_bits +-#if OPENSSL_VERSION_1_1 + ,"aead", aead ? Py_True : Py_False, + "symmetric", skcipher, + "digest", digest, + "kea", kx, + "auth", auth +-#endif + ); + } +-#endif + + /*[clinic input] + _ssl._SSLSocket.shared_ciphers +@@ -2145,28 +1967,6 @@ _ssl__SSLSocket_version_impl(PySSLSocket + return PyUnicode_FromString(version); + } + +-#if HAVE_NPN +-/*[clinic input] +-_ssl._SSLSocket.selected_npn_protocol +-[clinic start generated code]*/ +- +-static PyObject * +-_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self) +-/*[clinic end generated code: output=b91d494cd207ecf6 input=c28fde139204b826]*/ +-{ +- const unsigned char *out; +- unsigned int outlen; +- +- SSL_get0_next_proto_negotiated(self->ssl, +- &out, &outlen); +- +- if (out == NULL) +- Py_RETURN_NONE; +- return PyUnicode_FromStringAndSize((char *)out, outlen); +-} +-#endif +- +-#if HAVE_ALPN + /*[clinic input] + _ssl._SSLSocket.selected_alpn_protocol + [clinic start generated code]*/ +@@ -2184,7 +1984,6 @@ _ssl__SSLSocket_selected_alpn_protocol_i + Py_RETURN_NONE; + return PyUnicode_FromStringAndSize((char *)out, outlen); + } +-#endif + + /*[clinic input] + _ssl._SSLSocket.compression +@@ -2221,11 +2020,6 @@ static int PySSL_set_context(PySSLSocket + void *closure) { + + if (PyObject_TypeCheck(value, &PySSLContext_Type)) { +-#if !HAVE_SNI +- PyErr_SetString(PyExc_NotImplementedError, "setting a socket's " +- "context is not supported by your OpenSSL library"); +- return -1; +-#else + Py_INCREF(value); + Py_SETREF(self->ctx, (PySSLContext *)value); + SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); +@@ -2234,7 +2028,6 @@ static int PySSL_set_context(PySSLSocket + self->ssl, + self->ctx->msg_cb ? _PySSL_msg_callback : NULL + ); +-#endif + } else { + PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); + return -1; +@@ -2859,8 +2652,6 @@ _ssl__SSLSocket_verify_client_post_hands + #endif + } + +-#ifdef OPENSSL_VERSION_1_1 +- + static SSL_SESSION* + _ssl_session_dup(SSL_SESSION *session) { + SSL_SESSION *newsession = NULL; +@@ -2901,7 +2692,6 @@ _ssl_session_dup(SSL_SESSION *session) { + } + return NULL; + } +-#endif + + static PyObject * + PySSL_get_session(PySSLSocket *self, void *closure) { +@@ -2910,7 +2700,6 @@ PySSL_get_session(PySSLSocket *self, voi + PySSLSession *pysess; + SSL_SESSION *session; + +-#ifdef OPENSSL_VERSION_1_1 + /* duplicate session as workaround for session bug in OpenSSL 1.1.0, + * https://github.com/openssl/openssl/issues/1550 */ + session = SSL_get0_session(self->ssl); /* borrowed reference */ +@@ -2920,12 +2709,10 @@ PySSL_get_session(PySSLSocket *self, voi + if ((session = _ssl_session_dup(session)) == NULL) { + return NULL; + } +-#else + session = SSL_get1_session(self->ssl); + if (session == NULL) { + Py_RETURN_NONE; + } +-#endif + pysess = PyObject_GC_New(PySSLSession, &PySSLSession_Type); + if (pysess == NULL) { + SSL_SESSION_free(session); +@@ -2944,9 +2731,7 @@ static int PySSL_set_session(PySSLSocket + void *closure) + { + PySSLSession *pysess; +-#ifdef OPENSSL_VERSION_1_1 + SSL_SESSION *session; +-#endif + int result; + + if (!PySSLSession_Check(value)) { +@@ -2970,7 +2755,6 @@ static int PySSL_set_session(PySSLSocket + "Cannot set session after handshake."); + return -1; + } +-#ifdef OPENSSL_VERSION_1_1 + /* duplicate session */ + if ((session = _ssl_session_dup(pysess->session)) == NULL) { + return -1; +@@ -2978,9 +2762,6 @@ static int PySSL_set_session(PySSLSocket + result = SSL_set_session(self->ssl, session); + /* free duplicate, SSL_set_session() bumps ref count */ + SSL_SESSION_free(session); +-#else +- result = SSL_set_session(self->ssl, pysess->session); +-#endif + if (result == 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return -1; +@@ -3031,7 +2812,6 @@ static PyMethodDef PySSLMethods[] = { + _SSL__SSLSOCKET_CIPHER_METHODDEF + _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF + _SSL__SSLSOCKET_VERSION_METHODDEF +- _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF + _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF + _SSL__SSLSOCKET_COMPRESSION_METHODDEF + _SSL__SSLSOCKET_SHUTDOWN_METHODDEF +@@ -3125,9 +2905,6 @@ _ssl__SSLContext_impl(PyTypeObject *type + SSL_CTX *ctx = NULL; + X509_VERIFY_PARAM *params; + int result; +-#if defined(SSL_MODE_RELEASE_BUFFERS) +- unsigned long libver; +-#endif + + PySSL_BEGIN_ALLOW_THREADS + switch(proto_version) { +@@ -3192,19 +2969,10 @@ _ssl__SSLContext_impl(PyTypeObject *type + self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; + self->protocol = proto_version; + self->msg_cb = NULL; +-#ifdef HAVE_OPENSSL_KEYLOG + self->keylog_filename = NULL; + self->keylog_bio = NULL; +-#endif +-#if HAVE_NPN +- self->npn_protocols = NULL; +-#endif +-#if HAVE_ALPN + self->alpn_protocols = NULL; +-#endif +-#ifndef OPENSSL_NO_TLSEXT + self->set_sni_cb = NULL; +-#endif + /* Don't check host name by default */ + if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { + self->check_hostname = 1; +@@ -3266,37 +3034,9 @@ _ssl__SSLContext_impl(PyTypeObject *type + return NULL; + } + +-#if defined(SSL_MODE_RELEASE_BUFFERS) + /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory +- usage for no cost at all. However, don't do this for OpenSSL versions +- between 1.0.1 and 1.0.1h or 1.0.0 and 1.0.0m, which are affected by CVE +- 2014-0198. I can't find exactly which beta fixed this CVE, so be +- conservative and assume it wasn't fixed until release. We do this check +- at runtime to avoid problems from the dynamic linker. +- See #25672 for more on this. */ +- libver = OpenSSL_version_num(); +- if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && +- !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { +- SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); +- } +-#endif +- +- +-#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) +- /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use +- prime256v1 by default. This is Apache mod_ssl's initialization +- policy, so we should be safe. OpenSSL 1.1 has it enabled by default. +- */ +-#if defined(SSL_CTX_set_ecdh_auto) +- SSL_CTX_set_ecdh_auto(self->ctx, 1); +-#else +- { +- EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); +- SSL_CTX_set_tmp_ecdh(self->ctx, key); +- EC_KEY_free(key); +- } +-#endif +-#endif ++ usage for no cost at all. */ ++ SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); + + #define SID_CTX "Python" + SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX, +@@ -3304,11 +3044,9 @@ _ssl__SSLContext_impl(PyTypeObject *type + #undef SID_CTX + + params = SSL_CTX_get0_param(self->ctx); +-#ifdef X509_V_FLAG_TRUSTED_FIRST + /* Improve trust chain building when cross-signed intermediate + certificates are present. See https://bugs.python.org/issue23476. */ + X509_VERIFY_PARAM_set_flags(params, X509_V_FLAG_TRUSTED_FIRST); +-#endif + X509_VERIFY_PARAM_set_hostflags(params, self->hostflags); + + #ifdef TLS1_3_VERSION +@@ -3322,9 +3060,7 @@ _ssl__SSLContext_impl(PyTypeObject *type + static int + context_traverse(PySSLContext *self, visitproc visit, void *arg) + { +-#ifndef OPENSSL_NO_TLSEXT + Py_VISIT(self->set_sni_cb); +-#endif + Py_VISIT(self->msg_cb); + return 0; + } +@@ -3332,11 +3068,8 @@ context_traverse(PySSLContext *self, vis + static int + context_clear(PySSLContext *self) + { +-#ifndef OPENSSL_NO_TLSEXT + Py_CLEAR(self->set_sni_cb); +-#endif + Py_CLEAR(self->msg_cb); +-#ifdef HAVE_OPENSSL_KEYLOG + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + PySSL_BEGIN_ALLOW_THREADS +@@ -3344,7 +3077,6 @@ context_clear(PySSLContext *self) + PySSL_END_ALLOW_THREADS + self->keylog_bio = NULL; + } +-#endif + return 0; + } + +@@ -3355,12 +3087,7 @@ context_dealloc(PySSLContext *self) + PyObject_GC_UnTrack(self); + context_clear(self); + SSL_CTX_free(self->ctx); +-#if HAVE_NPN +- PyMem_FREE(self->npn_protocols); +-#endif +-#if HAVE_ALPN + PyMem_FREE(self->alpn_protocols); +-#endif + Py_TYPE(self)->tp_free(self); + } + +@@ -3387,7 +3114,6 @@ _ssl__SSLContext_set_ciphers_impl(PySSLC + Py_RETURN_NONE; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10002000UL + /*[clinic input] + _ssl._SSLContext.get_ciphers + [clinic start generated code]*/ +@@ -3430,10 +3156,8 @@ _ssl__SSLContext_get_ciphers_impl(PySSLC + return result; + + } +-#endif + + +-#if HAVE_NPN || HAVE_ALPN + static int + do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, + const unsigned char *server_protocols, unsigned int server_protocols_len, +@@ -3457,77 +3181,7 @@ do_protocol_selection(int alpn, unsigned + + return SSL_TLSEXT_ERR_OK; + } +-#endif + +-#if HAVE_NPN +-/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ +-static int +-_advertiseNPN_cb(SSL *s, +- const unsigned char **data, unsigned int *len, +- void *args) +-{ +- PySSLContext *ssl_ctx = (PySSLContext *) args; +- +- if (ssl_ctx->npn_protocols == NULL) { +- *data = (unsigned char *)""; +- *len = 0; +- } else { +- *data = ssl_ctx->npn_protocols; +- *len = ssl_ctx->npn_protocols_len; +- } +- +- return SSL_TLSEXT_ERR_OK; +-} +-/* this callback gets passed to SSL_CTX_set_next_proto_select_cb */ +-static int +-_selectNPN_cb(SSL *s, +- unsigned char **out, unsigned char *outlen, +- const unsigned char *server, unsigned int server_len, +- void *args) +-{ +- PySSLContext *ctx = (PySSLContext *)args; +- return do_protocol_selection(0, out, outlen, server, server_len, +- ctx->npn_protocols, ctx->npn_protocols_len); +-} +-#endif +- +-/*[clinic input] +-_ssl._SSLContext._set_npn_protocols +- protos: Py_buffer +- / +-[clinic start generated code]*/ +- +-static PyObject * +-_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, +- Py_buffer *protos) +-/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/ +-{ +-#if HAVE_NPN +- PyMem_Free(self->npn_protocols); +- self->npn_protocols = PyMem_Malloc(protos->len); +- if (self->npn_protocols == NULL) +- return PyErr_NoMemory(); +- memcpy(self->npn_protocols, protos->buf, protos->len); +- self->npn_protocols_len = (int) protos->len; +- +- /* set both server and client callbacks, because the context can +- * be used to create both types of sockets */ +- SSL_CTX_set_next_protos_advertised_cb(self->ctx, +- _advertiseNPN_cb, +- self); +- SSL_CTX_set_next_proto_select_cb(self->ctx, +- _selectNPN_cb, +- self); +- +- Py_RETURN_NONE; +-#else +- PyErr_SetString(PyExc_NotImplementedError, +- "The NPN extension requires OpenSSL 1.0.1 or later."); +- return NULL; +-#endif +-} +- +-#if HAVE_ALPN + static int + _selectALPN_cb(SSL *s, + const unsigned char **out, unsigned char *outlen, +@@ -3539,7 +3193,6 @@ _selectALPN_cb(SSL *s, + ctx->alpn_protocols, ctx->alpn_protocols_len, + client_protocols, client_protocols_len); + } +-#endif + + /*[clinic input] + _ssl._SSLContext._set_alpn_protocols +@@ -3552,7 +3205,6 @@ _ssl__SSLContext__set_alpn_protocols_imp + Py_buffer *protos) + /*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ + { +-#if HAVE_ALPN + if ((size_t)protos->len > UINT_MAX) { + PyErr_Format(PyExc_OverflowError, + "protocols longer than %u bytes", UINT_MAX); +@@ -3571,11 +3223,6 @@ _ssl__SSLContext__set_alpn_protocols_imp + SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); + + Py_RETURN_NONE; +-#else +- PyErr_SetString(PyExc_NotImplementedError, +- "The ALPN extension requires OpenSSL 1.0.2 or later."); +- return NULL; +-#endif + } + + static PyObject * +@@ -3651,9 +3298,6 @@ set_verify_flags(PySSLContext *self, PyO + } + + /* Getter and setter for protocol version */ +-#if defined(SSL_CTRL_GET_MAX_PROTO_VERSION) +- +- + static int + set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) + { +@@ -3748,9 +3392,8 @@ set_maximum_version(PySSLContext *self, + { + return set_min_max_proto_version(self, arg, 1); + } +-#endif /* SSL_CTRL_GET_MAX_PROTO_VERSION */ + +-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) ++#ifdef TLS1_3_VERSION + static PyObject * + get_num_tickets(PySSLContext *self, void *c) + { +@@ -3781,7 +3424,7 @@ set_num_tickets(PySSLContext *self, PyOb + + PyDoc_STRVAR(PySSLContext_num_tickets_doc, + "Control the number of TLSv1.3 session tickets"); +-#endif /* OpenSSL 1.1.1 */ ++#endif /* TLS1_3_VERSION */ + + static PyObject * + get_options(PySSLContext *self, void *c) +@@ -3799,13 +3442,7 @@ set_options(PySSLContext *self, PyObject + clear = opts & ~new_opts; + set = ~opts & new_opts; + if (clear) { +-#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS + SSL_CTX_clear_options(self->ctx, clear); +-#else +- PyErr_SetString(PyExc_ValueError, +- "can't clear options before OpenSSL 0.9.8m"); +- return -1; +-#endif + } + if (set) + SSL_CTX_set_options(self->ctx, set); +@@ -4503,7 +4140,6 @@ _ssl__SSLContext_set_default_verify_path + Py_RETURN_NONE; + } + +-#ifndef OPENSSL_NO_ECDH + /*[clinic input] + _ssl._SSLContext.set_ecdh_curve + name: object +@@ -4538,9 +4174,7 @@ _ssl__SSLContext_set_ecdh_curve(PySSLCon + EC_KEY_free(key); + Py_RETURN_NONE; + } +-#endif + +-#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) + static int + _servername_callback(SSL *s, int *al, void *args) + { +@@ -4644,7 +4278,6 @@ error: + PyGILState_Release(gstate); + return ret; + } +-#endif + + static PyObject * + get_sni_callback(PySSLContext *self, void *c) +@@ -4665,7 +4298,6 @@ set_sni_callback(PySSLContext *self, PyO + "sni_callback cannot be set on TLS_CLIENT context"); + return -1; + } +-#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) + Py_CLEAR(self->set_sni_cb); + if (arg == Py_None) { + SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); +@@ -4683,13 +4315,6 @@ set_sni_callback(PySSLContext *self, PyO + SSL_CTX_set_tlsext_servername_arg(self->ctx, self); + } + return 0; +-#else +- PyErr_SetString(PyExc_NotImplementedError, +- "The TLS extension servername callback, " +- "SSL_CTX_set_tlsext_servername_callback, " +- "is not in the current OpenSSL library."); +- return -1; +-#endif + } + + /* Shim of X509_STORE_get1_objects API from OpenSSL 3.3 +@@ -4885,21 +4510,17 @@ static PyGetSetDef context_getsetlist[] + (setter) set_check_hostname, NULL}, + {"_host_flags", (getter) get_host_flags, + (setter) set_host_flags, NULL}, +-#if SSL_CTRL_GET_MAX_PROTO_VERSION + {"minimum_version", (getter) get_minimum_version, + (setter) set_minimum_version, NULL}, + {"maximum_version", (getter) get_maximum_version, + (setter) set_maximum_version, NULL}, +-#endif +-#ifdef HAVE_OPENSSL_KEYLOG + {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, + (setter) _PySSLContext_set_keylog_filename, NULL}, +-#endif + {"_msg_callback", (getter) _PySSLContext_get_msg_callback, + (setter) _PySSLContext_set_msg_callback, NULL}, + {"sni_callback", (getter) get_sni_callback, + (setter) set_sni_callback, PySSLContext_sni_callback_doc}, +-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) ++#ifdef TLS1_3_VERSION + {"num_tickets", (getter) get_num_tickets, + (setter) set_num_tickets, PySSLContext_num_tickets_doc}, + #endif +@@ -4926,7 +4547,6 @@ static struct PyMethodDef context_method + _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF + _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF + _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF +- _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF + _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF + _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF + _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF +@@ -5444,11 +5064,7 @@ PySSL_RAND(int len, int pseudo) + if (bytes == NULL) + return NULL; + if (pseudo) { +-#ifdef PY_OPENSSL_1_1_API + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +-#else +- ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +-#endif + if (ok == 0 || ok == 1) + return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); + } +@@ -6003,92 +5619,6 @@ static PyMethodDef PySSL_methods[] = { + }; + + +-#ifdef HAVE_OPENSSL_CRYPTO_LOCK +- +-/* an implementation of OpenSSL threading operations in terms +- * of the Python C thread library +- * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code. +- */ +- +-static PyThread_type_lock *_ssl_locks = NULL; +- +-#if OPENSSL_VERSION_NUMBER >= 0x10000000 +-/* use new CRYPTO_THREADID API. */ +-static void +-_ssl_threadid_callback(CRYPTO_THREADID *id) +-{ +- CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident()); +-} +-#else +-/* deprecated CRYPTO_set_id_callback() API. */ +-static unsigned long +-_ssl_thread_id_function (void) { +- return PyThread_get_thread_ident(); +-} +-#endif +- +-static void _ssl_thread_locking_function +- (int mode, int n, const char *file, int line) { +- /* this function is needed to perform locking on shared data +- structures. (Note that OpenSSL uses a number of global data +- structures that will be implicitly shared whenever multiple +- threads use OpenSSL.) Multi-threaded applications will +- crash at random if it is not set. +- +- locking_function() must be able to handle up to +- CRYPTO_num_locks() different mutex locks. It sets the n-th +- lock if mode & CRYPTO_LOCK, and releases it otherwise. +- +- file and line are the file number of the function setting the +- lock. They can be useful for debugging. +- */ +- +- if ((_ssl_locks == NULL) || +- (n < 0) || ((unsigned)n >= _ssl_locks_count)) +- return; +- +- if (mode & CRYPTO_LOCK) { +- PyThread_acquire_lock(_ssl_locks[n], 1); +- } else { +- PyThread_release_lock(_ssl_locks[n]); +- } +-} +- +-static int _setup_ssl_threads(void) { +- +- unsigned int i; +- +- if (_ssl_locks == NULL) { +- _ssl_locks_count = CRYPTO_num_locks(); +- _ssl_locks = PyMem_Calloc(_ssl_locks_count, +- sizeof(PyThread_type_lock)); +- if (_ssl_locks == NULL) { +- PyErr_NoMemory(); +- return 0; +- } +- for (i = 0; i < _ssl_locks_count; i++) { +- _ssl_locks[i] = PyThread_allocate_lock(); +- if (_ssl_locks[i] == NULL) { +- unsigned int j; +- for (j = 0; j < i; j++) { +- PyThread_free_lock(_ssl_locks[j]); +- } +- PyMem_Free(_ssl_locks); +- return 0; +- } +- } +- CRYPTO_set_locking_callback(_ssl_thread_locking_function); +-#if OPENSSL_VERSION_NUMBER >= 0x10000000 +- CRYPTO_THREADID_set_callback(_ssl_threadid_callback); +-#else +- CRYPTO_set_id_callback(_ssl_thread_id_function); +-#endif +- } +- return 1; +-} +- +-#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */ +- + PyDoc_STRVAR(module_doc, + "Implementation module for SSL socket operations. See the socket module\n\ + for documentation."); +@@ -6155,14 +5685,6 @@ PyInit__ssl(void) + return NULL; + PySocketModule = *socket_api; + +-#ifndef OPENSSL_VERSION_1_1 +- /* Load all algorithms and initialize cpuid */ +- OPENSSL_add_all_algorithms_noconf(); +- /* Init OpenSSL */ +- SSL_load_error_strings(); +- SSL_library_init(); +-#endif +- + #ifdef HAVE_OPENSSL_CRYPTO_LOCK + /* note that this will start threading if not already started */ + if (!_setup_ssl_threads()) { +@@ -6269,10 +5791,8 @@ PyInit__ssl(void) + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", + X509_V_FLAG_X509_STRICT); +-#ifdef X509_V_FLAG_TRUSTED_FIRST + PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", + X509_V_FLAG_TRUSTED_FIRST); +-#endif + + /* Alert Descriptions from ssl.h */ + /* note RESERVED constants no longer intended for use have been removed */ +@@ -6429,31 +5949,11 @@ PyInit__ssl(void) + PyModule_AddObject((m), (key), bool_obj); \ + } while (0) + +-#if HAVE_SNI + addbool(m, "HAS_SNI", 1); +-#else +- addbool(m, "HAS_SNI", 0); +-#endif +- + addbool(m, "HAS_TLS_UNIQUE", 1); +- +-#ifndef OPENSSL_NO_ECDH + addbool(m, "HAS_ECDH", 1); +-#else +- addbool(m, "HAS_ECDH", 0); +-#endif +- +-#if HAVE_NPN +- addbool(m, "HAS_NPN", 1); +-#else + addbool(m, "HAS_NPN", 0); +-#endif +- +-#if HAVE_ALPN + addbool(m, "HAS_ALPN", 1); +-#else +- addbool(m, "HAS_ALPN", 0); +-#endif + + #if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) + addbool(m, "HAS_SSLv2", 1); +--- a/Modules/_ssl/debughelpers.c ++++ b/Modules/_ssl/debughelpers.c +@@ -114,8 +114,6 @@ _PySSLContext_set_msg_callback(PySSLCont + return 0; + } + +-#ifdef HAVE_OPENSSL_KEYLOG +- + static void + _PySSL_keylog_callback(const SSL *ssl, const char *line) + { +@@ -219,5 +217,3 @@ _PySSLContext_set_keylog_filename(PySSLC + SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); + return 0; + } +- +-#endif +--- a/Modules/clinic/_hashopenssl.c.h ++++ b/Modules/clinic/_hashopenssl.c.h +@@ -420,7 +420,7 @@ exit: + return return_value; + } + +-#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) ++#if defined(PY_OPENSSL_HAS_SCRYPT) + + PyDoc_STRVAR(_hashlib_scrypt__doc__, + "scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n" +@@ -548,7 +548,7 @@ exit: + return return_value; + } + +-#endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ ++#endif /* defined(PY_OPENSSL_HAS_SCRYPT) */ + + PyDoc_STRVAR(_hashlib_hmac_digest__doc__, + "hmac_digest($module, /, key, msg, digest)\n" +--- a/Modules/clinic/_ssl.c.h ++++ b/Modules/clinic/_ssl.c.h +@@ -139,29 +139,6 @@ _ssl__SSLSocket_version(PySSLSocket *sel + return _ssl__SSLSocket_version_impl(self); + } + +-#if (HAVE_NPN) +- +-PyDoc_STRVAR(_ssl__SSLSocket_selected_npn_protocol__doc__, +-"selected_npn_protocol($self, /)\n" +-"--\n" +-"\n"); +- +-#define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF \ +- {"selected_npn_protocol", (PyCFunction)_ssl__SSLSocket_selected_npn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_npn_protocol__doc__}, +- +-static PyObject * +-_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self); +- +-static PyObject * +-_ssl__SSLSocket_selected_npn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +-{ +- return _ssl__SSLSocket_selected_npn_protocol_impl(self); +-} +- +-#endif /* (HAVE_NPN) */ +- +-#if (HAVE_ALPN) +- + PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, + "selected_alpn_protocol($self, /)\n" + "--\n" +@@ -179,8 +156,6 @@ _ssl__SSLSocket_selected_alpn_protocol(P + return _ssl__SSLSocket_selected_alpn_protocol_impl(self); + } + +-#endif /* (HAVE_ALPN) */ +- + PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, + "compression($self, /)\n" + "--\n" +@@ -457,8 +432,6 @@ exit: + return return_value; + } + +-#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL) +- + PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, + "get_ciphers($self, /)\n" + "--\n" +@@ -476,44 +449,6 @@ _ssl__SSLContext_get_ciphers(PySSLContex + return _ssl__SSLContext_get_ciphers_impl(self); + } + +-#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */ +- +-PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__, +-"_set_npn_protocols($self, protos, /)\n" +-"--\n" +-"\n"); +- +-#define _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF \ +- {"_set_npn_protocols", (PyCFunction)_ssl__SSLContext__set_npn_protocols, METH_O, _ssl__SSLContext__set_npn_protocols__doc__}, +- +-static PyObject * +-_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, +- Py_buffer *protos); +- +-static PyObject * +-_ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) +-{ +- PyObject *return_value = NULL; +- Py_buffer protos = {NULL, NULL}; +- +- if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { +- goto exit; +- } +- if (!PyBuffer_IsContiguous(&protos, 'C')) { +- _PyArg_BadArgument("_set_npn_protocols", "argument", "contiguous buffer", arg); +- goto exit; +- } +- return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); +- +-exit: +- /* Cleanup for protos */ +- if (protos.obj) { +- PyBuffer_Release(&protos); +- } +- +- return return_value; +-} +- + PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, + "_set_alpn_protocols($self, protos, /)\n" + "--\n" +@@ -844,8 +779,6 @@ _ssl__SSLContext_set_default_verify_path + return _ssl__SSLContext_set_default_verify_paths_impl(self); + } + +-#if !defined(OPENSSL_NO_ECDH) +- + PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, + "set_ecdh_curve($self, name, /)\n" + "--\n" +@@ -854,8 +787,6 @@ PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_c + #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ + {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, + +-#endif /* !defined(OPENSSL_NO_ECDH) */ +- + PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, + "cert_store_stats($self, /)\n" + "--\n" +@@ -1455,22 +1386,6 @@ exit: + + #endif /* defined(_MSC_VER) */ + +-#ifndef _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF +- #define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF +-#endif /* !defined(_SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF) */ +- +-#ifndef _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF +- #define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF +-#endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */ +- +-#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF +- #define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF +-#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */ +- +-#ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF +- #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF +-#endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */ +- + #ifndef _SSL_RAND_EGD_METHODDEF + #define _SSL_RAND_EGD_METHODDEF + #endif /* !defined(_SSL_RAND_EGD_METHODDEF) */ +--- a/Tools/ssl/multissltests.py ++++ b/Tools/ssl/multissltests.py +@@ -43,8 +43,6 @@ import tarfile + log = logging.getLogger("multissl") + + OPENSSL_OLD_VERSIONS = [ +- "1.0.2u", +- "1.1.0l", + ] + + OPENSSL_RECENT_VERSIONS = [ +@@ -53,11 +51,9 @@ OPENSSL_RECENT_VERSIONS = [ + ] + + LIBRESSL_OLD_VERSIONS = [ +- "2.9.2", + ] + + LIBRESSL_RECENT_VERSIONS = [ +- "3.1.0", + ] + + # store files in ../multissl +--- a/configure ++++ b/configure +@@ -88,6 +88,13 @@ fi + # splitting by setting IFS to empty value.) + IFS=" "" $as_nl" + ++# IFS ++# We need space, tab and new line, in precisely that order. Quoting is ++# there to prevent editors from complaining about space-tab. ++# (If _AS_PATH_WALK were called with IFS unset, it would disable word ++# splitting by setting IFS to empty value.) ++IFS=" "" $as_nl" ++ + # Find who we are. Look in the path if we contain no directory separator. + as_myself= + case $0 in #(( +@@ -17734,7 +17741,6 @@ as_fn_error () + as_fn_exit $as_status + } # as_fn_error + +- + # as_fn_set_status STATUS + # ----------------------- + # Set $? to STATUS, without forking. +@@ -18780,4 +18786,3 @@ if test "$Py_OPT" = 'false' -a "$Py_DEBU + echo "" >&6 + echo "" >&6 + fi +- +--- a/configure.ac ++++ b/configure.ac +@@ -5622,42 +5622,6 @@ ac_includes_default="$save_includes_defa + # Check for usable OpenSSL + AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no]) + +-if test "$have_openssl" = yes; then +- AC_MSG_CHECKING([for X509_VERIFY_PARAM_set1_host in libssl]) +- +- save_LIBS="$LIBS" +- save_LDFLAGS="$LDFLAGS" +- save_CPPFLAGS="$CPPFLAGS" +- LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" +- LIBS="$OPENSSL_LIBS $LIBS" +- CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" +- +- AC_LINK_IFELSE([AC_LANG_PROGRAM([ +- [#include ] +- ], [ +- [X509_VERIFY_PARAM *p = X509_VERIFY_PARAM_new();] +- [X509_VERIFY_PARAM_set1_host(p, "localhost", 0);] +- [X509_VERIFY_PARAM_set1_ip_asc(p, "127.0.0.1");] +- [X509_VERIFY_PARAM_set_hostflags(p, 0);] +- ]) +- ], +- [ +- ac_cv_has_x509_verify_param_set1_host=yes +- ], +- [ +- ac_cv_has_x509_verify_param_set1_host=no +- ]) +- AC_MSG_RESULT($ac_cv_has_x509_verify_param_set1_host) +- if test "$ac_cv_has_x509_verify_param_set1_host" = "yes"; then +- AC_DEFINE(HAVE_X509_VERIFY_PARAM_SET1_HOST, 1, +- [Define if libssl has X509_VERIFY_PARAM_set1_host and related function]) +- fi +- +- CPPFLAGS="$save_CPPFLAGS" +- LDFLAGS="$save_LDFLAGS" +- LIBS="$save_LIBS" +-fi +- + # ssl module default cipher suite string + AH_TEMPLATE(PY_SSL_DEFAULT_CIPHERS, + [Default cipher suites list for ssl module. +--- a/pyconfig.h.in ++++ b/pyconfig.h.in +@@ -1335,9 +1335,6 @@ + /* Define to 1 if you have the `writev' function. */ + #undef HAVE_WRITEV + +-/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ +-#undef HAVE_X509_VERIFY_PARAM_SET1_HOST +- + /* Define if the zlib library has inflateCopy */ + #undef HAVE_ZLIB_COPY + +--- a/setup.py ++++ b/setup.py +@@ -439,10 +439,7 @@ class PyBuildExt(build_ext): + for l in (self.missing, self.failed, self.failed_on_import)): + print() + print("Could not build the ssl module!") +- print("Python requires an OpenSSL 1.0.2 or 1.1 compatible " +- "libssl with X509_VERIFY_PARAM_set1_host().") +- print("LibreSSL 2.6.4 and earlier do not provide the necessary " +- "APIs, https://github.com/libressl-portable/portable/issues/381") ++ print("Python requires a OpenSSL 1.1.1 or newer") + print() + + def build_extension(self, ext): +@@ -2196,13 +2193,13 @@ class PyBuildExt(build_ext): + self.missing.extend(['_ssl', '_hashlib']) + return None, None + +- # OpenSSL 1.0.2 uses Kerberos for KRB5 ciphers +- krb5_h = find_file( +- 'krb5.h', self.inc_dirs, +- ['/usr/kerberos/include'] ++ self.add(Extension( ++ '_ssl', ['_ssl.c'], ++ include_dirs=openssl_includes, ++ library_dirs=openssl_libdirs, ++ libraries=openssl_libs, ++ depends=['socketmodule.h', '_ssl/debughelpers.c']) + ) +- if krb5_h: +- ssl_incs.extend(krb5_h) + + if config_vars.get("HAVE_X509_VERIFY_PARAM_SET1_HOST"): + self.add(Extension( +@@ -2217,8 +2214,6 @@ class PyBuildExt(build_ext): + '_ssl_data_111.h', + '_ssl_data_300.h', + ])) +- else: +- self.missing.append('_ssl') + + self.add(Extension('_hashlib', ['_hashopenssl.c'], + depends=['hashlib.h'], diff --git a/F00102-lib64.patch b/F00102-lib64.patch new file mode 100644 index 0000000..b91424a --- /dev/null +++ b/F00102-lib64.patch @@ -0,0 +1,236 @@ +From 81904771db8b112c8617a111e989b68e55af7a9c Mon Sep 17 00:00:00 2001 +From: David Malcolm +Date: Wed, 13 Jan 2010 21:25:18 +0000 +Subject: [PATCH] 00102: Change the various install paths to use /usr/lib64/ + instead or /usr/lib/ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Only used when "%{_lib}" == "lib64". + +Co-authored-by: David Malcolm +Co-authored-by: Thomas Spura +Co-authored-by: Slavek Kabrda +Co-authored-by: Matej Stuchlik +Co-authored-by: Tomas Orsava +Co-authored-by: Charalampos Stratakis +Co-authored-by: Petr Viktorin +Co-authored-by: Miro Hrončok +Co-authored-by: Iryna Shcherbina +--- + Lib/distutils/command/install.py | 4 ++-- + Lib/distutils/sysconfig.py | 6 +++++- + Lib/distutils/tests/test_install.py | 3 ++- + Lib/site.py | 4 ++++ + Lib/sysconfig.py | 12 ++++++------ + Lib/test/test_site.py | 4 ++-- + Makefile.pre.in | 2 +- + Modules/getpath.c | 6 +++--- + configure | 4 ++-- + configure.ac | 4 ++-- + setup.py | 6 +++--- + 11 files changed, 32 insertions(+), 23 deletions(-) + +--- a/Lib/distutils/command/install.py ++++ b/Lib/distutils/command/install.py +@@ -30,14 +30,14 @@ WINDOWS_SCHEME = { + INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', +- 'platlib': '$platbase/lib/python$py_version_short/site-packages', ++ 'platlib': '$platbase/lib64/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', +- 'platlib': '$base/lib/python', ++ 'platlib': '$base/lib64/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', +--- a/Lib/distutils/sysconfig.py ++++ b/Lib/distutils/sysconfig.py +@@ -146,8 +146,12 @@ def get_python_lib(plat_specific=0, stan + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": ++ if plat_specific or standard_lib: ++ lib = "lib64" ++ else: ++ lib = "lib" + libpython = os.path.join(prefix, +- "lib", "python" + get_python_version()) ++ lib, "python" + get_python_version()) + if standard_lib: + return libpython + else: +--- a/Lib/distutils/tests/test_install.py ++++ b/Lib/distutils/tests/test_install.py +@@ -57,8 +57,9 @@ class InstallTestCase(support.TempdirMan + self.assertEqual(got, expected) + + libdir = os.path.join(destination, "lib", "python") ++ platlibdir = os.path.join(destination, "lib", "python") + check_path(cmd.install_lib, libdir) +- check_path(cmd.install_platlib, libdir) ++ check_path(cmd.install_platlib, platlibdir) + check_path(cmd.install_purelib, libdir) + check_path(cmd.install_headers, + os.path.join(destination, "include", "python", "foopkg")) +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -344,11 +344,15 @@ def getsitepackages(prefixes=None): + seen.add(prefix) + + if os.sep == '/': ++ sitepackages.append(os.path.join(prefix, "lib64", ++ "python" + sys.version[:3], ++ "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", + "python%d.%d" % sys.version_info[:2], + "site-packages")) + else: + sitepackages.append(prefix) ++ sitepackages.append(os.path.join(prefix, "lib64", "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-packages")) + return sitepackages + +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -25,10 +25,10 @@ _ALWAYS_STR = { + + _INSTALL_SCHEMES = { + 'posix_prefix': { +- 'stdlib': '{installed_base}/lib/python{py_version_short}', +- 'platstdlib': '{platbase}/lib/python{py_version_short}', ++ 'stdlib': '{installed_base}/lib64/python{py_version_short}', ++ 'platstdlib': '{platbase}/lib64/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', +- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{platbase}/lib64/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': +@@ -67,10 +67,10 @@ _INSTALL_SCHEMES = { + 'data': '{userbase}', + }, + 'posix_user': { +- 'stdlib': '{userbase}/lib/python{py_version_short}', +- 'platstdlib': '{userbase}/lib/python{py_version_short}', ++ 'stdlib': '{userbase}/lib64/python{py_version_short}', ++ 'platstdlib': '{userbase}/lib64/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', +- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{userbase}/lib64/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', +--- a/Lib/test/test_site.py ++++ b/Lib/test/test_site.py +@@ -307,8 +307,8 @@ class HelperFunctionsTests(unittest.Test + dirs = site.getsitepackages() + if os.sep == '/': + # OS X, Linux, FreeBSD, etc +- self.assertEqual(len(dirs), 1) +- wanted = os.path.join('xoxo', 'lib', ++ self.assertEqual(len(dirs), 2) ++ wanted = os.path.join('xoxo', 'lib64', + 'python%d.%d' % sys.version_info[:2], + 'site-packages') + self.assertEqual(dirs[0], wanted) +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -143,7 +143,7 @@ LIBDIR= @libdir@ + MANDIR= @mandir@ + INCLUDEDIR= @includedir@ + CONFINCLUDEDIR= $(exec_prefix)/include +-SCRIPTDIR= $(prefix)/lib ++SCRIPTDIR= $(prefix)/lib64 + ABIFLAGS= @ABIFLAGS@ + + # Detailed destination directories +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -730,7 +730,7 @@ calculate_exec_prefix(PyCalculatePath *c + if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { + return PATHLEN_ERR(); + } +- status = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len); ++ status = joinpath(exec_prefix, L"lib64/lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } +@@ -1063,7 +1063,7 @@ calculate_zip_path(PyCalculatePath *calc + return PATHLEN_ERR(); + } + } +- status = joinpath(zip_path, L"lib/python00.zip", zip_path_len); ++ status = joinpath(zip_path, L"lib64/python00.zip", zip_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } +@@ -1193,7 +1193,7 @@ calculate_init(PyCalculatePath *calculat + if (!calculate->exec_prefix) { + return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); + } +- calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len); ++ calculate->lib_python = Py_DecodeLocale("lib64/python" VERSION, &len); + if (!calculate->lib_python) { + return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); + } +--- a/configure ++++ b/configure +@@ -15276,9 +15276,9 @@ fi + + + if test x$PLATFORM_TRIPLET = x; then +- LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}" ++ LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}" + else +- LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" ++ LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" + fi + + +--- a/configure.ac ++++ b/configure.ac +@@ -4722,9 +4722,9 @@ fi + dnl define LIBPL after ABIFLAGS and LDVERSION is defined. + AC_SUBST(PY_ENABLE_SHARED) + if test x$PLATFORM_TRIPLET = x; then +- LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}" ++ LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}" + else +- LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" ++ LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" + fi + AC_SUBST(LIBPL) + +--- a/setup.py ++++ b/setup.py +@@ -634,7 +634,7 @@ class PyBuildExt(build_ext): + # directories (i.e. '.' and 'Include') must be first. See issue + # 10520. + if not CROSS_COMPILING: +- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') ++ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64') + add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + # only change this for cross builds for 3.3, issues on Mageia + if CROSS_COMPILING: +@@ -938,11 +938,11 @@ class PyBuildExt(build_ext): + elif curses_library: + readline_libs.append(curses_library) + elif self.compiler.find_library_file(self.lib_dirs + +- ['/usr/lib/termcap'], ++ ['/usr/lib64/termcap'], + 'termcap'): + readline_libs.append('termcap') + self.add(Extension('readline', ['readline.c'], +- library_dirs=['/usr/lib/termcap'], ++ library_dirs=['/usr/lib64/termcap'], + extra_link_args=readline_extra_link_args, + libraries=readline_libs)) + else: diff --git a/F00251-change-user-install-location.patch b/F00251-change-user-install-location.patch new file mode 100644 index 0000000..6dada6c --- /dev/null +++ b/F00251-change-user-install-location.patch @@ -0,0 +1,57 @@ +From 910f38d9768d39d4d31426743ae4081ed1ab66b6 Mon Sep 17 00:00:00 2001 +From: Michal Cyprian +Date: Mon, 26 Jun 2017 16:32:56 +0200 +Subject: [PATCH] 00251: Change user install location + +Set values of prefix and exec_prefix in distutils install command +to /usr/local if executable is /usr/bin/python* and RPM build +is not detected to make pip and distutils install into separate location. + +Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe +--- + Lib/distutils/command/install.py | 15 +++++++++++++-- + Lib/site.py | 9 ++++++++- + 2 files changed, 21 insertions(+), 3 deletions(-) + +--- a/Lib/distutils/command/install.py ++++ b/Lib/distutils/command/install.py +@@ -418,8 +418,19 @@ class install(Command): + raise DistutilsOptionError( + "must not supply exec-prefix without prefix") + +- self.prefix = os.path.normpath(sys.prefix) +- self.exec_prefix = os.path.normpath(sys.exec_prefix) ++ # self.prefix is set to sys.prefix + /local/ ++ # if neither RPM build nor virtual environment is ++ # detected to make pip and distutils install packages ++ # into the separate location. ++ if (not (hasattr(sys, 'real_prefix') or ++ sys.prefix != sys.base_prefix) and ++ 'RPM_BUILD_ROOT' not in os.environ): ++ addition = "/local" ++ else: ++ addition = "" ++ ++ self.prefix = os.path.normpath(sys.prefix) + addition ++ self.exec_prefix = os.path.normpath(sys.exec_prefix) + addition + + else: + if self.exec_prefix is None: +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -357,7 +357,14 @@ def getsitepackages(prefixes=None): + return sitepackages + + def addsitepackages(known_paths, prefixes=None): +- """Add site-packages to sys.path""" ++ """Add site-packages to sys.path ++ ++ '/usr/local' is included in PREFIXES if RPM build is not detected ++ to make packages installed into this location visible. ++ ++ """ ++ if ENABLE_USER_SITE and 'RPM_BUILD_ROOT' not in os.environ: ++ PREFIXES.insert(0, "/usr/local") + for sitedir in getsitepackages(prefixes): + if os.path.isdir(sitedir): + addsitedir(sitedir, known_paths) diff --git a/PACKAGING-NOTES b/PACKAGING-NOTES new file mode 100644 index 0000000..e28c88c --- /dev/null +++ b/PACKAGING-NOTES @@ -0,0 +1,26 @@ +Notes for packagers of Python3 +============================== + +0. Faster build turnaround +-------------------------- + +By default, python builds with profile-guided optimization. This needs +an additional run of the test suite and it is generally slow. +PGO build takes around 50 minutes. + +For development, use "--without profileopt" option to disable PGO. This +shortens the build time to ~5 minutes including test suite. + +1. import_failed.map +---------------------- + +This is a mechanism installed as part of python3-base, that places shim modules +on python's path (through a generated zzzz-import-failed-hooks.pth file, so that +it is imported as much at the end as makes sense; and an _import_failed subdir +of /usr/lib/pythonX.Y). Then when the user tries to import a module that is part +of a subpackage, the ImportError will contain a helpful message telling them +which missing subpackage to install. + +This can sometimes cause problems on non-standard configurations, if the pth +gets included too early (for instance if you are using a script to include all +pths by hand in some strange order). Just something to look out for. diff --git a/Python-3.8.20.tar.xz b/Python-3.8.20.tar.xz new file mode 100644 index 0000000..90c5002 --- /dev/null +++ b/Python-3.8.20.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fb89a7124201c61125c0ab4cf7f6894df339a40c02833bfd28ab4d7691fafb4 +size 18962788 diff --git a/Python-3.8.20.tar.xz.asc b/Python-3.8.20.tar.xz.asc new file mode 100644 index 0000000..39d771f --- /dev/null +++ b/Python-3.8.20.tar.xz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEE4/8oOcBIslwITevpsmmV4xAlBWgFAmbcKdUACgkQsmmV4xAl +BWhI0Q/+MWwQirWSn5ZApMU4EmKrZ0x8fuAeMHam6Dg1FaATYxJxgkf8ep5TN7Xp +VQpNVa40PqXbAf93x4KSavv/QS464Whv1PX5FsBkJBwzPPR3xY8CAfisPXchrOQV +12OKmhXnT7nebqaax56SLJsnen8EZB35X7d8RzDVqdNu+Xl7ICOY7d3LkPW14SGk +/pHgF2YgfClQSAh4MLRR0EYhUVlzKENJkGnMTdU9VicOnjJ5LtkGbHhVYPAEqALf +r6hrn2gyorPF8gtY+uN8d2/UKh9Xih/tRPhM3GGbX6Q9EBNpivvNK7829jEAkw1P +NZKtAOfiQGJU4I1PQkiYDMcbtc/fhDaj96nA+X3LxKih7dzLCXVGwDLsBYN6PJp4 +ogR+nL7d5ZcikGrzHHaxZjncj2nPrbk5+aNoIZWHq29RiuZ0c74GRl9ILYYijk/E +vXsiBtuzwbA2UCF+gRVrZA3a9G4dMkLvftmbDemnUw5xGTWNEEInKD5Sv3fDhvMx +vdRI72RglYy1VNrgcG5mcH7bviXFy+voExUUjvsHOGkqHvyK+tVV0T+EMfEtRp6k +rCVdswN0LFIkmerVfr6XXHFty1mlKRvX+hyeiRXIhdFZieDQHdVH+3rvaft31LcQ +S2Mv+EGDeUP9llrF80Slbw7XPFfclkOBtzOOKwcTN+2NlpvczOw= +=9/j+ +-----END PGP SIGNATURE----- diff --git a/README.SUSE b/README.SUSE new file mode 100644 index 0000000..0053bcf --- /dev/null +++ b/README.SUSE @@ -0,0 +1,43 @@ +Python 3 in SUSE +============== + +* Subpackages * + +Python 3 is split into several subpackages, based on external dependencies. +The main package 'python3' has soft dependencies on all subpackages needed to +assemble the standard library; however, these might not all be installed by default. + +If you attempt to import a module that is currently not installed, an ImportError is thrown, +with instructions to install the missing subpackage. Installing the subpackage might result +in installing libraries that the subpackage requires to function. + + +* ensurepip * + +The 'ensurepip' module from Python 3 standard library (PEP 453) is supposed to deploy +a bundled copy of the pip installer. This makes no sense in a managed distribution like SUSE. +Instead, you need to install package 'python3-pip'. Usually this will be installed automatically +with 'python3'. + +Using 'ensurepip' when pip is not installed will result in an ImportError with instructions +to install 'python3-pip'. + + +* Documentation * + +You can find documentation in seprarate packages: python3-doc and +python3-doc-pdf. These contan following documents: + + Tutorial, What's New in Python, Global Module Index, Library Reference, + Macintosh Module Reference, Installing Python Modules, Distributing Python + Modules, Language Reference, Extending and Embedding, Python/C API, + Documenting Python + +The python3-doc package constains many text files from source tarball. + + +* Interactive mode * + +Interactive mode is by default enhanced with of history and command completion. +If you don't like these features, you can unset the PYTHONSTARTUP variable +in your .profile or disable it system wide in /etc/profile.d/python.sh. diff --git a/SUSE-FEDORA-multilib.patch b/SUSE-FEDORA-multilib.patch new file mode 100644 index 0000000..7c40741 --- /dev/null +++ b/SUSE-FEDORA-multilib.patch @@ -0,0 +1,411 @@ +--- + Lib/distutils/command/install.py | 18 +++++++++--------- + Lib/distutils/sysconfig.py | 7 ++----- + Lib/site.py | 19 +++++++++---------- + Lib/sysconfig.py | 12 ++++++------ + Lib/test/test_embed.py | 10 +++++++--- + Lib/test/test_site.py | 7 +++++-- + Lib/test/test_sysconfig.py | 14 +++++++++++++- + Makefile.pre.in | 6 +++++- + Modules/getpath.c | 24 ++++++++++++------------ + configure | 4 ++-- + configure.ac | 18 ++++++++++++++++-- + setup.py | 6 +++--- + 12 files changed, 89 insertions(+), 56 deletions(-) + +--- a/Lib/distutils/command/install.py ++++ b/Lib/distutils/command/install.py +@@ -30,14 +30,14 @@ WINDOWS_SCHEME = { + INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', +- 'platlib': '$platbase/lib64/python$py_version_short/site-packages', ++ 'platlib': '$platbase/$platsubdir/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', +- 'platlib': '$base/lib64/python', ++ 'platlib': '$base/lib/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', +@@ -281,7 +281,7 @@ class install(Command): + # about needing recursive variable expansion (shudder). + + py_version = sys.version.split()[0] +- (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') ++ (prefix, exec_prefix, platsubdir) = get_config_vars('prefix', 'exec_prefix', 'platsubdir') + try: + abiflags = sys.abiflags + except AttributeError: +@@ -298,6 +298,7 @@ class install(Command): + 'sys_exec_prefix': exec_prefix, + 'exec_prefix': exec_prefix, + 'abiflags': abiflags, ++ 'platsubdir': platsubdir, + } + + if HAS_USER_SITE: +@@ -419,12 +420,11 @@ class install(Command): + "must not supply exec-prefix without prefix") + + # self.prefix is set to sys.prefix + /local/ +- # if neither RPM build nor virtual environment is +- # detected to make pip and distutils install packages +- # into the separate location. +- if (not (hasattr(sys, 'real_prefix') or +- sys.prefix != sys.base_prefix) and +- 'RPM_BUILD_ROOT' not in os.environ): ++ # if the executable is /usr/bin/python* and RPM build ++ # is not detected to make pip and distutils install into ++ # the separate location. ++ if (sys.executable.startswith("/usr/bin/python") ++ and 'RPM_BUILD_ROOT' not in os.environ): + addition = "/local" + else: + addition = "" +--- a/Lib/distutils/sysconfig.py ++++ b/Lib/distutils/sysconfig.py +@@ -146,12 +146,9 @@ def get_python_lib(plat_specific=0, stan + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": +- if plat_specific or standard_lib: +- lib = "lib64" +- else: +- lib = "lib" ++ libdir = plat_specific and get_config_var("platsubdir") or "lib" + libpython = os.path.join(prefix, +- lib, "python" + get_python_version()) ++ libdir, "python" + get_python_version()) + if standard_lib: + return libpython + else: +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -344,12 +344,18 @@ def getsitepackages(prefixes=None): + seen.add(prefix) + + if os.sep == '/': +- sitepackages.append(os.path.join(prefix, "lib64", ++ from sysconfig import get_config_var ++ platsubdir = get_config_var("platsubdir") ++ sitepackages.append(os.path.join(prefix, platsubdir, + "python" + sys.version[:3], + "site-packages")) +- sitepackages.append(os.path.join(prefix, "lib", ++ sitepackages.append(os.path.join(prefix, platsubdir, + "python%d.%d" % sys.version_info[:2], + "site-packages")) ++ if platsubdir != "lib": ++ sitepackages.append(os.path.join(prefix, "lib", ++ "python%d.%d" % sys.version_info[:2], ++ "site-packages")) + else: + sitepackages.append(prefix) + sitepackages.append(os.path.join(prefix, "lib64", "site-packages")) +@@ -357,14 +363,7 @@ def getsitepackages(prefixes=None): + return sitepackages + + def addsitepackages(known_paths, prefixes=None): +- """Add site-packages to sys.path +- +- '/usr/local' is included in PREFIXES if RPM build is not detected +- to make packages installed into this location visible. +- +- """ +- if ENABLE_USER_SITE and 'RPM_BUILD_ROOT' not in os.environ: +- PREFIXES.insert(0, "/usr/local") ++ """Add site-packages to sys.path""" + for sitedir in getsitepackages(prefixes): + if os.path.isdir(sitedir): + addsitedir(sitedir, known_paths) +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -25,10 +25,10 @@ _ALWAYS_STR = { + + _INSTALL_SCHEMES = { + 'posix_prefix': { +- 'stdlib': '{installed_base}/lib64/python{py_version_short}', +- 'platstdlib': '{platbase}/lib64/python{py_version_short}', ++ 'stdlib': '{installed_base}/{platsubdir}/python{py_version_short}', ++ 'platstdlib': '{platbase}/{platsubdir}/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', +- 'platlib': '{platbase}/lib64/python{py_version_short}/site-packages', ++ 'platlib': '{platbase}/{platsubdir}/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': +@@ -67,10 +67,10 @@ _INSTALL_SCHEMES = { + 'data': '{userbase}', + }, + 'posix_user': { +- 'stdlib': '{userbase}/lib64/python{py_version_short}', +- 'platstdlib': '{userbase}/lib64/python{py_version_short}', ++ 'stdlib': '{userbase}/lib/python{py_version_short}', ++ 'platstdlib': '{userbase}/lib/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', +- 'platlib': '{userbase}/lib64/python{py_version_short}/site-packages', ++ 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', +--- a/Lib/test/test_embed.py ++++ b/Lib/test/test_embed.py +@@ -10,6 +10,7 @@ import re + import shutil + import subprocess + import sys ++import sysconfig + import tempfile + import textwrap + +@@ -1072,12 +1073,13 @@ class InitConfigTests(EmbeddingTestsMixi + return config['config']['module_search_paths'] + else: + ver = sys.version_info ++ platsubdir = sysconfig.get_config_var('platsubdir') + return [ + os.path.join(prefix, 'lib', + f'python{ver.major}{ver.minor}.zip'), +- os.path.join(prefix, 'lib', ++ os.path.join(prefix, platsubdir, + f'python{ver.major}.{ver.minor}'), +- os.path.join(exec_prefix, 'lib', ++ os.path.join(exec_prefix, platsubdir, + f'python{ver.major}.{ver.minor}', 'lib-dynload'), + ] + +@@ -1188,13 +1190,15 @@ class InitConfigTests(EmbeddingTestsMixi + def test_init_pyvenv_cfg(self): + # Test path configuration with pyvenv.cfg configuration file + ++ platsubdir = sysconfig.get_config_var('platsubdir') ++ + with self.tmpdir_with_python() as tmpdir, \ + tempfile.TemporaryDirectory() as pyvenv_home: + ver = sys.version_info + + if not MS_WINDOWS: + lib_dynload = os.path.join(pyvenv_home, +- 'lib', ++ platsubdir, + f'python{ver.major}.{ver.minor}', + 'lib-dynload') + os.makedirs(lib_dynload) +--- a/Lib/test/test_site.py ++++ b/Lib/test/test_site.py +@@ -307,8 +307,11 @@ class HelperFunctionsTests(unittest.Test + dirs = site.getsitepackages() + if os.sep == '/': + # OS X, Linux, FreeBSD, etc +- self.assertEqual(len(dirs), 2) +- wanted = os.path.join('xoxo', 'lib64', ++ self.assertTrue(len(dirs) in (1,2,3), ++ "dirs = {} has len not in (1,2,3).".format(dirs)) ++ ++ platsubdir = sysconfig.get_config_var('platsubdir') ++ wanted = os.path.join('xoxo', platsubdir, + 'python%d.%d' % sys.version_info[:2], + 'site-packages') + self.assertEqual(dirs[0], wanted) +--- a/Lib/test/test_sysconfig.py ++++ b/Lib/test/test_sysconfig.py +@@ -243,6 +243,7 @@ class TestSysConfig(unittest.TestCase): + # is similar to the global posix_prefix one + base = get_config_var('base') + user = get_config_var('userbase') ++ platsubdir = get_config_var("platsubdir") + # the global scheme mirrors the distinction between prefix and + # exec-prefix but not the user scheme, so we have to adapt the paths + # before comparing (issue #9100) +@@ -257,8 +258,19 @@ class TestSysConfig(unittest.TestCase): + # before comparing + global_path = global_path.replace(sys.base_prefix, sys.prefix) + base = base.replace(sys.base_prefix, sys.prefix) ++ ++ if platsubdir != "lib": ++ platbase = os.path.join(base, platsubdir) ++ purebase = os.path.join(base, "lib") ++ userlib = os.path.join(user, "lib") ++ # replace platbase first because usually purebase is a prefix of platbase ++ # /usr/lib is prefix of /usr/lib64 and would get replaced first ++ modified_path = global_path.replace(platbase, userlib, 1).replace(purebase, userlib, 1) ++ else: ++ modified_path = global_path.replace(base, user, 1) ++ + user_path = get_path(name, 'posix_user') +- self.assertEqual(user_path, global_path.replace(base, user, 1)) ++ self.assertEqual(user_path, modified_path) + + def test_main(self): + # just making sure _main() runs and returns things in the stdout +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -137,13 +137,16 @@ exec_prefix= @exec_prefix@ + # Install prefix for data files + datarootdir= @datarootdir@ + ++# Name of "lib" directory under prefix ++platsubdir= @platsubdir@ ++ + # Expanded directories + BINDIR= @bindir@ + LIBDIR= @libdir@ + MANDIR= @mandir@ + INCLUDEDIR= @includedir@ + CONFINCLUDEDIR= $(exec_prefix)/include +-SCRIPTDIR= $(prefix)/lib64 ++SCRIPTDIR= @libdir@ + ABIFLAGS= @ABIFLAGS@ + + # Detailed destination directories +@@ -766,6 +769,7 @@ Modules/getpath.o: $(srcdir)/Modules/get + -DEXEC_PREFIX='"$(exec_prefix)"' \ + -DVERSION='"$(VERSION)"' \ + -DVPATH='"$(VPATH)"' \ ++ -DPLATLIBDIR='"$(platsubdir)"' \ + -o $@ $(srcdir)/Modules/getpath.c + + Programs/python.o: $(srcdir)/Programs/python.c +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -55,12 +55,12 @@ + * pybuilddir.txt. If the landmark is found, we're done. + * + * For the remaining steps, the prefix landmark will always be +- * lib/python$VERSION/os.py and the exec_prefix will always be +- * lib/python$VERSION/lib-dynload, where $VERSION is Python's version +- * number as supplied by the Makefile. Note that this means that no more +- * build directory checking is performed; if the first step did not find +- * the landmarks, the assumption is that python is running from an +- * installed setup. ++ * $lib/python$VERSION/os.py and the exec_prefix will always be ++ * $lib/python$VERSION/lib-dynload, where $VERSION is Python's version ++ * number and $lib is PLATLIBDIR as supplied by the Makefile. Note that ++ * this means that no more build directory checking is performed; if the ++ * first step did not find the landmarks, the assumption is that python ++ * is running from an installed setup. + * + * Step 2. See if the $PYTHONHOME environment variable points to the + * installed location of the Python libraries. If $PYTHONHOME is set, then +@@ -86,7 +86,7 @@ + * containing the shared library modules is appended. The environment + * variable $PYTHONPATH is inserted in front of it all. Finally, the + * prefix and exec_prefix globals are tweaked so they reflect the values +- * expected by other code, by stripping the "lib/python$VERSION/..." stuff ++ * expected by other code, by stripping the "$lib/python$VERSION/..." stuff + * off. If either points to the build directory, the globals are reset to + * the corresponding preprocessor variables (so sys.prefix will reflect the + * installation location, even though sys.path points into the build +@@ -105,8 +105,8 @@ extern "C" { + #endif + + +-#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH) +-#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined" ++#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH) || !defined(PLATLIBDIR) ++#error "PREFIX, EXEC_PREFIX, VERSION, VPATH, and PLATLIBDIR must be constant defined" + #endif + + #ifndef LANDMARK +@@ -730,7 +730,7 @@ calculate_exec_prefix(PyCalculatePath *c + if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { + return PATHLEN_ERR(); + } +- status = joinpath(exec_prefix, L"lib64/lib-dynload", exec_prefix_len); ++ status = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } +@@ -1063,7 +1063,7 @@ calculate_zip_path(PyCalculatePath *calc + return PATHLEN_ERR(); + } + } +- status = joinpath(zip_path, L"lib64/python00.zip", zip_path_len); ++ status = joinpath(zip_path, L"lib/python00.zip", zip_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } +@@ -1193,7 +1193,7 @@ calculate_init(PyCalculatePath *calculat + if (!calculate->exec_prefix) { + return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); + } +- calculate->lib_python = Py_DecodeLocale("lib64/python" VERSION, &len); ++ calculate->lib_python = Py_DecodeLocale(PLATLIBDIR "/python" VERSION, &len); + if (!calculate->lib_python) { + return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); + } +--- a/configure ++++ b/configure +@@ -15276,9 +15276,9 @@ fi + + + if test x$PLATFORM_TRIPLET = x; then +- LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}" ++ LIBPL='$(prefix)'"/${platsubdir}/python${VERSION}/config-${LDVERSION}" + else +- LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" ++ LIBPL='$(prefix)'"/${platsubdir}/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" + fi + + +--- a/configure.ac ++++ b/configure.ac +@@ -4719,12 +4719,26 @@ else + LIBPYTHON='' + fi + ++# platsubdir must be defined before LIBPL definition ++AC_MSG_CHECKING(for custom platsubdir) ++AC_ARG_WITH(custom-platsubdir, ++ [AS_HELP_STRING([--with-custom-platsubdir=], ++ [set the platsubdir name to a custom string])], ++ [], ++ [with_custom_platsubdir=yes]) ++AS_CASE($with_custom_platsubdir, ++ [yes],[platsubdir=`basename ${libdir}`], ++ [no],[platsubdir=lib], ++ [platsubdir=$with_custom_platsubdir]) ++AC_MSG_RESULT($platsubdir) ++AC_SUBST(platsubdir) ++ + dnl define LIBPL after ABIFLAGS and LDVERSION is defined. + AC_SUBST(PY_ENABLE_SHARED) + if test x$PLATFORM_TRIPLET = x; then +- LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}" ++ LIBPL='$(prefix)'"/${platsubdir}/python${VERSION}/config-${LDVERSION}" + else +- LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" ++ LIBPL='$(prefix)'"/${platsubdir}/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" + fi + AC_SUBST(LIBPL) + +--- a/setup.py ++++ b/setup.py +@@ -634,7 +634,7 @@ class PyBuildExt(build_ext): + # directories (i.e. '.' and 'Include') must be first. See issue + # 10520. + if not CROSS_COMPILING: +- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64') ++ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') + add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + # only change this for cross builds for 3.3, issues on Mageia + if CROSS_COMPILING: +@@ -938,11 +938,11 @@ class PyBuildExt(build_ext): + elif curses_library: + readline_libs.append(curses_library) + elif self.compiler.find_library_file(self.lib_dirs + +- ['/usr/lib64/termcap'], ++ ['/usr/lib/termcap'], + 'termcap'): + readline_libs.append('termcap') + self.add(Extension('readline', ['readline.c'], +- library_dirs=['/usr/lib64/termcap'], ++ library_dirs=['/usr/lib/termcap'], + extra_link_args=readline_extra_link_args, + libraries=readline_libs)) + else: diff --git a/_multibuild b/_multibuild new file mode 100644 index 0000000..1d50bc4 --- /dev/null +++ b/_multibuild @@ -0,0 +1,4 @@ + + base + doc + diff --git a/baselibs.conf b/baselibs.conf new file mode 100644 index 0000000..45da3e6 --- /dev/null +++ b/baselibs.conf @@ -0,0 +1,3 @@ +python38-base +python38 +libpython3_8-1_0 diff --git a/bpo-31046_ensurepip_honours_prefix.patch b/bpo-31046_ensurepip_honours_prefix.patch new file mode 100644 index 0000000..1adfaf9 --- /dev/null +++ b/bpo-31046_ensurepip_honours_prefix.patch @@ -0,0 +1,163 @@ +From 5754521af1d51aa8e445cba07a093bbc0c88596d Mon Sep 17 00:00:00 2001 +From: Zackery Spytz +Date: Mon, 16 Dec 2019 18:24:08 -0700 +Subject: [PATCH] bpo-31046: ensurepip does not honour the value of $(prefix) + +Co-Authored-By: Xavier de Gaye +--- + Doc/library/ensurepip.rst | 9 +++-- + Lib/ensurepip/__init__.py | 18 +++++++--- + Lib/test/test_ensurepip.py | 11 ++++++ + Makefile.pre.in | 4 +- + Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst | 1 + 5 files changed, 34 insertions(+), 9 deletions(-) + create mode 100644 Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst + +--- a/Doc/library/ensurepip.rst ++++ b/Doc/library/ensurepip.rst +@@ -56,8 +56,9 @@ is at least as recent as the one bundled + By default, ``pip`` is installed into the current virtual environment + (if one is active) or into the system site packages (if there is no + active virtual environment). The installation location can be controlled +-through two additional command line options: ++through some additional command line options: + ++* ``--prefix ``: Installs ``pip`` using the given directory prefix. + * ``--root ``: Installs ``pip`` relative to the given root directory + rather than the root of the currently active virtual environment (if any) + or the default root for the current Python installation. +@@ -89,7 +90,7 @@ Module API + Returns a string specifying the bundled version of pip that will be + installed when bootstrapping an environment. + +-.. function:: bootstrap(root=None, upgrade=False, user=False, \ ++.. function:: bootstrap(root=None, prefix=None, upgrade=False, user=False, \ + altinstall=False, default_pip=False, \ + verbosity=0) + +@@ -99,6 +100,8 @@ Module API + If *root* is ``None``, then installation uses the default install location + for the current environment. + ++ *prefix* specifies the directory prefix to use when installing. ++ + *upgrade* indicates whether or not to upgrade an existing installation + of an earlier version of ``pip`` to the bundled version. + +@@ -119,6 +122,8 @@ Module API + *verbosity* controls the level of output to :data:`sys.stdout` from the + bootstrapping operation. + ++ .. versionchanged:: 3.9 the *prefix* parameter was added. ++ + .. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap + + .. note:: +--- a/Lib/ensurepip/__init__.py ++++ b/Lib/ensurepip/__init__.py +@@ -55,27 +55,27 @@ def _disable_pip_configuration_settings( + os.environ['PIP_CONFIG_FILE'] = os.devnull + + +-def bootstrap(*, root=None, upgrade=False, user=False, ++def bootstrap(*, root=None, prefix=None, upgrade=False, user=False, + altinstall=False, default_pip=False, + verbosity=0): + """ + Bootstrap pip into the current Python installation (or the given root +- directory). ++ and directory prefix). + + Note that calling this function will alter both sys.path and os.environ. + """ + # Discard the return value +- _bootstrap(root=root, upgrade=upgrade, user=user, ++ _bootstrap(root=root, prefix=prefix, upgrade=upgrade, user=user, + altinstall=altinstall, default_pip=default_pip, + verbosity=verbosity) + + +-def _bootstrap(*, root=None, upgrade=False, user=False, ++def _bootstrap(*, root=None, prefix=None, upgrade=False, user=False, + altinstall=False, default_pip=False, + verbosity=0): + """ + Bootstrap pip into the current Python installation (or the given root +- directory). Returns pip command status code. ++ and directory prefix). Returns pip command status code. + + Note that calling this function will alter both sys.path and os.environ. + """ +@@ -118,6 +118,8 @@ def _bootstrap(*, root=None, upgrade=Fal + args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir] + if root: + args += ["--root", root] ++ if prefix: ++ args += ["--prefix", prefix] + if upgrade: + args += ["--upgrade"] + if user: +@@ -190,6 +192,11 @@ def _main(argv=None): + help="Install everything relative to this alternate root directory.", + ) + parser.add_argument( ++ "--prefix", ++ default=None, ++ help="Install everything using this prefix.", ++ ) ++ parser.add_argument( + "--altinstall", + action="store_true", + default=False, +@@ -208,6 +215,7 @@ def _main(argv=None): + + return _bootstrap( + root=args.root, ++ prefix=args.prefix, + upgrade=args.upgrade, + user=args.user, + verbosity=args.verbosity, +--- a/Lib/test/test_ensurepip.py ++++ b/Lib/test/test_ensurepip.py +@@ -61,6 +61,17 @@ class TestBootstrap(EnsurepipMixin, unit + unittest.mock.ANY, + ) + ++ def test_bootstrapping_with_prefix(self): ++ ensurepip.bootstrap(prefix="/foo/bar/") ++ self.run_pip.assert_called_once_with( ++ [ ++ "install", "--no-cache-dir", "--no-index", "--find-links", ++ unittest.mock.ANY, "--prefix", "/foo/bar/", ++ "setuptools", "pip", ++ ], ++ unittest.mock.ANY, ++ ) ++ + def test_bootstrapping_with_user(self): + ensurepip.bootstrap(user=True) + +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -1200,7 +1200,7 @@ install: @FRAMEWORKINSTALLFIRST@ commoni + install|*) ensurepip="" ;; \ + esac; \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \ +- $$ensurepip --root=$(DESTDIR)/ ; \ ++ $$ensurepip --root=$(DESTDIR)/ --prefix=$(prefix) ; \ + fi + + altinstall: commoninstall +@@ -1210,7 +1210,7 @@ altinstall: commoninstall + install|*) ensurepip="--altinstall" ;; \ + esac; \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \ +- $$ensurepip --root=$(DESTDIR)/ ; \ ++ $$ensurepip --root=$(DESTDIR)/ --prefix=$(prefix) ; \ + fi + + commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst +@@ -0,0 +1 @@ ++A directory prefix can now be specified when using :mod:`ensurepip`. diff --git a/bpo34022-stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch b/bpo34022-stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch new file mode 100644 index 0000000..e155da6 --- /dev/null +++ b/bpo34022-stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch @@ -0,0 +1,152 @@ +From 2c096b513273a758b446405d9e5efe4860af1036 Mon Sep 17 00:00:00 2001 +From: Elvis Pranskevichus +Date: Thu, 27 Sep 2018 13:05:14 -0400 +Subject: [PATCH] bpo-34022: Stop forcing of hash-based invalidation with + SOURCE_DATE_EPOCH + +Unconditional forcing of ``CHECKED_HASH`` invalidation was introduced in +3.7.0 in bpo-29708. The change is bad, as it unconditionally overrides +*invalidation_mode*, even if it was passed as an explicit argument to +``py_compile.compile()`` or ``compileall``. An environment variable +should *never* override an explicit argument to a library function. +That change leads to multiple test failures if the ``SOURCE_DATE_EPOCH`` +environment variable is set. + +This changes ``py_compile.compile()`` to only look at +``SOURCE_DATE_EPOCH`` if no explicit *invalidation_mode* was specified. +I also made various relevant tests run with explicit control over the +value of ``SOURCE_DATE_EPOCH``. + +While looking at this, I noticed that ``zipimport`` does not work +with hash-based .pycs _at all_, though I left the fixes for +subsequent commits. +--- + Doc/library/compileall.rst | 11 ++-- + Doc/library/py_compile.rst | 13 ++-- + Lib/compileall.py | 20 ++++-- + Lib/py_compile.py | 13 +++- + Lib/test/test_compileall.py | 50 ++++++++++++-- + .../test_importlib/source/test_file_loader.py | 15 +++++ + Lib/test/test_py_compile.py | 66 +++++++++++++++++-- + .../2018-09-27-13-14-15.bpo-34022.E2cl0r.rst | 3 + + 8 files changed, 161 insertions(+), 30 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2018-09-27-13-14-15.bpo-34022.E2cl0r.rst + +--- a/Doc/library/py_compile.rst ++++ b/Doc/library/py_compile.rst +@@ -92,6 +92,11 @@ byte-code cache files in the directory c + .. versionchanged:: 3.8 + The *quiet* parameter was added. + ++ .. versionchanged:: 3.7.2 ++ The :envvar:`SOURCE_DATE_EPOCH` environment variable no longer ++ overrides the value of the *invalidation_mode* argument, and determines ++ its default value instead. ++ + + .. class:: PycInvalidationMode + +--- a/Lib/test/test_compileall.py ++++ b/Lib/test/test_compileall.py +@@ -209,6 +209,21 @@ class CompileallTestsWithoutSourceEpoch( + pass + + ++ ++class CompileallTestsWithSourceEpoch(CompileallTestsBase, ++ unittest.TestCase, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=True): ++ pass ++ ++ ++class CompileallTestsWithoutSourceEpoch(CompileallTestsBase, ++ unittest.TestCase, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=False): ++ pass ++ ++ + class EncodingTest(unittest.TestCase): + """Issue 6716: compileall should escape source code when printing errors + to stdout.""" +@@ -620,6 +635,21 @@ class CommandLineTestsBase: + + + class CommmandLineTestsWithSourceEpoch(CommandLineTestsBase, ++ unittest.TestCase, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=True): ++ pass ++ ++ ++class CommmandLineTestsNoSourceEpoch(CommandLineTestsBase, ++ unittest.TestCase, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=False): ++ pass ++ ++ ++ ++class CommmandLineTestsWithSourceEpoch(CommandLineTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=True): +--- a/Lib/test/test_importlib/source/test_file_loader.py ++++ b/Lib/test/test_importlib/source/test_file_loader.py +@@ -22,6 +22,9 @@ from test.support import make_legacy_pyc + from test.test_py_compile import without_source_date_epoch + from test.test_py_compile import SourceDateEpochTestMeta + ++from test.test_py_compile import without_source_date_epoch ++from test.test_py_compile import SourceDateEpochTestMeta ++ + + class SimpleTest(abc.LoaderTests): + +@@ -363,6 +366,17 @@ class SimpleTest(abc.LoaderTests): + + + class SourceDateEpochTestMeta(SourceDateEpochTestMeta, ++ type(Source_SimpleTest)): ++ pass ++ ++ ++class SourceDateEpoch_SimpleTest(Source_SimpleTest, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=True): ++ pass ++ ++ ++class SourceDateEpochTestMeta(SourceDateEpochTestMeta, + type(Source_SimpleTest)): + pass + +--- a/Lib/test/test_py_compile.py ++++ b/Lib/test/test_py_compile.py +@@ -272,5 +272,19 @@ class PyCompileCLITestCase(unittest.Test + self.assertIn(b'No such file or directory', stderr) + + ++class PyCompileTestsWithSourceEpoch(PyCompileTestsBase, ++ unittest.TestCase, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=True): ++ pass ++ ++ ++class PyCompileTestsWithoutSourceEpoch(PyCompileTestsBase, ++ unittest.TestCase, ++ metaclass=SourceDateEpochTestMeta, ++ source_date_epoch=False): ++ pass ++ ++ + if __name__ == "__main__": + unittest.main() +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2018-09-27-13-14-15.bpo-34022.E2cl0r.rst +@@ -0,0 +1,3 @@ ++The :envvar:`SOURCE_DATE_EPOCH` environment variable no longer overrides the ++value of the *invalidation_mode* argument to :func:`py_compile.compile`, and ++determines its default value instead. diff --git a/bpo34990-2038-problem-compileall.patch b/bpo34990-2038-problem-compileall.patch new file mode 100644 index 0000000..8a251f4 --- /dev/null +++ b/bpo34990-2038-problem-compileall.patch @@ -0,0 +1,115 @@ +From 9d3b6b2472f7c7ef841e652825de652bc8af85d7 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Tue, 24 Aug 2021 08:07:31 -0700 +Subject: [PATCH] [3.9] bpo-34990: Treat the pyc header's mtime in compileall + as an unsigned int (GH-19708) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +(cherry picked from commit bb21e28fd08f894ceff2405544a2f257d42b1354) + +Co-authored-by: Ammar Askar +Co-authored-by: Stéphane Wirtel +--- + Lib/compileall.py | 4 - + Lib/test/test_compileall.py | 23 +++++++++- + Lib/test/test_zipimport.py | 17 ++++--- + Misc/NEWS.d/next/Library/2020-04-24-20-39-38.bpo-34990.3SmL9M.rst | 2 + 4 files changed, 35 insertions(+), 11 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2020-04-24-20-39-38.bpo-34990.3SmL9M.rst + +--- a/Lib/compileall.py ++++ b/Lib/compileall.py +@@ -148,8 +148,8 @@ def compile_file(fullname, ddir=None, fo + if not force: + try: + mtime = int(os.stat(fullname).st_mtime) +- expect = struct.pack('<4sll', importlib.util.MAGIC_NUMBER, +- 0, mtime) ++ expect = struct.pack('<4sLL', importlib.util.MAGIC_NUMBER, ++ 0, mtime & 0xFFFF_FFFF) + with open(cfile, 'rb') as chandle: + actual = chandle.read(12) + if expect == actual: +--- a/Lib/test/test_compileall.py ++++ b/Lib/test/test_compileall.py +@@ -54,9 +54,28 @@ class CompileallTestsBase: + with open(self.bc_path, 'rb') as file: + data = file.read(12) + mtime = int(os.stat(self.source_path).st_mtime) +- compare = struct.pack('<4sll', importlib.util.MAGIC_NUMBER, 0, mtime) ++ compare = struct.pack('<4sLL', importlib.util.MAGIC_NUMBER, 0, ++ mtime & 0xFFFF_FFFF) + return data, compare + ++ def test_year_2038_mtime_compilation(self): ++ # Test to make sure we can handle mtimes larger than what a 32-bit ++ # signed number can hold as part of bpo-34990 ++ try: ++ os.utime(self.source_path, (2**32 - 1, 2**32 - 1)) ++ except (OverflowError, OSError): ++ self.skipTest("filesystem doesn't support timestamps near 2**32") ++ self.assertTrue(compileall.compile_file(self.source_path)) ++ ++ def test_larger_than_32_bit_times(self): ++ # This is similar to the test above but we skip it if the OS doesn't ++ # support modification times larger than 32-bits. ++ try: ++ os.utime(self.source_path, (2**35, 2**35)) ++ except (OverflowError, OSError): ++ self.skipTest("filesystem doesn't support large timestamps") ++ self.assertTrue(compileall.compile_file(self.source_path)) ++ + def recreation_check(self, metadata): + """Check that compileall recreates bytecode when the new metadata is + used.""" +@@ -75,7 +94,7 @@ class CompileallTestsBase: + + def test_mtime(self): + # Test a change in mtime leads to a new .pyc. +- self.recreation_check(struct.pack('<4sll', importlib.util.MAGIC_NUMBER, ++ self.recreation_check(struct.pack('<4sLL', importlib.util.MAGIC_NUMBER, + 0, 1)) + + def test_magic_number(self): +--- a/Lib/test/test_zipimport.py ++++ b/Lib/test/test_zipimport.py +@@ -34,14 +34,9 @@ raise_src = 'def do_raise(): raise TypeE + + def make_pyc(co, mtime, size): + data = marshal.dumps(co) +- if type(mtime) is type(0.0): +- # Mac mtimes need a bit of special casing +- if mtime < 0x7fffffff: +- mtime = int(mtime) +- else: +- mtime = int(-0x100000000 + int(mtime)) + pyc = (importlib.util.MAGIC_NUMBER + +- struct.pack(" +Date: Mon, 5 Jun 2017 17:33:33 +0200 +Subject: [PATCH] bpo-36302: Sort list of sources + +when building packages (e.g. for openSUSE Linux) +(random) filesystem order of input files +influences ordering of functions in the output .so files. +Thus without the patch, builds (in disposable VMs) would usually differ. + +Without this patch, all callers have to be patched individually +https://github.com/dugsong/libdnet/pull/42 +https://github.com/sass/libsass-python/pull/212 +https://github.com/tahoe-lafs/pycryptopp/pull/41 +https://github.com/yt-project/yt/pull/2206 +https://github.com/pyproj4/pyproj/pull/142 +https://github.com/pytries/datrie/pull/49 +https://github.com/Roche/pyreadstat/pull/37 +but that is an infinite effort. + +See https://reproducible-builds.org/ for why this matters. +--- + Lib/distutils/command/build_ext.py | 3 ++- + .../next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst + +diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py +index 2d7cdf063f01..38bb8fd93c27 100644 +--- a/Lib/distutils/command/build_ext.py ++++ b/Lib/distutils/command/build_ext.py +@@ -490,7 +490,8 @@ def build_extension(self, ext): + "in 'ext_modules' option (extension '%s'), " + "'sources' must be present and must be " + "a list of source filenames" % ext.name) +- sources = list(sources) ++ # sort to make the resulting .so file build reproducible ++ sources = sorted(sources) + + ext_path = self.get_ext_fullpath(ext.name) + depends = sources + ext.depends +diff --git a/Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst b/Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst +new file mode 100644 +index 000000000000..fe01b5915d5d +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst +@@ -0,0 +1,2 @@ ++distutils sorts source file lists so that Extension .so files ++build more reproducibly by default diff --git a/bpo44426-complex-keyword-sphinx.patch b/bpo44426-complex-keyword-sphinx.patch new file mode 100644 index 0000000..ed23189 --- /dev/null +++ b/bpo44426-complex-keyword-sphinx.patch @@ -0,0 +1,44 @@ +From 29b463879b71a3ade67541c34daafb2929269fc4 Mon Sep 17 00:00:00 2001 +From: Mark Dickinson +Date: Wed, 16 Jun 2021 18:43:49 +0100 +Subject: [PATCH] bpo-44426: Use of 'complex' as a C variable name confuses + Sphinx; change it to 'num'. (GH-26744) (cherry picked from commit + 7247f6f433846c6e37308a550e8e5eb6be379856) + +Co-authored-by: Mark Dickinson +--- + Doc/c-api/complex.rst | 4 ++-- + Doc/c-api/object.rst | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/Doc/c-api/complex.rst ++++ b/Doc/c-api/complex.rst +@@ -46,9 +46,9 @@ pointers. This is consistent throughout + :c:type:`Py_complex` representation. + + +-.. c:function:: Py_complex _Py_c_neg(Py_complex complex) ++.. c:function:: Py_complex _Py_c_neg(Py_complex num) + +- Return the negation of the complex number *complex*, using the C ++ Return the negation of the complex number *num*, using the C + :c:type:`Py_complex` representation. + + +--- a/Doc/c-api/object.rst ++++ b/Doc/c-api/object.rst +@@ -483,12 +483,12 @@ Object Protocol + returned. This is the equivalent to the Python expression ``len(o)``. + + +-.. c:function:: Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t default) ++.. c:function:: Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t def_size) + + Return an estimated length for the object *o*. First try to return its + actual length, then an estimate using :meth:`~object.__length_hint__`, and + finally return the default value. On error return ``-1``. This is the +- equivalent to the Python expression ``operator.length_hint(o, default)``. ++ equivalent to the Python expression ``operator.length_hint(o, def_size)``. + + .. versionadded:: 3.4 + diff --git a/bso1227999-reproducible-builds.patch b/bso1227999-reproducible-builds.patch new file mode 100644 index 0000000..b85f4b8 --- /dev/null +++ b/bso1227999-reproducible-builds.patch @@ -0,0 +1,37 @@ +From ac2b8869724d7a57d9b5efbdce2f20423214e8bb Mon Sep 17 00:00:00 2001 +From: "Bernhard M. Wiedemann" +Date: Tue, 16 Jul 2024 21:39:33 +0200 +Subject: [PATCH] Allow to override build date with SOURCE_DATE_EPOCH + +to make builds reproducible. +See https://reproducible-builds.org/ for why this is good +and https://reproducible-builds.org/specs/source-date-epoch/ +for the definition of this variable. +--- + Doc/conf.py | 3 ++- + Doc/library/functions.rst | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/Doc/conf.py ++++ b/Doc/conf.py +@@ -78,7 +78,8 @@ html_short_title = '%s Documentation' % + + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, + # using the given strftime format. +-html_last_updated_fmt = '%b %d, %Y' ++html_time = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) ++html_last_updated_fmt = time.strftime('%b %d, %Y (%H:%M UTC)', time.gmtime(html_time)) + + # Path to find HTML templates. + templates_path = ['tools/templates'] +--- a/Doc/library/functions.rst ++++ b/Doc/library/functions.rst +@@ -1238,7 +1238,7 @@ are always available. They are listed h + (where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`, + and :mod:`shutil`. + +- .. audit-event:: open file,mode,flags open ++ .. audit-event:: open path,mode,flags open + + The ``mode`` and ``flags`` arguments may have been modified or inferred from + the original call. diff --git a/decimal-3.8.patch b/decimal-3.8.patch new file mode 100644 index 0000000..3cf0b30 --- /dev/null +++ b/decimal-3.8.patch @@ -0,0 +1,36 @@ +--- + Modules/_decimal/_decimal.c | 4 ++-- + setup.py | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/Modules/_decimal/_decimal.c ++++ b/Modules/_decimal/_decimal.c +@@ -3284,7 +3284,7 @@ dec_format(PyObject *dec, PyObject *args + } + else { + size_t n = strlen(spec.dot); +- if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) { ++ if (n > 1 || (n == 1 && !isascii((unsigned char)spec.dot[0]))) { + /* fix locale dependent non-ascii characters */ + dot = dotsep_as_utf8(spec.dot); + if (dot == NULL) { +@@ -3293,7 +3293,7 @@ dec_format(PyObject *dec, PyObject *args + spec.dot = PyBytes_AS_STRING(dot); + } + n = strlen(spec.sep); +- if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) { ++ if (n > 1 || (n == 1 && !isascii((unsigned char)spec.sep[0]))) { + /* fix locale dependent non-ascii characters */ + sep = dotsep_as_utf8(spec.sep); + if (sep == NULL) { +--- a/setup.py ++++ b/setup.py +@@ -2055,7 +2055,7 @@ class PyBuildExt(build_ext): + undef_macros = [] + if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"): + include_dirs = [] +- libraries = [':libmpdec.so.2'] ++ libraries = ['mpdec'] + sources = ['_decimal/_decimal.c'] + depends = ['_decimal/docstrings.h'] + else: diff --git a/distutils-reproducible-compile.patch b/distutils-reproducible-compile.patch new file mode 100644 index 0000000..f290b8e --- /dev/null +++ b/distutils-reproducible-compile.patch @@ -0,0 +1,11 @@ +--- a/Lib/distutils/util.py ++++ b/Lib/distutils/util.py +@@ -432,7 +432,7 @@ byte_compile(files, optimize=%r, force=% + else: + from py_compile import compile + +- for file in py_files: ++ for file in sorted(py_files): + if file[-3:] != ".py": + # This lets us be lazy and not filter filenames in + # the "install_lib" command. diff --git a/gh120226-fix-sendfile-test-kernel-610.patch b/gh120226-fix-sendfile-test-kernel-610.patch new file mode 100644 index 0000000..15cdd6b --- /dev/null +++ b/gh120226-fix-sendfile-test-kernel-610.patch @@ -0,0 +1,31 @@ +From 1b3f6523a5c83323cdc44031b33a1c062e5dc698 Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao +Date: Fri, 7 Jun 2024 23:51:32 +0800 +Subject: [PATCH] gh-120226: Fix + test_sendfile_close_peer_in_the_middle_of_receiving on Linux >= 6.10 + (GH-120227) + +The worst case is that the kernel buffers 17 pages with a page size of 64k. +(cherry picked from commit a7584245661102a5768c643fbd7db8395fd3c90e) + +Co-authored-by: Xi Ruoyao +--- + Lib/test/test_asyncio/test_sendfile.py | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/Lib/test/test_asyncio/test_sendfile.py ++++ b/Lib/test/test_asyncio/test_sendfile.py +@@ -86,9 +86,10 @@ class MyProto(asyncio.Protocol): + + class SendfileBase: + +- # 128 KiB plus small unaligned to buffer chunk +- DATA = b"SendfileBaseData" * (1024 * 8 + 1) +- ++ # Linux >= 6.10 seems buffering up to 17 pages of data. ++ # So DATA should be large enough to make this test reliable even with a ++ # 64 KiB page configuration. ++ DATA = b"x" * (1024 * 17 * 64 + 1) + # Reduce socket buffer size to test on relative small data sets. + BUF_SIZE = 4 * 1024 # 4 KiB + diff --git a/idle3.appdata.xml b/idle3.appdata.xml new file mode 100644 index 0000000..554b7c4 --- /dev/null +++ b/idle3.appdata.xml @@ -0,0 +1,35 @@ + + + + + idle3.desktop + IDLE3 + CC0 + Python-2.0 + Python 3 Integrated Development and Learning Environment + +

+ IDLE is Python’s Integrated Development and Learning Environment. + The GUI is uniform between Windows, Unix, and Mac OS X. + IDLE provides an easy way to start writing, running, and debugging + Python code. +

+

+ IDLE is written in pure Python, and uses the tkinter GUI toolkit. + It provides: +

+
    +
  • a Python shell window (interactive interpreter) with colorizing of code input, output, and error messages,
  • +
  • a multi-window text editor with multiple undo, Python colorizing, smart indent, call tips, auto completion, and other features,
  • +
  • search within any window, replace within editor windows, and search through multiple files (grep),
  • +
  • a debugger with persistent breakpoints, stepping, and viewing of global and local namespaces.
  • +
+
+ https://docs.python.org/3/library/idle.html + + http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-main-window.png + http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-class-browser.png + http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-code-viewer.png + + zbyszek@in.waw.pl +
diff --git a/idle3.desktop b/idle3.desktop new file mode 100644 index 0000000..43f5a4c --- /dev/null +++ b/idle3.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Version=1.0 +Name=IDLE 3 +GenericName=Python 3 IDE +Comment=Python 3 Integrated Development and Learning Environment +Exec=idle3 %F +TryExec=idle3 +Terminal=false +Type=Application +Icon=idle3 +Categories=Development;IDE; +MimeType=text/x-python; diff --git a/import_failed.map b/import_failed.map new file mode 100644 index 0000000..351fccf --- /dev/null +++ b/import_failed.map @@ -0,0 +1,7 @@ +python38-curses: curses _curses _curses_panel +python38-dbm: dbm _dbm _gdbm +python38-idle: idlelib +python38-testsuite: test _ctypes_test _testbuffer _testcapi _testinternalcapi _testimportmultiple _testmultiphase xxlimited +python38-tk: tkinter _tkinter +python38-tools: turtledemo +python38: sqlite3 readline _sqlite3 nis diff --git a/import_failed.py b/import_failed.py new file mode 100644 index 0000000..258b5a5 --- /dev/null +++ b/import_failed.py @@ -0,0 +1,23 @@ +import sys, os +from sysconfig import get_path + +failed_map_path = os.path.join(get_path('stdlib'), '_import_failed', 'import_failed.map') + +if __spec__: + failed_name = __spec__.name +else: + failed_name = __name__ + +with open(failed_map_path) as fd: + for line in fd: + package = line.split(':')[0] + imports = line.split(':')[1] + if failed_name in imports: + raise ImportError(f"""Module '{failed_name}' is not installed. +Use: + sudo zypper install {package} +to install it.""") + +raise ImportError(f"""Module '{failed_name}' is not installed. +It is supposed to be part of python3 distribution, but missing from failed import map. +Please file a bug on the SUSE Bugzilla.""") diff --git a/macros.python3 b/macros.python3 new file mode 100644 index 0000000..37a501e --- /dev/null +++ b/macros.python3 @@ -0,0 +1,30 @@ +# macros for the primary python3 providing python flavor +%have_python3 1 + +# commented out legacy macro definitions +#py3_prefix /usr +#py3_incdir /usr/include/python3.5m +#py3_ver 3.5 + +# these should now be provided by macros.python_all +#python3_sitearch /usr/lib64/python3.5/site-packages +#python3_sitelib /usr/lib/python3.5/site-packages +#python3_version 3.5 + +# hard to say if anyone ever used these? +#py3_soflags cpython-35m-x86_64-linux-gnu +#py3_abiflags m +%cpython3_soabi %(python3 -c "import sysconfig; print(sysconfig.get_config_var('SOABI'))") +%py3_soflags %cpython3_soabi + +# compilation macros that might be in use somewhere +%py3_compile(O) \ +find %1 -name '*.pyc' -exec rm -f {} ";"\ +python3 -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1\ +%{-O:\ +find %1 -name '*.pyo' -exec rm -f {} ";"\ +python3 -O -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1\ +} + +%python3_default %(s=$(rpm -qf /usr/bin/python3); echo ${s%%%%-*}) +%default_python3 %(s=$(rpm -qf /usr/bin/python3); echo ${s%%%%-*}) diff --git a/platlibdir-in-sys.patch b/platlibdir-in-sys.patch new file mode 100644 index 0000000..b9d25f5 --- /dev/null +++ b/platlibdir-in-sys.patch @@ -0,0 +1,124 @@ +--- + Include/cpython/initconfig.h | 1 + + Lib/test/test_embed.py | 1 + + Makefile.pre.in | 5 +++++ + Python/initconfig.c | 21 +++++++++++++++++++++ + Python/sysmodule.c | 1 + + 5 files changed, 29 insertions(+) + +--- a/Include/cpython/initconfig.h ++++ b/Include/cpython/initconfig.h +@@ -381,6 +381,7 @@ typedef struct { + wchar_t *base_prefix; /* sys.base_prefix */ + wchar_t *exec_prefix; /* sys.exec_prefix */ + wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ ++ wchar_t *platlibdir; /* sys.platlibdir */ + + /* --- Parameter only used by Py_Main() ---------- */ + +--- a/Lib/test/test_embed.py ++++ b/Lib/test/test_embed.py +@@ -382,6 +382,7 @@ class InitConfigTests(EmbeddingTestsMixi + 'exec_prefix': GET_DEFAULT_CONFIG, + 'base_exec_prefix': GET_DEFAULT_CONFIG, + 'module_search_paths': GET_DEFAULT_CONFIG, ++ 'platlibdir': sys.platlibdir, + + 'site_import': 1, + 'bytes_warning': 0, +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -811,6 +811,11 @@ Python/sysmodule.o: $(srcdir)/Python/sys + $(MULTIARCH_CPPFLAGS) \ + -o $@ $(srcdir)/Python/sysmodule.c + ++Python/initconfig.o: $(srcdir)/Python/initconfig.c ++ $(CC) -c $(PY_CORE_CFLAGS) \ ++ -DPLATLIBDIR='"$(platsubdir)"' \ ++ -o $@ $(srcdir)/Python/initconfig.c ++ + $(IO_OBJS): $(IO_H) + + .PHONY: regen-grammar +--- a/Python/initconfig.c ++++ b/Python/initconfig.c +@@ -596,6 +596,7 @@ PyConfig_Clear(PyConfig *config) + CLEAR(config->base_prefix); + CLEAR(config->exec_prefix); + CLEAR(config->base_exec_prefix); ++ CLEAR(config->platlibdir); + + CLEAR(config->filesystem_encoding); + CLEAR(config->filesystem_errors); +@@ -834,6 +835,7 @@ _PyConfig_Copy(PyConfig *config, const P + COPY_WSTR_ATTR(base_prefix); + COPY_WSTR_ATTR(exec_prefix); + COPY_WSTR_ATTR(base_exec_prefix); ++ COPY_WSTR_ATTR(platlibdir); + + COPY_ATTR(site_import); + COPY_ATTR(bytes_warning); +@@ -935,6 +937,7 @@ config_as_dict(const PyConfig *config) + SET_ITEM_WSTR(base_prefix); + SET_ITEM_WSTR(exec_prefix); + SET_ITEM_WSTR(base_exec_prefix); ++ SET_ITEM_WSTR(platlibdir); + SET_ITEM_INT(site_import); + SET_ITEM_INT(bytes_warning); + SET_ITEM_INT(inspect); +@@ -1336,6 +1339,14 @@ config_read_env_vars(PyConfig *config) + config->malloc_stats = 1; + } + ++ if(config->platlibdir == NULL) { ++ status = CONFIG_GET_ENV_DUP(config, &config->platlibdir, ++ L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR"); ++ if (_PyStatus_EXCEPTION(status)) { ++ return status; ++ } ++ } ++ + if (config->pythonpath_env == NULL) { + status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env, + L"PYTHONPATH", "PYTHONPATH"); +@@ -1786,6 +1797,14 @@ config_read(PyConfig *config) + } + } + ++ if(config->platlibdir == NULL) { ++ status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR, ++ "PLATLIBDIR macro"); ++ if (_PyStatus_EXCEPTION(status)) { ++ return status; ++ } ++ } ++ + if (config->_install_importlib) { + status = _PyConfig_InitPathConfig(config); + if (_PyStatus_EXCEPTION(status)) { +@@ -2565,6 +2584,7 @@ PyConfig_Read(PyConfig *config) + assert(config->exec_prefix != NULL); + assert(config->base_exec_prefix != NULL); + } ++ assert(config->platlibdir != NULL); + assert(config->filesystem_encoding != NULL); + assert(config->filesystem_errors != NULL); + assert(config->stdio_encoding != NULL); +@@ -2715,6 +2735,7 @@ _Py_DumpPathConfig(PyThreadState *tstate + DUMP_SYS(_base_executable); + DUMP_SYS(base_prefix); + DUMP_SYS(base_exec_prefix); ++ DUMP_SYS(platlibdir); + DUMP_SYS(executable); + DUMP_SYS(prefix); + DUMP_SYS(exec_prefix); +--- a/Python/sysmodule.c ++++ b/Python/sysmodule.c +@@ -2981,6 +2981,7 @@ _PySys_InitMain(_PyRuntimeState *runtime + SET_SYS_FROM_WSTR("base_prefix", config->base_prefix); + SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix); + SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix); ++ SET_SYS_FROM_WSTR("platlibdir", config->platlibdir); + + if (config->pycache_prefix != NULL) { + SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); diff --git a/pre_checkin.sh b/pre_checkin.sh new file mode 100644 index 0000000..a2cf992 --- /dev/null +++ b/pre_checkin.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +export LC_ALL=C + +master=python*.spec + +# create import_failed.map from package definitions +pkgname=$(grep python_pkg_name $master |grep define |awk -F' ' '{print $3}') +MAPFILE=import_failed.map +function new_map_line () { + package=$1 + package=$(echo $1 |sed -e "s:%{python_pkg_name}:$pkgname:") + modules=$2 + if [ -z "$package" -o -z "$modules" ]; then + return + fi + if [[ "$package" =~ "-base" ]]; then + return + fi + echo "$package:$modules" >> $MAPFILE.tmp +} + +for spec in *.spec; do + basename=${spec%.spec} + package= + modules= + while read line; do + case $line in + "%files -n "*) + new_map_line $package "$modules" + package=${line#"%files -n "} + modules= + ;; + "%files "*) + new_map_line $package "$modules" + package=$basename-${line#"%files "} + modules= + ;; + "%files") + new_map_line $package "$modules" + package=$basename + modules= + ;; + "%{sitedir}/config-"*) + # ignore + ;; + "%{sitedir}/"*) + word=${line#"%{sitedir}/"} + if ! echo $word | grep -q /; then + modules="$modules $word" + fi + ;; + "%{dynlib "*"}") + word=${line#"%{dynlib "} + word=${word%"}"} + modules="$modules $word" + ;; + esac + done < $spec + new_map_line $package "$modules" +done + +cat $MAPFILE.tmp |sort -u > $MAPFILE +rm $MAPFILE.tmp + +# run test inclusion check +tar xJf Python-*.xz +python3 skipped_tests.py + +# generate baselibs.conf +VERSION=$(grep ^Version $master|awk -F':' '{print $2}' |sed -e 's/ //g') +python_version=${VERSION:0:3} # 3.3 +python_version_abitag=${python_version//./} # 33 +python_version_soname=${python_version//./_} # 3_3 +echo "$pkgname-base" > baselibs.conf +echo "$pkgname" >> baselibs.conf +echo "libpython$python_version_soname-1_0" >> baselibs.conf + diff --git a/python-3.3.0b1-fix_date_time_compiler.patch b/python-3.3.0b1-fix_date_time_compiler.patch new file mode 100644 index 0000000..1800adc --- /dev/null +++ b/python-3.3.0b1-fix_date_time_compiler.patch @@ -0,0 +1,25 @@ +--- + Makefile.pre.in | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -758,11 +758,18 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \ + $(DTRACE_OBJS) \ + $(srcdir)/Modules/getbuildinfo.c + $(CC) -c $(PY_CORE_CFLAGS) \ ++ -DDATE="\"`date -u -r Makefile.pre.in +"%b %d %Y"`\"" \ ++ -DTIME="\"`date -u -r Makefile.pre.in +"%T"`\"" \ + -DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \ + -DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \ + -DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \ + -o $@ $(srcdir)/Modules/getbuildinfo.c + ++Python/getcompiler.o: $(srcdir)/Python/getcompiler.c Makefile ++ $(CC) -c $(PY_CORE_CFLAGS) \ ++ -DCOMPILER='"[GCC]"' \ ++ -o $@ $(srcdir)/Python/getcompiler.c ++ + Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile + $(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \ + -DPREFIX='"$(prefix)"' \ diff --git a/python-3.3.0b1-localpath.patch b/python-3.3.0b1-localpath.patch new file mode 100644 index 0000000..f527f1f --- /dev/null +++ b/python-3.3.0b1-localpath.patch @@ -0,0 +1,15 @@ +--- + Lib/site.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -77,7 +77,7 @@ import io + import stat + + # Prefixes for site-packages; add additional prefixes like /usr/local here +-PREFIXES = [sys.prefix, sys.exec_prefix] ++PREFIXES = [sys.prefix, sys.exec_prefix, '/usr/local'] + # Enable per user site-packages directory + # set it to False to disable the feature or True to force the feature + ENABLE_USER_SITE = None diff --git a/python-3.3.0b1-test-posix_fadvise.patch b/python-3.3.0b1-test-posix_fadvise.patch new file mode 100644 index 0000000..d993fdd --- /dev/null +++ b/python-3.3.0b1-test-posix_fadvise.patch @@ -0,0 +1,11 @@ +--- a/Lib/test/test_posix.py ++++ b/Lib/test/test_posix.py +@@ -421,7 +421,7 @@ class PosixTester(unittest.TestCase): + def test_posix_fadvise(self): + fd = os.open(support.TESTFN, os.O_RDONLY) + try: +- posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED) ++ posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_RANDOM) + finally: + os.close(fd) + diff --git a/python.keyring b/python.keyring new file mode 100644 index 0000000..d4f24b4 --- /dev/null +++ b/python.keyring @@ -0,0 +1,664 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +Lrfee+7yz1F9N6mVsuyl21KxQV8PGw== +=r/zi +-----END PGP PUBLIC KEY BLOCK----- diff --git a/python3-imp-returntype.patch b/python3-imp-returntype.patch new file mode 100644 index 0000000..78f4d53 --- /dev/null +++ b/python3-imp-returntype.patch @@ -0,0 +1,53 @@ +From 7bd6f0e5500f778e940374237b94651f60ae1990 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Fri, 6 Jul 2018 21:00:45 -0700 +Subject: [PATCH] closes bpo-34056: Always return bytes from + _HackedGetData.get_data(). (GH-8130) + +* Always return bytes from _HackedGetData.get_data(). + +Ensure the imp.load_source shim always returns bytes by reopening the file in +binary mode if needed. Hash-based pycs have to receive the source code in bytes. + +It's tempting to change imp.get_suffixes() to always return 'rb' as a mode, but +that breaks some stdlib tests and likely 3rdparty code, too. +(cherry picked from commit b0274f2cddd36b49fe5080efbe160277ef546471) + +Co-authored-by: Benjamin Peterson +--- + Lib/imp.py | 13 ++++++------- + Lib/test/test_imp.py | 15 +++++++++++++++ + .../2018-07-05-22-45-46.bpo-34056.86isrU.rst | 3 +++ + 3 files changed, 24 insertions(+), 7 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2018-07-05-22-45-46.bpo-34056.86isrU.rst + +--- a/Lib/test/test_imp.py ++++ b/Lib/test/test_imp.py +@@ -376,6 +376,20 @@ class ImportTests(unittest.TestCase): + mod = imp.load_module('mymod', file, path, description) + self.assertEqual(mod.x, 42) + ++ def test_find_and_load_checked_pyc(self): ++ # issue 34056 ++ with support.temp_cwd(): ++ with open('mymod.py', 'wb') as fp: ++ fp.write(b'x = 42\n') ++ py_compile.compile( ++ 'mymod.py', ++ doraise=True, ++ invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH, ++ ) ++ file, path, description = imp.find_module('mymod', path=['.']) ++ mod = imp.load_module('mymod', file, path, description) ++ self.assertEqual(mod.x, 42) ++ + + class ReloadTests(unittest.TestCase): + +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2018-07-05-22-45-46.bpo-34056.86isrU.rst +@@ -0,0 +1,3 @@ ++Ensure the loader shim created by ``imp.load_module`` always returns bytes ++from its ``get_data()`` function. This fixes using ``imp.load_module`` with ++:pep:`552` hash-based pycs. diff --git a/python38.changes b/python38.changes new file mode 100644 index 0000000..4f05907 --- /dev/null +++ b/python38.changes @@ -0,0 +1,2777 @@ +------------------------------------------------------------------- +Thu Sep 19 00:14:25 UTC 2024 - Matej Cepl + +- Update CVE-2023-52425-libexpat-2.6.0-backport.patch + so that it uses features sniffing, not just + comparing version number. Include also + support-expat-CVE-2022-25236-patched.patch. + +------------------------------------------------------------------- +Mon Sep 9 20:27:46 UTC 2024 - Matej Cepl + +- Update to 3.8.20: + - Tests + - gh-112769: The tests now correctly compare zlib version when + :const:`zlib.ZLIB_RUNTIME_VERSION` contains non-integer suffixes. For + example zlib-ng defines the version as ``1.3.0.zlib-ng``. + - gh-117187: Fix XML tests for vanilla Expat <2.6.0. + - Security + - gh-123678: Upgrade libexpat to 2.6.3 + - gh-121957: Fixed missing audit events around interactive use of Python, + now also properly firing for ``python -i``, as well as for ``python -m + asyncio``. The event in question is ``cpython.run_stdin``. + - gh-122133: Authenticate the socket connection for the + ``socket.socketpair()`` fallback on platforms where ``AF_UNIX`` is not + available like Windows. + Patch by Gregory P. Smith and Seth Larson + . Reported by Ellie + - gh-121285: Remove backtracking from tarfile header parsing for + ``hdrcharset``, PAX, and GNU sparse headers + (bsc#1230227, CVE-2024-6232). + - gh-118486: :func:`os.mkdir` on Windows now accepts *mode* of ``0o700`` to + restrict the new directory to the current user. This fixes CVE-2024-4030 + affecting :func:`tempfile.mkdtemp` in scenarios where the base temporary + directory is more permissive than the default. + - gh-114572: :meth:`ssl.SSLContext.cert_store_stats` and + :meth:`ssl.SSLContext.get_ca_certs` now correctly lock access to the + certificate store, when the :class:`ssl.SSLContext` is shared across + multiple threads (bsc#1226447, CVE-2024-0397). + - gh-116741: Update bundled libexpat to 2.6.2 + - Library + - gh-123270: Applied a more surgical fix for malformed payloads in + :class:`zipfile.Path` causing infinite loops (gh-122905) without breaking + contents using legitimate characters (bsc#1229704, CVE-2024-8088). + - gh-123067: Fix quadratic complexity in parsing ``"``-quoted cookie values + with backslashes by :mod:`http.cookies`. + - gh-121650: :mod:`email` headers with embedded newlines are now quoted on + output. The :mod:`~email.generator` will now refuse to serialize (write) + headers that are unsafely folded or delimited; see + :attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas + Bloemsaat and Petr Viktorin in :gh:`121650`; CVE-2024-6923, bsc#1228780). + - gh-113171: Fixed various false positives and false negatives in + * :attr:`ipaddress.IPv4Address.is_private` (see these docs for details) + * :attr:`ipaddress.IPv4Address.is_global` + * :attr:`ipaddress.IPv6Address.is_private` + * :attr:`ipaddress.IPv6Address.is_global` + Also in the corresponding :class:`ipaddress.IPv4Network` and + :class:`ipaddress.IPv6Network` attributes. + Fixes bsc#1226448 (CVE-2024-4032). + - gh-102988: :func:`email.utils.getaddresses` and + :func:`email.utils.parseaddr` now return ``('', '')`` 2-tuples in more + situations where invalid email addresses are encountered instead of + potentially inaccurate values. Add optional *strict* parameter to these + two functions: use ``strict=False`` to get the old behavior, accept + malformed inputs. ``getattr(email.utils, 'supports_strict_parsing', + False)`` can be use to check if the *strict* paramater is available. Patch + by Thomas Dwyer and Victor Stinner to improve the CVE-2023-27043 fix + (bsc#1210638). + - gh-67693: Fix :func:`urllib.parse.urlunparse` and + :func:`urllib.parse.urlunsplit` for URIs with path starting with multiple + slashes and no authority. Based on patch by Ashwin Ramaswami. + - Core and Builtins + - gh-112275: A deadlock involving ``pystate.c``'s ``HEAD_LOCK`` in + ``posixmodule.c`` at fork is now fixed. Patch by ChuBoning based on + previous Python 3.12 fix by Victor Stinner. + +- Remove upstreamed patches: + - old-libexpat.patch + - CVE-2024-4032-private-IP-addrs.patch + - CVE-2024-6923-email-hdr-inject.patch + - CVE-2024-6232-cookies-quad-complex.patch + - CVE-2023-27043-email-parsing-errors.patch + - CVE-2024-8088-inf-loop-zipfile_Path.patch + - CVE-2024-0397-memrace_ssl.SSLContext_cert_store.patch + +------------------------------------------------------------------- +Thu Sep 5 13:44:48 UTC 2024 - Matej Cepl + +- Add CVE-2024-6232-cookies-quad-complex.patch to avoid quadratic + complexity in parsing "-quoted cookie values with backslashes + (bsc#1229596, CVE-2024-6232). + +------------------------------------------------------------------- +Mon Sep 2 09:44:26 UTC 2024 - Matej Cepl + +- Add gh120226-fix-sendfile-test-kernel-610.patch to avoid + failing test_sendfile_close_peer_in_the_middle_of_receiving + tests on Linux >= 6.10 (GH-120227). + +------------------------------------------------------------------- +Wed Aug 28 16:54:34 UTC 2024 - Matej Cepl + +- Add CVE-2024-8088-inf-loop-zipfile_Path.patch to prevent + malformed payload to cause infinite loops in zipfile.Path + (bsc#1229704, CVE-2024-8088). + +------------------------------------------------------------------- +Thu Aug 8 19:30:36 UTC 2024 - Matej Cepl + +- Adding bso1227999-reproducible-builds.patch fixing bsc#1227999 + adding reproducibility patches from gh#python/cpython!121872 + and gh#python/cpython!121883. +- Add CVE-2024-6923-email-hdr-inject.patch to prevent email + header injection due to unquoted newlines (bsc#1228780, + CVE-2024-6923). +- Add CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch removing + support for anything but OpenSSL 1.1.1 or newer (bsc#1227233, + CVE-2024-5642). +- %{profileopt} variable is set according to the variable + %{do_profiling} (bsc#1227999) + +------------------------------------------------------------------- +Mon Jul 22 21:20:54 UTC 2024 - Matej Cepl + +- Remove %suse_update_desktop_file macro as it is not useful any + more. + +------------------------------------------------------------------- +Mon Jul 15 12:17:33 UTC 2024 - Matej Cepl + +- Stop using %%defattr, it seems to be breaking proper executable + attributes on /usr/bin/ scripts (bsc#1227378). + +------------------------------------------------------------------- +Tue Jun 25 21:57:40 UTC 2024 - Matej Cepl + +- Add CVE-2024-4032-private-IP-addrs.patch to fix bsc#1226448 + (CVE-2024-4032) rearranging definition of private v global IP + addresses. + +------------------------------------------------------------------- +Fri Jun 21 09:44:24 UTC 2024 - Matej Cepl + +- Add CVE-2024-0397-memrace_ssl.SSLContext_cert_store.patch + fixing bsc#1226447 (CVE-2024-0397) by removing memory race + condition in ssl.SSLContext certificate store methods. + +------------------------------------------------------------------- +Sun Mar 24 00:43:14 UTC 2024 - Matej Cepl + +- Add old-libexpat.patch making the test suite work with + libexpat < 2.6.0 (gh#python/cpython#117187). + +------------------------------------------------------------------- +Thu Mar 21 20:29:12 UTC 2024 - Matej Cepl + +- Update to 3.8.19: + - Security + - gh-115398: Allow controlling Expat >=2.6.0 reparse deferral + (CVE-2023-52425, bsc#1219559) by adding five new methods: + xml.etree.ElementTree.XMLParser.flush() + xml.etree.ElementTree.XMLPullParser.flush() + xml.parsers.expat.xmlparser.GetReparseDeferralEnabled() + xml.parsers.expat.xmlparser.SetReparseDeferralEnabled() + xml.sax.expatreader.ExpatParser.flush() + - gh-115399: Update bundled libexpat to 2.6.0 + - gh-113659: Skip .pth files with names starting with a dot + or hidden file attribute. + - Core and Builtins + - gh-102388: Fix a bug where iso2022_jp_3 and iso2022_jp_2004 + codecs read out of bounds + - Library + - gh-115197: urllib.request no longer resolves the hostname + before checking it against the system’s proxy bypass list + on macOS and Windows. + - gh-115133: Fix tests for XMLPullParser with Expat 2.6.0. + - gh-81194: Fix a crash in socket.if_indextoname() with + specific value (UINT_MAX). Fix an integer overflow in + socket.if_indextoname() on 64-bit non-Windows platforms. + - gh-109858: Protect zipfile from “quoted-overlap” + zipbomb. It now raises BadZipFile when try to read an entry + that overlaps with other entry or central directory + (CVE-2024-0450, bsc#1221854). + - gh-107077: Seems that in some conditions, OpenSSL will + return SSL_ERROR_SYSCALL instead of SSL_ERROR_SSL + when a certification verification has failed, but + the error parameters will still contain ERR_LIB_SSL + and SSL_R_CERTIFICATE_VERIFY_FAILED. We are now + detecting this situation and raising the appropiate + ssl.SSLCertVerificationError. Patch by Pablo Galindo + - gh-91133: Fix a bug in tempfile.TemporaryDirectory cleanup, + which now no longer dereferences symlinks when working + around file system permission errors (CVE-2023-6597, + bsc#1219666). + - Documentation + - gh-115399: Document CVE-2023-52425 of Expat <2.6.0 under + “XML vulnerabilities”. + - Tests + - gh-108310: SSL tests for pre-handshake close were + previously not enabled on Python 3.8 due to an incorrect + backport. This is now fixed. Patch by Lumír Balhar. +- Remove upstreamed patches: + - CVE-2023-6597-TempDir-cleaning-symlink.patch + - libexpat260.patch +- Refreshed patches: + - CVE-2019-5010-null-defer-x509-cert-DOS.patch + - F00102-lib64.patch + - F00251-change-user-install-location.patch + - python-3.3.0b1-localpath.patch + - skip_random_failing_tests.patch + - SUSE-FEDORA-multilib.patch + +------------------------------------------------------------------- +Wed Mar 6 14:13:58 UTC 2024 - Pedro Monreal + +- Use the system-wide crypto-policies [bsc#1211301] + * Use the system default cipher list instead of hardcoded values + * Add the --with-ssl-default-suites=openssl configure option + +------------------------------------------------------------------- +Fri Feb 23 01:06:42 UTC 2024 - Matej Cepl + +- (bsc#1219666, CVE-2023-6597) Add + CVE-2023-6597-TempDir-cleaning-symlink.patch (patch from + gh#python/cpython!99930) fixing symlink bug in cleanup of + tempfile.TemporaryDirectory. + +------------------------------------------------------------------- +Tue Feb 20 22:14:02 UTC 2024 - Matej Cepl + +- Remove double definition of /usr/bin/idle%%{version} in + %%files. + +------------------------------------------------------------------- +Thu Feb 15 10:29:07 UTC 2024 - Daniel Garcia + +- Add upstream patch libexpat260.patch, Fix tests for XMLPullParser + with Expat 2.6.0, gh#python/cpython#115289 + +------------------------------------------------------------------- +Mon Dec 18 16:20:58 UTC 2023 - Matej Cepl + +- Refresh CVE-2023-27043-email-parsing-errors.patch to + gh#python/cpython!111116, fixing bsc#1210638 (CVE-2023-27043). +- Thus we can remove Revert-gh105127-left-tests.patch, which is + now useless. + +------------------------------------------------------------------- +Wed Sep 6 06:09:33 UTC 2023 - Daniel Garcia + +- Update to 3.8.18 (bsc#1214692): + - gh-108310: Fixed an issue where instances of ssl.SSLSocket were + vulnerable to a bypass of the TLS handshake and included + protections (like certificate verification) and treating sent + unencrypted data as if it were post-handshake TLS encrypted data. + Security issue reported as CVE-2023-40217 by Aapo Oksman. Patch by + Gregory P. Smith. + - gh-107845: tarfile.data_filter() now takes the location of + symlinks into account when determining their target, so it will no + longer reject some valid tarballs with + LinkOutsideDestinationError. + - gh-107565: Update multissltests and GitHub CI workflows to use + OpenSSL 1.1.1v, 3.0.10, and 3.1.2. + +------------------------------------------------------------------- +Thu Aug 3 14:53:38 UTC 2023 - Matej Cepl + +- IT MEANS THAT bsc#1210638 STILL HAS NOT BEEN FIXED! +- Add Revert-gh105127-left-tests.patch (gh#python/cpython!106941) + partially reverting CVE-2023-27043-email-parsing-errors.patch, + because of the regression in gh#python/cpython#106669. +- (bsc#1210638, CVE-2023-27043) Add + CVE-2023-27043-email-parsing-errors.patch, which detects email + address parsing errors and returns empty tuple to indicate the + parsing error (old API). (The patch is faulty, + gh#python/cpython#106669, but upstream decided not to just + revert it). + +------------------------------------------------------------------- +Wed Jun 28 16:57:46 UTC 2023 - Matej Cepl + +- Update to 3.8.17: + - gh-103142: The version of OpenSSL used in Windows and + Mac installers has been upgraded to 1.1.1u to address + CVE-2023-2650, CVE-2023-0465, CVE-2023-0466, CVE-2023-0464, + as well as CVE-2023-0286, CVE-2022-4303, and CVE-2022-4303 + fixed previously in 1.1.1t (gh-101727). + - gh-102153: urllib.parse.urlsplit() now strips leading C0 + control and space characters following the specification for + URLs defined by WHATWG in response to CVE-2023-24329 + (bsc#1208471). + - gh-99889: Fixed a security in flaw in uu.decode() that could + allow for directory traversal based on the input if no + out_file was specified. + - gh-104049: Do not expose the local on-disk + location in directory indexes produced by + http.client.SimpleHTTPRequestHandler. + - gh-103935: trace.__main__ now uses io.open_code() for files + to be executed instead of raw open(). + - gh-102953: The extraction methods in tarfile, and + shutil.unpack_archive(), have a new filter argument that + allows limiting tar features than may be surprising or + dangerous, such as creating files outside the destination + directory. See Extraction filters for details (fixing + CVE-2007-4559, bsc#1203750). +- Remove upstreamed patches: + - CVE-2023-24329-blank-URL-bypass.patch + - CVE-2007-4559-filter-tarfile_extractall.patch + +------------------------------------------------------------------- +Sat May 6 17:31:35 UTC 2023 - Matej Cepl + +- Add 99366-patch.dict-can-decorate-async.patch fixing + gh#python/cpython#98086 (backport from Python 3.10 patch in + gh#python/cpython!99366), fixing bsc#1211158. + +------------------------------------------------------------------- +Wed May 3 14:09:37 UTC 2023 - Matej Cepl + +- Add CVE-2007-4559-filter-tarfile_extractall.patch to fix + CVE-2007-4559 (bsc#1203750) by adding the filter for + tarfile.extractall (PEP 706). + +------------------------------------------------------------------- +Tue Apr 18 05:00:11 UTC 2023 - Steve Kowalik + +- Use python3 modules to build the documentation. + +------------------------------------------------------------------- +Wed Mar 1 14:43:31 UTC 2023 - Matej Cepl + +- Add CVE-2023-24329-blank-URL-bypass.patch (CVE-2023-24329, + bsc#1208471) blocklists bypass via the urllib.parse component + when supplying a URL that starts with blank characters + +------------------------------------------------------------------- +Tue Feb 21 11:34:49 UTC 2023 - Matej Cepl + +- Add provides for readline and sqlite3 to the main Python + package. + +------------------------------------------------------------------- +Fri Jan 27 15:00:21 UTC 2023 - Thorsten Kukuk + +- Disable NIS for new products, it's deprecated and gets removed + +------------------------------------------------------------------- +Fri Jan 13 08:04:11 UTC 2023 - Martin Liška + +- Suppress warnings for Sphinx 6.0+. + +------------------------------------------------------------------- +Thu Dec 8 10:32:15 UTC 2022 - Matej Cepl + +- Update to 3.8.16: + - python -m http.server no longer allows terminal + control characters sent within a garbage request to be + printed to the stderr server log. + This is done by changing the http.server + BaseHTTPRequestHandler .log_message method to replace control + characters with a \xHH hex escape before printing. + - Avoid publishing list of active per-interpreter + audit hooks via the gc module + - The IDNA codec decoder used on DNS hostnames by + socket or asyncio related name resolution functions no + longer involves a quadratic algorithm. This prevents a + potential CPU denial of service if an out-of-spec excessive + length hostname involving bidirectional characters were + decoded. Some protocols such as urllib http 3xx redirects + potentially allow for an attacker to supply such a + name (CVE-2022-45061). + - Update bundled libexpat to 2.5.0 + - Port XKCP’s fix for the buffer overflows in SHA-3 + (CVE-2022-37454). + - The deprecated mailcap module now refuses to inject + unsafe text (filenames, MIME types, parameters) into shell + commands. Instead of using such text, it will warn and act + as if a match was not found (or for test commands, as if the + test failed). +- Removed upstream patches: + - CVE-2022-37454-sha3-buffer-overflow.patch + - CVE-2022-45061-DoS-by-IDNA-decode.patch + +------------------------------------------------------------------- +Wed Nov 9 18:31:23 UTC 2022 - Matej Cepl + +- Add CVE-2022-45061-DoS-by-IDNA-decode.patch to avoid + CVE-2022-45061 (bsc#1205244) allowing DoS by IDNA decoding + extremely long domain names. + +------------------------------------------------------------------- +Fri Oct 28 19:43:13 UTC 2022 - Matej Cepl + +- Add CVE-2022-37454-sha3-buffer-overflow.patch to fix + bsc#1204577 (CVE-2022-37454, gh#python/cpython#98517) buffer + overflow in hashlib.sha3_* implementations (originally from the + XKCP library). + +------------------------------------------------------------------- +Fri Oct 21 10:14:03 UTC 2022 - Matej Cepl + +- Add 98437-sphinx.locale._-as-gettext-in-pyspecific.patch to + allow building of documentation with the latest Sphinx 5.3.0 + (gh#python/cpython#98366). + +------------------------------------------------------------------- +Thu Oct 20 11:49:44 UTC 2022 - Daniel Garcia + +- Add platlibdir-in-sys.patch to provide sys.platlibdir attribute. This is used + by python-setuptools in distutils.sysconfig.get_python_lib bsc#1204395 + +------------------------------------------------------------------- +Wed Oct 19 07:12:23 UTC 2022 - Matej Cepl + +- Update to 3.8.15: + - Fix multiplying a list by an integer (list *= int): detect + the integer overflow when the new allocated length is close + to the maximum size. + - Fix a shell code injection vulnerability in the + get-remote-certificate.py example script. The script no + longer uses a shell to run openssl commands. (originally + filed as CVE-2022-37460, later withdrawn) + - Fix command line parsing: reject -X int_max_str_digits option + with no value (invalid) when the PYTHONINTMAXSTRDIGITS + environment variable is set to a valid limit. + - When ValueError is raised if an integer is larger than the + limit, mention the sys.set_int_max_str_digits() function in + the error message. + - Update bundled libexpat to 2.4.9 + - Fixes a potential buffer overrun in msilib. + +------------------------------------------------------------------- +Sun Sep 11 09:07:38 UTC 2022 - Matej Cepl + +- Update to 3.8.14: + - (CVE-2020-10735, bsc#1203125). Converting between int + and str in bases other than 2 (binary), 4, 8 (octal), 16 + (hexadecimal), or 32 such as base 10 (decimal) now raises a + ValueError if the number of digits in string form is above a + limit to avoid potential denial of service attacks due to the + algorithmic complexity. + This new limit can be configured or disabled by environment + variable, command line flag, or sys APIs. See the integer + string conversion length limitation documentation. The + default limit is 4300 digits in string form. + - (CVE-2021-28861, bsc#1202624) http.server: Fix an open + redirection vulnerability in the HTTP server when an URI path + starts with //. Vulnerability discovered, and initial fix + proposed, by Hamza Avvan. + - Also other bugfixes: + - Fix contextvars HAMT implementation to handle iteration + over deep trees. The bug was discovered and fixed by Eli + Libman. See MagicStack/immutables#84 for more details. + - Fix ensurepip environment isolation for subprocess running + pip. + - Raise ProgrammingError instead of segfaulting on recursive + usage of cursors in sqlite3 converters. Patch by Sergey + Fedoseev. + - Add a new gh role to the documentation to link to GitHub + issues. + - Pin Jinja to a version compatible with Sphinx version + 2.4.4. + - test_ssl is now checking for supported TLS version and + protocols in more tests. + - Fix test case for OpenSSL 3.0.1 version. OpenSSL 3.0 uses + 0xMNN00PP0L. +- Removed upstreamed patches: + - CVE-2021-28861-double-slash-path.patch +- Readjusted patches: + - bpo-31046_ensurepip_honours_prefix.patch + - sphinx-update-removed-function.patch + +------------------------------------------------------------------- +Sat Sep 3 02:20:54 UTC 2022 - Matej Cepl + +- (bsc#1196784, CVE-2022-25236) Add patch + support-expat-CVE-2022-25236-patched.patch to allow working + with different versions of libexpat. + +------------------------------------------------------------------- +Thu Sep 1 04:20:04 UTC 2022 - Steve Kowalik + +- Add patch CVE-2021-28861-double-slash-path.patch: + * http.server: Fix an open redirection vulnerability in the HTTP server + when an URI path starts with //. (bsc#1202624, CVE-2021-28861) + +------------------------------------------------------------------- +Wed Aug 31 08:47:57 UTC 2022 - Matej Cepl + +- Add bpo34990-2038-problem-compileall.patch making compileall.py + compliant with year 2038 (bsc#1202666, gh#python/cpython#79171), + backport of fix to Python 3.8. +- Add conditional for requiring rpm-build-python, so we should be + compilable on SLE/Leap. + +------------------------------------------------------------------- +Thu Jul 21 14:19:54 UTC 2022 - Matej Cepl + +- Switch from %primary_interpreter to prjconf-defined + %primary_python (gh#openSUSE/python-rpm-macros#127). + +------------------------------------------------------------------- +Thu May 5 14:34:56 UTC 2022 - Matej Cepl + +- Switch primary_interpreter from python38 to python310 + +------------------------------------------------------------------- +Sat Mar 26 21:59:44 UTC 2022 - Matej Cepl + +- Update to 3.8.13: +Core and Builtins + bpo-46794: Bump up the libexpat version into 2.4.6 + bpo-46985: Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + bpo-46932: Update bundled libexpat to 2.4.7 + bpo-46811: Make test suite support Expat >=2.4.5 + bpo-46784: Fix libexpat symbols collisions with user + dynamically loaded or statically linked libexpat in embedded + Python. + bpo-46400: expat: Update libexpat from 2.4.1 to 2.4.4 + bpo-46474: In importlib.metadata.EntryPoint.pattern, avoid + potential REDoS by limiting ambiguity in consecutive + whitespace. + bpo-44849: Fix the os.set_inheritable() function on FreeBSD + 14 for file descriptor opened with the O_PATH flag: ignore + the EBADF error on ioctl(), fallback on the fcntl() + implementation. + bpo-41028: Language and version switchers, previously + maintained in every cpython branches, are now handled by + docsbuild-script. + bpo-45195: Fix test_readline.test_nonascii(): sometimes, the + newline character is not written at the end, so don’t + expect it in the output. + bpo-44949: Fix auto history tests of test_readline: + sometimes, the newline character is not written at the end, + so don’t expect it in the output. + bpo-45405: Prevent internal configure error when running + configure with recent versions of clang. +- Remove upstreamed patches: + - support-expat-245.patch + +------------------------------------------------------------------- +Tue Feb 22 05:53:06 UTC 2022 - Steve Kowalik + +- Add patch support-expat-245.patch: + * Support Expat >= 2.4.5 + +------------------------------------------------------------------- +Mon Nov 29 00:17:07 UTC 2021 - Matej Cepl + +- Remove shebangs from from python-base libraries in _libdir + (bsc#1193179). +- Readjust patches: + - bpo-31046_ensurepip_honours_prefix.patch + - decimal.patch + - python-3.3.0b1-fix_date_time_compiler.patch + +------------------------------------------------------------------- +Tue Oct 12 12:22:53 UTC 2021 - Dominique Leuenberger + +- BuildRequire rpm-build-python: The provider to inject python(abi) + has been moved there. rpm-build pulls rpm-build-python + automatically in when building anything against python3-base, but + this implies that the initial build of python3-base does not + trigger the automatic installation. + +------------------------------------------------------------------- +Tue Aug 31 01:18:08 UTC 2021 - Fusion Future + +- Update to 3.8.12 + * Complete list of changes is available at + https://docs.python.org/release/3.8.12/whatsnew/changelog.html + * Security + - bpo-42278: Replaced usage of tempfile.mktemp() with + TemporaryDirectory to avoid a potential race condition. + - bpo-44394: Update the vendored copy of libexpat to 2.4.1 + (from 2.2.8) to get the fix for the CVE-2013-0340 “Billion + Laughs” vulnerability. This copy is most used on Windows and + macOS. + - bpo-43124: Made the internal putcmd function in smtplib + sanitize input for presence of \r and \n characters to avoid + (unlikely) command injection. + - bpo-36384: ipaddress module no longer accepts any leading + zeros in IPv4 address strings. Leading zeros are ambiguous + and interpreted as octal notation by some libraries. For + example the legacy function socket.inet_aton() treats leading + zeros as octal notation. glibc implementation of modern + inet_pton() does not accept any leading zeros. For a while + the ipaddress module used to accept ambiguous leading zeros. +- Refreshed patch: + * decimal-3.8.patch + +------------------------------------------------------------------- +Fri Aug 27 12:00:12 UTC 2021 - Matej Cepl + +- Add decimal-3.8.patch to add building with --with-system-libmpdec + option (bsc#1189356). + +------------------------------------------------------------------- +Thu Aug 26 12:00:25 UTC 2021 - Andreas Schwab + +- test_faulthandler is still problematic under qemu linux-user emulation, + disable it there +- Reenable profileopt with qemu emulation, test_faulthandler is no longer + run during profiling + +------------------------------------------------------------------- +Tue Aug 10 00:25:26 UTC 2021 - Fusion Future + +- Update to 3.8.11 + * Security + - bpo-44022 (boo#1189241): mod:http.client now avoids + infinitely reading potential HTTP headers after a 100 + Continue status response from the server. + - bpo-43882: The presence of newline or tab characters in parts + of a URL could allow some forms of attacks. + Following the controlling specification for URLs defined by + WHATWG urllib.parse() now removes ASCII newlines and tabs + from URLs, preventing such attacks. + - bpo-42800: Audit hooks are now fired for frame.f_code, + traceback.tb_frame, and generator code/frame attribute + access. + * Core and Builtins + - bpo-44070: No longer eagerly makes import filenames absolute, + except for extension modules, which was introduced in 3.8.10. + * Library + - bpo-44061: Fix regression in previous release when calling + pkgutil.iter_modules() with a list of pathlib.Path objects + +------------------------------------------------------------------- +Mon Aug 2 12:35:43 UTC 2021 - Matej Cepl + +- Use versioned python-Sphinx to avoid dependency on other + version of Python (bsc#1183858). + +------------------------------------------------------------------- +Fri Jun 18 22:45:17 UTC 2021 - Matej Cepl + +- Add bpo44426-complex-keyword-sphinx.patch allowing generating + documentation with Sphinx 4 (bpo#44426). + +------------------------------------------------------------------- +Tue Jun 8 11:18:08 UTC 2021 - Dirk Müller + +- allow building against sphinx 3.x+ + +------------------------------------------------------------------- +Fri May 21 15:13:59 UTC 2021 - Matej Cepl + +- Stop providing "python" symbol (bsc#1185588), which means + python2 currently. + +------------------------------------------------------------------- +Wed May 5 15:29:30 UTC 2021 - Matej Cepl + +- Update to 3.8.10: + - Security + - bpo-43434: Creating a sqlite3.Connection object now also + produces a sqlite3.connect auditing event. Previously this + event was only produced by sqlite3.connect() calls. Patch + by Erlend E. Aasland. + - bpo-43472: Ensures interpreter-level audit hooks receive + the cpython.PyInterpreterState_New event when called + through the _xxsubinterpreters module. + - bpo-43075: Fix Regular Expression Denial of Service (ReDoS) + vulnerability in urllib.request.AbstractBasicAuthHandler. + The ReDoS-vulnerable regex has quadratic worst-case + complexity and it allows cause a denial of service when + identifying crafted invalid RFCs. This ReDoS issue is on + the client side and needs remote attackers to control the + HTTP server. + - Core and Builtins + - bpo-43105: Importlib now resolves relative paths when + creating module spec objects from file locations. + - bpo-42924: Fix bytearray repetition incorrectly copying + data from the start of the buffer, even if the data is + offset within the buffer (e.g. after reassigning a slice at + the start of the bytearray to a shorter byte string). + - Library + - bpo-43993: Update bundled pip to 21.1.1. + - bpo-43937: Fixed the turtle module working with non-default + root window. + - bpo-43930: Update bundled pip to 21.1 and setuptools to + 56.0.0 + - bpo-43920: OpenSSL 3.0.0: load_verify_locations() now + returns a consistent error message when cadata contains no + valid certificate. + - bpo-43607: urllib can now convert Windows paths with \\?\ + prefixes into URL paths. + - bpo-43284: platform.win32_ver derives the windows version + from sys.getwindowsversion().platform_version which in turn + derives the version from kernel32.dll (which can be of + a different version than Windows itself). Therefore change + the platform.win32_ver to determine the version using the + platform module’s _syscmd_ver private function to return an + accurate version. + - bpo-42248: [Enum] ensure exceptions raised in _missing__ + are released + - bpo-43799: OpenSSL 3.0.0: define OPENSSL_API_COMPAT 1.1.1 + to suppress deprecation warnings. Python requires OpenSSL + 1.1.1 APIs. + - bpo-43794: Add ssl.OP_IGNORE_UNEXPECTED_EOF constants + (OpenSSL 3.0.0) + - bpo-43789: OpenSSL 3.0.0: Don’t call the password callback + function a second time when first call has signaled an + error condition. + - bpo-43788: The header files for ssl error codes are now + OpenSSL version-specific. Exceptions will now show correct + reason and library codes. The make_ssl_data.py script has + been rewritten to use OpenSSL’s text file with error codes. + - bpo-43655: tkinter dialog windows are now recognized as + dialogs by window managers on macOS and X Window. + - bpo-43534: turtle.textinput() and turtle.numinput() create + now a transient window working on behalf of the canvas + window. + - bpo-43522: Fix problem with hostname_checks_common_name. + OpenSSL does not copy hostflags from struct SSL_CTX to + struct SSL. + - bpo-42967: Allow bytes separator argument in + urllib.parse.parse_qs and urllib.parse.parse_qsl when + parsing str query strings. Previously, this raised + a TypeError. + - bpo-43176: Fixed processing of a dataclass that inherits + from a frozen dataclass with no fields. It is now correctly + detected as an error. + - bpo-34463: Fixed discrepancy between traceback and the + interpreter in formatting of SyntaxError with lineno not + set (traceback was changed to match interpreter). + - bpo-41735: Fix thread locks in zlib module may go wrong in + rare case. Patch by Ma Lin. + - bpo-26053: Fixed bug where the pdb interactive run command + echoed the args from the shell command line, even if those + have been overridden at the pdb prompt. + - bpo-36470: Fix dataclasses with InitVars and replace(). + Patch by Claudiu Popa. + - bpo-28577: The hosts method on 32-bit prefix length + IPv4Networks and 128-bit prefix IPv6Networks now returns + a list containing the single Address instead of an empty + list. + - bpo-32745: Fix a regression in the handling of ctypes’ + ctypes.c_wchar_p type: embedded null characters would cause + a ValueError to be raised. Patch by Zackery Spytz. + - Documentation + - bpo-43959: The documentation on the PyContextVar C-API was + clarified. + - bpo-43938: Update dataclasses documentation to express that + FrozenInstanceError is derived from AttributeError. + - bpo-43739: Fixing the example code in + Doc/extending/extending.rst to declare and initialize the + pmodule variable to be of the right type. + - Tests + - bpo-43842: Fix a race condition in the SMTP test of + test_logging. Don’t close a file descriptor (socket) from + a different thread while asyncore.loop() is polling the + file descriptor. Patch by Victor Stinner. + - bpo-43811: Tests multiple OpenSSL versions on GitHub + Actions. Use ccache to speed up testing. + - bpo-43791: OpenSSL 3.0.0: Disable testing of legacy + protocols TLS 1.0 and 1.1. Tests are failing with + TLSV1_ALERT_INTERNAL_ERROR. + - IDLE + - bpo-43655: IDLE dialog windows are now recognized as + dialogs by window managers on macOS and X Window. + - C API + - bpo-43962: _PyInterpreterState_IDIncref() now calls + _PyInterpreterState_IDInitref() and always increments + id_refcount. Previously, calling + _xxsubinterpreters.get_current() could create an + id_refcount inconsistency when + a _xxsubinterpreters.InterpreterID object was deallocated. + Patch by Victor Stinner. +- Reapplied patches: + - CVE-2019-5010-null-defer-x509-cert-DOS.patch + - F00102-lib64.patch + - SUSE-FEDORA-multilib.patch + - bpo-31046_ensurepip_honours_prefix.patch + - python-3.3.0b1-fix_date_time_compiler.patch + +------------------------------------------------------------------- +Sun May 2 09:20:06 UTC 2021 - Ben Greiner + +- Make sure to close the import_failed.map file after the exception + has been raised in order to avoid ResourceWarnings when the + failing import is part of a try...except block. + +------------------------------------------------------------------- +Wed Apr 28 17:32:55 UTC 2021 - Matej Cepl + +- Update to 3.8.9: + - bpo#42988 (bsc#1183374) CVE-2021-3426: Remove the getfile + feature of the pydoc module which could be abused to read + arbitrary files on the disk (directory traversal + vulnerability). Moreover, even source code of Python modules + can contain sensitive data like passwords. Vulnerability + reported by David Schwörer. + - bpo-43285: ftplib no longer trusts the IP address value + returned from the server in response to the PASV command by + default. This prevents a malicious FTP server from using the + response to probe IPv4 address and port combinations on the + client network. + - Code that requires the former vulnerable behavior may set + a trust_server_pasv_ipv4_address attribute on their + ftplib.FTP instances to True to re-enable it. + - bpo-43439: Add audit hooks for gc.get_objects(), + gc.get_referrers() and gc.get_referents(). Patch by Pablo + Galindo. + - bpo-43660: Fix crash that happens when replacing sys.stderr + with a callable that can remove the object while an exception + is being printed. Patch by Pablo Galindo. + - bpo-35883: Python no longer fails at startup with a fatal + error if a command line argument contains an invalid Unicode + character. The Py_DecodeLocale() function now escapes byte + sequences which would be decoded as Unicode characters + outside the [U+0000; U+10ffff] range. + - bpo-43406: Fix a possible race condition where + PyErr_CheckSignals tries to execute a non-Python signal + handler. + - bpo-35930: Raising an exception raised in a “future” instance + will create reference cycles. + - bpo-43577: Fix deadlock when using ssl.SSLContext debug + callback with ssl.SSLContext.sni_callback(). + - bpo-43423: subprocess.communicate() no longer raises an + IndexError when there is an empty stdout or stderr IO buffer + during a timeout on Windows. + - bpo-27820: Fixed long-standing bug of smtplib.SMTP where + doing AUTH LOGIN with initial_response_ok=False will fail. + The cause is that SMTP.auth_login _always_ returns a password + if provided with a challenge string, thus non-compliant with + the standard for AUTH LOGIN. Also fixes bug with the test for + smtpd. + - bpo-43399: Fix ElementTree.extend not working on iterators + when using the Python implementation + - bpo-43316: The python -m gzip command line application now + properly fails when detecting an unsupported extension. It + exits with a non-zero exit code and prints an error message + to stderr. + - bpo-43260: Fix TextIOWrapper can not flush internal buffer + forever after very large text is written. + - bpo-42782: Fail fast in shutil.move() to avoid creating + destination directories on failure. + - bpo-37193: Fixed memory leak in socketserver.ThreadingMixIn + introduced in Python 3.7. + - bpo-43199: Answer “Why is there no goto?” in the Design and + History FAQ. + - bpo-43407: Clarified that a result from time.monotonic(), + time.perf_counter(), time.process_time(), or + time.thread_time() can be compared with the result from any + following call to the same function - not just the next + immediate call. + - bpo-27646: Clarify that ‘yield from ’ works with any + iterable, not just iterators. + - bpo-36346: Update some deprecated unicode APIs which are + documented as “will be removed in 4.0” to “3.12”. See PEP 623 + for detail. + - bpo-37945: Fix test_getsetlocale_issue1813() of test_locale: + skip the test if setlocale() fails. Patch by Victor Stinner. + - bpo-41561: Add workaround for Ubuntu’s custom OpenSSL + security level policy. + - bpo-43631: Update macOS, Windows, and CI to OpenSSL 1.1.1k. + - bpo-43617: Improve configure.ac: Check for presence of + autoconf-archive package and remove our copies of M4 macros. + - bpo-41837: Update macOS installer build to use OpenSSL + 1.1.1j. + - bpo-42225: Document that IDLE can fail on Unix either from + misconfigured IP masquerage rules or failure displaying + complex colored (non-ascii) characters. + - bpo-43283: Document why printing to IDLE’s Shell is often + slower than printing to a system terminal and that it can be + made faster by pre-formatting a single string before + printing. + +------------------------------------------------------------------- +Fri Feb 19 16:40:59 UTC 2021 - Matej Cepl + +- Update to 3.8.8: + - bpo#42938 (bsc#1181126): Avoid static buffers when computing + the repr of ctypes.c_double and ctypes.c_longdouble + values. This issue was assigned CVE-2021-3177. + - bpo#42967 (bsc#1182379): Fix web cache poisoning + vulnerability by defaulting the query args separator to &, + and allowing the user to choose a custom separator. This + issue was assigned CVE-2021-23336. +- Remove bsc1167501-invalid-alignment.patch and + CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch, which were included + into the upstream tarball. + +------------------------------------------------------------------- +Tue Feb 9 01:37:01 UTC 2021 - Steve Kowalik + +- Add Obsoletes for python3-base when primary interpreter is set to + properly replace it during upgrades. (bsc#1181324) + +------------------------------------------------------------------- +Fri Feb 5 15:35:29 UTC 2021 - Ben Greiner + +- Provide %have_ for all python flavors + gh#openSUSE/python-rpm-macros#96 +- Add %python3_default and %default_python3 for the primary python3 + flavor + +------------------------------------------------------------------- +Fri Jan 29 17:22:48 UTC 2021 - Matej Cepl + +- Add CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch fixing + bsc#1181126 (CVE-2021-3177) buffer overflow in PyCArg_repr in + _ctypes/callproc.c, which may lead to remote code execution. + +------------------------------------------------------------------- +Tue Jan 5 09:15:36 UTC 2021 - Matej Cepl + +- (bsc#1180125) We really don't Require python-rpm-macros package. + Unnecessary dependency. + +------------------------------------------------------------------- +Tue Dec 22 08:27:08 UTC 2020 - Matej Cepl + +- Update to 3.8.7: + - bugfix release + - multiple patches realigned: + - F00102-lib64.patch + - SUSE-FEDORA-multilib.patch + - bpo-31046_ensurepip_honours_prefix.patch + - skip_random_failing_tests.patch + +------------------------------------------------------------------- +Thu Dec 10 00:26:51 UTC 2020 - Benjamin Greiner + +- Last try before this results in an editwar: + * remove importlib_resources and importlib-metadata + provides/obsoletes + * import importlib_resources is not the same as + import importlib.resources, same for metadata + * The backport packages from PyPI needed for older flavors are + specified as such for setuptools or in pyproject.toml. If a + package requires them they typically add them with a python + version qualifier and the packages have their own version + numbers. + +------------------------------------------------------------------- +Sat Dec 5 16:55:12 UTC 2020 - Matej Cepl + +- Add patch sphinx-update-removed-function.patch to no longer call + a now removed function and to make documentation build independent of + the Sphinx version (bsc#1179630, gh#python/cpython#13236). + +------------------------------------------------------------------- +Wed Dec 2 10:57:45 UTC 2020 - Matej Cepl + +- Add importlib_resources provide/obsolete as it is integral + part of the lang since 3.7 release + +------------------------------------------------------------------- +Fri Nov 20 14:40:09 UTC 2020 - Benjamin Greiner + +- The Python stdlib >= does not provide importlib_metadata or + importlib_resources but importlib.metadata and importlib.resources. + If a package specifically asks for importlib_*, they actually + require the dedicated package with extended API. + +------------------------------------------------------------------- +Mon Nov 9 10:51:30 UTC 2020 - Matej Cepl + +- Update to 3.8.6, which contains various bug fixes including security + fix of included pip and setuptools (bpo#41490, bsc#1176262, + CVE-2019-20916). Full list of changes is available at + https://docs.python.org/release/3.8.6/whatsnew/changelog.html#python-3-8-6 +- Revert previous patch, and readd bpo-31046_ensurepip_honours_prefix.patch. + +------------------------------------------------------------------- +Fri Oct 30 17:49:32 CET 2020 - Matej Cepl + +- Replace ensurepip with simple script instructing to install + packaged pip (bsc#1176262). +- Remove bpo-31046_ensurepip_honours_prefix.patch, which is not + necessary anymore. + +------------------------------------------------------------------- +Fri Oct 9 16:05:50 UTC 2020 - Dominique Leuenberger + +- Fix build with RPM 4.16: error: bare words are no longer + supported, please use "...": x86 == ppc. + +------------------------------------------------------------------- +Fri Sep 25 06:58:03 UTC 2020 - Dominique Leuenberger + +- Buildrequire timezone only for general flavor. It's used in this + flavor for the test suite. + +------------------------------------------------------------------- +Tue Sep 1 10:16:34 UTC 2020 - Matej Cepl + +- Just cleanup and reordering items to synchronize with python39 + +------------------------------------------------------------------- +Mon Jul 20 17:46:54 UTC 2020 - Callum Farmer + +- Update to version 3.8.5: + - bpo-39603: Prevent http header injection by rejecting control + characters in http.client.putrequest(…). + - bpo-41295: Resolve a regression in CPython 3.8.4 where defining + “__setattr__” in a multi-inheritance setup and calling up the + hierarchy chain could fail if builtins/extension types were + involved in the base types. + - bpo-41288: Unpickling invalid NEWOBJ_EX opcode with the + C implementation raises now UnpicklingError instead of + crashing. + - bpo-39017: Avoid infinite loop when reading specially crafted + TAR files using the tarfile module (CVE-2019-20907, bsc#1174091). + - bpo-37703: Updated Documentation to comprehensively elaborate + on the behaviour of gather.cancel() + - bpo-41302: Enable building Python 3.8 with libmpdec-2.5.0 to + ease maintenance for Linux distributions. Patch by Felix Yan. + - bpo-41300: Save files with non-ascii chars. Fix regression + released in 3.9.0b4 and 3.8.4. +- This release also fixes CVE-2020-26116 (bsc#1177211). + +------------------------------------------------------------------- +Fri Jul 17 06:39:45 UTC 2020 - Tomáš Chvátal + +- Few minor fixes for the non-primary-interpreter option found + in py3.9 + +------------------------------------------------------------------- +Wed Jul 15 10:05:28 UTC 2020 - Callum Farmer + +- Minor spec file fixes + +------------------------------------------------------------------- +Wed Jul 15 09:10:42 UTC 2020 - Tomáš Chvátal + +- Fix minor issues found in the staging. + +------------------------------------------------------------------- +Tue Jul 14 20:27:24 UTC 2020 - Matej Cepl + +- Update to 3.8.4: + - Assignment expressions (PEP-572) + - Positional-only parameters (PEP-570) + - Parallel filesystem cache for compiled bytecode files + (PYTHONPYCACHEPREFIX variable) + - Debug build uses the same ABI as release build + - f-strings support = for self-documenting expressions + and debugging + - Python Runtime Audit Hooks (PEP-578) + - Python Initialization Configuration (PEP-587) + - Vectorcall: a fast calling protocol for CPython (PEP-590) + - Pickle protocol 5 with out-of-band data buffers (PEP-574) + - Many other smaller bug fixes +- Removed OBS_dev-shm.patch: contained in upstream +- Removed bpo40784-Fix-sqlite3-deterministic-test.patch: + contained in upstream +- Changed bpo-31046_ensurepip_honours_prefix.patch: to be + compatible with new version + +------------------------------------------------------------------- +Mon Jul 13 11:19:08 UTC 2020 - Callum Farmer + +- Fix %py3_compile being incorrectly defined + +------------------------------------------------------------------- +Fri Jul 10 10:55:15 UTC 2020 - Tomáš Chvátal + +- Update pre_checkin.sh and regenerate + +------------------------------------------------------------------- +Fri Jul 10 10:11:39 UTC 2020 - Tomáš Chvátal + +- Convert few dependencies to their pkgconfig counterparts + +------------------------------------------------------------------- +Fri Jul 10 10:08:48 UTC 2020 - Tomáš Chvátal + +- Remove release requirement on libpython, it is not really needed + to be equal as the abi changes with versions + +------------------------------------------------------------------- +Fri Jul 10 10:07:50 UTC 2020 - Tomáš Chvátal + +- Add provides python3-bla on all the subpkgs in case we are + primary provider of the functionality + +------------------------------------------------------------------- +Fri Jul 10 10:02:01 UTC 2020 - Tomáš Chvátal + +- Remove unversioned files from devel subpkg too +- Remove main python3 files from -base based whether we are + primary interpreter or not +- Fix idle to be co-installable +- Add condition to be primary to provide/obsolete python3-* +- Fix doc to build in versioned folder so the pythons can be + installed next to each other + +------------------------------------------------------------------- +Fri Jul 10 07:57:10 UTC 2020 - Tomáš Chvátal + +- Revert the full versioning of calls on the macros. These + are generic so they should really just call python3 X + +------------------------------------------------------------------- +Fri Jul 10 07:56:11 UTC 2020 - Tomáš Chvátal + +- For the doc package we can build with generic flavor, we don't + need the our-interpreter based one + +------------------------------------------------------------------- +Fri Jul 10 07:18:53 UTC 2020 - Tomáš Chvátal + +- Add provides for pytohn3X-typing/etc to allow BR on those still + to work when needed + +------------------------------------------------------------------- +Fri Jul 10 07:14:33 UTC 2020 - Tomáš Chvátal + +- Change macros.python3 to use full versioned 3.8 instead of just 3 + for python interpreter + +------------------------------------------------------------------- +Wed Jul 1 11:50:19 UTC 2020 - Tomáš Chvátal + +- Reduce some now unused conditionals + +------------------------------------------------------------------- +Wed Jul 1 11:00:40 UTC 2020 - Tomáš Chvátal + +- Redux the -base dependencies to match up pre-merge layout + +------------------------------------------------------------------- +Wed Jul 1 09:24:39 UTC 2020 - Tomáš Chvátal + +- Generate baselibs in pre-checkin too + +------------------------------------------------------------------- +Wed Jul 1 09:14:33 UTC 2020 - Tomáš Chvátal + +- Generate the importlib-failed using pre_checking again +- Add back the information about skipped tests on the pre_checkin + output + +------------------------------------------------------------------- +Tue Jun 30 07:11:19 UTC 2020 - Tomáš Chvátal + +- Use %python_pkg_name instead of hardcoding python3 where + applicable +- Sort out preamble with spec-cleaner + +------------------------------------------------------------------- +Mon Jun 29 14:36:10 UTC 2020 - Matej Cepl + +- Calculate required variables instead of relying on their continuous manual update + +------------------------------------------------------------------- +Thu Jun 25 10:44:08 UTC 2020 - Tomáš Chvátal + +- Fix the -base module build again to generate only the deps + we need + +------------------------------------------------------------------- +Wed Jun 17 18:42:51 UTC 2020 - Matej Cepl + +- Replace OBS_dev-shm.patch with the upstream PR#20944 + +------------------------------------------------------------------- +Thu Jun 10 14:30:15 UTC 2020 - Tomáš Chvátal + +- Use the %{python_pkg_name} on more places to allow easier + multiversioning +- Switch to _multibuild approach for easier maintenance of this + package. All is now in one spec file with 3 conditionals: + * bcond_with base + * bcond_with doc + * bcond_with general + +------------------------------------------------------------------- +Mon Jun 8 14:26:00 UTC 2020 - Matej Cepl + +- add requires python3-base on libpython subpackage (bsc#1167008) + +------------------------------------------------------------------- +Fri Jun 5 06:08:12 UTC 2020 - Dirk Mueller + +- build against Sphinx 2.x until python is compatible with + Sphinx 3.x (see gh#python/cpython#19397, bpo#40204) + +------------------------------------------------------------------- +Fri May 29 19:59:01 UTC 2020 - Andreas Stieger + +- Fix build with SQLite 3.32 (bpo#40783) + add bpo40784-Fix-sqlite3-deterministic-test.patch + +------------------------------------------------------------------- +Sun May 17 15:37:35 UTC 2020 - Callum Farmer + +- Update to version 3.8.3: + - Complete list of changes is available at + https://docs.python.org/release/3.8.3/whatsnew/changelog.html#python-3-8-3-final, + but most of them are just bugfixes. + - Removed patch CVE-2020-8492-urllib-ReDoS.patch: contained in upstream + +------------------------------------------------------------------- +Thu Apr 16 12:06:01 UTC 2020 - Matej Cepl + +- Add #!BuildIgnore: gdk-pixbuf-loader-rsvg to python3 SPEC + +------------------------------------------------------------------- +Thu Mar 26 15:36:55 UTC 2020 - Matej Cepl + +- Add patch bsc1167501-invalid-alignment.patch + (bsc#1167501, bpo#40052) to fix alignment in abstract.h header file. + +------------------------------------------------------------------- +Wed Mar 11 11:09:41 UTC 2020 - Andreas Schwab + +- Update list of skipped tests for qemu linux-user build, test_setegid + (test.test_os.PosixUidGidTests) is confusing it + +------------------------------------------------------------------- +Thu Mar 5 18:40:29 UTC 2020 - Matej Cepl + +- Update to 3.8.2: + - Complete list of changes is available at + https://docs.python.org/release/3.8.2/whatsnew/changelog.html#python-3-8-2-final, + but most of them are just bugfixes. + - Updated patches: + - F00102-lib64.patch + - OBS_dev-shm.patch + - SUSE-FEDORA-multilib.patch + - subprocess-raise-timeout.patch + +------------------------------------------------------------------- +Sun Feb 9 00:14:24 CET 2020 - Matej Cepl + +- Add CVE-2020-8492-urllib-ReDoS.patch fixing the security bug + "Python urrlib allowed an HTTP server to conduct Regular + Expression Denial of Service (ReDoS)" (bsc#1162367) + +------------------------------------------------------------------- +Sat Feb 8 22:21:10 CET 2020 - Matej Cepl + +- Add Requires: libpython%{so_version} == %{version}-%{release} + to python3-base to keep both packages always synchronized + (bsc#1162224). + +------------------------------------------------------------------- +Mon Feb 3 20:27:54 UTC 2020 - Tomáš Chvátal + +- Do not pull in bluez in base again, explain the cycle, + it needs to be solved by bluez maintainer for us by providing + just the headers separately + +------------------------------------------------------------------- +Mon Feb 3 19:54:25 UTC 2020 - Tomáš Chvátal + +- Reame idle icons to idle3 in order to not conflict with python2 + variant of the package + * renamed the icons + * renamed icon load in desktop file + +------------------------------------------------------------------- +Thu Jan 16 09:50:03 UTC 2020 - Tomáš Chvátal + +- Add importlib_resources provide/obsolete as it is integral + part of the lang since 3.7 release + +------------------------------------------------------------------- +Mon Jan 13 11:10:47 UTC 2020 - Martin Liška + +- Add -fno-semantic-interposition as it brings speed up: + https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup + +------------------------------------------------------------------- +Thu Dec 19 16:25:26 CET 2019 - Matej Cepl + +- Update to 3.8.1: + - This is mainly bugfix release and no significant changes to + API are expected. The full changelog is available on + https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-1 + - Remove bpo-38688_shutil.copytree_prevent-infinite-recursion.patch, + which is included in the upstream tarball. + +------------------------------------------------------------------- +Thu Dec 19 14:57:32 CET 2019 - Matej Cepl + +- Add bpo-31046_ensurepip_honours_prefix.patch which makes + ensurepip to honour the value of $(prefix). Proposed fix for + bpo#31046.. + +------------------------------------------------------------------- +Tue Dec 10 11:07:16 UTC 2019 - Tomáš Chvátal + +- Move bluez-devel dependency to base as it is needed for + socket.AF_BLUETOOTH and otherwise does not work + +------------------------------------------------------------------- +Mon Dec 2 16:52:32 CET 2019 - Matej Cepl + +- Reintroduce QtHelp with the help of the new BR + python-sphinxcontrib-qthelp. + +------------------------------------------------------------------- +Mon Oct 21 18:51:00 UTC 2019 - Stefan Brüns + +- Fix SUSE-FEDORA-multilib.patch, the platform agnostic infix for + library installation is "lib", not "dir". + +------------------------------------------------------------------- +Thu Oct 17 14:19:20 UTC 2019 - Stefan Brüns + +- Move idle subpackage build from python3-base to python3. + appstream-glib required for packaging introduces considerable + extra dependencies and a build loop via rust/librsvg. +- Correct installation of idle IDE icons: + + idle.png is not the target directory + + non-GNOME-specific icons belong into icons/hicolor +- Add required Name key to idle3 desktop file + +------------------------------------------------------------------- +Tue Oct 15 16:39:12 CEST 2019 - Matej Cepl + +- Update to the final release 3.8.0. . + - New Features: + - Assignment expressions + - Positional-only parameters + - Parallel filesystem cache for compiled bytecode files + - Debug build uses the same ABI as release build + - f-strings support = for self-documenting expressions and + debugging + - PEP 578: Python Runtime Audit Hooks + - PEP 587: Python Initialization Configuration + - Vectorcall: a fast calling protocol for CPython + - Pickle protocol 5 with out-of-band data buffers + - New modules: + - importlib.metadata + - Improved modules: + - ast asyncio, builtins, collections, curses, ctypes, + datetime, functools, gc, gettext, gzip, idelib and IDLE, + inspect, io, json.tool, math, mmap, multiprocessing, os, + os.path, pathlib, pickle, plistlib, py_compile, shlex, + shutil, socket, ssl, statistics, sys, tarfile, threading, + tokenize, tkinter, time, typing, unicodedata, unittest, + venv, weakref, xml + - C API improvements + - bdist_winnst command has been deprecated (use bdist_wheel) +- https://docs.python.org/3.8/whatsnew/3.8.html remains rest of + changes including documentation on how to port your programs to + the current version of Python. + +------------------------------------------------------------------- +Mon Oct 14 15:02:08 CEST 2019 - Matej Cepl + +- Add idle3.appdata.xml and idle3.desktop (originally from + Fedora) to make Idle3 full GUI desktop application. + (bsc#1153830) + +------------------------------------------------------------------- +Wed Oct 9 19:09:16 UTC 2019 - Michael Gorse + +- Drop intltool from BuildRequires. Doesn't appear to be used. + +------------------------------------------------------------------- +Wed Oct 9 10:37:59 UTC 2019 - Tomáš Chvátal + +- Add folder version to allow tarball downloads even for beta/rc + releases + +------------------------------------------------------------------- +Tue Oct 8 14:53:54 CEST 2019 - Matej Cepl + +- Revert patches from Fedora (F00102-lib64.patch and + F00251-change-user-install-location.patch) into their original + prisitine Fedora versions, SUSE-FEDORA-multilib.patch refreshed + accordingly. + +------------------------------------------------------------------- +Mon Oct 7 14:33:30 UTC 2019 - Matej Cepl + +- Correct quotation of platsubdir in Lib/distutils/command/install.py + +------------------------------------------------------------------- +Thu Oct 3 13:59:57 CEST 2019 - Matej Cepl + +- Replace python-3.6.0-multilib.patch with two patches from + Fedora (F00102-lib64.patch and + F00251-change-user-install-location.patch), and our own + SUSE-FEDORA-multilib.patch to allow better cooperation with + Fedora and better upstreaming. +- Add OBS_dev-shm.patch fixing bpo#38377 + +------------------------------------------------------------------- +Thu Oct 3 08:39:18 UTC 2019 - Tomáš Chvátal + +- Pull in just gettext and let solver to sort out between: + gettext-runtime-mini and gettext-runtime + +------------------------------------------------------------------- +Wed Oct 2 15:00:09 CEST 2019 - Matej Cepl + +- Update to 3.8.0rc1. Overall changes from 3.7: + - PEP 572, Assignment expressions + - PEP 570, Positional-only arguments + - PEP 587, Python Initialization Configuration (improved + embedding) + - PEP 590, Vectorcall: a fast calling protocol for CPython + - PEP 578, Runtime audit hooks + - PEP 574, Pickle protocol 5 with out-of-band data + - Typing-related: PEP 591 (Final qualifier), PEP 586 (Literal + types), and PEP 589 (TypedDict) + - Parallel filesystem cache for compiled bytecode + - Debug builds share ABI as release builds, also the 'm' ABI + tag was removed (irrelevant since 3.4), bpo#36707 + - f-strings support a handy = specifier for debugging + - continue is now legal in finally: blocks + - on Windows, the default asyncio event loop is now + ProactorEventLoop + - on macOS, the spawn start method is now used by default in + multiprocessing + - multiprocessing can now use shared memory segments to avoid + pickling costs between processes + - typed_ast is merged back to CPython + - LOAD_GLOBAL is now 40% faster + - pickle now uses Protocol 4 by default, improving performance +- Refreshed patches: + - CVE-2019-5010-null-defer-x509-cert-DOS.patch + - python-3.3.0b1-fix_date_time_compiler.patch + - python-3.6.0-multilib.patch + - subprocess-raise-timeout.patch + +------------------------------------------------------------------- +Wed Sep 25 09:46:41 UTC 2019 - Bernhard Wiedemann + +- Add bpo36302-sort-module-sources.patch (boo#1041090) + +------------------------------------------------------------------- +Tue Sep 10 13:43:18 UTC 2019 - Tomáš Chvátal + +- Try harder obsoleting importlib-metadata + +------------------------------------------------------------------- +Sat Aug 31 00:16:47 CEST 2019 - Matej Cepl + +- Update to 3.8.0b4: + Many bugfixes, full list on + https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-0-beta-4 + +------------------------------------------------------------------- +Thu Aug 29 06:28:15 UTC 2019 - Guillaume GARDET + +- Re-enable test_threading on aarch64 + +------------------------------------------------------------------- +Sat Aug 17 13:21:15 UTC 2019 - John Vandenberg + +- Remove xrpm from subpackage tk description + +------------------------------------------------------------------- +Tue Aug 6 14:24:55 CEST 2019 - Matej Cepl + +- Update to 3.8.0b3: + Many bugfixes, full list on + https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-0-beta-3 +- Patches reapplied: + - python-3.3.0b1-fix_date_time_compiler.patch + - python-3.3.0b1-test-posix_fadvise.patch + - python-3.6.0-multilib.patch + - subprocess-raise-timeout.patch + +------------------------------------------------------------------- +Tue Jul 23 13:20:49 UTC 2019 - Matej Cepl + +- Add Provides: python3-importlib-metadata + +------------------------------------------------------------------- +Sun Jul 7 19:08:48 CEST 2019 - Matej Cepl + +- Update to 3.8.0b2: + Many bugfixes, full list on + https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-0-beta-2 +- Patches included in upstream: + - bpo-37169_PyObject_IsFreed.patch +- Patches reapplied: + - 00251-change-user-install-location.patch + - distutils-reproducible-compile.patch + - python-3.3.0b1-localpath.patch + - python-3.6.0-multilib.patch + +------------------------------------------------------------------- +Tue Jul 2 09:03:04 UTC 2019 - Andreas Schwab + +- Update list of skipped tests for qemu linux-user build +- Don't do profiling in qemu linux-user build + +------------------------------------------------------------------- +Wed Jun 5 12:19:09 CEST 2019 - Matej Cepl + +- Update to 3.8.0b1 (changes since 3.7.*): + - PEP 572, Assignment expressions + - PEP 570, Positional-only arguments + - PEP 587, Python Initialization Configuration (improved embedding) + - PEP 590, Vectorcall: a fast calling protocol for CPython + - PEP 578, Runtime audit hooks + - PEP 574, Pickle protocol 5 with out-of-band data + - Typing-related: PEP 591 (Final qualifier), PEP 586 (Literal + types), and PEP 589 (TypedDict) + - Parallel filesystem cache for compiled bytecode + - Debug builds share ABI as release builds + - f-strings support a handy = specifier for debugging + - continue is now legal in finally: blocks + - multiprocessing can now use shared memory segments to avoid + pickling costs between processes + - typed_ast is merged back to CPython + - LOAD_GLOBAL is now 40% faster + - pickle now uses Protocol 4 by default, improving performance +- Remove patches which were included in the upstream: + - 00251-change-user-install-location.patch + - 00316-mark-bdist_wininst-unsupported.patch + - CVE-2019-9947-no-ctrl-char-http.patch + - raise_SIGING_not_handled.patch + +------------------------------------------------------------------- +Wed May 22 10:53:03 UTC 2019 - Martin Liška + +- Set _lto_cflags to nil as the package is using LTO via --enable-lto. + That will prevent to propage LTO for Python modules that are + built in a separate package. + +------------------------------------------------------------------- +Sat May 4 21:29:20 CEST 2019 - Matej Cepl + +- Update to 3.8.0.a3: + - PEP 572: Assignment Expressions. + - Other (mostly small) changes are on + https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-0-alpha-3 + +------------------------------------------------------------------- +Mon Apr 29 15:40:34 CEST 2019 - Matej Cepl + +- bsc#1130840 (CVE-2019-9947): add CVE-2019-9947-no-ctrl-char-http.patch + Address the issue by disallowing URL paths with embedded + whitespace or control characters through into the underlying + http client request. Such potentially malicious header + injection URLs now cause a ValueError to be raised. + +------------------------------------------------------------------- +Wed Apr 10 10:22:58 CEST 2019 - Matej Cepl + +- Fix metadata of patches. +- Rename boo1071941-make-install-in-sep-loc.patch to + 00251-change-user-install-location.patch which is the original + name, so it can be looked up in the Fedora VCS. + +------------------------------------------------------------------- +Tue Apr 9 04:55:24 UTC 2019 - John Vandenberg + +- Mark distutils bdist_wininst command unsupported + with 00316-mark-bdist_wininst-unsupported.patch +- Remove Windows bdist_wininst executables from runtime package + +------------------------------------------------------------------- +Tue Apr 9 01:21:45 CEST 2019 - Matej Cepl + +- Update to 3.7.3, which is the maintenance release without any + significant changes in API. + - Updated patches: + - CVE-2019-5010-null-defer-x509-cert-DOS.patch + - distutils-reproducible-compile.patch + - python-3.3.0b1-fix_date_time_compiler.patch + - python-3.6.0-multilib.patch + - raise_SIGING_not_handled.patch + +------------------------------------------------------------------ +Wed Mar 20 14:59:58 UTC 2019 - Matěj Cepl + +- Remove building of Qt Develop help files. + +------------------------------------------------------------------- +Fri Mar 15 15:10:30 CET 2019 - Matej Cepl + +- Return distutils-reproducible-compile.patch which is still + missing (still unfinished bpo#29708). + +------------------------------------------------------------------- +Mon Feb 25 23:30:56 CET 2019 - Matej Cepl + +- Update to 3.8.0a2: + * List of all (mostly small) changes are on + https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-0-alpha-2 + +------------------------------------------------------------------- +Tue Feb 12 10:25:52 CET 2019 - Matej Cepl + +- Build nis module again. + +------------------------------------------------------------------- +Tue Feb 12 10:06:17 CET 2019 - Matej Cepl + +- Update to 3.8.0a1: + * The most visible change so far is probably the + implementation of PEP 572: Assignment Expressions. For + a detailed list of changes, see: + https://docs.python.org/3.8/whatsnew/changelog.html + * Recover building of nis module properly in python3 package +- Update patches: + * CVE-2019-5010-null-defer-x509-cert-DOS.patch + * python-3.3.0b1-fix_date_time_compiler.patch + * python-3.3.0b1-test-posix_fadvise.patch + * python-3.6.0-multilib.patch + * raise_SIGING_not_handled.patch + +------------------------------------------------------------------- +Wed Jan 30 18:07:49 CET 2019 - mcepl@suse.com + +- Put LICENSE file where it belongs (bsc#1121852) + +------------------------------------------------------------------- +Sat Jan 19 16:19:38 CET 2019 - mcepl@suse.com + +- bsc#1122191: add CVE-2019-5010-null-defer-x509-cert-DOS.patch + fixing bpo-35746. + An exploitable denial-of-service vulnerability exists in the + X509 certificate parser of Python.org Python 2.7.11 / 3.7.2. + A specially crafted X509 certificate can cause a NULL pointer + dereference, resulting in a denial of service. An attacker can + initiate or accept TLS connections using crafted certificates + to trigger this vulnerability. + +------------------------------------------------------------------- +Tue Jan 8 12:51:01 UTC 2019 - Tomáš Chvátal + +- Do not require full gettext in order to avoid pulling in the + glib2 as a dependency + +------------------------------------------------------------------- +Tue Jan 8 12:25:27 UTC 2019 - Tomáš Chvátal + +- Update to 3.7.2: + * bugfix release: + https://docs.python.org/3.7/whatsnew/changelog.html#changelog + +------------------------------------------------------------------- +Wed Jan 2 12:51:48 CET 2019 - mcepl@suse.com + +- Stop applying python-3.6.0-multilib-new.patch (which is still + WIP), and apply the old proven python-3.6.0-multilib.patch + instead. + +------------------------------------------------------------------- +Wed Dec 19 19:29:44 UTC 2018 - Todd R + +- Use upstream-recommended %{_rpmconfigdir}/macros.d directory + for the rpm macros. + +------------------------------------------------------------------- +Mon Dec 17 17:24:49 CET 2018 - mcepl@suse.com + +- Upgrade to 3.7.2rc1: + * bugfix release, for the full list of all changes see + https://docs.python.org/3.7/whatsnew/changelog.html#changelog +- Make run of the test suite more verbose + +------------------------------------------------------------------- +Tue Dec 11 01:52:45 UTC 2018 - Jan Engelhardt + +- Write summaries without em dashes. + +------------------------------------------------------------------- +Mon Dec 3 13:27:54 UTC 2018 - Matěj Cepl + +- Remove python-3.3.0b1-curses-panel.patch it is unnecessary anymore. +- Add boo1071941-make-install-in-sep-loc.patch to make pip and + distutils in user environment install into separate location + (boo#1071941) + + Set values of prefix and exec_prefix in distutils install + command to /usr/local if executable is /usr/bin/python* and RPM + build is not detected to make pip and distutils install into + separate location +- Remove finally python-3.3.3-skip-distutils-test_sysconfig_module.patch +- Remove distutils-reproducible-compile.patch which doesn't make + really much difference in reproducibility (see + gh#python/cpython#8057 and discussion there). + +------------------------------------------------------------------- +Sat Dec 1 00:14:28 CET 2018 - mcepl@suse.com + +- Rename Stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch + to bpo34022-stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch + +------------------------------------------------------------------- +Wed Nov 7 12:10:41 CET 2018 - mcepl@suse.com + +- Add dependency on bluez-devel to build support for Bluetooth + (boo#1109998) + +------------------------------------------------------------------- +Tue Nov 6 13:52:45 CET 2018 - mcepl@suse.com + +- Add devhelp subpackage and split qthelp into another + subpackage. + +------------------------------------------------------------------- +Wed Oct 24 12:38:00 UTC 2018 - Matěj Cepl + +- Remove python-3.0b1-record-rpm.patch and + Python-3.0b1-record-rpm.patch, as they are not needed anymore + +------------------------------------------------------------------- +Tue Oct 23 14:14:16 UTC 2018 - Matej Cepl + +- Switch off test_threading for optimization builds. + +------------------------------------------------------------------- +Mon Oct 22 14:41:59 CEST 2018 - mcepl@suse.com + +- Update to python-3.7.1. This is just a brief overview, complete + changelog available at + https://docs.python.org/3.7/whatsnew/changelog.html#python-3-7-1-final: + Library + bpo-34970: Protect tasks weak set manipulation in asyncio.all_tasks() +- Patches already accepted upstream are removed: + * 00307-allow-to-call-Py_Main-after-Py_Initialize.patch + * 00308-tls-1.3.patch +- New patches added: + * Stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch + * raise_SIGING_not_handled.patch +- All other patches refreshed via quilt. + +------------------------------------------------------------------- +Mon Oct 22 12:22:19 UTC 2018 - Matej Cepl + +- Add raise_SIGING_not_handled.patch to fix bsc#1094814 + +------------------------------------------------------------------- +Wed Oct 17 14:04:35 UTC 2018 - Tomáš Chvátal + +- Add patch to fix importlib return types: + * python3-imp-returntype.patch + +------------------------------------------------------------------- +Mon Oct 15 13:46:32 CEST 2018 - mcepl@suse.com + +- bpo-34022 still not completely fixed, so we have to keep + excluding test_cmd_line_script, + test_multiprocessing_main_handling, and test_runpy from the + test suite. + +------------------------------------------------------------------- +Sun Oct 14 15:57:24 UTC 2018 - Matej Cepl + +- Update to python 3.7.1~rc2: + Core and Builtins + bpo-34879: Fix a possible null pointer dereference in + bytesobject.c. Patch by Zackery Spytz. + bpo-34854: Fixed a crash in compiling string annotations + containing a lambda with a keyword-only argument that + doesn’t have a default value. + bpo-34320: Fix dict(od) didn’t copy iteration order of + OrderedDict. + Library + bpo-34769: Fix for async generators not finalizing when event + loop is in debug mode and garbage collector runs in another + thread. + bpo-34922: Fixed integer overflow in the digest() and + hexdigest() methods for the SHAKE algorithm in the hashlib + module. + bpo-34900: Fixed unittest.TestCase.debug() when used to call + test methods with subtests. Patch by Bruno Oliveira. + bpo-34871: Fix inspect module polluted sys.modules when parsing + __text_signature__ of callable. + bpo-34872: Fix self-cancellation in C implementation of + asyncio.Task + bpo-34819: Use a monotonic clock to compute timeouts in + Executor.map() and as_completed(), in order to prevent + timeouts from deviating when the system clock is adjusted. + bpo-34334: In QueueHandler, clear exc_text from LogRecord to + prevent traceback from being written twice. + bpo-6721: Acquire the logging module’s commonly used internal + locks while fork()ing to avoid deadlocks in the child + process. + bpo-34172: Fix a reference issue inside multiprocessing.Pool + that caused the pool to remain alive if it was deleted + without being closed or terminated explicitly. + Documentation + bpo-32174: chm document displays non-ASCII charaters properly on + some MBCS Windows systems. + Tests + bpo-32962: Fixed test_gdb when Python is compiled with flags + -mcet -fcf-protection -O0. + C API + bpo-34910: Ensure that PyObject_Print() always returns -1 on + error. Patch by Zackery Spytz. + +------------------------------------------------------------------- +Fri Oct 12 20:46:58 CEST 2018 - mcepl@suse.com + +- Add Stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch to + fix problems with SOURCE_DATE_EPOCH variable (bpo-34022) + +------------------------------------------------------------------- +Mon Sep 17 09:44:02 UTC 2018 - Tomáš Chvátal + +- Add patch to fix build with tls1.3 supported openssl + * 00308-tls-1.3.patch +- Add patch to fix Py_Main calls after Py_initialize + * 00307-allow-to-call-Py_Main-after-Py_Initialize.patch + +------------------------------------------------------------------- +Mon Sep 3 15:22:42 UTC 2018 - Matěj Cepl + +- Add -fwrapv to OPTS, which is default for python3 anyway + See for example https://github.com/zopefoundation/persistent/issues/86 + for bugs which are caused by avoiding it. + +------------------------------------------------------------------- +Tue Jul 10 11:12:32 UTC 2018 - mcepl@suse.com + +- Fix ownership of _contextvars, _queue, and _xxtestfuzz + +------------------------------------------------------------------- +Tue Jul 3 15:04:48 UTC 2018 - mcepl@suse.com + +- Switch off LTO for distros with older GCC +- Fix %files + +------------------------------------------------------------------- +Fri Jun 29 14:20:03 UTC 2018 - tchvatal@suse.com + +- Add dependency over libuuid-devel + +------------------------------------------------------------------- +Thu Jun 28 10:42:15 UTC 2018 - mimi.vx@gmail.com + +- update to python 3.7.0 + Complete overview of changes is available on + https://docs.python.org/3/whatsnew/3.7.html, these are just + highlights: + * PEP 563, postponed evaluation of type annotations. + * async and await are now reserved keywords. + * New library modules: + contextvars: PEP 567 – Context Variables + dataclasses: PEP 557 – Data Classes + importlib.resources + * New built-in features: + PEP 553, the new breakpoint() function. + * Python data model improvements: + PEP 562, customization of access to module attributes. + PEP 560, core support for typing module and generic types. + the insertion-order preservation nature of dict objects + has been declared to be an official part of the Python + language spec. + * Significant improvements in the standard library: + The asyncio module has received new features, significant + usability and performance improvements. + The time module gained support for functions with + nanosecond resolution. + * CPython implementation improvements: + Avoiding the use of ASCII as a default text encoding: + PEP 538, legacy C locale coercion + PEP 540, forced UTF-8 runtime mode + PEP 552, deterministic .pycs + the new development runtime mode + PEP 565, improved DeprecationWarning handling + * C API improvements: + PEP 539, new C API for thread-local storage + * Documentation improvements: + PEP 545, Python documentation translations + New documentation translations: Japanese, French, and Korean. +- drop python3-sorted_tar.patch +- drop 0001-allow-for-reproducible-builds-of-python-packages.patch +- refresh python-3.6.0-multilib-new.patch +- refresh subprocess-raise-timeout.patch + * new C API for thread-local storage + * Deterministic pyc files + * Built-in breakpoint() + * Data Classes + * Core support for typing module and generic types + * Customization of access to module attributes + * Postponed evaluation of annotations + * Time functions with nanosecond resolution + * Improved DeprecationWarning handling + * Context Variables + * Avoiding the use of ASCII as a default text encoding + (PEP 538, legacy C locale coercion and PEP 540, forced UTF-8 runtime mode) + * The insertion-order preservation nature of dict objects is now + an official part of the Python language spec. + * Notable performance improvements in many areas. + +------------------------------------------------------------------- +Thu May 17 18:26:42 UTC 2018 - hpj@urpla.net + +- disable lto with gcc versions below 7 (results in link failures) + +------------------------------------------------------------------- +Mon Apr 30 15:23:24 UTC 2018 - jengelh@inai.de + +- Use faster find subcommand execution strategies. + +------------------------------------------------------------------- +Fri Apr 20 16:17:29 UTC 2018 - tchvatal@suse.com + +- Do not mention the testsuite disabling in opts as it was moved to + main pkg so base is test-free + +------------------------------------------------------------------- +Tue Apr 17 08:36:08 UTC 2018 - tchvatal@suse.com + +- As we run in main python package do not generate the pre_checkin + from both now + +------------------------------------------------------------------- +Mon Apr 16 14:11:56 UTC 2018 - tchvatal@suse.com + +- Move the tests from base to generic package wrt bsc#1088573 + * We still fail the whole distro if python3 is not build + * The other archs than x86_64 took couple of hours to unblock + build of other software, this way we work around the issue +- Some tests are still run in -base for the LTO tweaking, but at + least it is not run twice + +------------------------------------------------------------------- +Sat Mar 31 19:41:12 UTC 2018 - mimi.vx@gmail.com + +- update to 3.6.5 + * bugfix release + * see Misc/NEWS for details +- drop ctypes-pass-by-value.patch +- drop fix-localeconv-encoding-for-LC_NUMERIC.patch +- refresh python-3.6.0-multilib-new.patch + +------------------------------------------------------------------ +Wed Mar 7 09:16:39 UTC 2018 - adam@mizerski.pl + +- Created %so_major and %so_minor macros +- Put Tools/gdb/libpython.py script into proper place and ship it with devel + subpackage. + +------------------------------------------------------------------- +Tue Feb 20 15:04:56 UTC 2018 - schwab@suse.de + +- ctypes-pass-by-value.patch: Fix pass by value for structs on aarch64 + +------------------------------------------------------------------- +Tue Feb 20 14:28:00 UTC 2018 - bwiedemann@suse.com + +- Add python3-sorted_tar.patch (boo#1081750) + +------------------------------------------------------------------- +Tue Feb 20 14:08:57 UTC 2018 - tchvatal@suse.com + +- Drop python3-tk and python3-idle recommends to reduce python3 + always pulling X stack bsc#1081751 + +------------------------------------------------------------------- +Wed Feb 7 09:10:03 UTC 2018 - tchvatal@suse.com + +- Add patch to fix glibc 2.27 fail bsc#1079761: + * fix-localeconv-encoding-for-LC_NUMERIC.patch + +------------------------------------------------------------------- +Mon Feb 5 17:14:43 UTC 2018 - normand@linux.vnet.ibm.com + +- Update skip_random_failing_tests.patch (for PowerPC) + to avoid test_call_later failure + +------------------------------------------------------------------- +Wed Jan 24 14:35:58 UTC 2018 - jmatejek@suse.com + +- move XML modules and python3-xml provide to python3-base + (fixes bsc#1077230) +- move ensurepip to base + +------------------------------------------------------------------- +Thu Jan 18 12:31:47 UTC 2018 - normand@linux.vnet.ibm.com + +- Add skip_random_failing_tests.patch only for PowerPC + +------------------------------------------------------------------- +Wed Jan 3 12:18:51 UTC 2018 - jmatejek@suse.com + +- update to 3.6.4 + * bugfix release, over a hundred bugs fixed + * see Misc/NEWS for details +- drop upstreamed python3-ncurses-6.0-accessors.patch +- drop PYTHONSTARTUP hooks that cause spurious startup errors + * fixes bsc#1070738 + * the relevant feature (REPL history) is now built into Python itself + +------------------------------------------------------------------- +Sat Dec 2 11:11:46 UTC 2017 - dimstar@opensuse.org + +- Install 2to3-%{python_version} executable (override defattr of + the -tools package). 2to3 (unversioned) is a symlink and does not + carry permissions (bsc#1070853). + +------------------------------------------------------------------- +Thu Nov 16 11:02:18 UTC 2017 - mimi.vx@gmail.com + +- move 2to3 to python3-tools package + +------------------------------------------------------------------- +Wed Oct 11 13:15:23 UTC 2017 - jmatejek@suse.com + +- update to 3.6.3 + * bugfix release, over a hundred bugs fixed + * see Misc/NEWS for details +- drop upstreamed 0001-3.6-bpo-30714-ALPN-changes-for-OpenSSL-1.1.0f-3093.patch + +------------------------------------------------------------------- +Wed Sep 20 09:54:05 UTC 2017 - dmueller@suse.com + +- drop python-2.7-libffi-aarch64.patch: this patches the intree + copy of libffi which is unused/deleted in the line afterwards +- fix build against system libffi: include flags weren't set + so it actually used the in-tree libffi headers. + +------------------------------------------------------------------- +Thu Sep 14 13:23:10 UTC 2017 - vcizek@suse.com + +- Fix test broken with OpenSSL 1.1 (bsc#1042670) + * add 0001-3.6-bpo-30714-ALPN-changes-for-OpenSSL-1.1.0f-3093.patch + +------------------------------------------------------------------- +Tue Sep 5 11:47:05 UTC 2017 - jengelh@inai.de + +- Update RPM group for python documentation. + +------------------------------------------------------------------- +Thu Aug 31 08:39:31 UTC 2017 - schwab@suse.de + +- fix missing %{?armsuffix} + +------------------------------------------------------------------- +Wed Aug 30 13:41:38 UTC 2017 - jmatejek@suse.com + +- distutils-reproducible-compile.patch: ensure distutils order files + before compiling, which works around bsc#1049186 + +------------------------------------------------------------------- +Thu Aug 17 08:59:05 CEST 2017 - kukuk@suse.de + +- Add libnsl-devel build requires for glibc obsoleting libnsl + +------------------------------------------------------------------- +Thu Aug 3 16:09:26 UTC 2017 - jmatejek@suse.com + +- update to 3.6.2 + * bugfix release, over a hundred bugs fixed + * see Misc/NEWS for details +- drop upstreamed test-socket-aead-kernel49.patch +- add Provides: python3-typing (fixes bsc#1050653) +- drop duplicate Provides: python3 + +------------------------------------------------------------------- +Mon Jun 26 12:10:07 UTC 2017 - jmatejek@suse.com + +- drop db-devel from requirements + +------------------------------------------------------------------- +Tue Jun 20 09:26:52 UTC 2017 - asn@cryptomilk.org + +- Add missing link to python library in config dir (bsc#1040164) + +------------------------------------------------------------------- +Thu Mar 23 12:42:59 UTC 2017 - jmatejek@suse.com + +- update to 3.6.1 + * bugfix release, over a hundred bugs fixed + * never add import location's parent directory to sys.path + * switch to git for version control, build changes related to that + * fix "failed to get random numbers" on old kernels (bsc#1029902) + * several crashes and memory leaks corrected + * f-string are no longer accepted as docstrings + +------------------------------------------------------------------- +Mon Mar 13 14:04:22 UTC 2017 - jmatejek@suse.com + +- prevent regenerating AST at build-time more robustly +- add "--without profileopt" and "--without testsuite" options to python3-base + to allow short circuiting when working on the package + +------------------------------------------------------------------- +Sat Feb 25 20:55:57 UTC 2017 - bwiedemann@suse.com + +- Add 0001-allow-for-reproducible-builds-of-python-packages.patch + upstream https://github.com/python/cpython/pull/296 + +------------------------------------------------------------------- +Wed Feb 8 12:30:20 UTC 2017 - jmatejek@suse.com + +- reenable test_socket with AEAD patch (test-socket-aead-kernel49.patch) +- reintroduce %py3_soflags macro (and better named %cpython3_soabi equivalent) + +------------------------------------------------------------------- +Wed Jan 11 14:57:07 UTC 2017 - jmatejek@suse.com + +- update to 3.6.0 + * PEP 498 Formated string literals + * PEP 515 Underscores in numeric literals + * PEP 526 Syntax for variable annotations + * PEP 525 Asynchronous generators + * PEP 530 Asynchronous comprehensions + * PEP 506 New "secrets" module for safe key generation + * less memory consumed by dicts + * dtrace and systemtap support + * improved asyncio module + * better defaults for ssl + * new hashing algorithms in hashlib + * bytecode format changed to allow more optimizations + * "async" and "await" are on track to be reserved words + * StopIteration from generators is deprecated + * support for openssl < 1.0.2 is deprecated + * os.urandom now blocks when getrandom() blocks + * huge number of new features, bugfixes and optimizations + * see https://docs.python.org/3.6/whatsnew/3.6.html for details +- rework multilib patch: drop Python-3.5.0-multilib.patch, implement + upstreamable python-3.6.0-multilib-new.patch +- refresh python-3.3.0b1-localpath.patch, subprocess-raise-timeout.patch +- drop upstreamed Python-3.5.1-fix_lru_cache_copying.patch +- finally drop python-2.6b1-canonicalize2.patch that was not applied in source + and only kept around in case we needed it in the future. (which we don't, as it seems) +- update import_failed map and baselibs +- build ctypes against system libffi + (buildrequire libffi-devel in python3-base) +- add new key to keyring (signed by keys already in keyring) +- introduced common configure section between python3 and python3-base +- moved pyconfig.h and Makefile to devel subpackage as distutils no longer + need it at runtime +- added python-rpm-macros dependency, regenerated macros file, drop macros.python3.py + because it is not used now +- improve summaries and descriptions (fixes bsc#917607) +- enabled Link-Time Optimization, see what happens +- including skipped_tests.py in pre_checkin.sh run +- run specs through spec-cleaner, rearrange sections + +------------------------------------------------------------------- +Fri Apr 22 17:20:29 UTC 2016 - jmatejek@suse.com + +- move _hashlib and _ssl modules and tests to python3-base +- recommend python3 + +------------------------------------------------------------------- +Tue Mar 15 15:05:23 UTC 2016 - schwab@suse.de + +- Skip test_asyncio under qemu_user_space_build + +------------------------------------------------------------------- +Mon Mar 7 20:38:11 UTC 2016 - toddrme2178@gmail.com + +- Add Python-3.5.1-fix_lru_cache_copying.patch + Fix copying the lru_cache() wrapper object. + Fixes deep-copying lru_cache regression, which worked on + previous versions of python but fails on python 3.5. + This fixes a bunch of packages in devel:languages:python3. + See: https://bugs.python.org/issue25447 + +------------------------------------------------------------------- +Sun Jan 24 00:44:08 UTC 2016 - arichardson.kde@gmail.com + +- Build the docs in .qch format as well + +------------------------------------------------------------------- +Wed Dec 9 07:35:20 UTC 2015 - toddrme2178@gmail.com + +- update to 3.5.1 + * bugfix-only release, dozens of bugs fixed +- Drop upstreamed Python-3.5.0-_Py_atomic_xxx-symbols.patch +- "Python3" to "Python 3" in summary + * This seems cleaner and fixes and rpmlint warning + +------------------------------------------------------------------- +Wed Oct 14 20:21:52 UTC 2015 - toddrme2178@gmail.com + +- Add Python-3.5.0-_Py_atomic_xxx-symbols.patch + This fixes a build error for many packages that use the Python, + C-API. + This patch is already accepted upstream and is slated to appear in + python 3.5.1. + +------------------------------------------------------------------- +Tue Sep 29 15:53:24 UTC 2015 - jmatejek@suse.com + +- update to 3.5.0 + * coroutines with async/await syntax + * matrix multiplication operator `@` + * unpacking generalizations + * new modules `typing` and `zipapp` + * type annotations + * .pyo files replaced by custom suffixes for optimization levels in __pycache__ + * support for memory BIO in ssl module + * performance improvements in several modules + * and many more +- removals and behavior changes + * deprecated `__version__` is removed + * support for .pyo files was removed + * system calls are auto-retried on EINTR + * bare generator expressions in function calls now cause SyntaxError + (change "f(x for x in i)" to "f((x for x in i))" to fix) + * removed undocumented `format` member of private `PyMemoryViewObject` struct + * renamed `PyMemAllocator` to `PyMemAllocatorEx` +- redefine %dynlib macro to reflect that modules now have arch+os as part of name +- module `time` is now built-in +- dropped upstreamed patches: + python-3.4.1-fix-faulthandler.patch + python-3.4.3-test-conditional-ssl.patch + python-fix-short-dh.patch (also dropped dh2048.pem required for this patch) +- updated patch Python-3.3.0b2-multilib.patch to Python-3.5.0-multilib.patch +- python-ncurses-6.0-accessors.patch taken from python 2 to fix build failure + with new gcc + ncurses + +------------------------------------------------------------------- +Wed Sep 9 11:51:22 UTC 2015 - dimstar@opensuse.org + +- Add python3-ncurses-6.0-accessors.patch: Fix build with + NCurses 6.0 and OPAQUE_WINDOW set to 1. + +------------------------------------------------------------------- +Mon Aug 24 17:02:08 UTC 2015 - jmatejek@suse.com + +- improve import_failed hook to do the right thing when invoking + missing modules with "python3 -m modulename" (boo#942751) + +------------------------------------------------------------------- +Thu Jul 23 22:08:10 UTC 2015 - fisiu@opensuse.org + +- Build with --enable-loadable-sqlite-extensions to make it works + as geospatial database. + +------------------------------------------------------------------- +Wed Jul 1 07:07:26 UTC 2015 - dimstar@opensuse.org + +- Fix source list for previous change (add dh2048.pem). + +------------------------------------------------------------------- +Wed Jun 24 06:54:30 UTC 2015 - meissner@suse.com + +- dh2048.pem: added generated 2048 dh parameter set to fix + ssl test (bsc#935856) +- python-fix-short-dh.patch: replace the 512 bits dh parameter set + by 2048 bits to fix build with new openssl 1.0.2c (bsc#935856) + +------------------------------------------------------------------- +Tue May 19 14:59:30 UTC 2015 - schwab@suse.de + +- ctypes-libffi-aarch64.patch: remove upstreamed patch +- python-2.7-libffi-aarch64.patch: Fix argument passing in libffi for + aarch64 + +------------------------------------------------------------------- +Thu May 14 10:58:36 UTC 2015 - jmatejek@suse.com + +- drop the PDF subpackage + (removes the massive texlive dependency, and most likely nobody is + using the PDFs anyway) + +------------------------------------------------------------------- +Thu May 14 09:53:29 UTC 2015 - jmatejek@suse.com + +- python-3.4.3-test-conditional-ssl.patch - restore tests failing because + test_urllib was unconditionally importing ssl (without really needing it) +- restore functionality of multilib patch +- drop libffi-ppc64le.diff because upstream completely changed everything + yet again (sorry ppc64 folks :| ) + + +------------------------------------------------------------------- +Fri May 1 15:11:21 UTC 2015 - mailaender@opensuse.org + +- Update to version 3.4.3 +- Drop upstreamed CVE-2014-4650-CGIHTTPServer-traversal.patch + (bpo#21766) + +------------------------------------------------------------------- +Wed Mar 25 10:57:28 UTC 2015 - rguenther@suse.com + +- Add python-3.4.1-fix-faulthandler.patch, upstream patch for bogus + faulthandler which fails with GCC 5. + +------------------------------------------------------------------- +Sun Jan 11 13:01:30 UTC 2015 - p.drouand@gmail.com + +- asyncio has been merged in python3 main package; provide and + obsolete it +- Remove obsolete AUTHORS section +- Remove redundant %clean section + +------------------------------------------------------------------- +Sat Oct 18 20:14:54 UTC 2014 - crrodriguez@opensuse.org + +- Only pkgconfig(x11) is required for build, not the whole + set of packages provided by xorg-x11-devel metapackage. + +------------------------------------------------------------------- +Mon Oct 13 13:38:20 UTC 2014 - jmatejek@suse.com + +- add %python3_version rpm macro for Fedora compatibility +- add missing argument in import_failed, rename Novell Bugzilla + to SUSE Bugzilla + +------------------------------------------------------------------- +Thu Jul 31 17:24:59 UTC 2014 - dimstar@opensuse.org + +- Rename rpmlintrc to %{name}-rpmlintrc. + Follow the packaging guidelines. + +------------------------------------------------------------------- +Wed Jul 23 16:31:02 UTC 2014 - jmatejek@suse.com + +- CVE-2014-4650-CGIHTTPServer-traversal.patch: CGIHTTPServer file + disclosure and directory traversal through URL-encoded characters + (CVE-2014-4650, bnc#885882) + +------------------------------------------------------------------- +Tue Jul 22 13:55:57 UTC 2014 - jmatejek@suse.com + +- drop python-3.4.1-SUSE-ensurepip.patch for compatibility reasons, + reinstate bundled copies of pip and setuptools + (fixes bnc#885662) +- add more files as sources to silence the validator + +------------------------------------------------------------------- +Wed May 21 11:01:56 UTC 2014 - jmatejek@suse.com + +- update to 3.4.1 + * bugfix-only release, over 300 bugs fixed +- drop upstreamed python-3.4.0rc2-sqlite-3.8.4-tests.patch +- drop upstreamed CVE-2014-2667-mkdir.patch +- include Python release manager keyring and signature file + for the source archive (thus renumbering of source files) + (see https://www.python.org/download/#openpgp-public-keys ) +- move ensurepip to python3, because it transitively requires ssl + +------------------------------------------------------------------- +Fri Apr 4 16:21:40 UTC 2014 - jmatejek@suse.com + +- CVE-2014-2667-mkdir.patch: race condition with reseting umask + in os.makedirs + (CVE-2014-2667, bnc#871152) +- updated multilib patch to include ~/.local/lib64 (bnc#637176) + +------------------------------------------------------------------- +Wed Mar 26 15:24:46 UTC 2014 - jmatejek@suse.com + +- raise timeout value for test_subprocess to 10s (might fix + intermittent build failures in OBS) + +------------------------------------------------------------------- +Mon Mar 24 17:29:31 UTC 2014 - dmueller@suse.com + +- remove blacklisting of test_posix on aarch64: qemu bug is fixed + +------------------------------------------------------------------- +Mon Mar 17 18:26:58 UTC 2014 - jmatejek@suse.com + +- update to 3.4.0 final +- drop upstreamed python-3.4rc2-importlib.patch + +------------------------------------------------------------------- +Sun Mar 16 16:33:25 UTC 2014 - schwab@suse.de + +- Only build with profile-opt if profiling is enabled +- Update test exclusion lists: + * test_ctypes no longer fails on arm + * test_io no longer fails on ppc* + * test_multiprocessing has been split in multiple tests + * test_posix and test_signal fail due to qemu bugs + +------------------------------------------------------------------- +Fri Mar 14 20:26:03 UTC 2014 - andreas.stieger@gmx.de + +- Fix build with SQLite 3.8.4 [bnc#867887], fixing SQLite tests, + adding python-2.7.6-sqlite-3.8.4-tests.patch + +------------------------------------------------------------------- +Thu Feb 27 14:08:40 UTC 2014 - jmatejek@suse.com + +- update to 3.4.0 rc2 + * pre-release bugfixes + * improvements to asyncio library +- drop upstreamed tracemalloc_gcov.patch +- python-3.4rc2-importlib.patch fixes backwards-incompatibility + in the reworked importlib module that blocks build of vim + +------------------------------------------------------------------- +Fri Jan 17 18:45:27 UTC 2014 - jmatejek@suse.com + +- initial commit of 3.4.0 beta 3 + * new stdlib modules: pathlib, enum, statistics, tracemalloc + * asynchronous IO with new asyncio module + * introspection data for builtins + * subprocesses no longer inherit open file descriptors + * standardized metadata for packages + * internal hashing changed to SipHash + * new pickle protocol + * improved handling of codecs + * TLS 1.2 support + * major speed improvements for internal unicode handling + * many bugfixes and optimizations +- see porting guide at: + http://docs.python.org/3.4/whatsnew/3.4.html#porting-to-python-3-4 +- moved several modules to -testsuite subpackage +- updated list of binary extensions, refreshed patches +- tracemalloc_gcov.patch fixes profile-based optimization build +- updated packages and pre_checkin.sh to use ~-version notation + for prereleases +- fix-shebangs part of build process moved to common %prep +- drop python-3.3.2-no-REUSEPORT.patch (upstreamed) +- update baselibs for new soname + +- TODOs: + * require python-pip, make ensurepip work with zypper + +------------------------------------------------------------------- +Wed Dec 4 13:21:26 UTC 2013 - matz@suse.de + +- add ppc64le (ELFv2) support for libffi copy for ctypes module +- Adjust Python-3.3.0b2-multilib.patch for ppc64le (make sys.lib be + "lib64"). +- added patches: + * libffi-ppc64le.diff +------------------------------------------------------------------- +Tue Dec 3 09:51:43 UTC 2013 - adrian@suse.de + +- add ppc64le rules + +------------------------------------------------------------------- +Fri Nov 22 13:17:23 UTC 2013 - speilicke@suse.com + +- Add python-3.3.3-skip-distutils-test_sysconfig_module.patch: + + Disable global and distutils sysconfig comparison test, we deviate + from the default depending on optflags + +------------------------------------------------------------------- +Tue Nov 19 14:28:41 UTC 2013 - jmatejek@suse.com + +- update to 3.3.3 + * bugfix-only release + * many SSL-related fixes + * upstream fix for CVE-2013-4238 + * upstream fixes for CVE-2013-1752 +- move example module xxlimited to python3-testsuite +- drop CVE-2013-4238_py33.patch - it is upstreamed +- remove --with-wide-unicode config option, it is now the default + (and only) choice +- don't touch anything between make and makeinstall +- drop python-3.2b2-buildtime-generate.patch - the issue was caused + by touching things between make and makeinstall +- link pycache entries for import_failed hooks properly + +------------------------------------------------------------------- +Tue Oct 15 17:44:08 UTC 2013 - crrodriguez@opensuse.org + +- build with -DOPENSSL_LOAD_CONF for the same reasons + described in the python2 package. + +------------------------------------------------------------------- +Fri Aug 16 11:35:15 UTC 2013 - jmatejek@suse.com + +- handle NULL bytes in certain fields of SSL certificates + (CVE-2013-4238, bnc#834601) + +------------------------------------------------------------------- +Thu Aug 8 14:54:49 UTC 2013 - dvaleev@suse.com + +- Exclue test_faulthandler from tests on powerpc due to bnc#831629 + +------------------------------------------------------------------- +Thu Jun 13 15:05:34 UTC 2013 - jmatejek@suse.com + +- update to 3.3.2 + * bugfix-only release + * fixes several regressions introduced in 3.3.1 +- switch to xz compression +- move _lzma module to python3-base +- python-3.3.2-no-REUSEPORT.patch to fix build on kernels without SO_REUSEPORT + +------------------------------------------------------------------- +Mon Apr 29 22:32:43 UTC 2013 - schwab@suse.de + +- Readd missing bits from ctypes-libffi-aarch64.patch + +------------------------------------------------------------------- +Sat Apr 13 07:56:51 UTC 2013 - idonmez@suse.com + +- Update to version 3.3.1 + * Fix the –enable-profiling configure switch. + * In IDLE, close the replace dialog after it is used. +- Too many bugfixes to list here, + see See http://hg.python.org/cpython/file/v3.3.0/Misc/NEWS +- Refresh Python-3.3.0b2-multilib.patch +- Refresh python-3.2b2-buildtime-generate.patch +- Drop upstream patches: ctypes-libffi-aarch64.patch, + python-3.2.3rc2-pypirc-secure.patch, python-3.3.0-getdents64.patch + +------------------------------------------------------------------- +Mon Apr 8 11:25:30 UTC 2013 - speilicke@suse.com + +- Exclude sqlite/test and tk/test directories from the respective + sub-packages. These are owned by the testsuite sub-package already + +------------------------------------------------------------------- +Fri Apr 5 12:59:20 UTC 2013 - idonmez@suse.com + +- Add Source URL, see https://en.opensuse.org/title=SourceUrls + +------------------------------------------------------------------- +Wed Apr 3 15:36:04 UTC 2013 - jmatejek@suse.com + +- remove spurious modification of python-3.3.0b1-localpath.patch + that would force installation into /usr/local. + this fixes bnc#809831 + +------------------------------------------------------------------- +Thu Mar 28 18:38:51 UTC 2013 - jmatejek@suse.com + +- replace broken movetogetdents64.diff patch with a correct one + from upstream repo (python-3.3.0-getdents64.patch) + +------------------------------------------------------------------- +Fri Mar 1 07:42:21 UTC 2013 - dmueller@suse.com + +- add ctypes-libffi-aarch64.patch: + * import aarch64 support for libffi in _ctypes module +- add aarch64 to the list of lib64 based archs +- add movetogetdents64.diff: + * port to getdents64, as SYS_getdents is not implemented everywhere + +------------------------------------------------------------------- +Tue Feb 26 08:57:55 UTC 2013 - saschpe@suse.de + +- /etc/rpm/macros.python3 is no %config, it is not meant to be changed + by users. +- Add rpmlintrc with some obvious filters + +------------------------------------------------------------------- +Mon Jan 28 18:14:39 UTC 2013 - jmatejek@suse.com + +- update baselibs for new version of libpython3 + +------------------------------------------------------------------- +Thu Nov 29 17:02:37 UTC 2012 - jmatejek@suse.com + +- fix include path in macros (bnc#787526) +- implement failed import handlers for modules that live in + subpackages - e.g. "import ssl" will now throw a sensible error + message telling you to install "python3" + +------------------------------------------------------------------- +Wed Nov 28 17:02:07 UTC 2012 - jmatejek@suse.com + +- merge python3-xml into python3 +- merge python3-2to3 library into python3-base + and the 2to3 binary into python3-devel + (python3-devel is now in conflict with python-2to3, which + will be dropped) +- enable --with-system-expat for python3, making the xml modules + (and thus python3) depend on expat +- reconfigure tests to disable network and GUI resources, which + the upstream apparently thought is a good idea to enable by default. + this fixes build failures in Factory +- add lzma-devel to build the _lzma module +- moved %dynlib macro definition to common section + +------------------------------------------------------------------- +Mon Nov 5 20:01:46 UTC 2012 - coolo@suse.com + +- buildrequire timezone for the test suite + +------------------------------------------------------------------- +Mon Oct 29 18:21:45 UTC 2012 - dmueller@suse.com + +- disable more checks for qemu builds as they use syscalls not + implemented yet + +------------------------------------------------------------------- +Thu Oct 25 08:14:36 UTC 2012 - Rene.vanPaassen@gmail.com + +- exclude test_math for SLE 11; math library fails on negative + gamma function values close to integers and 0, probably + due to imprecision in -lm on SLE_11_SP2. + +------------------------------------------------------------------- +Tue Oct 16 12:15:34 UTC 2012 - coolo@suse.com + +- buildrequire libbz2-devel explicitly + +------------------------------------------------------------------- +Mon Oct 8 14:33:08 UTC 2012 - jmatejek@suse.com + +- remove distutils.cfg (bnc#658604) + * this changes default prefix for distutils to /usr + * see ML for details: +http://lists.opensuse.org/opensuse-packaging/2012-09/msg00254.html + +------------------------------------------------------------------- +Mon Oct 1 08:53:03 UTC 2012 - idonmez@suse.com + +- Update to final 3.3.0 release + * See http://hg.python.org/cpython/file/v3.3.0/Misc/NEWS + +------------------------------------------------------------------- +Thu Sep 27 12:35:01 UTC 2012 - idonmez@suse.com + +- Correct dependency for python3-testsuite, + python3-tkinter -> python3-tk + +------------------------------------------------------------------- +Thu Aug 23 13:08:11 UTC 2012 - jmatejek@suse.com + +- update to 3.3.0 RC1 + +------------------------------------------------------------------- +Fri Aug 3 12:09:34 UTC 2012 - jmatejek@suse.com + +- update to 3.3.0 beta 1 + * flexible string representation, no longer distinguishing + between wide and narrow Unicode builds + * importlib-based import system + * virtualenv support in core + * namespace packages + * explicit Unicode literals for easier porting + * key-sharing dict implementation reduces memory footprint + of OO code + * hash randomization on by default + * many other new bugfixes and features, check NEWS for details + +- pre_checkin.sh now autofills various version strings in specs +- ship hashlib's fallback modules - those uselessly take up space + when real _hashlib.so from python3 is present, but the space wasted + is only 114kB and it provides python3-base with a working hashlib + module. + (also, this fixes bnc#743787) + +------------------------------------------------------------------- +Fri Jul 27 09:02:41 UTC 2012 - dvaleev@suse.com + +- skip test_io on ppc +- drop test_io ppc patch + +------------------------------------------------------------------- +Thu Jun 28 07:57:58 UTC 2012 - saschpe@suse.de + +- Satisfy source_validator by uncommenting an otherwise unused "Patch" + line + +------------------------------------------------------------------- +Tue Jun 12 15:39:08 UTC 2012 - adrian@suse.de + +- fix logic of checks exclusion + +------------------------------------------------------------------- +Fri May 18 11:50:27 UTC 2012 - idonmez@suse.com + +- update to 3.2.3 + * No changes since rc2 + +------------------------------------------------------------------- +Thu Mar 29 15:44:33 UTC 2012 - jmatejek@suse.com + +- update to 3.2.3rc2 + * fixes several security issues: + * CVE-2012-0845, bnc#747125 + * CVE-2012-1150, bnc#751718 + * CVE-2011-4944, bnc#754447 + * CVE-2011-3389, bnc#754677 +- fix for insecure .pypirc (CVE-2011-4944, bnc#754447) +- disable test_gdb because it is broken by our gdb + +------------------------------------------------------------------- +Thu Feb 16 12:33:12 UTC 2012 - dvaleev@suse.com + +- skip broken test_io test on ppc + +------------------------------------------------------------------- +Wed Jan 18 15:49:47 UTC 2012 - jmatejek@suse.com + +- update to 3.2.2 + * bugfix-only release + * reports "linux2" as sys.platform regardless of Linux kernel +- added pre_checkin.sh to copy common spec sections to python3.spec +- added PACKAGING-NOTES with some helpful info for packagers + +------------------------------------------------------------------- +Sun Dec 25 13:25:01 UTC 2011 - idonmez@suse.com + +- Use system ffi, included one is broken see + http://bugs.python.org/issue11729 and + http://bugs.python.org/issue12081 + +------------------------------------------------------------------- +Fri Dec 9 17:19:55 UTC 2011 - jmatejek@suse.com + +- license.opensuse.org-compatible license headers + +------------------------------------------------------------------- +Fri Dec 2 16:46:44 UTC 2011 - coolo@suse.com + +- add automake as buildrequire to avoid implicit dependency + +------------------------------------------------------------------- +Thu Nov 24 12:42:25 UTC 2011 - agraf@suse.com + +- fix ARM build (exclude some test cases which break for us) + +------------------------------------------------------------------- +Tue Aug 16 17:02:22 UTC 2011 - termim@gmail.com + +- use sysconfig module to get py3_incdir, py3_abiflags, + py3_soflags, python3_sitelib and python3_sitearch + +------------------------------------------------------------------- +Mon Jul 18 16:22:31 UTC 2011 - jmatejek@novell.com + +- update to 3.2.1 + * bugfix-only release, no major changes +- fix build on linux3 platform +- remove upstreamed pybench patch +- install /usr/lib directories in all cases to prevent spurious + "directory not owned" in dependent packages + +------------------------------------------------------------------- +Wed Jun 15 14:16:38 UTC 2011 - jmatejek@novell.com + +- replaced dynamic so version with manual so version, because + autobuild does not support autogeneration + +------------------------------------------------------------------- +Tue May 24 13:39:06 UTC 2011 - jmatejek@novell.com + +- generate macros.python3 at compile-time with fixed values +- don't include bogus values in pyconfig.h, as they can break + third-party packages (bnc#673071) + +------------------------------------------------------------------- +Tue May 17 12:52:51 UTC 2011 - jmatejek@novell.com + +- added Obsoletes: python3 < 3.1 so that the transition from + non-split to split packages goes smoothly + +------------------------------------------------------------------- +Fri May 13 12:38:19 UTC 2011 - jmatejek@novell.com + +- fixed RPM macros to use python3 instead of python +- updated to build --with-wide-unicode (for compatibility with + fedora and our own python 2.x series) + +------------------------------------------------------------------- +Thu Apr 21 03:39:25 UTC 2011 - termim@gmail.com + +- fix python3-base build failure due to pybench.py crash by + python-3.2-pybench.patch +- move pyconfig.h from python3-devel to python3-base package to + make python3-base functional again + +------------------------------------------------------------------- +Wed Mar 23 04:26:28 UTC 2011 - termim@gmail.com + +- update to python 3.2 + * stable ABI, ABI-tagged .so files + * concurrent.futures and many other new or upgraded modules + * PYC repository directories ( __pycache__ ) + * python WSGI 1.0.1 + * Unicode 6.0.0 support + * a great number of bugfixes and assorted improvements + +------------------------------------------------------------------- +Tue Feb 8 19:42:17 CET 2011 - matejcik@suse.cz + +- update to python 3.2 RC2 +- renamed python3-demo to python3-tools, because the demo part + became much smaller than the tools part +- added rpm macros + +------------------------------------------------------------------- +Tue Jan 18 14:13:04 UTC 2011 - jmatejek@novell.com + +- update to python 3.2 beta 2, see NEWS for details +- split off -base package with less dependencies, and a shlib-policy + compliant libpython3 package +- mostly rewritten the spec file with more detailed comments +- cleaned up lists of patches + diff --git a/python38.spec b/python38.spec new file mode 100644 index 0000000..dcc8818 --- /dev/null +++ b/python38.spec @@ -0,0 +1,1047 @@ +# +# spec file for package python38 +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%global flavor @BUILD_FLAVOR@%{nil} +%if "%{flavor}" == "doc" +%define psuffix -documentation +%bcond_without doc +%bcond_with base +%bcond_with general +%endif +%if "%{flavor}" == "base" +%define psuffix -core +%bcond_with doc +%bcond_without base +%bcond_with general +%endif +%if "%{flavor}" == "" +%define psuffix %{nil} +%bcond_with doc +%bcond_with base +%bcond_without general +%endif + +%if 0%{?do_profiling} && !0%{?qemu_user_space_build} +%bcond_without profileopt +%else +%bcond_with profileopt +%endif + +%define python_pkg_name python38 +%if "%{python_pkg_name}" == "%{primary_python}" +%define primary_interpreter 1 +%else +%define primary_interpreter 0 +%endif + +%define _version %(c=%{version}; echo ${c/[a-z]*/}) +%define tar_suffix %(c=%{_version}; echo ${c#%{_version}}) +%define python_version %(c=%{_version}; echo ${c:0:3}) +# based on the current source tarball +%define python_version_abitag %(c=%{python_version}; echo ${c//./}) +# FIXME %%define python_version_soname %%(c=%%{python_version}; echo ${c//./_}) +%define python_version_soname 3_8 +%if 0%(test -n "%{tar_suffix}" && echo 1) +%define _version %(echo "%{_version}~%{tar_suffix}") +%define tarversion %{version} +%else +%define tarversion %{version} +%endif +%define folderversion %{tarversion} +%define tarname Python-%{tarversion} +%define sitedir %{_libdir}/python%{python_version} +# three possible ABI kinds: m - pymalloc, d - debug build; see PEP 3149 +%define abi_kind %{nil} +# python ABI version - used in some file names +%define python_abi %{python_version}%{abi_kind} +# soname ABI tag defined in PEP 3149 +%define abi_tag %{python_version_abitag}%{abi_kind} +# version part of "libpython" package +%define so_major 1 +%define so_minor 0 +%define so_version %{python_version_soname}%{abi_kind}-%{so_major}_%{so_minor} +# rpm and python have different ideas about what is an arch-dependent name, so: +%if "%{__isa_name}" == "ppc" +%define archname %(echo %{_arch} | sed s/ppc/powerpc/) +%else +%define archname %{_arch} +%endif +# our arm has Hardware-Floatingpoint +%if "%{_arch}" == "arm" +%define armsuffix hf +%endif +# Decide whether we want to use mpdecimal +%if 0%{?suse_version} >= 1550 +%bcond_without mpdecimal +%else +%bcond_with mpdecimal +%endif +# pyexpat.cpython-35m-x86_64-linux-gnu +# pyexpat.cpython-35m-powerpc64le-linux-gnu +# pyexpat.cpython-35m-armv7-linux-gnueabihf +# _md5.cpython-38m-x86_64-linux-gnu.so +%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so +%bcond_without profileopt +Name: %{python_pkg_name}%{psuffix} +Version: 3.8.20 +Release: 0 +Summary: Python 3 Interpreter +License: Python-2.0 +URL: https://www.python.org/ +Source0: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz +Source1: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz.asc +Source2: baselibs.conf +Source3: README.SUSE +Source7: macros.python3 +Source8: import_failed.py +Source9: import_failed.map +Source10: pre_checkin.sh +Source11: skipped_tests.py +Source19: idle3.desktop +Source20: idle3.appdata.xml +# Used to be https://www.python.org/static/files/pubkeys.txt#/python.keyring +Source99: python.keyring +# The following files are not used in the build. +# They are listed here to work around missing functionality in rpmbuild, +# which would otherwise exclude them from distributed src.rpm files. +Source100: PACKAGING-NOTES +# First series of patches supportin lib-vs-lib64 distinction +# PATCH-FEATURE-UPSTREAM F00102-lib64.patch bsc#[0-9]+ mcepl@suse.com +# Change the various install paths to use /usr/lib64/ instead or /usr/lib/ +Patch01: F00102-lib64.patch +# PATCH-FEATURE-UPSTREAM F00251-change-user-install-location.patch bsc#[0-9]+ mcepl@suse.com +# Fix installation in /usr/local (boo#1071941), originally from Fedora +# https://src.fedoraproject.org/rpms/python3/blob/master/f/00251-change-user-install-location.patch +# Set values of prefix and exec_prefix in distutils install command +# to /usr/local if executable is /usr/bin/python* and RPM build +# is not detected to make pip and distutils install into separate location +Patch02: F00251-change-user-install-location.patch +# PATCH-FEATURE-UPSTREAM SUSE-FEDORA-multilib.patch bsc#[0-9]+ mcepl@suse.com +# Add support for platlib variable +Patch03: SUSE-FEDORA-multilib.patch +# PATCH-FEATURE-UPSTREAM decimal-3.8.patch bsc#1189356 mcepl@suse.com +# fix building with mpdecimal +# https://www.bytereef.org/contrib/decimal-3.8.diff +Patch05: decimal-3.8.patch +# PATCH-FEATURE-UPSTREAM distutils-reproducible-compile.patch gh#python/cpython#8057 mcepl@suse.com +# Improve reproduceability +Patch06: distutils-reproducible-compile.patch +# support finding packages in /usr/local, install to /usr/local by default +Patch07: python-3.3.0b1-localpath.patch +# replace DATE, TIME and COMPILER by fixed definitions to aid reproducible builds +Patch08: python-3.3.0b1-fix_date_time_compiler.patch +# POSIX_FADV_WILLNEED throws EINVAL. Use a different constant in test +Patch09: python-3.3.0b1-test-posix_fadvise.patch +# Raise timeout value for test_subprocess +Patch15: subprocess-raise-timeout.patch +# skip some tests only for PowerPC +Patch23: skip_random_failing_tests.patch +# Fix SOURCE_DATE_EPOCH problems (bpo#34022, bpo#29708) +# gh#python/cpython#10775 gh#python/cpython#10327 +Patch24: bpo34022-stop_hash-based_invalidation_w_SOURCE_DATE_EPOCH.patch +Patch25: python3-imp-returntype.patch +# PATCH-FIX-UPSTREAM CVE-2019-5010-null-defer-x509-cert-DOS.patch bnc#1122191 mcepl@suse.com +# https://github.com/python/cpython/pull/11569 +# Fix segfault in ssl's cert parser +Patch27: CVE-2019-5010-null-defer-x509-cert-DOS.patch +# PATCH-FIX-UPSTREAM bpo36302-sort-module-sources.patch bsc#1041090 bwiedemann@suse.com +# Sort list of sources to have stable order in the compiled .so library. +Patch28: bpo36302-sort-module-sources.patch +# PATCH-FEATURE-UPSTREAM bpo-31046_ensurepip_honours_prefix.patch bpo#31046 mcepl@suse.com +# ensurepip should honour the value of $(prefix) +Patch29: bpo-31046_ensurepip_honours_prefix.patch +# PATCH-FIX-UPSTREAM stop calling removed Sphinx function gh#python/cpython#13236 +Patch32: sphinx-update-removed-function.patch +# PATCH-FIX-UPSTREAM bpo44426-complex-keyword-sphinx.patch bpo#44426 mcepl@suse.com +# Use of 'complex' as a C variable name confuses Sphinx; change it to 'num' +# The same goes for 'default', which I had to change to 'def_size' +Patch33: bpo44426-complex-keyword-sphinx.patch +# PATCH-FIX-UPSTREAM bpo34990-2038-problem-compileall.patch gh#python/cpython#79171 mcepl@suse.com +# Make compileall.py compatible with year 2038 +Patch34: bpo34990-2038-problem-compileall.patch +# PATCH-FIX-OPENSUSE CVE-2023-52425-libexpat-2.6.0-backport.patch +# This problem on libexpat is patched on SLE without version +# update, this patch changes the tests to match the libexpat provided +# by SUSE +Patch36: CVE-2023-52425-libexpat-2.6.0-backport.patch +# PATCH-FIX-OPENSUSE platlibdir-in-sys.patch bsc#1204395 +Patch37: platlibdir-in-sys.patch +# PATCH-FIX-UPSTREAM 98437-sphinx.locale._-as-gettext-in-pyspecific.patch gh#python/cpython#98366 mcepl@suse.com +# this patch makes things totally awesome +Patch38: 98437-sphinx.locale._-as-gettext-in-pyspecific.patch +# PATCH-FIX-UPSTREAM 99366-patch.dict-can-decorate-async.patch bsc#[0-9]+ mcepl@suse.com +# Patch for gh#python/cpython#98086 +Patch41: 99366-patch.dict-can-decorate-async.patch +# PATCH-FIX-UPSTREAM bso1227999-reproducible-builds.patch bsc#1227999 mcepl@suse.com +# reproducibility patches +Patch46: bso1227999-reproducible-builds.patch +# PATCH-FIX-UPSTREAM CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch bsc#1227233 mcepl@suse.com +# Remove for support for anything but OpenSSL 1.1.1 or newer +Patch48: CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch +# PATCH-FIX-UPSTREAM gh120226-fix-sendfile-test-kernel-610.patch gh#python/cpython#120226 mcepl@suse.com +# Fix test_sendfile_close_peer_in_the_middle_of_receiving on Linux >= 6.10 (GH-120227) +Patch50: gh120226-fix-sendfile-test-kernel-610.patch + +BuildRequires: autoconf-archive +BuildRequires: automake +BuildRequires: fdupes +BuildRequires: gmp-devel +BuildRequires: lzma-devel +BuildRequires: netcfg +BuildRequires: openssl-devel +BuildRequires: pkgconfig +%if 0%{?suse_version} >= 1550 +# The provider for python(abi) is in rpm-build-python +BuildRequires: rpm-build-python +%endif +BuildRequires: xz +BuildRequires: pkgconfig(bzip2) +BuildRequires: pkgconfig(expat) +BuildRequires: pkgconfig(libffi) +BuildRequires: pkgconfig(uuid) +BuildRequires: pkgconfig(zlib) +#!BuildIgnore: gdk-pixbuf-loader-rsvg +%if 0%{?suse_version} >= 1500 && 0%{?suse_version} < 1599 +BuildRequires: pkgconfig(libnsl) +BuildRequires: pkgconfig(libtirpc) +%endif +%if %{with mpdecimal} +BuildRequires: mpdecimal-devel +%endif +%if %{with doc} +%if 0%{?suse_version} > 1500 +BuildRequires: python3-Sphinx +BuildRequires: python3-python-docs-theme +BuildRequires: python3-sphinxcontrib-qthelp >= 1.0.2 +%endif +%endif +%if %{with general} +# required for idle3 (.desktop and .appdata.xml files) +BuildRequires: appstream-glib +BuildRequires: gcc-c++ +BuildRequires: gdbm-devel +BuildRequires: gettext +BuildRequires: readline-devel +BuildRequires: sqlite-devel +BuildRequires: timezone +BuildRequires: pkgconfig(ncurses) +BuildRequires: pkgconfig(tk) +BuildRequires: pkgconfig(x11) +Requires: %{python_pkg_name}-base = %{version} +Provides: %{python_pkg_name}-readline +Provides: %{python_pkg_name}-sqlite3 +Recommends: %{python_pkg_name}-curses +Recommends: %{python_pkg_name}-dbm +Recommends: %{python_pkg_name}-pip +%if %{primary_interpreter} +Provides: python3 = %{python_version} +Provides: python3-readline +Provides: python3-sqlite3 +%endif +%endif + +%description +Python 3 is modern interpreted, object-oriented programming language, +often compared to Tcl, Perl, Scheme, or Java. You can find an overview +of Python in the documentation and tutorials included in the python3-doc +package. + +This package supplies rich command line features provided by readline, +and sqlite3 support for the interpreter core, thus forming a so called +"extended" runtime. +Installing "python3" is sufficient for the vast majority of usecases. +In addition, recommended packages provide UI toolkit support (python3-curses, +python3-tk), legacy UNIX database bindings (python3-dbm), and the IDLE +development environment (python3-idle). + +%package -n %{python_pkg_name}-tk +Summary: TkInter, a Python Tk Interface +Requires: %{python_pkg_name} = %{version} +%if %{primary_interpreter} +Provides: python3-tk = %{version} +%endif + +%description -n %{python_pkg_name}-tk +Python interface to Tk. Tk is the GUI toolkit that comes with Tcl. + +%package -n %{python_pkg_name}-curses +Summary: Python Interface to the (N)Curses Library +Requires: %{python_pkg_name} = %{version} +%if %{primary_interpreter} +Provides: python3-curses +%endif + +%description -n %{python_pkg_name}-curses +An easy to use interface to the (n)curses CUI library. CUI stands for +Console User Interface. + +%package -n %{python_pkg_name}-dbm +Summary: Python Interface to the GDBM Library +Requires: %{python_pkg_name} = %{version} +%if %{primary_interpreter} +Provides: python3-dbm +%endif + +%description -n %{python_pkg_name}-dbm +An easy to use interface for Unix DBM databases, and more specifically, +the GNU implementation GDBM. + +%package -n %{python_pkg_name}-idle +Summary: An Integrated Development Environment for Python +Requires: %{python_pkg_name} = %{version} +Requires: %{python_pkg_name}-tk +%if %{primary_interpreter} +Provides: python3-idle = %{version} +%endif + +%description -n %{python_pkg_name}-idle +IDLE is a Tkinter based integrated development environment for Python. +It features a multi-window text editor with multiple undo, Python +colorizing, and many other things, as well as a Python shell window and +a debugger. + +%package -n %{python_pkg_name}-doc +Summary: Package Documentation for Python 3 +Enhances: %{python_pkg_name} = %{python_version} +%if %{primary_interpreter} +Provides: python3-doc = %{version} +%endif + +%description -n %{python_pkg_name}-doc +Tutorial, Global Module Index, Language Reference, Library Reference, +Extending and Embedding Reference, Python/C API Reference, Documenting +Python, and Macintosh Module Reference in HTML format. + +%package -n %{python_pkg_name}-doc-devhelp +Summary: Additional Package Documentation for Python 3 in devhelp format +%if %{primary_interpreter} +Provides: python3-doc-devhelp = %{version} +%endif + +%description -n %{python_pkg_name}-doc-devhelp +Tutorial, Global Module Index, Language Reference, Library Reference, +Extending and Embedding Reference, Python/C API Reference, Documenting +Python, and Macintosh Module Reference in format for devhelp. + +%package -n %{python_pkg_name}-base +Summary: Python 3 Interpreter and Stdlib Core +Requires: libpython%{so_version} = %{version} +Recommends: %{python_pkg_name} = %{version} +#Recommends: python3-ensurepip +# python 3.1 didn't have a separate python-base, so it is wrongly +# not a conflict to have python3-3.1 and python3-base > 3.1 +Obsoletes: python3 < 3.2 +# no Provides, because python3 is obviously provided by package python3 +# python 3.4 provides asyncio +Provides: %{python_pkg_name}-asyncio = %{version} +# python 3.6 provides typing +Provides: %{python_pkg_name}-typing = %{version} +# python3-xml was merged into python3, now moved into -base +Provides: %{python_pkg_name}-xml = %{version} +%if %{primary_interpreter} +Provides: python3-asyncio = %{version} +Obsoletes: python3-asyncio < %{version} +Provides: python3-base = %{version} +Obsoletes: python3-base < %{version} +Provides: python3-typing = %{version} +Obsoletes: python3-typing < %{version} +Provides: python3-xml = %{version} +Obsoletes: python3-xml < %{version} +%endif + +%description -n %{python_pkg_name}-base +Python is an interpreted, object-oriented programming language, and is +often compared to Tcl, Perl, Scheme, or Java. You can find an overview +of Python in the documentation and tutorials included in the python-doc +package. + +This package contains the interpreter core and most commonly used modules +from the standard library. This is sufficient for many usecases, but it +excludes components that depend on external libraries, most notably XML, +database and UI toolkits support. + +%package -n %{python_pkg_name}-tools +Summary: Python Utility and Demonstration Scripts +Requires: %{python_pkg_name}-base = %{version} +Provides: %{python_pkg_name}-2to3 = %{version} +Provides: %{python_pkg_name}-demo = %{version} +%if %{primary_interpreter} +Provides: python3-2to3 = %{version} +Provides: python3-demo = %{version} +Provides: python3-tools = %{version} +Obsoletes: python3-2to3 < %{version} +Obsoletes: python3-demo < %{version} +%endif + +%description -n %{python_pkg_name}-tools +A number of scripts that are useful for building, testing or extending Python, +and a set of demonstration programs. + +%package -n %{python_pkg_name}-devel +Summary: Include Files and Libraries Mandatory for Building Python Modules +Requires: %{python_pkg_name}-base = %{version} +%if %{primary_interpreter} +Provides: python3-devel = %{version} +%endif + +%description -n %{python_pkg_name}-devel +The Python programming language's interpreter can be extended with +dynamically loaded extensions and can be embedded in other programs. + +This package contains header files, a static library, and development +tools for building Python modules, extending the Python interpreter or +embedding Python in applications. + +This also includes the Python distutils, which were in the Python +package up to version 2.2.2. + +%package -n %{python_pkg_name}-testsuite +Summary: Unit tests for Python and its standard library +Requires: %{python_pkg_name} = %{version} +Requires: %{python_pkg_name}-tk = %{version} +%if %{primary_interpreter} +Provides: python3-testsuite = %{version} +%endif + +%description -n %{python_pkg_name}-testsuite +Unit tests that are useful for verifying integrity and functionality +of the installed Python interpreter and standard library. +They are a documented part of stdlib, as a module 'test'. + +%package -n libpython%{so_version} +Summary: Python Interpreter shared library +Requires: %{python_pkg_name}-base >= %{version} + +%description -n libpython%{so_version} +Python is an interpreted, object-oriented programming language, and is +often compared to Tcl, Perl, Scheme, or Java. You can find an overview +of Python in the documentation and tutorials included in the python-doc +(HTML) or python-doc-pdf (PDF) packages. + +This package contains libpython3.2 shared library for embedding in +other applications. + +%prep +%setup -q -n %{tarname} +%if "%{_lib}" == "lib64" +%patch -P 01 -p1 +%endif +%patch -P 02 -p1 +%if "%{_lib}" == "lib64" +%patch -P 03 -p1 +%endif +%if %{with mpdecimal} +%patch -P 05 -p1 +%endif + +%patch -p1 -P 06 +%patch -p1 -P 07 +%patch -p1 -P 08 +%patch -p1 -P 09 +%patch -p1 -P 15 +%patch -p1 -P 23 +%patch -p1 -P 24 +%patch -p1 -P 25 +%patch -p1 -P 27 +%patch -p1 -P 28 +%patch -p1 -P 29 +%patch -p1 -P 32 +%patch -p1 -P 33 +%patch -p1 -P 34 +%patch -p1 -P 36 +%patch -p1 -P 37 +%patch -p1 -P 38 +%patch -p1 -P 41 +%patch -p1 -P 46 +%patch -p1 -P 48 +%patch -p1 -P 50 + +# drop Autoconf version requirement +sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac + +%if %{primary_interpreter} +# fix shebangs - convert /usr/local/bin/python and /usr/bin/env/python to /usr/bin/python3 +for dir in Lib Tools; do + # find *.py, filter to files that contain bad shebangs + # break up "/""usr" like this to prevent replacing with %%{_prefix} + find $dir -name '*.py' -type f -print0 \ + | xargs -0 grep -lE '^#! *(/''usr/.*bin/(env +)?)?python' \ + | xargs sed -r -i -e '1s@^#![[:space:]]*(/''usr/(local/)?bin/(env +)?)?python([0-9]+(\.[0-9]+)?)?@#!%{_bindir}/python3@' +done +%else +# For non-primary Python, just don't bother (bsc#1193179) and remove all +# those shebangs +for dir in Lib Tools; do + find $dir -name '*.py' -type f -exec sed -i '1{/^#!.*python/ d}' '{}' \; +done +%endif + +# drop in-tree libffi and expat +rm -r Modules/_ctypes/libffi* Modules/_ctypes/darwin +rm -r Modules/expat + +# drop duplicate README from site-packages +rm Lib/site-packages/README.txt + +%build +%if %{with doc} +TODAY_DATE=`date -r %{SOURCE0} "+%%B %%d, %%Y"` +# TODO use not date of tarball but date of latest patch + +cd Doc +sed -i "s/^today = .*/today = '$TODAY_DATE'/" conf.py + +%if 0%{?suse_version} >= 1550 +# Sphinx 6.0+ reports various warnings that are not backported +# branch. +%make_build html SPHINXERRORHANDLING="" +%else +%make_build -j1 html +%endif + +# Build also devhelp files +sphinx-build -a -b devhelp . build/devhelp +rm -rfv build/devhelp/.doctrees +%else +%define _lto_cflags %{nil} +# use rpm_opt_flags +export OPT="%{optflags} -DOPENSSL_LOAD_CONF -fwrapv $(pkg-config --cflags-only-I libffi) -fno-semantic-interposition" + +touch -r %{SOURCE0} Makefile.pre.in + +autoreconf -fvi + +%if 0%{?sles_version} +sed -e 's/-fprofile-correction//' -i Makefile.pre.in +%endif + +%configure \ + --docdir=%{_docdir}/python \ + --enable-ipv6 \ + --enable-shared \ + --with-ensurepip=no \ + --with-system-ffi \ + --with-system-expat \ + --with-lto \ +%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400 + --with-ssl-default-suites=openssl \ +%endif +%if %{with profileopt} + --enable-optimizations \ +%endif +%if %{with mpdecimal} + --with-system-libmpdec \ +%endif + --enable-loadable-sqlite-extensions + +# prevent make from trying to rebuild PYTHON_FOR_GEN stuff +%make_build -t Python/Python-ast.c \ + Include/Python-ast.h \ + Objects/typeslots.inc \ + Python/opcode_targets.h \ + Include/opcode.h + +%if %{with general} +%make_build +%endif +%if %{with base} +%if %{with profileopt} + target=profile-opt +%else + target=all +%endif +LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \ + %make_build $target +%endif +%endif + +%check +%if %{with general} +# exclude test_gdb -- it doesn't run in buildservice anyway, and fails on missing debuginfos +# when you install gdb into your test env +EXCLUDE="test_gdb" +# we patch out the message to recommend zypper in and thus this would fail +EXCLUDE="$EXCLUDE test_pydoc" + +%ifarch %{arm} s390x +# test_multiprocessing_forkserver is racy +EXCLUDE="$EXCLUDE test_multiprocessing_forkserver" +%endif +%ifarch ppc ppc64 ppc64le +# exclue test_faulthandler due to bnc#831629 +EXCLUDE="$EXCLUDE test_faulthandler" +%endif +# some tests break in QEMU +%if 0%{?qemu_user_space_build} +EXCLUDE="$EXCLUDE test_faulthandler test_multiprocessing_forkserver test_multiprocessing_spawn test_os test_posix test_signal test_socket test_subprocess" +%endif + +# This test (part of test_uuid) requires real network interfaces +# so that ifconfig output has "HWaddr ". Some kvm instances +# done have any such interface breaking the uuid module. +EXCLUDE="$EXCLUDE test_uuid" + +# TEMPORARILY EXCLUDE test_capi bpo#37169 +EXCLUDE="$EXCLUDE test_capi" + +# Limit virtual memory to avoid spurious failures +if test $(ulimit -v) = unlimited || test $(ulimit -v) -gt 10000000; then + ulimit -v 10000000 || : +fi + +export PYTHONPATH="$(pwd -P)/Lib" +# Use timeout, like make target buildbottest +# We cannot run tests parallel, because osc build environment doesn’t +# have /dev/shm +%make_build -j1 test TESTOPTS="-u curses -v -x $EXCLUDE --timeout=1200" +# use network, be verbose: +#make test TESTOPTS="-l -u network -v" +%endif + +%install +%if %{with doc} +export PDOCS=%{buildroot}%{_docdir}/python%{python_version} +mkdir -p $PDOCS +# generated docs +rm Doc/build/*/.buildinfo +cp -r Doc/build/html $PDOCS +# misc +install -d -m 755 $PDOCS/Misc +rm Misc/README.AIX +for i in Misc/* ; do + [ -f $i ] && install -c -m 644 $i $PDOCS/Misc/ +done +# devhelp +mkdir -p %{buildroot}%{_datadir}/gtk-doc/html +cp -r Doc/build/devhelp %{buildroot}%{_datadir}/gtk-doc/html/Python%{python_version} +rm -rf %{buildroot}%{_datadir}/gtk-doc/html/Python%{python_version}/.doctrees +%endif +%if %{with general} +%make_install + +# clean out stuff that is in python-base and subpackages + +find %{buildroot}%{_bindir} -mindepth 1 -not -name "*idle3*" -print -delete +rm %{buildroot}%{_libdir}/lib* +rm -r %{buildroot}%{_libdir}/pkgconfig +rm -r %{buildroot}%{_mandir}/* +rm -r %{buildroot}%{_includedir}/* + +rm -r %{buildroot}%{sitedir}/config* +find %{buildroot}%{sitedir} -name "*.egg-info" -delete +rm -r %{buildroot}%{sitedir}/__pycache__ +rm -r %{buildroot}%{sitedir}/site-packages +rm %{buildroot}%{sitedir}/*.* + +for module in \ + asyncio ctypes collections concurrent distutils email encodings \ + ensurepip html http \ + importlib json logging multiprocessing pydoc_data unittest \ + urllib venv wsgiref lib2to3 test turtledemo \ + xml xmlrpc +do + rm -r %{buildroot}%{sitedir}/$module +done + +for library in \ + array _asyncio audioop binascii _bisect _bz2 cmath _codecs_* \ + _contextvars _crypt _csv _ctypes _datetime _decimal fcntl grp \ + _hashlib _heapq _json _lsprof _lzma math mmap _multibytecodec \ + _multiprocessing _opcode ossaudiodev parser _pickle _posixshmem \ + _posixsubprocess _queue _random resource select _ssl _socket spwd \ + _statistics _struct syslog termios _testbuffer _testimportmultiple \ + _testmultiphase unicodedata zlib _ctypes_test _testinternalcapi _testcapi xxlimited \ + _xxtestfuzz _xxsubinterpreters _elementtree pyexpat _md5 _sha1 \ + _sha256 _sha512 _blake2 _sha3 _uuid +do + eval rm "%{buildroot}%{sitedir}/lib-dynload/$library.*" +done + +# Idle is not packaged in base due to the appstream-glib dependency +# move idle config into /etc +install -d -m 755 %{buildroot}%{_sysconfdir}/idle%{python_version} +( + cd %{buildroot}/%{sitedir}/idlelib/ + for file in *.def ; do + mv $file %{buildroot}%{_sysconfdir}/idle%{python_version}/ + ln -sf %{_sysconfdir}/idle%{python_version}/$file %{buildroot}/%{sitedir}/idlelib/ + done +) + +# keep just idle3.X +rm %{buildroot}%{_bindir}/idle3 + +# install idle icons +for size in 16 32 48 ; do + install -m 644 -D Lib/idlelib/Icons/idle_${size}.png \ + %{buildroot}%{_datadir}/icons/hicolor/${size}x${size}/apps/idle%{python_version}.png +done + +# install idle desktop file +cp %{SOURCE19} idle%{python_version}.desktop +sed -i -e 's:idle3:idle%{python_version}:g' idle%{python_version}.desktop +install -m 644 -D -t %{buildroot}%{_datadir}/applications idle%{python_version}.desktop + +cp %{SOURCE20} idle%{python_version}.appdata.xml +sed -i -e 's:idle3.desktop:idle%{python_version}.desktop:g' idle%{python_version}.appdata.xml +install -m 644 -D -t %{buildroot}%{_datadir}/metainfo idle%{python_version}.appdata.xml +appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/idle%{python_version}.appdata.xml + +%fdupes %{buildroot}/%{_libdir}/python%{python_version} +%endif +%if %{with base} +%make_install + +# remove .a +find %{buildroot} -name "*.a" -delete + +# install "site-packages" and __pycache__ for third parties +install -d -m 755 %{buildroot}%{sitedir}/site-packages +install -d -m 755 %{buildroot}%{sitedir}/site-packages/__pycache__ +# and their 32bit counterparts explicitly +mkdir -p %{buildroot}%{_prefix}/lib/python%{python_version}/site-packages/__pycache__ + +# cleanup parts that don't belong +for dir in curses dbm sqlite3 tkinter idlelib; do + find "%{buildroot}/%{sitedir}/$dir"/* -maxdepth 0 -name "test" -o -exec rm -rf {} + +done +rm -fv %{buildroot}%{dynlib nis} + +# overwrite the copied binary with a link +ln -sf python%{python_version} %{buildroot}%{_bindir}/python3 + +# decide to ship python3 or just python3.X +%if !%{primary_interpreter} +# base +rm %{buildroot}%{_bindir}/python3 +rm %{buildroot}%{_bindir}/pydoc3 +rm %{buildroot}%{_mandir}/man1/python3.1 +# devel +rm %{buildroot}%{_bindir}/python3-config +rm %{buildroot}%{_libdir}/libpython3.so +rm %{buildroot}%{_libdir}/pkgconfig/{python3,python3-embed}.pc +%endif + +# link shared library instead of static library that tools expect +ln -s ../../libpython%{python_abi}.so %{buildroot}%{_libdir}/python%{python_version}/config-%{python_abi}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}/libpython%{python_abi}.so + +# delete idle3, which has to many packaging dependencies for base +rm %{buildroot}%{_bindir}/idle3* + +# delete the generic 2to3 binary if we are not primary +%if !%{primary_interpreter} +rm %{buildroot}%{_bindir}/2to3 +%endif + +# replace duplicate .pyo/.pyc with hardlinks +%fdupes %{buildroot}/%{sitedir} + +# documentation +export PDOCS=%{buildroot}%{_docdir}/%{name} +install -d -m 755 $PDOCS +install -c -m 644 %{SOURCE3} $PDOCS/ +install -c -m 644 README.rst $PDOCS/ + +# tools +for x in `find Tools/ \( -not -name Makefile \) -print | sort` ; do + test -d $x && ( install -c -m 755 -d $PDOCS/$x ) \ + || ( install -c -m 644 $x $PDOCS/$x ) +done +# gdb script is shipped with devel subpackage +rm -r $PDOCS/Tools/gdb +# clean up the bat files +find "$PDOCS" -name "*.bat" -delete + +# put gdb helper script into place +install -m 755 -D Tools/gdb/libpython.py %{buildroot}%{_datadir}/gdb/auto-load/%{_libdir}/libpython%{python_abi}.so.%{so_major}.%{so_minor}-gdb.py + +# install devel files to /config +#cp Makefile Makefile.pre.in Makefile.pre $RPM_BUILD_ROOT%%{sitedir}/config-%%{python_abi}/ + +# RPM macros +mkdir -p %{buildroot}%{_rpmconfigdir}/macros.d/ +# primary python3 macros +%if %{primary_interpreter} +install -m 644 %{SOURCE7} %{buildroot}%{_rpmconfigdir}/macros.d/ # macros.python3 +%endif +# flavor specific macros, only to be supplied "if we are in the buildset", e.g. installed. +echo ' +# macros for the %%{python_pkg_name} flavor +%%have_%{python_pkg_name} 1 +' > %{buildroot}%{_rpmconfigdir}/macros.d/macros.%{python_pkg_name} + +# import_failed hooks +FAILDIR=%{buildroot}/%{sitedir}/_import_failed +mkdir $FAILDIR +install -m 644 %{SOURCE8} %{SOURCE9} $FAILDIR # import_failed.* +LD_LIBRARY_PATH=. ./python -c "from py_compile import compile; compile('$FAILDIR/import_failed.py', dfile='%{sitedir}/_import_failed/import_failed.py')" +LD_LIBRARY_PATH=. ./python -O -c "from py_compile import compile; compile('$FAILDIR/import_failed.py', dfile='%{sitedir}/_import_failed/import_failed.py')" +( + cd $FAILDIR + while read package modules; do + for module in $modules; do + ln import_failed.py $module.py + pushd __pycache__ + for i in import_failed*; do + ln $i "$module${i#import_failed}" + done + popd + done + done < %{SOURCE9} +) +echo %{sitedir}/_import_failed > %{buildroot}/%{sitedir}/site-packages/zzzz-import-failed-hooks.pth +%endif + +%if %{with general} +%files -n %{python_pkg_name}-tk +%{sitedir}/tkinter +%exclude %{sitedir}/tkinter/test +%{dynlib _tkinter} + +%files -n %{python_pkg_name}-curses +%{sitedir}/curses +%{dynlib _curses} +%{dynlib _curses_panel} + +%files -n %{python_pkg_name}-dbm +%{sitedir}/dbm +%{dynlib _dbm} +%{dynlib _gdbm} + +%files -n %{python_pkg_name} +%dir %{sitedir} +%dir %{sitedir}/lib-dynload +%{sitedir}/sqlite3 +%exclude %{sitedir}/sqlite3/test +%{dynlib readline} +%{dynlib _sqlite3} +%if 0%{?suse_version} >= 1500 && 0%{?suse_version} < 1599 +%{dynlib nis} +%endif + +%files -n %{python_pkg_name}-idle +%{sitedir}/idlelib +%dir %{_sysconfdir}/idle%{python_version} +%config %{_sysconfdir}/idle%{python_version}/* +%doc Lib/idlelib/NEWS.txt +%doc Lib/idlelib/README.txt +%doc Lib/idlelib/TODO.txt +%doc Lib/idlelib/extend.txt +%doc Lib/idlelib/ChangeLog +%{_bindir}/idle%{python_version} +%{_datadir}/applications/idle%{python_version}.desktop +%{_datadir}/metainfo/idle%{python_version}.appdata.xml +%{_datadir}/icons/hicolor/*/apps/idle%{python_version}.png +%dir %{_datadir}/icons/hicolor +%dir %{_datadir}/icons/hicolor/16x16 +%dir %{_datadir}/icons/hicolor/32x32 +%dir %{_datadir}/icons/hicolor/48x48 +%dir %{_datadir}/icons/hicolor/*/apps +# endif for if general +%endif + +%if %{with doc} +%files -n %{python_pkg_name}-doc +%dir %{_docdir}/python%{python_version} +%doc %{_docdir}/python%{python_version}/Misc +%doc %{_docdir}/python%{python_version}/html + +%files -n %{python_pkg_name}-doc-devhelp +%dir %{_datadir}/gtk-doc +%dir %{_datadir}/gtk-doc/html +%doc %{_datadir}/gtk-doc/html/Python%{python_version} +%endif + +%if %{with base} +%post -n libpython%{so_version} -p /sbin/ldconfig +%postun -n libpython%{so_version} -p /sbin/ldconfig + +%files -n libpython%{so_version} +%{_libdir}/libpython%{python_abi}.so.%{so_major}.%{so_minor} + +%files -n %{python_pkg_name}-tools +%{sitedir}/turtledemo +%if %{primary_interpreter} +%{_bindir}/2to3 +%endif +%attr(755, root, root)%{_bindir}/2to3-%{python_version} +%doc %{_docdir}/%{name}/Tools + +%files -n %{python_pkg_name}-devel +%{_libdir}/libpython%{python_abi}.so +%if %{primary_interpreter} +%{_libdir}/libpython3.so +%endif +%{_libdir}/pkgconfig/* +%{_includedir}/python%{python_abi} +%{sitedir}/config-%{python_abi}-* +%{_bindir}/python%{python_abi}-config +%if %{primary_interpreter} +%{_bindir}/python3-config +%endif +# Own these directories to not depend on gdb +%dir %{_datadir}/gdb +%dir %{_datadir}/gdb/auto-load +%dir %{_datadir}/gdb/auto-load%{_prefix} +%dir %{_datadir}/gdb/auto-load%{_libdir} +%{_datadir}/gdb/auto-load/%{_libdir}/libpython%{python_abi}.so.%{so_major}.%{so_minor}-gdb.py + +%files -n %{python_pkg_name}-testsuite +%{sitedir}/test +%{sitedir}/*/test +%{sitedir}/*/tests +%{dynlib _ctypes_test} +%{dynlib _testbuffer} +%{dynlib _testcapi} +%{dynlib _testinternalcapi} +%{dynlib _testimportmultiple} +%{dynlib _testmultiphase} +%{dynlib xxlimited} +# workaround for missing packages +%dir %{sitedir}/sqlite3 +%dir %{sitedir}/tkinter + +%files -n %{python_pkg_name}-base +# docs +%dir %{_docdir}/%{name} +%doc %{_docdir}/%{name}/README.rst +%license LICENSE +%doc %{_docdir}/%{name}/README.SUSE +%if %{primary_interpreter} +%{_mandir}/man1/python3.1%{?ext_man} +%endif +%{_mandir}/man1/python%{python_version}.1%{?ext_man} +# license text, not a doc because the code can use it at run-time +%{sitedir}/LICENSE.txt +# RPM macros +%if %{primary_interpreter} +%{_rpmconfigdir}/macros.d/macros.python3 +%endif +%{_rpmconfigdir}/macros.d/macros.%{python_pkg_name} +# binary parts +%dir %{sitedir}/lib-dynload +%{dynlib array} +%{dynlib _asyncio} +%{dynlib audioop} +%{dynlib binascii} +%{dynlib _bisect} +%{dynlib _bz2} +%{dynlib cmath} +%{dynlib _codecs_cn} +%{dynlib _codecs_hk} +%{dynlib _codecs_iso2022} +%{dynlib _codecs_jp} +%{dynlib _codecs_kr} +%{dynlib _codecs_tw} +%{dynlib _contextvars} +%{dynlib _crypt} +%{dynlib _csv} +%{dynlib _ctypes} +%{dynlib _datetime} +%{dynlib _decimal} +%{dynlib _elementtree} +%{dynlib fcntl} +%{dynlib grp} +%{dynlib _hashlib} +%{dynlib _heapq} +%{dynlib _json} +%{dynlib _lsprof} +%{dynlib _lzma} +%{dynlib math} +%{dynlib mmap} +%{dynlib _multibytecodec} +%{dynlib _multiprocessing} +%{dynlib _opcode} +%{dynlib ossaudiodev} +%{dynlib parser} +%{dynlib _pickle} +%{dynlib _posixshmem} +%{dynlib _posixsubprocess} +%{dynlib pyexpat} +%{dynlib _queue} +%{dynlib _random} +%{dynlib resource} +%{dynlib select} +%{dynlib _socket} +%{dynlib spwd} +%{dynlib _ssl} +%{dynlib _statistics} +%{dynlib _struct} +%{dynlib syslog} +%{dynlib termios} +%{dynlib unicodedata} +%{dynlib _uuid} +%{dynlib _xxsubinterpreters} +%{dynlib _xxtestfuzz} +%{dynlib zlib} +# hashlib fallback modules +%{dynlib _blake2} +%{dynlib _md5} +%{dynlib _sha1} +%{dynlib _sha256} +%{dynlib _sha512} +%{dynlib _sha3} +# python parts +%dir %{_prefix}/lib/python%{python_version} +%dir %{_prefix}/lib/python%{python_version}/site-packages +%dir %{_prefix}/lib/python%{python_version}/site-packages/__pycache__ +%dir %{sitedir} +%dir %{sitedir}/site-packages +%dir %{sitedir}/site-packages/__pycache__ +%exclude %{sitedir}/*/test +%exclude %{sitedir}/*/tests +%{sitedir}/*.py +%{sitedir}/asyncio +%{sitedir}/ctypes +%{sitedir}/collections +%{sitedir}/concurrent +%{sitedir}/distutils +%{sitedir}/email +%{sitedir}/encodings +%{sitedir}/ensurepip +%{sitedir}/html +%{sitedir}/http +%{sitedir}/importlib +%{sitedir}/json +%{sitedir}/lib2to3 +%{sitedir}/logging +%{sitedir}/multiprocessing +%{sitedir}/pydoc_data +%{sitedir}/unittest +%{sitedir}/urllib +%{sitedir}/venv +%{sitedir}/wsgiref +%{sitedir}/xml +%{sitedir}/xmlrpc +%{sitedir}/__pycache__ +# import-failed hooks +%{sitedir}/_import_failed +%{sitedir}/site-packages/zzzz-import-failed-hooks.pth +# symlinks +%if %{primary_interpreter} +%{_bindir}/python3 +%{_bindir}/pydoc3 +%endif +# executables +%attr(755, root, root) %{_bindir}/pydoc%{python_version} +# %%attr(755, root, root) %%{_bindir}/python%%{python_abi} +%attr(755, root, root) %{_bindir}/python%{python_version} +# endif for if base +%endif + +%changelog diff --git a/skip_random_failing_tests.patch b/skip_random_failing_tests.patch new file mode 100644 index 0000000..9ec0f25 --- /dev/null +++ b/skip_random_failing_tests.patch @@ -0,0 +1,143 @@ +From: Michel Normand +Subject: skip random failing tests +Date: Thu, 18 Jan 2018 15:48:52 +0100 + +skip random failing tests: +in _test_multiprocessing.py: + test_async_timeout + test_waitfor_timeout + test_wait_integer +in test_events.py: + test_run_until_complete + test_signal_handling_args + test_call_later + +Reported to fail on ppc64le host on multiple osc build trials: +(all failed for ppc64le, except one for ppc) +=== +[michel@abanc:~/work/home:michel_mno:branches:devel:languages:python:Factory/python3] +$idx=1; while test 1; do echo "trial $idx:"; osc build \ +--vm-type kvm -j 8 --threads 4 openSUSE_Factory_PowerPC ppc64le \ +>/tmp/python3_trialx_${idx}.log 2>&1 || break; ((idx++)); done +=== +FAIL: test_async_timeout (test.test_multiprocessing_fork.WithProcessesTestPool) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/_test_multiprocessing.py", line 2017, in test_async_timeout + self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2) + AssertionError: TimeoutError not raised by +=== +FAIL: test_waitfor_timeout (test.test_multiprocessing_spawn.WithManagerTestCondition) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/_test_multiprocessing.py", line 1169, in test_waitfor_timeout + self.assertTrue(success.value) +AssertionError: False is not true +=== +FAIL: test_run_until_complete (test.test_asyncio.test_events.SelectEventLoopTests) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/test_asyncio/test_events.py", line 285, in test_run_until_complete + self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) +AssertionError: False is not true : 3.966844968999993 +=== +FAIL: test_signal_handling_args (test.test_asyncio.test_events.SelectEventLoopTests) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/test_asyncio/test_events.py", line 566, in test_signal_handling_args + self.assertEqual(caught, 1) +AssertionError: 0 != 1 +=== (ppc) +FAIL: test_wait_integer (test.test_multiprocessing_spawn.TestWait) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/_test_multiprocessing.py", line 3762, in test_wait_integer + self.assertLess(delta, expected + 2) +AssertionError: 5.576360702514648 not less than 5 +=== +=== +====================================================================== +FAIL: test_call_later (test.test_asyncio.test_events.PollEventLoopTests) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/test_asyncio/test_events.py", line 309, in test_call_later + self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) +AssertionError: False is not true : 2.7154626529999746 + +====================================================================== +FAIL: test_call_later (test.test_asyncio.test_events.SelectEventLoopTests) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/test/test_asyncio/test_events.py", line 309, in test_call_later + self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) +AssertionError: False is not true : 4.137590406000015 +=== + + +Signed-off-by: Michel Normand +--- + Lib/test/_test_multiprocessing.py | 3 +++ + Lib/test/test_asyncio/test_events.py | 4 +++- + Lib/test/test_buffer.py | 1 + + 3 files changed, 7 insertions(+), 1 deletion(-) + +--- a/Lib/test/_test_multiprocessing.py ++++ b/Lib/test/_test_multiprocessing.py +@@ -1542,6 +1542,7 @@ class _TestCondition(BaseTestCase): + success.value = True + + @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') ++ @unittest.skip("transient failure on PowerPC") + def test_waitfor_timeout(self): + # based on test in test/lock_tests.py + cond = self.Condition() +@@ -2432,6 +2433,7 @@ class _TestPool(BaseTestCase): + self.assertEqual(get(), 49) + self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) + ++ @unittest.skip("transient failure on PowerPC") + def test_async_timeout(self): + res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 1.0)) + get = TimingWrapper(res.get) +@@ -4651,6 +4653,7 @@ class TestWait(unittest.TestCase): + sem.release() + time.sleep(period) + ++ @unittest.skip("transient failure on PowerPC") + def test_wait_integer(self): + from multiprocessing.connection import wait + +--- a/Lib/test/test_asyncio/test_events.py ++++ b/Lib/test/test_asyncio/test_events.py +@@ -268,11 +268,12 @@ class EventLoopTestsMixin: + # Note: because of the default Windows timing granularity of + # 15.6 msec, we use fairly long sleep times here (~100 msec). + ++ @unittest.skip("transient failure on PowerPC") + def test_run_until_complete(self): + t0 = self.loop.time() + self.loop.run_until_complete(asyncio.sleep(0.1)) + t1 = self.loop.time() +- self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) ++ self.assertTrue(0.08 <= t1-t0 <= 5.0, t1-t0) + + def test_run_until_complete_stopped(self): + +@@ -477,6 +478,7 @@ class EventLoopTestsMixin: + self.assertEqual(caught, 1) + + @unittest.skipUnless(hasattr(signal, 'SIGALRM'), 'No SIGALRM') ++ @unittest.skip("transient failure on PowerPC") + def test_signal_handling_args(self): + some_args = (42,) + caught = 0 +--- a/Lib/test/test_buffer.py ++++ b/Lib/test/test_buffer.py +@@ -2506,6 +2506,7 @@ class TestBufferProtocol(unittest.TestCa + a = ndarray(items, shape=[2, 2, 2], format="b") + check(memoryview(a), vsize(base_struct + 3 * per_dim)) + ++ @unittest.skip("transient failure on PowerPC") + def test_memoryview_struct_module(self): + + class INT(object): diff --git a/skipped_tests.py b/skipped_tests.py new file mode 100644 index 0000000..8b4d1a0 --- /dev/null +++ b/skipped_tests.py @@ -0,0 +1,69 @@ +#!/usr/bin/python3 +""" +Simple regexp-based skipped test checker. +It lists tests that are mentioned (presumably for exclusion) +in BASE, and in MAIN (presumably for inclusion) +and reports discrepancies. + +This will have a number of +""" + +MAIN = "python38.spec" + +import glob +import re +from os.path import basename + +alltests = set() +qemu_exclusions = set() + +for item in glob.glob("Python-*/Lib/test/test_*"): + testname = basename(item) + if testname.endswith(".py"): + testname = testname[:-3] + alltests.add(testname) + +testre = re.compile(r'[\s"](test_\w+)\b') + +def find_tests_in_spec(specname): + global qemu_exclusions + + found_tests = set() + with open(specname) as spec: + in_qemu = False + for line in spec: + line = line.strip() + if "#" in line: + line = line[:line.index("#")] + tests = set(testre.findall(line)) + found_tests |= tests + if line == "%if 0%{?qemu_user_space_build} > 0": + in_qemu = True + if in_qemu: + if line == "%endif": + in_qemu = False + qemu_exclusions |= tests + return found_tests + +excluded = find_tests_in_spec(MAIN) + +#print("--- excluded tests:", " ".join(sorted(excluded))) +#print("--- included tests:", " ".join(sorted(included))) + +mentioned = excluded +nonexistent = mentioned - alltests +missing = excluded - qemu_exclusions + +print("--- the following tests are excluded for QEMU and not tested in python") +print("--- (that probably means we don't need to worry about them)") +for test in sorted(qemu_exclusions - excluded): + print(test) + +print("--- the following tests might be excluded in python:") +for test in sorted(missing): + print(test) + +if nonexistent: + print("--- the following tests don't exist:") + for test in sorted(nonexistent): + print(test) diff --git a/sphinx-update-removed-function.patch b/sphinx-update-removed-function.patch new file mode 100644 index 0000000..2dca49b --- /dev/null +++ b/sphinx-update-removed-function.patch @@ -0,0 +1,26 @@ +From 960bb883769e5c64a63b014590d75654db87ffb0 Mon Sep 17 00:00:00 2001 +From: Pablo Galindo +Date: Fri, 10 May 2019 22:58:17 +0100 +Subject: [PATCH] Fix sphinx deprecation warning about env.note_versionchange() + (GH-13236) + +--- + Doc/tools/extensions/pyspecific.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/Doc/tools/extensions/pyspecific.py ++++ b/Doc/tools/extensions/pyspecific.py +@@ -384,7 +384,12 @@ class DeprecatedRemoved(Directive): + translatable=False) + node.append(para) + env = self.state.document.settings.env +- env.get_domain('changeset').note_changeset(node) ++ # new method ++ if hasattr(env, 'get_domain'): ++ env.get_domain('changeset').note_changeset(node) ++ # deprecated pre-Sphinx-2 method ++ else: ++ env.note_versionchange('deprecated', version[0], node, self.lineno) + return [node] + messages + + diff --git a/subprocess-raise-timeout.patch b/subprocess-raise-timeout.patch new file mode 100644 index 0000000..703faa3 --- /dev/null +++ b/subprocess-raise-timeout.patch @@ -0,0 +1,12 @@ +--- a/Lib/test/test_subprocess.py ++++ b/Lib/test/test_subprocess.py +@@ -1147,7 +1147,8 @@ class ProcessTestCase(BaseTestCase): + self.assertIn("0.0001", str(c.exception)) # For coverage of __str__. + # Some heavily loaded buildbots (sparc Debian 3.x) require this much + # time to start. +- self.assertEqual(p.wait(timeout=3), 0) ++ # OBS might require even more ++ self.assertEqual(p.wait(timeout=10), 0) + + def test_invalid_bufsize(self): + # an invalid type of the bufsize argument should raise diff --git a/support-expat-CVE-2022-25236-patched.patch b/support-expat-CVE-2022-25236-patched.patch new file mode 100644 index 0000000..c225a8f --- /dev/null +++ b/support-expat-CVE-2022-25236-patched.patch @@ -0,0 +1,71 @@ +From 7da97f61816f3cadaa6788804b22a2434b40e8c5 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Mon, 21 Feb 2022 08:16:09 -0800 +Subject: [PATCH] bpo-46811: Make test suite support Expat >=2.4.5 (GH-31453) + (GH-31472) + +Curly brackets were never allowed in namespace URIs +according to RFC 3986, and so-called namespace-validating +XML parsers have the right to reject them a invalid URIs. + +libexpat >=2.4.5 has become strcter in that regard due to +related security issues; with ET.XML instantiating a +namespace-aware parser under the hood, this test has no +future in CPython. + +References: +- https://datatracker.ietf.org/doc/html/rfc3968 +- https://www.w3.org/TR/xml-names/ + +Also, test_minidom.py: Support Expat >=2.4.5 +(cherry picked from commit 2cae93832f46b245847bdc252456ddf7742ef45e) + +Co-authored-by: Sebastian Pipping +--- + Lib/test/test_minidom.py | 25 +++++++++++-------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst + +--- a/Lib/test/test_minidom.py ++++ b/Lib/test/test_minidom.py +@@ -1149,14 +1149,12 @@ class MinidomTest(unittest.TestCase): + + # Verify that character decoding errors raise exceptions instead + # of crashing +- if pyexpat.version_info >= (2, 4, 5): +- self.assertRaises(ExpatError, parseString, +- b'') +- self.assertRaises(ExpatError, parseString, +- b'Comment \xe7a va ? Tr\xe8s bien ?') +- else: +- self.assertRaises(UnicodeDecodeError, parseString, +- b'Comment \xe7a va ? Tr\xe8s bien ?') ++ # It doesn’t make any sense to insist on the exact text of the ++ # error message, or even the exact Exception … it is enough that ++ # the error has been discovered. ++ with self.assertRaises((UnicodeDecodeError, ExpatError)): ++ parseString( ++ b'Comment \xe7a va ? Tr\xe8s bien ?') + + doc.unlink() + +@@ -1601,13 +1599,12 @@ class MinidomTest(unittest.TestCase): + self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE) + + def testExceptionOnSpacesInXMLNSValue(self): +- if pyexpat.version_info >= (2, 4, 5): +- context = self.assertRaisesRegex(ExpatError, 'syntax error') +- else: +- context = self.assertRaisesRegex(ValueError, 'Unsupported syntax') ++ # It doesn’t make any sense to insist on the exact text of the ++ # error message, or even the exact Exception … it is enough that ++ # the error has been discovered. ++ with self.assertRaises((ExpatError, ValueError)): ++ parseString('') + +- with context: +- parseString('') + + def testDocRemoveChild(self): + doc = parse(tstfile)