diff --git a/.gitignore b/.gitignore index 67901af..1107137 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /*.tar.* -/*-jit_stencils.h /*.src.rpm /results_python3* diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index b35197d..ff9c69b 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -30,7 +30,7 @@ Co-authored-by: Lumír Balhar 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Lib/site.py b/Lib/site.py -index aeb7c6cfc7..86f9ae9e76 100644 +index f932719715..e4ef914ec2 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -421,8 +421,15 @@ def getsitepackages(prefixes=None): @@ -51,7 +51,7 @@ index aeb7c6cfc7..86f9ae9e76 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index faf8273bd0..d7667bbc77 100644 +index 2ecbff222f..7211773bad 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -130,7 +130,7 @@ index faf8273bd0..d7667bbc77 100644 # On Windows we want to substitute 'lib' for schemes rather # than the native value (without modifying vars, in case it diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py -index 1fe4b6849f..e0cb3ec23a 100644 +index 09eff11179..c227815ebd 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -132,8 +132,19 @@ def test_get_path(self): @@ -154,7 +154,7 @@ index 1fe4b6849f..e0cb3ec23a 100644 os.path.normpath(expected), ) -@@ -397,7 +408,7 @@ def test_get_config_h_filename(self): +@@ -395,7 +406,7 @@ def test_get_config_h_filename(self): self.assertTrue(os.path.isfile(config_h), config_h) def test_get_scheme_names(self): @@ -163,7 +163,7 @@ index 1fe4b6849f..e0cb3ec23a 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -409,6 +420,8 @@ def test_symlink(self): # Issue 7880 +@@ -407,6 +418,8 @@ def test_symlink(self): # Issue 7880 cmd = "-c", "import sysconfig; print(sysconfig.get_platform())" self.assertEqual(py.call_real(*cmd), py.call_link(*cmd)) diff --git a/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch b/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch new file mode 100644 index 0000000..aea27d9 --- /dev/null +++ b/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Fri, 25 Apr 2025 09:33:37 +0200 +Subject: 00461: Downstream only: Install wheel in test venvs when setuptools < + 71 + +This can be removed when Fedora 41 goes EOL (or updates setuptools). +--- + Lib/test/support/__init__.py | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py +index 88f6110351..210ddcdbe3 100644 +--- a/Lib/test/support/__init__.py ++++ b/Lib/test/support/__init__.py +@@ -2512,9 +2512,16 @@ def run_command(cmd): + else: + python = os.path.join(venv, 'bin', python_exe) + ++ setuptools_whl = _findwheel('setuptools') ++ whl_filename = os.path.basename(setuptools_whl) ++ setuptools_major = int(whl_filename.split('-')[1].split('.')[0]) ++ if setuptools_major >= 71: # we need 70.1+, but that's OK ++ wheels = (setuptools_whl,) ++ else: ++ wheels = (setuptools_whl, _findwheel('wheel')) + cmd = (python, '-X', 'dev', + '-m', 'pip', 'install', +- _findwheel('setuptools'), ++ *wheels, + ) + run_command(cmd) + diff --git a/00464-enable-pac-and-bti-protections-for-aarch64.patch b/00464-enable-pac-and-bti-protections-for-aarch64.patch new file mode 100644 index 0000000..1a7acf3 --- /dev/null +++ b/00464-enable-pac-and-bti-protections-for-aarch64.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Tue, 3 Jun 2025 03:02:15 +0200 +Subject: 00464: Enable PAC and BTI protections for aarch64 + +Apply protection against ROP/JOP attacks for aarch64 on asm_trampoline.S + +The BTI flag must be applied in the assembler sources for this class +of attacks to be mitigated on newer aarch64 processors. + +Upstream PR: https://github.com/python/cpython/pull/130864/files + +The upstream patch is incomplete but only for the case where +frame pointers are not used on 3.13+. + +Since on Fedora we always compile with frame pointers the BTI/PAC +hardware protections can be enabled without losing Perf unwinding. +--- + Python/asm_trampoline.S | 4 +++ + Python/asm_trampoline_aarch64.h | 50 +++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + create mode 100644 Python/asm_trampoline_aarch64.h + +diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S +index a14e68c0e8..2513cde4e7 100644 +--- a/Python/asm_trampoline.S ++++ b/Python/asm_trampoline.S +@@ -1,3 +1,5 @@ ++#include "asm_trampoline_aarch64.h" ++ + .text + .globl _Py_trampoline_func_start + # The following assembly is equivalent to: +@@ -21,10 +23,12 @@ _Py_trampoline_func_start: + #if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__) + // ARM64 little endian, 64bit ABI + // generate with aarch64-linux-gnu-gcc 12.1 ++ SIGN_LR + stp x29, x30, [sp, -16]! + mov x29, sp + blr x3 + ldp x29, x30, [sp], 16 ++ VERIFY_LR + ret + #endif + #ifdef __riscv +diff --git a/Python/asm_trampoline_aarch64.h b/Python/asm_trampoline_aarch64.h +new file mode 100644 +index 0000000000..4b0ec4a7dc +--- /dev/null ++++ b/Python/asm_trampoline_aarch64.h +@@ -0,0 +1,50 @@ ++#ifndef ASM_TRAMPOLINE_AARCH_64_H_ ++#define ASM_TRAMPOLINE_AARCH_64_H_ ++ ++/* ++ * References: ++ * - https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros ++ * - https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst ++ */ ++ ++#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 ++ #define BTI_J hint 36 /* bti j: for jumps, IE br instructions */ ++ #define BTI_C hint 34 /* bti c: for calls, IE bl instructions */ ++ #define GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */ ++#else ++ #define BTI_J ++ #define BTI_C ++ #define GNU_PROPERTY_AARCH64_BTI 0 ++#endif ++ ++#if defined(__ARM_FEATURE_PAC_DEFAULT) ++ #if __ARM_FEATURE_PAC_DEFAULT & 1 ++ #define SIGN_LR hint 25 /* paciasp: sign with the A key */ ++ #define VERIFY_LR hint 29 /* autiasp: verify with the A key */ ++ #elif __ARM_FEATURE_PAC_DEFAULT & 2 ++ #define SIGN_LR hint 27 /* pacibsp: sign with the b key */ ++ #define VERIFY_LR hint 31 /* autibsp: verify with the b key */ ++ #endif ++ #define GNU_PROPERTY_AARCH64_POINTER_AUTH 2 /* bit 1 GNU Notes is for PAC support */ ++#else ++ #define SIGN_LR BTI_C ++ #define VERIFY_LR ++ #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 ++#endif ++ ++/* Add the BTI and PAC support to GNU Notes section */ ++#if GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 ++ .pushsection .note.gnu.property, "a"; /* Start a new allocatable section */ ++ .balign 8; /* align it on a byte boundry */ ++ .long 4; /* size of "GNU\0" */ ++ .long 0x10; /* size of descriptor */ ++ .long 0x5; /* NT_GNU_PROPERTY_TYPE_0 */ ++ .asciz "GNU"; ++ .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ ++ .long 4; /* Four bytes of data */ ++ .long (GNU_PROPERTY_AARCH64_BTI|GNU_PROPERTY_AARCH64_POINTER_AUTH); /* BTI or PAC is enabled */ ++ .long 0; /* padding for 8 byte alignment */ ++ .popsection; /* end the section */ ++#endif ++ ++#endif diff --git a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch b/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch deleted file mode 100644 index 43e2056..0000000 --- a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Wed, 12 Aug 2026 15:18:39 +0200 -Subject: 00466: Downstream only: Lower XML_COMBINED_VERSION threshold for - reparse deferral - -RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported -via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. -CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter -as a no-op, so SetReparseDeferralEnabled silently does nothing and -GetReparseDeferralEnabled always returns False, even though the expat -library actually supports (and enables) reparse deferral. - -Lower the threshold from 20600 to 20500 so that CPython uses the -backported function. This makes the Python API actually work on RHEL 9 -and fixes test failures (test_reparse_deferral_disabled, -test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). - -The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the -backported function is available. ---- - Lib/test/test_pyexpat.py | 6 +++--- - Lib/test/test_sax.py | 4 ++-- - Lib/test/test_xml_etree.py | 4 ++-- - Modules/pyexpat.c | 6 +++--- - 4 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index fd3077063b..34f86e2dbd 100644 ---- a/Lib/test/test_pyexpat.py -+++ b/Lib/test/test_pyexpat.py -@@ -1005,7 +1005,7 @@ def test_error_path_no_crash(self): - class ReparseDeferralTest(unittest.TestCase): - def test_getter_setter_round_trip(self): - parser = expat.ParserCreate() -- enabled = (expat.version_info >= (2, 6, 0)) -+ enabled = (expat.version_info >= (2, 5, 0)) - - self.assertIs(parser.GetReparseDeferralEnabled(), enabled) - parser.SetReparseDeferralEnabled(False) -@@ -1014,7 +1014,7 @@ def test_getter_setter_round_trip(self): - self.assertIs(parser.GetReparseDeferralEnabled(), enabled) - - def test_reparse_deferral_enabled(self): -- if expat.version_info < (2, 6, 0): -+ if expat.version_info < (2, 5, 0): - self.skipTest(f'Expat {expat.version_info} does not ' - 'support reparse deferral') - -@@ -1045,7 +1045,7 @@ def start_element(name, _): - - parser = expat.ParserCreate() - parser.StartElementHandler = start_element -- if expat.version_info >= (2, 6, 0): -+ if expat.version_info >= (2, 5, 0): - parser.SetReparseDeferralEnabled(False) - self.assertFalse(parser.GetReparseDeferralEnabled()) - -diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py -index 5c10bcedc6..114f002b0b 100644 ---- a/Lib/test/test_sax.py -+++ b/Lib/test/test_sax.py -@@ -1216,7 +1216,7 @@ def test_expat_incremental_reset(self): - - self.assertEqual(result.getvalue(), start + b"text") - -- @unittest.skipIf(pyexpat.version_info < (2, 6, 0), -+ @unittest.skipIf(pyexpat.version_info < (2, 5, 0), - f'Expat {pyexpat.version_info} does not ' - 'support reparse deferral') - def test_flush_reparse_deferral_enabled(self): -@@ -1250,7 +1250,7 @@ def test_flush_reparse_deferral_disabled(self): - for chunk in (""): - parser.feed(chunk) - -- if pyexpat.version_info >= (2, 6, 0): -+ if pyexpat.version_info >= (2, 5, 0): - parser._parser.SetReparseDeferralEnabled(False) - self.assertEqual(result.getvalue(), start) # i.e. no elements started - -diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 6da7c34dc4..d846ddf4e2 100644 ---- a/Lib/test/test_xml_etree.py -+++ b/Lib/test/test_xml_etree.py -@@ -1803,7 +1803,7 @@ def test_unknown_event(self): - with self.assertRaisesRegex(ValueError, "unknown event 'bogus'"): - ET.XMLPullParser(events=(x.decode() for x in (b'start', b'end', b'bogus'))) - -- @unittest.skipIf(pyexpat.version_info < (2, 6, 0), -+ @unittest.skipIf(pyexpat.version_info < (2, 5, 0), - f'Expat {pyexpat.version_info} does not ' - 'support reparse deferral') - def test_flush_reparse_deferral_enabled(self): -@@ -1833,7 +1833,7 @@ def test_flush_reparse_deferral_disabled(self): - for chunk in (""): - parser.feed(chunk) - -- if pyexpat.version_info >= (2, 6, 0): -+ if pyexpat.version_info >= (2, 5, 0): - if not ET is pyET: - self.skipTest(f'XMLParser.(Get|Set)ReparseDeferralEnabled ' - 'methods not available in C') -diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c -index f9fd7a7a5b..e88b7f16a8 100644 ---- a/Modules/pyexpat.c -+++ b/Modules/pyexpat.c -@@ -814,7 +814,7 @@ pyexpat_xmlparser_SetReparseDeferralEnabled_impl(xmlparseobject *self, - int enabled) - /*[clinic end generated code: output=5ec539e3b63c8c49 input=021eb9e0bafc32c5]*/ - { --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - XML_SetReparseDeferralEnabled(self->itself, enabled ? XML_TRUE : XML_FALSE); - self->reparse_deferral_enabled = (bool)enabled; - #endif -@@ -1478,7 +1478,7 @@ newxmlparseobject(pyexpat_state *state, const char *encoding, - self->ns_prefixes = 0; - self->handlers = NULL; - self->intern = Py_XNewRef(intern); --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - self->reparse_deferral_enabled = true; - #else - self->reparse_deferral_enabled = false; -@@ -2396,7 +2396,7 @@ pyexpat_exec(PyObject *mod) - #else - capi->SetHashSalt16Bytes = NULL; - #endif --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - capi->SetReparseDeferralEnabled = XML_SetReparseDeferralEnabled; - #else - capi->SetReparseDeferralEnabled = NULL; diff --git a/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch new file mode 100644 index 0000000..953c18d --- /dev/null +++ b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Tue, 24 Jun 2025 11:12:13 +0200 +Subject: 00466: Downstream only: Skip tests not working with older expat + version + +We want to run these tests in Fedora and EPEL 10, but not in EPEL 9, +which has too old version of expat. We set the upper bound version +in the conditionalized skip to a release available in CentOS Stream 10, +which is tested as working. +--- + Lib/test/test_pyexpat.py | 2 ++ + Lib/test/test_sax.py | 2 ++ + Lib/test/test_xml_etree.py | 6 ++++++ + 3 files changed, 10 insertions(+) + +diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py +index a091430463..55ebf34c52 100644 +--- a/Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -826,6 +826,8 @@ def start_element(name, _): + + self.assertEqual(started, ['doc']) + ++ @unittest.skipIf(expat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_reparse_deferral_disabled(self): + started = [] + +diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py +index 5c10bcedc6..1fd7a273b5 100644 +--- a/Lib/test/test_sax.py ++++ b/Lib/test/test_sax.py +@@ -1241,6 +1241,8 @@ def test_flush_reparse_deferral_enabled(self): + + self.assertEqual(result.getvalue(), start + b"") + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_flush_reparse_deferral_disabled(self): + result = BytesIO() + xmlgen = XMLGenerator(result) +diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py +index bf6d5074fd..6f8ef34590 100644 +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -1547,9 +1547,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): + self.assert_event_tags(parser, [('end', 'root')]) + self.assertIsNone(parser.close()) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_simple_xml_chunk_1(self): + self.test_simple_xml(chunk_size=1, flush=True) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_simple_xml_chunk_5(self): + self.test_simple_xml(chunk_size=5, flush=True) + +@@ -1774,6 +1778,8 @@ def test_flush_reparse_deferral_enabled(self): + + self.assert_event_tags(parser, [('end', 'doc')]) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_flush_reparse_deferral_disabled(self): + parser = ET.XMLPullParser(events=('start', 'end')) + diff --git a/00475-cve-2025-15367.patch b/00475-cve-2025-15367.patch deleted file mode 100644 index 71c71c2..0000000 --- a/00475-cve-2025-15367.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Tue, 20 Jan 2026 14:46:32 -0600 -Subject: 00475: CVE-2025-15367 - -Downstream only: Reject control characters in POP3 commands ---- - Lib/poplib.py | 2 ++ - Lib/test/test_poplib.py | 8 ++++++++ - .../2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 + - 3 files changed, 11 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst - -diff --git a/Lib/poplib.py b/Lib/poplib.py -index 4469bff44b..b97274c5c3 100644 ---- a/Lib/poplib.py -+++ b/Lib/poplib.py -@@ -122,6 +122,8 @@ def _putline(self, line): - def _putcmd(self, line): - if self._debugging: print('*cmd*', repr(line)) - line = bytes(line, self.encoding) -+ if re.search(b'[\x00-\x1F\x7F]', line): -+ raise ValueError('Control characters not allowed in commands') - self._putline(line) - - -diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py -index ef2da97f86..18ca7cb556 100644 ---- a/Lib/test/test_poplib.py -+++ b/Lib/test/test_poplib.py -@@ -17,6 +17,7 @@ - from test.support import threading_helper - from test.support import asynchat - from test.support import asyncore -+from test.support import control_characters_c0 - - - test_support.requires_working_socket(module=True) -@@ -395,6 +396,13 @@ def test_quit(self): - self.assertIsNone(self.client.sock) - self.assertIsNone(self.client.file) - -+ def test_control_characters(self): -+ for c0 in control_characters_c0(): -+ with self.assertRaises(ValueError): -+ self.client.user(f'user{c0}') -+ with self.assertRaises(ValueError): -+ self.client.pass_(f'{c0}pass') -+ - @requires_ssl - def test_stls_capa(self): - capa = self.client.capa() -diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst -new file mode 100644 -index 0000000000..3cde4df3e0 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst -@@ -0,0 +1 @@ -+Reject control characters in POP3 commands. diff --git a/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch b/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch deleted file mode 100644 index 1ba9248..0000000 --- a/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Petr Viktorin -Date: Fri, 6 Feb 2026 10:51:02 +0100 -Subject: 00477: Raise an error when importing stdlib modules compiled for a - different Python version - -This is a downstream workaround "implementing" -https://github.com/python/cpython/pull/137212 - -the mechanism for the check exists in Python 3.15+, where it needs to be -added to the standard library modules. -In Fedora, we need it also in previous Python versions, as we experience -segmentation fault when importing stdlib modules after update while -Python is running. - -_tkinter, _tracemalloc and readline are not calling PyModuleDef_Init, -which is modified with this patch, hence they need a -direct call to the check function. - -Co-Authored-By: Karolina Surma ---- - Include/moduleobject.h | 43 ++++++++++++++++++++++++++++++++++++++++++ - Makefile.pre.in | 3 +++ - Modules/_tkinter.c | 6 ++++++ - Modules/_tracemalloc.c | 6 ++++++ - Modules/readline.c | 6 ++++++ - Objects/moduleobject.c | 1 + - 6 files changed, 65 insertions(+) - -diff --git a/Include/moduleobject.h b/Include/moduleobject.h -index 2a17c891dd..64017c666c 100644 ---- a/Include/moduleobject.h -+++ b/Include/moduleobject.h -@@ -116,6 +116,49 @@ struct PyModuleDef { - freefunc m_free; - }; - -+#if defined(_PyHack_check_version_on_modinit) && defined(Py_BUILD_CORE) -+/* The mechanism for the check has been implemented on Python 3.15+: -+ * https://github.com/python/cpython/pull/137212. -+ * In Fedora, we need this in older Pythons too: -+ * if somebody attempts to import a module compiled for a different Python version, -+ * instead of segmentation fault a meaningful error is raised. -+ */ -+PyAPI_DATA(const unsigned long) Py_Version; -+ -+static inline int -+_PyHack_CheckInternalAPIVersion(const char *mod_name) -+{ -+ if (PY_VERSION_HEX != Py_Version) { -+ PyErr_Format( -+ PyExc_ImportError, -+ "internal Python C API version mismatch: " -+ "module %s compiled with %lu.%lu.%lu; " -+ "runtime version is %lu.%lu.%lu", -+ mod_name, -+ (const unsigned long)((PY_VERSION_HEX >> 24) & 0xFF), -+ (const unsigned long)((PY_VERSION_HEX >> 16) & 0xFF), -+ (const unsigned long)((PY_VERSION_HEX >> 8) & 0xFF), -+ (const unsigned long)((Py_Version >> 24) & 0xFF), -+ (const unsigned long)((Py_Version >> 16) & 0xFF), -+ (const unsigned long)((Py_Version >> 8) & 0xFF) -+ ); -+ return -1; -+ } -+ return 0; -+} -+ -+static inline PyObject * -+PyModuleDef_Init_with_check(PyModuleDef *def) -+{ -+ if (_PyHack_CheckInternalAPIVersion(def->m_name) < 0) { -+ return NULL; -+ } -+ return PyModuleDef_Init(def); -+} -+ -+#define PyModuleDef_Init PyModuleDef_Init_with_check -+#endif -+ - #ifdef __cplusplus - } - #endif -diff --git a/Makefile.pre.in b/Makefile.pre.in -index 526d500fe0..506ec30408 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -3426,3 +3426,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h - # Local Variables: - # mode: makefile - # End: -+ -+# Fedora-specific, downstream only -+PY_STDMODULE_CFLAGS += -D_PyHack_check_version_on_modinit=1 -diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c -index 22126b67d8..7ef5b5d5cd 100644 ---- a/Modules/_tkinter.c -+++ b/Modules/_tkinter.c -@@ -3611,6 +3611,12 @@ static struct PyModuleDef _tkintermodule = { - PyMODINIT_FUNC - PyInit__tkinter(void) - { -+ #ifdef _PyHack_check_version_on_modinit -+ if (_PyHack_CheckInternalAPIVersion("_tkinter") < 0) { -+ return NULL; -+ } -+ #endif -+ - PyObject *m, *uexe, *cexe; - - tcl_lock = PyThread_allocate_lock(); -diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c -index be71fc9fc9..67922098b2 100644 ---- a/Modules/_tracemalloc.c -+++ b/Modules/_tracemalloc.c -@@ -215,6 +215,12 @@ static struct PyModuleDef module_def = { - PyMODINIT_FUNC - PyInit__tracemalloc(void) - { -+ #ifdef _PyHack_check_version_on_modinit -+ if (_PyHack_CheckInternalAPIVersion("_tracemalloc") < 0) { -+ return NULL; -+ } -+ #endif -+ - PyObject *mod = PyModule_Create(&module_def); - if (mod == NULL) { - return NULL; -diff --git a/Modules/readline.c b/Modules/readline.c -index 7708f47d4d..7c0b70caa4 100644 ---- a/Modules/readline.c -+++ b/Modules/readline.c -@@ -1612,6 +1612,12 @@ static struct PyModuleDef readlinemodule = { - PyMODINIT_FUNC - PyInit_readline(void) - { -+ #ifdef _PyHack_check_version_on_modinit -+ if (_PyHack_CheckInternalAPIVersion("readline") < 0) { -+ return NULL; -+ } -+ #endif -+ - const char *backend = "readline"; - PyObject *m; - readlinestate *mod_state; -diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c -index b68584b5dd..cbf95dc92a 100644 ---- a/Objects/moduleobject.c -+++ b/Objects/moduleobject.c -@@ -50,6 +50,7 @@ _PyModule_IsExtension(PyObject *obj) - } - - -+#undef PyModuleDef_Init - PyObject* - PyModuleDef_Init(PyModuleDef* def) - { diff --git a/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch b/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch deleted file mode 100644 index 79101b5..0000000 --- a/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Thu, 16 Apr 2026 14:39:41 +0200 -Subject: 00486: gh-148646: Add --enable-prebuilt-jit-stencils configure flag - ---- - ...-04-16-14-39-33.gh-issue-148646.iIIgWF.rst | 6 +++++ - Tools/jit/_targets.py | 3 ++- - Tools/jit/build.py | 6 +++++ - configure | 26 +++++++++++++++++++ - configure.ac | 13 ++++++++++ - 5 files changed, 53 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Build/2026-04-16-14-39-33.gh-issue-148646.iIIgWF.rst - -diff --git a/Misc/NEWS.d/next/Build/2026-04-16-14-39-33.gh-issue-148646.iIIgWF.rst b/Misc/NEWS.d/next/Build/2026-04-16-14-39-33.gh-issue-148646.iIIgWF.rst -new file mode 100644 -index 0000000000..52dbc347a0 ---- /dev/null -+++ b/Misc/NEWS.d/next/Build/2026-04-16-14-39-33.gh-issue-148646.iIIgWF.rst -@@ -0,0 +1,6 @@ -+Add a new ``--enable-prebuilt-jit-stencils`` configure flag that forces the -+build to use the existing provided JIT stencils even when the digest at the -+beginning of the file does not match expectations. That allows -+redistributors who prebuilt the JIT stencils on a system with a different -+autoconf version to still use them even when ``pyconfig.h`` is slightly -+different. -diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py -index f1085cc9bf..3d8af735e2 100644 ---- a/Tools/jit/_targets.py -+++ b/Tools/jit/_targets.py -@@ -205,6 +205,7 @@ def build( - *, - comment: str = "", - force: bool = False, -+ prebuilt: bool = False, - jit_stencils: pathlib.Path, - ) -> None: - """Build jit_stencils.h in the given directory.""" -@@ -218,7 +219,7 @@ def build( - if ( - not force - and jit_stencils.exists() -- and jit_stencils.read_text().startswith(digest) -+ and (prebuilt or jit_stencils.read_text().startswith(digest)) - ): - return - stencil_groups = ASYNCIO_RUNNER.run(self._build_stencils()) -diff --git a/Tools/jit/build.py b/Tools/jit/build.py -index a073300592..5580985974 100644 ---- a/Tools/jit/build.py -+++ b/Tools/jit/build.py -@@ -42,6 +42,11 @@ - parser.add_argument( - "--cflags", help="additional flags to pass to the compiler", default="" - ) -+ parser.add_argument( -+ "--prebuilt", -+ action="store_true", -+ help="accept prebuilt stencils even if the digest does not match", -+ ) - args = parser.parse_args() - for target in args.target: - target.debug = args.debug -@@ -52,6 +57,7 @@ - target.build( - comment=comment, - force=args.force, -+ prebuilt=args.prebuilt, - jit_stencils=args.output_dir / f"jit_stencils-{target.triple}.h", - ) - jit_stencils_h = args.output_dir / "jit_stencils.h" -diff --git a/configure b/configure -index 2cb22a7806..1b396c92b2 100755 ---- a/configure -+++ b/configure -@@ -1105,6 +1105,7 @@ with_strict_overflow - enable_safety - enable_slower_safety - enable_experimental_jit -+enable_prebuilt_jit_stencils - with_dsymutil - with_address_sanitizer - with_memory_sanitizer -@@ -1842,6 +1843,9 @@ Optional Features: - --enable-experimental-jit[=no|yes|yes-off|interpreter] - build the experimental just-in-time compiler - (default is no) -+ --enable-prebuilt-jit-stencils -+ accept prebuilt JIT stencils even if the digest does -+ not match (default is no) - --enable-loadable-sqlite-extensions - support loadable extensions in the sqlite3 module, - see Doc/library/sqlite3.rst (default is no) -@@ -11045,6 +11049,28 @@ fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tier2_flags $jit_flags" >&5 - printf "%s\n" "$tier2_flags $jit_flags" >&6; } - -+# Check for --enable-prebuilt-jit-stencils: -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-prebuilt-jit-stencils" >&5 -+printf %s "checking for --enable-prebuilt-jit-stencils... " >&6; } -+# Check whether --enable-prebuilt-jit-stencils was given. -+if test ${enable_prebuilt_jit_stencils+y} -+then : -+ enableval=$enable_prebuilt_jit_stencils; -+else case e in #( -+ e) enable_prebuilt_jit_stencils=no ;; -+esac -+fi -+ -+if test "x$enable_prebuilt_jit_stencils" = xno -+then : -+ -+else case e in #( -+ e) as_fn_append REGEN_JIT_COMMAND " --prebuilt" ;; -+esac -+fi -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_prebuilt_jit_stencils" >&5 -+printf "%s\n" "$enable_prebuilt_jit_stencils" >&6; } -+ - if test "$disable_gil" = "yes" -a "$enable_experimental_jit" != "no"; then - # GH-133171: This configuration builds the JIT but never actually uses it, - # which is surprising (and strictly worse than not building it at all): -diff --git a/configure.ac b/configure.ac -index 967d34d47a..51160cafc2 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2873,6 +2873,19 @@ AC_SUBST([REGEN_JIT_COMMAND]) - AC_SUBST([JIT_STENCILS_H]) - AC_MSG_RESULT([$tier2_flags $jit_flags]) - -+# Check for --enable-prebuilt-jit-stencils: -+AC_MSG_CHECKING([for --enable-prebuilt-jit-stencils]) -+AC_ARG_ENABLE([prebuilt-jit-stencils], -+ [AS_HELP_STRING([--enable-prebuilt-jit-stencils], -+ [accept prebuilt JIT stencils even if the digest does not match (default is no)])], -+ [], -+ [enable_prebuilt_jit_stencils=no]) -+AS_VAR_IF([enable_prebuilt_jit_stencils], -+ [no], -+ [], -+ [AS_VAR_APPEND([REGEN_JIT_COMMAND], [" --prebuilt"])]) -+AC_MSG_RESULT([$enable_prebuilt_jit_stencils]) -+ - if test "$disable_gil" = "yes" -a "$enable_experimental_jit" != "no"; then - # GH-133171: This configuration builds the JIT but never actually uses it, - # which is surprising (and strictly worse than not building it at all): diff --git a/download-jit-stencils-from-koji.sh b/download-jit-stencils-from-koji.sh deleted file mode 100644 index 296af97..0000000 --- a/download-jit-stencils-from-koji.sh +++ /dev/null @@ -1,23 +0,0 @@ -set -eu -export LANG=C.utf-8 - -taskid=$(echo "$1" | sed -E 's/.*=|^([0-9]+)/\1/') -filter='.*-debugsource-.*\.(x86_64|aarch64)\.rpm' - -download_stdout=$(koji download-task $taskid --filter "$filter" | tee /dev/stderr) -files=$(echo "$download_stdout" | grep -E '^Downloading ' | sed -E 's/.*\s+(\S+)/\1/' | sort) - -for file in $files; do - nvra=${file/.rpm} - snvra=${nvra/-debugsource} - version=$(echo $nvra | sed -E -e 's|.*-([^-]+)-[^-]+|\1|' -e 's|~||') - arch=$(echo $nvra | sed -E 's|.*\.([^.]+)|\1|') - rpm2cpio $file | cpio -idmv ./usr/src/debug/${snvra}/build/{debug,optimized}/jit_stencils-${arch}-redhat-linux-gnu.h - for build in debug optimized; do - mv -v ./usr/src/debug/${snvra}/build/${build}/jit_stencils-${arch}-redhat-linux-gnu.h Python-${version}-${arch}-${build}-jit_stencils.h > /dev/stderr - echo Python-${version}-${arch}-${build}-jit_stencils.h - done - rmdir ./usr/src/debug/${snvra}{/build{/{debug,optimized},},} || : - rm -v $file > /dev/stderr -done -rmdir ./usr{/src{/debug,},} || : diff --git a/plan.fmf b/plan.fmf index bb45dcc..f681007 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,24 +24,15 @@ discover: test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} CYTHON=true ./venv.sh" - name: selftest path: /selftest - test: "VERSION=${pybasever} X='-i test_check_probes' ./parallel.sh" + test: "VERSION=${pybasever} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - name: debugtest path: /selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_base_interpreter' ./parallel.sh" + # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651 + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter -i test_interrupt -i test_interrupt_no_handler' ./parallel.sh" - name: freethreadingtest path: /selftest - test: "VERSION=${pybasever}t X='-i test_check_probes -i test_base_interpreter' ./parallel.sh" - - name: selftest_jit - path: /selftest - # test_attr_promotion_failure: https://github.com/python/cpython/issues/141833 - test: "VERSION=${pybasever} PYTHON_JIT=1 X='-i test_check_probes -i test_attr_promotion_failure' ./parallel.sh" - - name: jit_disabled_by_default - test: "python${pybasever} -c 'import sys; assert not sys._jit.is_enabled()'" - - name: jit_disabled_explicitly - test: "PYTHON_JIT=0 python${pybasever} -c 'import sys; assert not sys._jit.is_enabled()'" - - name: jit_enabled_explicitly - test: "PYTHON_JIT=1 python${pybasever} -c 'import sys; assert sys._jit.is_enabled()'" + test: "VERSION=${pybasever}t X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter' ./parallel.sh" - name: optimizedflags path: /flags test: "python${pybasever} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" @@ -57,9 +48,6 @@ discover: - name: marshalparser path: /marshalparser test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh" - - name: required_symbols - path: /required-symbols - test: "VERSION=${pybasever} ./check.sh" prepare: - name: Install dependencies @@ -81,9 +69,8 @@ prepare: - virtualenv # for virtualenv tests - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser - - binutils # for nm (symbol inspection) - rpm # for debugging - - dnf # for upgrade and downgrade + - dnf # for upgrade - name: Update packages how: shell script: dnf upgrade -y diff --git a/python3.14.spec b/python3.14.spec index 2d68d27..1649c29 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,7 +45,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.7 +%global general_version %{pybasever}.0 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -78,16 +78,13 @@ License: Python-2.0.1 # PEP 744: JIT Compilation # Whether to build with the experimental JIT compiler -# Only possible on certain architectures: https://peps.python.org/pep-0744/#support +# We can only have this on Fedora 41+, where clang 19+ is available +# And only on certain architectures: https://peps.python.org/pep-0744/#support # The freethreading build (when enabled) does not support JIT yet -%bcond jit %["%{_arch}" == "x86_64" || "%{_arch}" == "aarch64"] -# Whether to build the JIT stencils (or else use the prebuilt ones) -# We can only do this on Fedora 41+, where clang 19 is available -# We don't do it in RHEL, see https://github.com/fedora-eln/eln/issues/207 -%bcond jit_build_stencils %[%{with jit} && 0%{?fedora} >= 41] +%bcond jit %[(0%{?fedora} >= 41) && ("%{_arch}" == "x86_64" || "%{_arch}" == "aarch64")] %if %{with jit} # When built with JIT, it still needs to be enabled on runtime via PYTHON_JIT=1 -%global jit_flag --enable-experimental-jit=yes-off %{!?with_jit_build_stencils:--enable-prebuilt-jit-stencils} +%global jit_flag --enable-experimental-jit=yes-off %endif # Main interpreter loop optimization @@ -112,30 +109,31 @@ License: Python-2.0.1 # This needs to be manually updated when we update Python. # Explore the sources tarball (you need the version before %%prep is executed): # $ tar -tf Python-%%{upstream_version}.tar.xz | grep whl -%global pip_version 26.2.1 +%global pip_version 25.2 %global setuptools_version 79.0.1 # All of those also include a list of indirect bundled libs: # pip # $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) %global pip_bundled_provides %{expand: -Provides: bundled(python3dist(cachecontrol)) = 0.14.4 -Provides: bundled(python3dist(certifi)) = 2026.6.17 -Provides: bundled(python3dist(distlib)) = 0.4.2 +Provides: bundled(python3dist(cachecontrol)) = 0.14.3 +Provides: bundled(python3dist(certifi)) = 2025.7.14 +Provides: bundled(python3dist(dependency-groups)) = 1.3.1 +Provides: bundled(python3dist(distlib)) = 0.4 Provides: bundled(python3dist(distro)) = 1.9 -Provides: bundled(python3dist(idna)) = 3.18 -Provides: bundled(python3dist(msgpack)) = 1.1.2 -Provides: bundled(python3dist(packaging)) = 26.2 -Provides: bundled(python3dist(platformdirs)) = 4.10 -Provides: bundled(python3dist(pygments)) = 2.20 +Provides: bundled(python3dist(idna)) = 3.10 +Provides: bundled(python3dist(msgpack)) = 1.1.1 +Provides: bundled(python3dist(packaging)) = 25 +Provides: bundled(python3dist(platformdirs)) = 4.3.8 +Provides: bundled(python3dist(pygments)) = 2.19.2 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 -Provides: bundled(python3dist(requests)) = 2.34.2 -Provides: bundled(python3dist(resolvelib)) = 1.2.1 -Provides: bundled(python3dist(rich)) = 14.2 +Provides: bundled(python3dist(requests)) = 2.32.4 +Provides: bundled(python3dist(resolvelib)) = 1.2 +Provides: bundled(python3dist(rich)) = 14.1 Provides: bundled(python3dist(setuptools)) = 70.3 -Provides: bundled(python3dist(tomli)) = 2.4.1 +Provides: bundled(python3dist(tomli)) = 2.2.1 Provides: bundled(python3dist(tomli-w)) = 1.2 -Provides: bundled(python3dist(truststore)) = 0.10.4 -Provides: bundled(python3dist(urllib3)) = 2.7 +Provides: bundled(python3dist(truststore)) = 0.10.1 +Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools # vendor.txt not in .whl @@ -261,7 +259,7 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\ BuildRequires: autoconf BuildRequires: bluez-libs-devel BuildRequires: bzip2-devel -BuildRequires: expat-devel >= 2.5.0-2 +BuildRequires: expat-devel BuildRequires: findutils BuildRequires: gcc BuildRequires: gdbm-devel @@ -275,6 +273,7 @@ BuildRequires: libzstd-devel BuildRequires: make BuildRequires: mpdecimal-devel BuildRequires: ncurses-devel +BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: readline-devel @@ -287,10 +286,6 @@ BuildRequires: xz-devel BuildRequires: zlib-devel BuildRequires: /usr/bin/dtrace -# Support for OpenSSL 4 only landed in Python 3.15 for now -# https://github.com/python/cpython/issues/146207 -BuildRequires: (openssl-devel < 1:4 or openssl3-devel) - %if %{with tests} BuildRequires: gcc-c++ BuildRequires: gdb @@ -298,7 +293,7 @@ BuildRequires: glibc-all-langpacks BuildRequires: tzdata %endif -%if %{with jit_build_stencils} +%if %{with jit} BuildRequires: clang(major) = 19 BuildRequires: llvm(major) = 19 %endif @@ -352,27 +347,6 @@ Source10: idle3.desktop # AppData file for idle3 Source11: idle3.appdata.xml -# Pre-generated JIT stencils (see PEP 774) -# As the PEP was deferred, we use stencils we built for ourselves. -# Only used on platforms without the required LLVM version. -# -# When updating Python: -# 1. scratch build Python on platform with required LLVM version (usually rawhide) -# 2. download the files from Koji: -# $ bash download-jit-stencils-from-koji.sh KOJI_TASK_URL|KOJI_TASK_ID -# 3. add the files to lookaside cache with fedpkg new-sources -Source30: download-jit-stencils-from-koji.sh -# This %%if-hack makes it easier to do step 1. from the above. -# Use `fedpkg sources --force` to get the conditionally defined sources from the lookaside cache. -%if (%{with jit} && %{without jit_build_stencils}) || %{exists:%{_sourcedir}/Python-%{upstream_version}-x86_64-optimized-jit_stencils.h} -Source31: Python-%{upstream_version}-aarch64-debug-jit_stencils.h -Source32: Python-%{upstream_version}-aarch64-optimized-jit_stencils.h -Source33: Python-%{upstream_version}-x86_64-debug-jit_stencils.h -Source34: Python-%{upstream_version}-x86_64-optimized-jit_stencils.h -%endif -%global jit_stencils_source %{_sourcedir}/Python-%{upstream_version}-%{_arch}-${ConfName}-jit_stencils.h -%global jit_stencils_filename jit_stencils-%{_arch}-redhat-linux-gnu.h - # (Patches taken from github.com/fedora-python/cpython) # 00251 # 5ac6e7781923cbb3e4606e3bca381a1167d322e5 @@ -392,50 +366,37 @@ Source34: Python-%{upstream_version}-x86_64-optimized-jit_stencils.h # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00466 # 713a1368544eddd55088d67f88a23ce31722a4cb -# Downstream only: Lower XML_COMBINED_VERSION threshold for reparse deferral +# 00461 # 920175020b21c0aff5edcc4c28d688b5061f591c +# Downstream only: Install wheel in test venvs when setuptools < 71 # -# RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported -# via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. -# CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter -# as a no-op, so SetReparseDeferralEnabled silently does nothing and -# GetReparseDeferralEnabled always returns False, even though the expat -# library actually supports (and enables) reparse deferral. -# -# Lower the threshold from 20600 to 20500 so that CPython uses the -# backported function. This makes the Python API actually work on RHEL 9 -# and fixes test failures (test_reparse_deferral_disabled, -# test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). -# -# The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the -# backported function is available. -Patch466: 00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch +# This can be removed when Fedora 41 goes EOL (or updates setuptools). +Patch461: 00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch -# 00475 # 91e12ebfb2a88b265f3764a0d852b6fa53b2386a -# CVE-2025-15367 +# 00464 # 292acffec7a379cb6d1f3c47b9e5a2f170bbadb6 +# Enable PAC and BTI protections for aarch64 # -# Downstream only: Reject control characters in POP3 commands -Patch475: 00475-cve-2025-15367.patch +# Apply protection against ROP/JOP attacks for aarch64 on asm_trampoline.S +# +# The BTI flag must be applied in the assembler sources for this class +# of attacks to be mitigated on newer aarch64 processors. +# +# Upstream PR: https://github.com/python/cpython/pull/130864/files +# +# The upstream patch is incomplete but only for the case where +# frame pointers are not used on 3.13+. +# +# Since on Fedora we always compile with frame pointers the BTI/PAC +# hardware protections can be enabled without losing Perf unwinding. +Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch -# 00477 # f9f53e560d161531a0c3476c08ee26b89a628bde -# Raise an error when importing stdlib modules compiled for a different Python version +# 00466 # e10760fb955ee33d2917f8a57bb4e24d71e5341c +# Downstream only: Skip tests not working with older expat version # -# This is a downstream workaround "implementing" -# https://github.com/python/cpython/pull/137212 - -# the mechanism for the check exists in Python 3.15+, where it needs to be -# added to the standard library modules. -# In Fedora, we need it also in previous Python versions, as we experience -# segmentation fault when importing stdlib modules after update while -# Python is running. -# -# _tkinter, _tracemalloc and readline are not calling PyModuleDef_Init, -# which is modified with this patch, hence they need a -# direct call to the check function. -Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch - -# 00486 # 5ae0b81b3135319f8d75a886fb7a11fa40ac11f4 -# gh-148646: Add --enable-prebuilt-jit-stencils configure flag -Patch486: 00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch +# We want to run these tests in Fedora and EPEL 10, but not in EPEL 9, +# which has too old version of expat. We set the upper bound version +# in the conditionalized skip to a release available in CentOS Stream 10, +# which is tested as working. +Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch # (New patches go here ^^^) # @@ -561,7 +522,7 @@ Summary: Python runtime libraries # Combined manually from https://docs.python.org/3.14/license.html # Hash of Doc/license.rst which is compared in %%prep, generated with: # $ sha256sum Doc/license.rst | cut -f1 -d" " -%global license_file_hash cd6f471c0bfdb099efefc25ddff9b3df8bf62e10428987f1f05e6f2f9e35d563 +%global license_file_hash c695d550b135e53e38807e76496d1db17d22c40e461d1f3f354c86188d3305dd # Licenses of incorporated software: # Mersenne Twister in _random C extension contains code under BSD-3-Clause # socket.getaddrinfo() and socket.getnameinfo() are BSD-3-Clause @@ -585,8 +546,7 @@ Summary: Python runtime libraries # parts of asyncio from uvloop are MIT # Python/qsbr.c is adapted from code under BSD-2-Clause # Zstandard bindings in Modules/_zstd and Lib/compression/zstd are BSD-3-Clause -# An extract of the `Unicode Character Database` converted to an internal format is Unicode-3.0 -%global libs_license Python-2.0.1 AND MIT AND BSD-3-Clause AND MIT-CMU AND HPND-SMC AND BSD-2-Clause AND dtoa AND Unicode-3.0 +%global libs_license Python-2.0.1 AND MIT AND BSD-3-Clause AND MIT-CMU AND HPND-SMC AND BSD-2-Clause AND dtoa %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 License: %{libs_license} @@ -618,27 +578,6 @@ Recommends: (%{pkgname}-tkinter%{?_isa} if tk%{?_isa}) # The zoneinfo module needs tzdata Requires: tzdata -# The requirement on libexpat is generated, but we need to version it. -# When built with a specific expat version, but installed with an older one, -# we sometimes get: -# ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so: -# undefined symbol: XML_... -# The pyexpat module has build-time checks for expat version to only use the -# available symbols. However, there is no runtime protection, so when the module -# is later installed with an older expat, it may error due to undefined symbols. -# This breaks many things, including python -m venv. -# We avoid this problem by requiring at least the same version of expat that -# was used during the build time. -# We also include release, in case pyxpat uses ABI that was backported -# (e.g. XML_SetReparseDeferralEnabled was added in c9s expat 2.5.0-2). -# Other subpackages (like -debug) also need this, but they all depend on -libs. -# Since expat 2.7.4, the library has versioned symbols and this is no longer needed, -# as the generated requirement will be in the form of libexpat.so.1(LIBEXPAT_2.7.2) etc. -%global expat_version %(LANG=C rpm -q --qf '%%{version}-%%{release}' expat.%{_target_cpu} | sed 's/.*not installed/0/') -%if v"%{expat_version}" < v"2.7.4" -Requires: expat%{?_isa} >= %{expat_version} -%endif - %description -n %{pkgname}-libs This package contains runtime libraries for use by Python: @@ -836,9 +775,6 @@ License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AN # See the comments in the definition of main -libs subpackage for detailed explanations Provides: bundled(mimalloc) = 2.12 Requires: tzdata -%if v"%{expat_version}" < v"2.7.4" -Requires: expat%{?_isa} >= %{expat_version} -%endif # There are files in the standard library that have python shebang. # We've filtered the automatic requirement out so libs are installable without @@ -860,7 +796,7 @@ This package contains runtime libraries for use by Free Threading Python: %package -n python%{pybasever}-freethreading-devel -Summary: Libraries and header files needed for Free Threading Python development +Summary: Libraries and header files needed for Free Threading Python evelopment # Bundled mimalloc header files are MIT License: Python-2.0.1 AND MIT Requires: python%{pybasever}-freethreading = %{version}-%{release} @@ -1084,6 +1020,9 @@ BuildPython() { # Since we changed directories, we need to tell %%configure where to look. %global _configure $topdir/configure + # A workaround for https://bugs.python.org/issue39761 + export DFLAGS=" " + %configure \ --with-platlibdir=%{_lib} \ --enable-ipv6 \ @@ -1106,12 +1045,6 @@ BuildPython() { $ExtraConfigArgs \ %{nil} -%if %{with jit} && %{without jit_build_stencils} - if [[ ! "$ConfName" =~ ^freethreading ]]; then - cp -a %{jit_stencils_source} %{jit_stencils_filename} - fi -%endif - %global flags_override EXTRA_CFLAGS="$MoreCFlags" CFLAGS_NODIST="$CFLAGS_NODIST $MoreCFlags" %if %{without bootstrap} @@ -1185,6 +1118,12 @@ topdir=$(pwd) DirHoldingGdbPy=%{_usr}/lib/debug/%{_libdir} mkdir -p %{buildroot}$DirHoldingGdbPy +# When the actual %%{dynload_dir} exists (it does when python3.X is installed for regen-all) +# %%{buildroot}%%{dynload_dir} is not created by make install and the extension modules are missing +# Reported upstream as https://github.com/python/cpython/issues/98782 +# A workaround is to create the directory before running make install +mkdir -p %{buildroot}%{dynload_dir} + # Multilib support for pyconfig.h # 32- and 64-bit versions of pyconfig.h are different. For multilib support # (making it possible to install 32- and 64-bit versions simultaneously), @@ -1423,11 +1362,6 @@ for file in %{buildroot}%{pylibdir}/pydoc_data/topics.py $(grep --include='*.py' rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py} done -%if %{without rpmwheels} -# Inject SBOM into the installed wheels (if the macro is available) -%{?python_wheel_inject_sbom:%python_wheel_inject_sbom %{buildroot}%{pylibdir}/ensurepip/_bundled/*.whl} -%endif - # ====================================================== # Checks for packaging issues # ====================================================== @@ -1463,17 +1397,6 @@ for Module in %{buildroot}/%{dynload_dir}/*.so ; do esac done -# Assert the pre-generated JIT stencils are up to date -%if %{with jit_build_stencils} -for ConfName in %{?with_debug_build:debug} optimized; do - if [ -s %{jit_stencils_source} ]; then - # The -I option ignores the checksum line (calculated from files incl. pyconfig.h which may change with new autoconf) - diff -u -I '^// [0-9a-f]\{64\}$' %{jit_stencils_source} build/${ConfName}/%{jit_stencils_filename} - else - echo "%{jit_stencils_source} is empty, not checking if it is up to date" - fi -done -%endif # ====================================================== # Running the upstream test suite @@ -1494,9 +1417,18 @@ CheckPython() { # Run the upstream test suite # --timeout=2700: kill test running for longer than 45 minutes + # test_freeze_simple_script is skipped, because it fails without bundled libs. + # the freeze tool is only usable from the source checkout anyway, + # we don't ship it in the RPM package. # test_check_probes is failing since it was introduced in 3.12.0rc1, # the test is skipped until it is fixed in upstream. # see: https://github.com/python/cpython/issues/104280#issuecomment-1669249980 + # test_signal is skipped due to https://github.com/python/cpython/issues/118989 + # test.test_concurrent_futures.test_deadlock tends to time out on s390x and ppc64le in + # freethreading{,-debug} build, skipping it to shorten the build time + # see: https://github.com/python/cpython/issues/121719 + # test_interrupt and test_interrupt_no_handler + # reported in https://github.com/python/cpython/issues/133651 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1504,7 +1436,17 @@ CheckPython() { %else --timeout=2700 \ %endif + -i test_freeze_simple_script \ -i test_check_probes \ + -i test_interrupt \ + -i test_interrupt_no_handler \ + %ifarch %{mips64} + -x test_ctypes \ + %endif + %ifarch s390x ppc64le + -x test_signal \ + -i test_deadlock \ + %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1994,53 +1936,6 @@ CheckPython freethreading # ====================================================== %changelog -* Tue Aug 18 2026 Miro Hrončok - 3.14.7-2 -- On RHEL 9, also supports reparse deferral in expat - -* Mon Aug 10 2026 Karolina Surma - 3.14.7-1 -- Update to Python 3.14.7 - -* Thu Jul 16 2026 Fedora Release Engineering - 3.14.6-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild - -* Thu Jun 11 2026 Karolina Surma - 3.14.6-1 -- Update to Python 3.14.6 - -* Wed Jun 03 2026 Python Maint - 3.14.5-2 -- Rebuilt as non-main Python on Fedora 45+ - -* Mon May 11 2026 Miro Hrončok - 3.14.5-1 -- Update to 3.14.5 - -* Tue May 05 2026 Miro Hrončok - 3.14.5~rc1-1 -- Update to 3.14.5rc1 - -* Thu Apr 16 2026 Charalampos Stratakis - 3.14.4-2 -- Security fixes for CVE-2026-1502, CVE-2026-4786, CVE-2026-5713, CVE-2026-6100 -Resolves: rhbz#2457944, rhbz#2458224, rhbz#2458488, rhbz#2458016 - -* Wed Apr 08 2026 Karolina Surma - 3.14.4-1 -- Update to Python 3.14.4 - -* Thu Mar 26 2026 Lumír Balhar - 3.14.3-2 -- Security fix for CVE-2026-4519 (rhbz#2449730) - -* Wed Feb 04 2026 Karolina Surma - 3.14.3-1 -- Update to Python 3.14.3 -- Fix CVE-2025-15366, CVE-2025-15367 - -* Sat Jan 17 2026 Fedora Release Engineering - 3.14.2-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild - -* Tue Jan 06 2026 Karolina Surma - 3.14.2-2 -- Require at least the same expat version as used during the build time - -* Fri Dec 05 2025 Miro Hrončok - 3.14.2-1 -- Update to Python 3.14.2 - -* Wed Dec 03 2025 Karolina Surma - 3.14.1-1 -- Update to Python 3.14.1 - * Fri Oct 17 2025 Karolina Surma - 3.14.0-2 - Split -freethreading package into analogs of the main Python diff --git a/rpmlint.toml b/rpmlint.toml index 7ed20ba..0864a1c 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -6,7 +6,7 @@ Filters = [ # TESTS: - '(zero-length|pem-certificate|uncompressed-zip|file-not-in-%lang) /usr/lib(64)?/python3\.\d+t?/test', + '(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3\.\d+t?/test', # OTHER DELIBERATES: @@ -21,9 +21,6 @@ Filters = [ 'unversioned Obsoletes: Obsoletes: python3\.\d+$', 'self-obsoletion python3\.\d+(-\S+)? obsoletes python3\.\d+(-\S+)?', - # freethreading subpackages obsolete python3.X-freethreading, but don't provide it - '^python3(\.\d+)?-freethreading(-\w+)?\.[^:]+: (E|W): obsolete-not-provided python3(\.\d+)?-freethreading$', - # intentionally hardcoded 'hardcoded-library-path in %{_prefix}/lib/(debug/%{_libdir}|python%{pybasever})', @@ -40,9 +37,6 @@ Filters = [ # if this regex needs to be relaxed in the future, make sure it **does not** match pyc files in __pycache__ 'python-bytecode-without-source /usr/lib(64)?/python3\.\d+t?/(encodings|pydoc_data)/[^/]+.pyc', - # https://docs.fedoraproject.org/en-US/packaging-guidelines/RPM_Source_Dir/#_exceptions - 'use-of-RPM_SOURCE_DIR', - # DUPLICATE FILES # test data are often duplicated '(E|W): files-duplicate /usr/lib(64)?/python3\.\d+t?/(test|__phello__)/', @@ -61,10 +55,7 @@ Filters = [ 'no-manual-page-for-binary python3\.\d+t?dm?$', # missing documentation from subpackages - '^python3(\.\d+)?-(freethreading(-\w+)?|debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation', - - # idle subpackages have no binaries - '^python3(\.\d+)?-(freethreading-)?idle\.[^:]+: (E|W): no-binary', + '^python3(\.\d+)?-(freethreading(-debug)?|debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation', # platform python is obsoleted, but not provided 'obsolete-not-provided platform-python', @@ -110,6 +101,6 @@ Filters = [ '\bpython3(\.\d+)?\.(src|spec): (E|W): specfile-error\s+$', # SPELLING ERRORS - 'spelling-error .*\b(bytecode|pyc|filename|tkinter|namespaces|pytest|unittest|gil|CPython)\b', + 'spelling-error .* en_US (bytecode|pyc|filename|tkinter|namespaces|pytest|unittest|gil) ', ] diff --git a/sources b/sources index 48e32a1..3a6d2f0 100644 --- a/sources +++ b/sources @@ -1,5 +1 @@ -SHA512 (Python-3.14.7.tar.xz) = 3d4e2e2f983b320dec47005c408d7178d3656a6de0c4430ce21514797174b972f461200898b25d3dfac2a455019ef87e45d0fb2bb6ec2ca887124d10037a2a07 -SHA512 (Python-3.14.7-aarch64-debug-jit_stencils.h) = 85bf4cdf5996ede2932aa1b5ffb0c3befe7fb395efdadaeedc05969bbf8f4db1fe825666276239183ec24caa58f2307983876b29efa86ac54bd5802c85ab1d3c -SHA512 (Python-3.14.7-aarch64-optimized-jit_stencils.h) = e7245f166126184655275dd5a90a4251e73ed042fc0d9b46624f55faa698a676a6714f8d2577aecd0a03fb54a6fda3d23b1391a1872b66c130b79b817699ab82 -SHA512 (Python-3.14.7-x86_64-debug-jit_stencils.h) = e34b31bcc3959b3fbd9cac07df69eababfab2ff42101a0dc14af34c67775c73ef48dcac658ac0c1f58c8c2957bd88a553a748f849e566d4cf66c0a5d9722f14d -SHA512 (Python-3.14.7-x86_64-optimized-jit_stencils.h) = d17bf0d61136580dfe589dbcac2d51bbb3fa75f467e008ad2000a7f778427f32aef3f88efb46a1c01c4aa4af8878d51d4f4e0b1d18976906ea332bfe6c11e1fe +SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53