From 42592ff6cab38758132c2f448489d44bbe36c6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 5 Dec 2024 11:50:31 +0100 Subject: [PATCH 01/88] Optimize patch 251 a tiny bit Before: $ python3.14 -m timeit -s 'import sysconfig' 'sysconfig.get_paths()' 2000 loops, best of 5: 157 usec per loop $ python3.14 -m timeit -s 'import sysconfig' 'sysconfig.get_paths()' 2000 loops, best of 5: 162 usec per loop $ python3.14 -m timeit -s 'import sysconfig' 'sysconfig.get_paths()' 1000 loops, best of 5: 146 usec per loop After: $ python3.14 -m timeit -s 'import sysconfig' 'sysconfig.get_paths()' 5000 loops, best of 5: 75.9 usec per loop $ python3.14 -m timeit -s 'import sysconfig' 'sysconfig.get_paths()' 5000 loops, best of 5: 77.1 usec per loop $ python3.14 -m timeit -s 'import sysconfig' 'sysconfig.get_paths()' 5000 loops, best of 5: 76.2 usec per loop This can be shipped together with the next alpha release. --- 00251-change-user-install-location.patch | 4 ++-- python3.14.spec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index c5e4b20..7f45c46 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -51,7 +51,7 @@ index 54f07ab5b4..69ceaa443e 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index 67a071963d..371e6844b8 100644 +index 67a071963d..0aa8313d6b 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -120,7 +120,7 @@ index 67a071963d..371e6844b8 100644 + # we only change the defaults here, so explicit --prefix will take precedence + # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe + if (scheme == 'posix_prefix' and -+ get_config_vars('prefix')[0] == '/usr' and ++ sys.prefix == '/usr' and + 'RPM_BUILD_ROOT' not in os.environ): + _extend_dict(vars, _config_vars_local()) + else: diff --git a/python3.14.spec b/python3.14.spec index c374f74..ddb9c9d 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -334,7 +334,7 @@ Source11: idle3.appdata.xml # (Patches taken from github.com/fedora-python/cpython) -# 00251 # f5b56b9d4a79df04e9d90ceff7388554c5f818b6 +# 00251 # 5ac6e7781923cbb3e4606e3bca381a1167d322e5 # Change user install location # # Set values of base and platbase in sysconfig from /usr From 1e0faaa82bf804e8e2abfc674e1c702c4913b8f3 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Sun, 8 Dec 2024 21:28:58 +0100 Subject: [PATCH 02/88] Security fix for CVE-2024-12254 Fixes: rhbz#2330928 --- ...elines-pauses-the-protocol-if-needed.patch | 60 +++++++++++++++++++ python3.14.spec | 14 ++++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch diff --git a/00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch b/00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch new file mode 100644 index 0000000..2a7b330 --- /dev/null +++ b/00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "J. Nick Koston" +Date: Thu, 5 Dec 2024 22:33:03 -0600 +Subject: [PATCH] 00445: CVE-2024-12254: Ensure + _SelectorSocketTransport.writelines pauses the protocol if needed + +Ensure _SelectorSocketTransport.writelines pauses the protocol if it reaches the high water mark as needed. + +Resolved upstream: https://github.com/python/cpython/issues/127655 + +Co-authored-by: Kumar Aditya +--- + Lib/asyncio/selector_events.py | 1 + + Lib/test/test_asyncio/test_selector_events.py | 12 ++++++++++++ + .../2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst | 1 + + 3 files changed, 14 insertions(+) + create mode 100644 Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst + +diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py +index f94bf10b42..f1ab9b12d6 100644 +--- a/Lib/asyncio/selector_events.py ++++ b/Lib/asyncio/selector_events.py +@@ -1175,6 +1175,7 @@ def writelines(self, list_of_data): + # If the entire buffer couldn't be written, register a write handler + if self._buffer: + self._loop._add_writer(self._sock_fd, self._write_ready) ++ self._maybe_pause_protocol() + + def can_write_eof(self): + return True +diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py +index aaeda33dd0..efca30f374 100644 +--- a/Lib/test/test_asyncio/test_selector_events.py ++++ b/Lib/test/test_asyncio/test_selector_events.py +@@ -805,6 +805,18 @@ def test_writelines_send_partial(self): + self.assertTrue(self.sock.send.called) + self.assertTrue(self.loop.writers) + ++ def test_writelines_pauses_protocol(self): ++ data = memoryview(b'data') ++ self.sock.send.return_value = 2 ++ self.sock.send.fileno.return_value = 7 ++ ++ transport = self.socket_transport() ++ transport._high_water = 1 ++ transport.writelines([data]) ++ self.assertTrue(self.protocol.pause_writing.called) ++ self.assertTrue(self.sock.send.called) ++ self.assertTrue(self.loop.writers) ++ + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_write_sendmsg_full(self): + data = memoryview(b'data') +diff --git a/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst b/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst +new file mode 100644 +index 0000000000..76cfc58121 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst +@@ -0,0 +1 @@ ++Fixed the :class:`!asyncio.selector_events._SelectorSocketTransport` transport not pausing writes for the protocol when the buffer reaches the high water mark when using :meth:`asyncio.WriteTransport.writelines`. diff --git a/python3.14.spec b/python3.14.spec index ddb9c9d..de45b89 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel a2 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -351,6 +351,14 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch +# 00445 # d1a32daddefad32ceb93155552858c0a0311b23e +# CVE-2024-12254: Ensure _SelectorSocketTransport.writelines pauses the protocol if needed +# +# Ensure _SelectorSocketTransport.writelines pauses the protocol if it reaches the high water mark as needed. +# +# Resolved upstream: https://github.com/python/cpython/issues/127655 +Patch445: 00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1688,6 +1696,10 @@ CheckPython freethreading # ====================================================== %changelog +* Sun Dec 08 2024 Charalampos Stratakis - 3.14.0~a2-2 +- Security fix for CVE-2024-12254 +- Fixes: rhbz#2330928 + * Wed Nov 20 2024 Karolina Surma - 3.14.0~a2-1 - Update to Python 3.14.0a2 From 31971f96ff4f938903775e5812fa065e6121a3bb Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 17 Dec 2024 19:27:38 +0100 Subject: [PATCH 03/88] Update to Python 3.14.0a3 selftest and debugtest in tests/tests.yml exclude test_sysconfigdata_json for now, reported upstream as: https://github.com/python/cpython/issues/128055 --- 00251-change-user-install-location.patch | 14 ++--- ...elines-pauses-the-protocol-if-needed.patch | 60 ------------------- python3.14.spec | 29 +++++---- sources | 2 +- tests/tests.yml | 4 +- 5 files changed, 26 insertions(+), 83 deletions(-) delete mode 100644 00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 7f45c46..ce93045 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -30,10 +30,10 @@ Co-authored-by: Lumír Balhar 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Lib/site.py b/Lib/site.py -index 54f07ab5b4..69ceaa443e 100644 +index 92bd1ccdad..951784f3b4 100644 --- a/Lib/site.py +++ b/Lib/site.py -@@ -414,8 +414,15 @@ def getsitepackages(prefixes=None): +@@ -420,8 +420,15 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): @@ -51,7 +51,7 @@ index 54f07ab5b4..69ceaa443e 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index 67a071963d..0aa8313d6b 100644 +index ed7b6a335d..2b1ee37775 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -130,10 +130,10 @@ index 67a071963d..0aa8313d6b 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 9bbf8d0c6c..609bf5c373 100644 +index ce504dc21a..054e514130 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py -@@ -130,8 +130,19 @@ def test_get_path(self): +@@ -138,8 +138,19 @@ def test_get_path(self): for scheme in _INSTALL_SCHEMES: for name in _INSTALL_SCHEMES[scheme]: expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars) @@ -154,7 +154,7 @@ index 9bbf8d0c6c..609bf5c373 100644 os.path.normpath(expected), ) -@@ -386,7 +397,7 @@ def test_get_config_h_filename(self): +@@ -394,7 +405,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 9bbf8d0c6c..609bf5c373 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -398,6 +409,8 @@ def test_symlink(self): # Issue 7880 +@@ -406,6 +417,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/00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch b/00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch deleted file mode 100644 index 2a7b330..0000000 --- a/00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "J. Nick Koston" -Date: Thu, 5 Dec 2024 22:33:03 -0600 -Subject: [PATCH] 00445: CVE-2024-12254: Ensure - _SelectorSocketTransport.writelines pauses the protocol if needed - -Ensure _SelectorSocketTransport.writelines pauses the protocol if it reaches the high water mark as needed. - -Resolved upstream: https://github.com/python/cpython/issues/127655 - -Co-authored-by: Kumar Aditya ---- - Lib/asyncio/selector_events.py | 1 + - Lib/test/test_asyncio/test_selector_events.py | 12 ++++++++++++ - .../2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst | 1 + - 3 files changed, 14 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst - -diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py -index f94bf10b42..f1ab9b12d6 100644 ---- a/Lib/asyncio/selector_events.py -+++ b/Lib/asyncio/selector_events.py -@@ -1175,6 +1175,7 @@ def writelines(self, list_of_data): - # If the entire buffer couldn't be written, register a write handler - if self._buffer: - self._loop._add_writer(self._sock_fd, self._write_ready) -+ self._maybe_pause_protocol() - - def can_write_eof(self): - return True -diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py -index aaeda33dd0..efca30f374 100644 ---- a/Lib/test/test_asyncio/test_selector_events.py -+++ b/Lib/test/test_asyncio/test_selector_events.py -@@ -805,6 +805,18 @@ def test_writelines_send_partial(self): - self.assertTrue(self.sock.send.called) - self.assertTrue(self.loop.writers) - -+ def test_writelines_pauses_protocol(self): -+ data = memoryview(b'data') -+ self.sock.send.return_value = 2 -+ self.sock.send.fileno.return_value = 7 -+ -+ transport = self.socket_transport() -+ transport._high_water = 1 -+ transport.writelines([data]) -+ self.assertTrue(self.protocol.pause_writing.called) -+ self.assertTrue(self.sock.send.called) -+ self.assertTrue(self.loop.writers) -+ - @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') - def test_write_sendmsg_full(self): - data = memoryview(b'data') -diff --git a/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst b/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst -new file mode 100644 -index 0000000000..76cfc58121 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst -@@ -0,0 +1 @@ -+Fixed the :class:`!asyncio.selector_events._SelectorSocketTransport` transport not pausing writes for the protocol when the buffer reaches the high water mark when using :meth:`asyncio.WriteTransport.writelines`. diff --git a/python3.14.spec b/python3.14.spec index de45b89..bf86280 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,10 +14,10 @@ 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}.0 -%global prerel a2 +%global prerel a3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -351,14 +351,6 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00445 # d1a32daddefad32ceb93155552858c0a0311b23e -# CVE-2024-12254: Ensure _SelectorSocketTransport.writelines pauses the protocol if needed -# -# Ensure _SelectorSocketTransport.writelines pauses the protocol if it reaches the high water mark as needed. -# -# Resolved upstream: https://github.com/python/cpython/issues/127655 -Patch445: 00445-cve-2024-12254-ensure-_selectorsockettransport-writelines-pauses-the-protocol-if-needed.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1247,8 +1239,8 @@ CheckPython() { # 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_ctypes.test_generated_structs.GeneratedTest.test_generated_data is skipped since - # 3.14.0a1, see: https://github.com/python/cpython/issues/121938 + # test_*_repeat_respect_immortality and test_immortals failures were reported: + # https://github.com/python/cpython/issues/128058 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1266,7 +1258,9 @@ CheckPython() { -i test_deadlock \ %endif %ifarch %{ix86} - -i test_generated_data \ + -i test_tuple_repeat_respect_immortality \ + -i test_list_repeat_respect_immortality \ + -i test_immortals \ %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1375,6 +1369,8 @@ CheckPython freethreading %pure_python_modules %{pylibdir} +%{pylibdir}/_sysconfig_vars_%{ABIFLAGS_optimized}_linux_%{platform_triplet}.json + # This will be in the tkinter package %exclude %{pylibdir}/turtle.py %exclude %{pylibdir}/__pycache__/turtle*%{bytecode_suffixes} @@ -1600,6 +1596,7 @@ CheckPython freethreading %{pylibdir}/_sysconfigdata_%{ABIFLAGS_debug}_linux_%{platform_triplet}.py %{pylibdir}/__pycache__/_sysconfigdata_%{ABIFLAGS_debug}_linux_%{platform_triplet}%{bytecode_suffixes} +%{pylibdir}/_sysconfig_vars_%{ABIFLAGS_debug}_linux_%{platform_triplet}.json %endif # with debug_build @@ -1621,6 +1618,8 @@ CheckPython freethreading %{pylibdir_freethreading}/tkinter/ %{pylibdir_freethreading}/turtledemo/ +%{pylibdir_freethreading}/_sysconfig_vars_%{ABIFLAGS_freethreading}_linux_%{platform_triplet}.json + # This will be in the -freethreading-debug package %if %{with debug_build} %exclude %{pylibdir_freethreading}/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}.py @@ -1672,6 +1671,7 @@ CheckPython freethreading %{pylibdir_freethreading}/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}.py %{pylibdir_freethreading}/__pycache__/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}%{bytecode_suffixes} +%{pylibdir_freethreading}/_sysconfig_vars_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}.json %endif # with freethreading_build && debug_build @@ -1696,6 +1696,9 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Dec 17 2024 Karolina Surma - 3.14.0~a3-1 +- Update to Python 3.14.0a3 + * Sun Dec 08 2024 Charalampos Stratakis - 3.14.0~a2-2 - Security fix for CVE-2024-12254 - Fixes: rhbz#2330928 diff --git a/sources b/sources index e127abd..e422e4c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0a2.tar.xz) = face78a7ef5d1a14b7e8c478125c660fe9745e793a5443932684c8426f0023324236c67ad73198e4286ba8793628452ae4d4d6332f007c009b285ba83ca1fc48 +SHA512 (Python-3.14.0a3.tar.xz) = e26c9736f00af680b5f1ff1ba0f06562c48550836088d79dd8b4c97016d52f9f76979de32fa8556e9d750a5dad488643e897807ab6cb0c1424882151fe5f3337 diff --git a/tests/tests.yml b/tests/tests.yml index 2a255a5..8af0de4 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -30,10 +30,10 @@ run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - selftest: dir: python/selftest - run: "VERSION={{ pybasever }} X='-i test_check_probes' ./parallel.sh" + run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - debugtest: dir: python/selftest - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes' ./parallel.sh" + run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 85202ae1eea9f130a88e96b03615fca10441e8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 2 Jan 2025 11:30:18 +0100 Subject: [PATCH 04/88] Bump the PYC magic number for a change in annotate functions --- 00447-gh-128089-bump-the-magic-number.patch | 44 +++++++++++++++++++++ python3.14.spec | 7 ++++ 2 files changed, 51 insertions(+) create mode 100644 00447-gh-128089-bump-the-magic-number.patch diff --git a/00447-gh-128089-bump-the-magic-number.patch b/00447-gh-128089-bump-the-magic-number.patch new file mode 100644 index 0000000..034bc96 --- /dev/null +++ b/00447-gh-128089-bump-the-magic-number.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jelle Zijlstra +Date: Thu, 19 Dec 2024 07:28:31 -0800 +Subject: [PATCH] 00447: gh-128089: Bump the PYC magic number for a change in + annotate functions + +The magic number should have been increased in release 3.14a3. Users running +3.14a3 with PYC files generated using earlier alphas may run into problems. +--- + Include/internal/pycore_magic_number.h | 3 ++- + .../2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst | 3 +++ + 2 files changed, 5 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst + +diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h +index 14e2957687..9ab327afb6 100644 +--- a/Include/internal/pycore_magic_number.h ++++ b/Include/internal/pycore_magic_number.h +@@ -262,6 +262,7 @@ Known values: + Python 3.14a1 3607 (Add pseudo instructions JUMP_IF_TRUE/FALSE) + Python 3.14a1 3608 (Add support for slices) + Python 3.14a2 3609 (Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST) ++ Python 3.14a4 3610 (Add VALUE_WITH_FAKE_GLOBALS format to annotationlib) + + Python 3.15 will start with 3650 + +@@ -274,7 +275,7 @@ PC/launcher.c must also be updated. + + */ + +-#define PYC_MAGIC_NUMBER 3609 ++#define PYC_MAGIC_NUMBER 3610 + /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes + (little-endian) and then appending b'\r\n'. */ + #define PYC_MAGIC_NUMBER_TOKEN \ +diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst +new file mode 100644 +index 0000000000..69687bc516 +--- /dev/null ++++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst +@@ -0,0 +1,3 @@ ++Bump the PYC magic number for an internal change in annotate functions. The ++magic number should have been increased in release 3.14a3. Users running ++3.14a3 with PYC files generated using earlier alphas may run into problems. diff --git a/python3.14.spec b/python3.14.spec index bf86280..d18ea94 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -351,6 +351,13 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch +# 00447 # 79a44c0acfc4c88a1051c133c386da35e10fdee2 +# gh-128089: Bump the PYC magic number for a change in annotate functions +# +# The magic number should have been increased in release 3.14a3. Users running +# 3.14a3 with PYC files generated using earlier alphas may run into problems. +Patch447: 00447-gh-128089-bump-the-magic-number.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., From 2f4307845b3e090f815fbb2b2bb6a121fe20c02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 2 Jan 2025 11:30:49 +0100 Subject: [PATCH 05/88] Remove unused GPG key --- Yhg1s.gpg | 136 ------------------------------------------------------ 1 file changed, 136 deletions(-) delete mode 100644 Yhg1s.gpg diff --git a/Yhg1s.gpg b/Yhg1s.gpg deleted file mode 100644 index e0000e5..0000000 --- a/Yhg1s.gpg +++ /dev/null @@ -1,136 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mQINBFUAInYBEACrmKcXagNRlo1VjznrJZMMUh0rxUn2iK2wy9H5qrCo4EgMYahZ -ibBunSWB4RNeVQevzUm3eSyOixnt+BmGZbSYqKp8tJIXRRcnKhEtC62X+7NVMc7B -9uPu/aJ3HNqXrsQwBJUzZxzLMLg6obCyarhhHAYbWmfaafU4yNk3J4dGNKoZtHvz -bjnUtlsUAkCmuyt3MsUuSYz34BviRLSEZEKW6xNoyQmD9dUhQ5exBuTPjtmdTf+x -gOKpBluRkJ4TADGlWf42lIkaI+8DYRj1R8eQdLFwS7sDTu/MMPceKU7nTWOoj8HF -3xXRJ+bJbpOJXZFEzVKjXHKuMFkhKr562i0LD8pdl1+s+9LRovmAvGwggt04Drzb -AK437QoyjPKiTnFlg4tOeIuN0Y+GGk2hXOdH7fNw79B9Tq5ENxth8NsnKVlz1zpF -X+aV0zCvAjNWutAUpikqZT/ibpwmM+NJcz3pgzQOq+LfPFskyrv7zkVODEjH3SG3 -s4ROvyoWfLPWmX92kJMOkvzyQObZmU2zWJgJbjYRApZiTfbfnH1tE+wxH4ZR5dji -FpEdUJn1yjpYp21Q10khIdsj6q9IvS3RDq0ygc5wfl5111byEsdP12y36lvPTclT -33VHBR1vxr+js9d8FI4wwt/o+7TmAO39DYhLrtn+ZgyRgIBYY65lhEaUtwARAQAB -tCJUaG9tYXMgV291dGVycyA8dGhvbWFzQHB5dGhvbi5vcmc+iQJXBBMBCgBBAhsD -BQsJCAcDBRUKCQgLBRYCAwEAAh4BAheABQkVRkQLFiEEcWlgX2LHUTVtBUomqCHm -gOX6YwUFAmM7V3UCGQEACgkQqCHmgOX6YwVFeRAAkXE+BC/8O7VVtNe3iCdcQtW3 -PiCINEJgOQbXSwjkIGjD/Noheu+2cdwznjUmAX3qgnOyxIvo1AzYXagRazKVl1A+ -AiMctMNUCuVAkPeTL3nUERzOzZP6fE9OB/XNyiFeNPGg3qGz/HEJH8OMzahfOpzM -VC3bCcZrn3JmMp6X8gLgArcK20L7qu/USO/Ico9vT8n+IkZIyxv9GNzfr4QZtGQN -DkcHXHbX7p6juffdF9PpQgeAHfP4F9ZuDC+Mc5AGQaxY0z+gNLQGbTEjBBxkrGqd -3iOHWb+RLLRJkHkF95KegatrgRkK3d+WLsHwCWzySDAKsjcvM33+N5YB9vWiL/K+ -kRbgEiecQHwsV1WT+DLY4yoLEBDVbThSw90R2b4bDzCOWShYMX8hDu5HaP3vT1Ye -lLSYT/1TxX1yvGeCuA8D+V9OZbSi7eKVT7W4pxqiCcDTpvMvx3o9NfiHEFGQfjlZ -nQsIBt9YeBG2c/GL0h1v4X9kBHjxv58576L9olEuWViuCam3OmW31Ik8OjYUwHs0 -tVqc/ciKsot/3ci96wxnG0RajkXL4ybQI7QzJ3OJJyLMZUPx7UTkdYlD7ZKJyU/N -kdcmEjtvBtWeCROZOdivvZeJnSe/vANbH9Oibongl9Zwlq0w/Sd8fHKJQZC7c4dA -bTVfbTLXuaLUE86ZCdSJAhwEEAEKAAYFAlUAQF8ACgkQq90IJmKQVoiM5w/+OT6z -14MgLePITzg+SCRH7H6QgMjLQXrIwEFzwJC8sG2OxIG/nr+M9R0VgsUqEdP2vwur -XDiadjvh4yfXkQst96EUk4l4HCSPo9YtXmPoM88n+rhHSI3UrQx/mqMdf6V4Z8AM -KZ6LEe9sctrVjyJdEixZVVh0F4BOluKVwOLFmZkQLzblj8nul5b/X2+r+B2Z3b9H -beI4EN/vBno/riv6L/ZHq3g7xztm1ZQE55PLtTkVD6PhEBXnLxuAHu9psWmFLAn3 -piz7GQg683y5ncrzHGJs11CXtE7BJ8iHet7whQneF2DY2LcVWVNjQtWslhlhp2+o -YE+aVSB5cJ6pjHnz7d0m9QyS1dzDkGfDbPxMES6qDymQpsrpDP3Kro+O7V6JB6To -8Qj9gEumjaze7mkQdC4A3NOiOgB6+c3P/ng3HYAA9T7KkiePj+2B4F7YrMdWQqhR -IB0uHLUblmw9BVbd0p5EVM7dxEziqHE6kvlka0M9kC8naF6XvHhZQlZhbNXgo4zH -JLFVNqQw/c2E983iiBEkBu18t5kz/lOnO0Oh5ARVGiw9cxwx9pzuw1s/VT50698r -l0g4IeWbrVbYKKXhFMgX6BRQZiOzbE9QTpWX2PFwd69FHs/mgqlFf9IF5lkBkXP4 -3qAShAqz6+rlQFesaliN3uF29AHZwB5NOY6lNh6JAj0EEwEKACcFAlUAP5cCGwMF -CQlmAYAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQqCHmgOX6YwUS/hAAqg57 -TwZlu8qof1e/2BTCqUiKPQ7XuokYORTKpNrXCMpl/ygZMW8jc6Q+iVKaDDhJN9pz -zh6ZBZQSNMwr4v8ndc858dId/WtAbMZ9eG96tIoFT4M+mSSW/YobRuvInuFyVvor -Z4pT19/UDG7hRZRKofT6X22Nzumoy97veT3Weuu0jny+H4AiiTobSnRSsZpjCMUs -0TzMk+v1+JdMmETGbJZrM4BYZFUmoOOOU1WOPoph4owmz8h2a+VxdnGB95sW9/04 -gKHld863oauFv01P33okRojin+Q2G97o14Lh+IxFjghiphz9MOzwytwTUNwwrSmf -Hjv2VHEtWc5P+GC0Gys7+l2jqUZm/j3H2Vu40R47sLudtty5iMV/sVmBBDRdyuVh -C7yJC0dWveFsuEuI/onjf1iKgICkM2fNSj8gCBLtnbK6m3ZURoAwdKfWZR+9vyrq -waazxmC+76IOoSBnRFqvdB2z+8CbVHWQ4bOcAUyMDTkwtM1qAiNnRln3aFIdzDdQ -GQh1j3p4kuda8XE+IMdcOY3Q9HSSQ76aVrh+zbyXIX2a8H5qN7Tn0a7G2PoThBMe -5CNl7aXdFF+v7yoRY4vyt+8p3wxlOli/1iMn2X879BlA3TJzbpSSBTd9aR75fshp -9cXSqsUb2ja93Ca6mWkJfDYQUIltTGgg4njduFq0IVRob21hcyBXb3V0ZXJzIDx0 -aG9tYXNAeHM0YWxsLm5sPokCVAQTAQoAPgIbAwULCQgHAwUVCgkICwUWAgMBAAIe -AQIXgAUJFUZECxYhBHFpYF9ix1E1bQVKJqgh5oDl+mMFBQJjO1dvAAoJEKgh5oDl -+mMFIlIQAKmkHcJbQ1ltBexoJSsoCi7+9IOCSJpD0fsP6210/hkcSdcbz4EuN9om -f7BdCW9SOicBB8bxVid3uF0NnLjqyRusNbRVIXiKWzxb2+36cA9D6ugv1u8oV7Fq -sD+zAEWJTNDjd4/rJjEMTMhUxN0EFNrQLDngDnx7AeJyGD2n4eFB6RCJ7qtJtCPq -xqiW9jH6vH+YlAz8zbWKF7Z52CPVxAt/yoo6dwLFV6615Mo5n4VN6NiXQeKw5XmZ -prXvxDQFkodpjBpoN3fcAX6UTX4yJOR9DhALorr2H1ldI9xdQ0pawlPTDT/gRMsY -uHh3NVflUzoLny7TWqd7xLyocH2TqC3OAsF78oR+4W2P0QxuEq/W1WAf+LIpRjeI -Q4Xt6TGDku694VHE0pfK5BjpHApyWlGRPVq89x6Z78pCrKiMMtoW30mCPWkSd63h -3cPgQNAzo+BBoNYUdvQCAAMEFdBpUjVCQaInAqFuKw1N8IpahsKKSg4jMheLmocG -KYbO5IIinjXxIz87skKD6xkukIwfcnhvRM/IkHuxuG+ltO17nbWQNvmvZtEZ47xN -9hAVZkaK/5eBDmICH1N8o0gHGU61KfEaCRLuQkFRe72QnbxzUkIwYtC9TCAiYieA -xsSRwY5boZsKEnzLmPfM1b96Rj7JKCiMDOBgNbUNcKXuAMqrOMZtiQIcBBABCgAG -BQJVAEBfAAoJEKvdCCZikFaI8xEQAIl7VghcbWLaiIcS+SB4mlVuVpFyj6YmD7Y2 -GWAkiRMyxMdzETOA1dKzcdZG8+0ClATFgdCl7FxZ5M2qRhjOqxRpMK0KpSn7xuXB -w+0LWo5gnEXk/+IrXOBNCCkaglyPGlW8GFE/hxGbBt4pDLyQ6nsYWSWLvPNOGdQg -J2/P3pa8mCmiFeAt88rz7Xj9wg7OZ7O+3tV6AlYRklfQEBAB/NP1VHv3xc2GsCA1 -t83f8Echq+CjsYNmcVIOhEKSPvacbfF1dpBp4AQooy6KRA4G1ERi0cXcSOnAdKZW -wG0fIl++ziz0iDIM9c7Lg7Jul1+ZpXM9nxCLu7KYGlXe05XK+xzQJdK02tJO96IX -oNcZrtqnIV9D/BBX4HMVHlSjoRVCnpXsuCiobgOFahvp94s7I6D48ABc64HPMS/2 -Nkw0QKLsmpNQ++QfNbNNOhcjMJFmlAy8si0cpBSQjVoctvgoZMo63KjDjvUiEMni -tvEq43xPLe4cAUgj3F6/Eq9NDXbS0Bvq2a2gPEfY+d0dSazUCpmPVe9eAGxCZ0QY -sPctUvLRf4scwJdQ676DAj+VvUwRKjAlR2wlHFWS38PQ/irvKgu02yHW3K1j99QS -2NBauBcKZlr/r3bIWbDxtgOBfvfKGFsEHesSAyNY06OgGONvqMncWiMT1dCKhbxQ -GdoSEaNkiQI9BBMBCgAnBQJVACJ2AhsDBQkJZgGABQsJCAcDBRUKCQgLBRYCAwEA -Ah4BAheAAAoJEKgh5oDl+mMFLxcP/17E5gEBa/ErPMnY+82r0jZ5rq0DGOotrjsY -fSvIX0YvDc6BaqLLuSTr8Klo2MueVHZY78px6VC661KP5+aRBJZHTTUJ+9ZVrP+R -pcNHQTKX70XrwYSnl2S7q0nc1K5CkCLYOuM05sAzvOBj/cAtpZuw9D009wxpQXd7 -kwSREBGcgZ8Ac7kqPbOojtmBkHFWFUg5Rx+fVsulcQkERs1j22tzTvPzsljGmrrY -7o6P0K4fzVfeQx43sKKltQrNNZwBtleHD+jQPLThVf09Rhjtq/+cb2wwiAqpHskf -dY1njeCh21Yl58IOMHQ6x0Mc6rF3A5wqrLVJ5GYVHl33unZLKcAWDmtV3MPvnvdF -WvLDPqkykozU08d1ieyZXFWlwViYaVzh7cjgIM8keCbPk0zFtGZkVUS2um332Xiv -pX02J8KqWhNsiioO/SAFOhS6+zR+mZghnr5eqD9SHmCKTJ1JWjG2wx2hibaaszQb -qypBW1mwoGMDj4MG91iKSnwMgjp3P8xQIyHy/XTAJ1DD9F//2MtQ2ZK5MqiWTYLn -iUzirq8M1E8rLHh8Met5xIOq5iIDcMn0HTBCwrWWPOyqTF2lWK3G6LOjTltQ01fJ -JaICpTe1Eirt9v+kr1iPLH1+zIeWZ1O469I/nxRp/WW6Oavzb9WRg5gDBKZ2v+rJ -jZLcaEBFtCRUaG9tYXMgV291dGVycyA8dHdvdXRlcnNAZ29vZ2xlLmNvbT6JAlQE -EwEKAD4CGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AWIQRxaWBfYsdRNW0FSiao -IeaA5fpjBQUCYOBlAQUJFUZECwAKCRCoIeaA5fpjBTvxEACfyEt5rN5QGmVgahD/ -83l7lQpZUzLSq5MnIfRjCz50seh+oWsOuecayHZ79IDVSkF2L2kE1rumcB7UKPez -0kHVrTdh3mQIsfCzQZEMsWTDYotlZbrPPvT3lKGL+O7fU321q9GVotJAssYcQFIK -9F2p3jhN2coOzguikVlSc4nswnq2KRIJ4BpSJ3fk1rWLr8oJxN2pSpskYtHdUyUx -fZ+fOrMHLbW94JWsLYDad4wpr8etBneVAaUPfphhbIwfhRXlHuTreDtwr3LJYKp1 -VjUjzGVVT2CXkS9LbJ7aM2BYa/1MJyHxkglu8O9LIDGH2arlbtmBKMbCXPSX/42H -sGpUgQYRwG4f+2CfPj4fNx5GK8LO/EJjaw2Qh542U0356RRVZquN6E6SS6Sndlf9 -sO4cKU/ptT8IsfWKKaLwvr0l71hgLRqqe3rSpTV54cKpJfYIG+Qf4Do69etJLxjY -UsyCqzuFocxZa0DGkqDQ+f1cD1bdg7Twso041NZG6y9+E7kCf3jtKkiYAHBY902q -Zi8FvtI2tDAqwlfJjdiH5rUtYZALO3KGT+l9p3FTYIdDD1iVC41CeF6loJk0gQZi -NmJtyY1TTyNS5Chtr8fSV9yYuoB5XoYYpLu1NCks4Cwva1tE45VhFrl8lPaM3EAB -OV+JeHYHX/DgooJRIwgpXCBmwYkCHAQQAQoABgUCVQBAXwAKCRCr3QgmYpBWiBLT -D/92NtklPiu0xYCsqUYQzy2dS9y93UHCY0IY7ZPS8k0gmmrxUxwyCARVvLKVy8pC -DTw1As8ziOPlwD4QrVxIGMVSKcjM6aEa1h87ezWcz9UCFFKG5NzP7ixBj0bfFlP3 -STisQXoa1jjT4x8gNw5QMnI4nnnqYRIUZYdsyOru9Kk4pJYMzXG7dHI2mPlGlZ67 -gsHVtN9w/cF2e+5MeejxJF5YkHwbXyWymFvEHB+yvtrqUKtnr+SKXpBiRaiA1UBS -Atus1HE+iEaNpfXjyGPT1/kj2dLS+PyKS61I0B8HF7msoXmbWClwOLAg19C7Gla8 -CLF53LgIqVjVH5c1+0VjmSyVOJoH9mFMd2rf6iJct9XlLfbAb9+liM/5FSRHtZCO -YR6tqfVy+9j5ZhCWfPOaEo4rGLwQ7vHP1qkwH3sZn/UTsQvT4gZX8eIZ3QjutzTD -TWfIWvxM7aeYCmNjPZFOB8hmnf3CYL4j5tMwnP19w2HWrYQHOBiIoPwGQxFFZf78 -F3GlPNYGqDUMNOgF7QxN0+GEh97JjSJ0P4JUX+nMOcousmrvZsH4IM6KIqhk0I59 -IjUuPxk7qpXU4z4ofEJzxEC0qTtmrNz4+kdvDQuJZY09hAbukzQ8xjl7i519Er+s -8iApBcxVZ1Kl4pl60OS6S5FkBS6JfyYDDA2a72R5EJbh/7kCDQRVACJ2ARAA4lpb -W8WeDqyRFffqQzVUK6456CkM7Fd77n1FdY0KwNeAmULYeiQ1Kp2PDzxFOyoJNe8a -QazB7jPqGth0+JgFCOxGlnAtBP7DQl2MrYAL+AcKJ0c5dXc96ObZ6xtd01n9gAoo -uppJINaA2aEX8P6nhQGu9qNz8yMBC22w0MYJZ+38ZVeXGcBCS3AGggeROwNPyNSZ -nW5TPVHi+Sea5bCE4eo5UYIAMqcToxieI3V4A2ciQV9nBERLF0bAadD1HEeCb6wM -g6h8z6VIRPitk45Dw73dy1yC6OvhkyGQ1yGuOPxwVnG3w0CLSUmMQeqyNAufmtN2 -yeoSMV74K9kOpkxCzzSulXGhEgCXWE7EXKC2g8i6M4BwYm3AaBGqeo+z7DinffWs -8W2UvQUN6JTAdGVgNUfacYbP8YR7fOO1EczJ/FYGxq+JnDUFRpKNsDouw6ZeRI1E -iQT3FEKWI3meNmTPBmIcWLoYGNYdmaeb4pqHBb6SfV45H4QjTyIjNHiW/LkpuI7o -No/vIlNF8OQwyUFtknXIx57A0VSdI+vfz1crneg/bg0qzBz5SoYZ0XZUfvmYLAoD -Z0/KLaqZ1x1Z9wiLbe3iK6nE1mjmWf7rOfmWHuxH/gbChXMDDfOMwgOYFXNXImsN -PWPX3XA2DrhFrlNWzA8kxi9hXJrgAfkRcx/84oUAEQEAAYkCPAQYAQoAJgIbDBYh -BHFpYF9ix1E1bQVKJqgh5oDl+mMFBQJg4GUPBQkVRkQZAAoJEKgh5oDl+mMFhIcP -/j3tJamzKpJGJAwcsoneFtYfmZnLA4UosffaPlsLGRVL1buyRuj2dFBr2WU4NAld -YrQPK4T+ciSpfogJ9Dk8s1eUMhZi7gxKmeOHUDyefPXIp7v3PSG4xcnfXjyEK9zC -714qFsI9ERjTg7uaw6qmFv8Xht8O8TLGMgqDijQIgrH2oGd6tEdYyOOCOPQ7d6PB -Sm5Sw53LlCWlW5I9bc0NCjbnwWjh7Z9UXtLffzZyxgxggSw0vfg5PuhcprZ2Rd3M -wzJmALI2BB7eWW1x+M0hXmtdqj7Opmajh+UMrFjLtAlEZfslJwzV9NkAFxDYzRi2 -jvsmJx78vOPB1XhXgTvlEOvA7qEYDXFaZJHlBDmFU9JqytGZ6PtiQENuLHIe4hO6 -aHbhJA4I9EqoG1U1COQAwrsHreV6+fpcFn4lXbu+gWPyUzKiQMQd9kI3EEiayObU -ro21OFHS7z131kKbMec/oc2RfADCvEwY8oay7o0S9aTqvPSQODs8nYkbZchNFoC+ -oF9n8pBMNzhYBsTk1OXleD1yMucsuywr5i0meyvu6oQ4+pdPYD6wh7JatJh0hayK -y33GGsXd278J1Ek1p6MEFnGLc/zH+NZZLIU7Qn1oFU+gK4cVeaLX2g0/BLKcQ/AE -mYIwnecLr8A+Y4mZVwwsnSHtfELtoGSsawN26bzKbnRs -=t995 ------END PGP PUBLIC KEY BLOCK----- \ No newline at end of file From 8d4a33cab36151ac11d3c33a4a3077ec7f78f7d7 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 18 Jan 2025 21:09:13 +0000 Subject: [PATCH 06/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index d18ea94..89b786d 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel a3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -1703,6 +1703,9 @@ CheckPython freethreading # ====================================================== %changelog +* Sat Jan 18 2025 Fedora Release Engineering - 3.14.0~a3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Tue Dec 17 2024 Karolina Surma - 3.14.0~a3-1 - Update to Python 3.14.0a3 From 83a2832b2b8b21208b647d173fb6ebeb5d3e3bca Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 15 Jan 2025 10:00:47 +0100 Subject: [PATCH 07/88] Update to Python 3.14.0a4 --- 00251-change-user-install-location.patch | 2 +- 00447-gh-128089-bump-the-magic-number.patch | 44 - ...rt-on-non--af_inet-sockets-gh-128933.patch | 84 ++ ...erated-struct-layout-tests-gh-128944.patch | 758 ++++++++++++++++++ python3.14.spec | 42 +- sources | 2 +- 6 files changed, 872 insertions(+), 60 deletions(-) delete mode 100644 00447-gh-128089-bump-the-magic-number.patch create mode 100644 00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch create mode 100644 00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index ce93045..264cfdf 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -51,7 +51,7 @@ index 92bd1ccdad..951784f3b4 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index ed7b6a335d..2b1ee37775 100644 +index 7a4a8f65a5..c8fca72c01 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ diff --git a/00447-gh-128089-bump-the-magic-number.patch b/00447-gh-128089-bump-the-magic-number.patch deleted file mode 100644 index 034bc96..0000000 --- a/00447-gh-128089-bump-the-magic-number.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jelle Zijlstra -Date: Thu, 19 Dec 2024 07:28:31 -0800 -Subject: [PATCH] 00447: gh-128089: Bump the PYC magic number for a change in - annotate functions - -The magic number should have been increased in release 3.14a3. Users running -3.14a3 with PYC files generated using earlier alphas may run into problems. ---- - Include/internal/pycore_magic_number.h | 3 ++- - .../2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst | 3 +++ - 2 files changed, 5 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst - -diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h -index 14e2957687..9ab327afb6 100644 ---- a/Include/internal/pycore_magic_number.h -+++ b/Include/internal/pycore_magic_number.h -@@ -262,6 +262,7 @@ Known values: - Python 3.14a1 3607 (Add pseudo instructions JUMP_IF_TRUE/FALSE) - Python 3.14a1 3608 (Add support for slices) - Python 3.14a2 3609 (Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST) -+ Python 3.14a4 3610 (Add VALUE_WITH_FAKE_GLOBALS format to annotationlib) - - Python 3.15 will start with 3650 - -@@ -274,7 +275,7 @@ PC/launcher.c must also be updated. - - */ - --#define PYC_MAGIC_NUMBER 3609 -+#define PYC_MAGIC_NUMBER 3610 - /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes - (little-endian) and then appending b'\r\n'. */ - #define PYC_MAGIC_NUMBER_TOKEN \ -diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst -new file mode 100644 -index 0000000000..69687bc516 ---- /dev/null -+++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-19-07-32-43.gh-issue-128089.3uOOM-.rst -@@ -0,0 +1,3 @@ -+Bump the PYC magic number for an internal change in annotate functions. The -+magic number should have been increased in release 3.14a3. Users running -+3.14a3 with PYC files generated using earlier alphas may run into problems. diff --git a/00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch b/00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch new file mode 100644 index 0000000..afee7af --- /dev/null +++ b/00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= +Date: Sat, 18 Jan 2025 01:49:16 +0100 +Subject: [PATCH] 00448: gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` + sockets (GH-128933) + +* gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` sockets + +Do not attempt to set ``SO_REUSEPORT`` on sockets of address familifies other +than ``AF_INET`` and ``AF_INET6``, as it is meaningless with these address +families, and the call with fail with Linux kernel 6.12.9 and newer. + +* Apply suggestions from code review + +Co-authored-by: Vinay Sajip + +--------- + +Co-authored-by: Vinay Sajip +--- + Lib/asyncio/base_events.py | 4 +++- + Lib/socket.py | 4 +++- + Lib/socketserver.py | 7 ++++++- + .../Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst | 3 +++ + 4 files changed, 15 insertions(+), 3 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst + +diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py +index 6e6e5aaac1..85018797db 100644 +--- a/Lib/asyncio/base_events.py ++++ b/Lib/asyncio/base_events.py +@@ -1593,7 +1593,9 @@ async def create_server( + if reuse_address: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, True) +- if reuse_port: ++ # Since Linux 6.12.9, SO_REUSEPORT is not allowed ++ # on other address families than AF_INET/AF_INET6. ++ if reuse_port and af in (socket.AF_INET, socket.AF_INET6): + _set_reuseport(sock) + if keep_alive: + sock.setsockopt( +diff --git a/Lib/socket.py b/Lib/socket.py +index be37c24d61..727b0e75f0 100644 +--- a/Lib/socket.py ++++ b/Lib/socket.py +@@ -937,7 +937,9 @@ def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, + # Fail later on bind(), for platforms which may not + # support this option. + pass +- if reuse_port: ++ # Since Linux 6.12.9, SO_REUSEPORT is not allowed ++ # on other address families than AF_INET/AF_INET6. ++ if reuse_port and family in (AF_INET, AF_INET6): + sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1) + if has_ipv6 and family == AF_INET6: + if dualstack_ipv6: +diff --git a/Lib/socketserver.py b/Lib/socketserver.py +index cd028ef1c6..35b2723de3 100644 +--- a/Lib/socketserver.py ++++ b/Lib/socketserver.py +@@ -468,7 +468,12 @@ def server_bind(self): + """ + if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"): + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +- if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"): ++ # Since Linux 6.12.9, SO_REUSEPORT is not allowed ++ # on other address families than AF_INET/AF_INET6. ++ if ( ++ self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT") ++ and self.address_family in (socket.AF_INET, socket.AF_INET6) ++ ): + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + self.socket.bind(self.server_address) + self.server_address = self.socket.getsockname() +diff --git a/Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst b/Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst +new file mode 100644 +index 0000000000..f2db341ef8 +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst +@@ -0,0 +1,3 @@ ++Do not attempt to set ``SO_REUSEPORT`` on sockets of address families ++other than ``AF_INET`` and ``AF_INET6``, as it is meaningless with these ++address families, and the call with fail with Linux kernel 6.12.9 and newer. diff --git a/00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch b/00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch new file mode 100644 index 0000000..345c562 --- /dev/null +++ b/00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch @@ -0,0 +1,758 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Petr Viktorin +Date: Tue, 21 Jan 2025 16:29:02 +0100 +Subject: [PATCH] 00449: gh-128889: Zero out memory ctypes for generated struct + layout tests (GH-128944) + +--- + .../test_ctypes/test_generated_structs.py | 5 +- + Modules/_ctypes/_ctypes_test_generated.c.h | 216 ++++++++++++------ + 2 files changed, 147 insertions(+), 74 deletions(-) + +diff --git a/Lib/test/test_ctypes/test_generated_structs.py b/Lib/test/test_ctypes/test_generated_structs.py +index d61754d6d4..1df9f0dc16 100644 +--- a/Lib/test/test_ctypes/test_generated_structs.py ++++ b/Lib/test/test_ctypes/test_generated_structs.py +@@ -443,7 +443,7 @@ def test_generated_data(self): + - None + - reason to skip the test (str) + +- This does depend on the C compiler keeping padding bits zero. ++ This does depend on the C compiler keeping padding bits unchanged. + Common compilers seem to do so. + """ + for name, cls in TESTCASES.items(): +@@ -696,7 +696,8 @@ def output(string): + output(' ' + line) + typename = f'{struct_or_union(cls)} {name}' + output(f""" +- {typename} value = {{0}}; ++ {typename} value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString({c_str_repr(name)})); + APPEND(PyLong_FromLong(sizeof({typename}))); + APPEND(PyLong_FromLong(_Alignof({typename}))); +diff --git a/Modules/_ctypes/_ctypes_test_generated.c.h b/Modules/_ctypes/_ctypes_test_generated.c.h +index 46a3e4b01e..d70b33eaa8 100644 +--- a/Modules/_ctypes/_ctypes_test_generated.c.h ++++ b/Modules/_ctypes/_ctypes_test_generated.c.h +@@ -56,7 +56,8 @@ + struct SingleInt { + int a; + }; +- struct SingleInt value = {0}; ++ struct SingleInt value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("SingleInt")); + APPEND(PyLong_FromLong(sizeof(struct SingleInt))); + APPEND(PyLong_FromLong(_Alignof(struct SingleInt))); +@@ -69,7 +70,8 @@ + union SingleInt_Union { + int a; + }; +- union SingleInt_Union value = {0}; ++ union SingleInt_Union value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("SingleInt_Union")); + APPEND(PyLong_FromLong(sizeof(union SingleInt_Union))); + APPEND(PyLong_FromLong(_Alignof(union SingleInt_Union))); +@@ -82,7 +84,8 @@ + struct SingleU32 { + uint32_t a; + }; +- struct SingleU32 value = {0}; ++ struct SingleU32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("SingleU32")); + APPEND(PyLong_FromLong(sizeof(struct SingleU32))); + APPEND(PyLong_FromLong(_Alignof(struct SingleU32))); +@@ -97,7 +100,8 @@ + int8_t y; + uint16_t z; + }; +- struct SimpleStruct value = {0}; ++ struct SimpleStruct value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("SimpleStruct")); + APPEND(PyLong_FromLong(sizeof(struct SimpleStruct))); + APPEND(PyLong_FromLong(_Alignof(struct SimpleStruct))); +@@ -114,7 +118,8 @@ + int8_t y; + uint16_t z; + }; +- union SimpleUnion value = {0}; ++ union SimpleUnion value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("SimpleUnion")); + APPEND(PyLong_FromLong(sizeof(union SimpleUnion))); + APPEND(PyLong_FromLong(_Alignof(union SimpleUnion))); +@@ -136,7 +141,8 @@ + int64_t i64; + uint64_t u64; + }; +- struct ManyTypes value = {0}; ++ struct ManyTypes value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("ManyTypes")); + APPEND(PyLong_FromLong(sizeof(struct ManyTypes))); + APPEND(PyLong_FromLong(_Alignof(struct ManyTypes))); +@@ -163,7 +169,8 @@ + int64_t i64; + uint64_t u64; + }; +- union ManyTypesU value = {0}; ++ union ManyTypesU value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("ManyTypesU")); + APPEND(PyLong_FromLong(sizeof(union ManyTypesU))); + APPEND(PyLong_FromLong(_Alignof(union ManyTypesU))); +@@ -197,7 +204,8 @@ + uint16_t z; + }; + }; +- struct Nested value = {0}; ++ struct Nested value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Nested")); + APPEND(PyLong_FromLong(sizeof(struct Nested))); + APPEND(PyLong_FromLong(_Alignof(struct Nested))); +@@ -223,7 +231,8 @@ + int64_t b; + }; + #pragma pack(pop) +- struct Packed1 value = {0}; ++ struct Packed1 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Packed1")); + APPEND(PyLong_FromLong(sizeof(struct Packed1))); + APPEND(PyLong_FromLong(_Alignof(struct Packed1))); +@@ -247,7 +256,8 @@ + int64_t b; + }; + #pragma pack(pop) +- struct Packed2 value = {0}; ++ struct Packed2 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Packed2")); + APPEND(PyLong_FromLong(sizeof(struct Packed2))); + APPEND(PyLong_FromLong(_Alignof(struct Packed2))); +@@ -271,7 +281,8 @@ + int64_t b; + }; + #pragma pack(pop) +- struct Packed3 value = {0}; ++ struct Packed3 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Packed3")); + APPEND(PyLong_FromLong(sizeof(struct Packed3))); + APPEND(PyLong_FromLong(_Alignof(struct Packed3))); +@@ -295,7 +306,8 @@ + int64_t b; + }; + #pragma pack(pop) +- struct Packed4 value = {0}; ++ struct Packed4 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Packed4")); + APPEND(PyLong_FromLong(sizeof(struct Packed4))); + APPEND(PyLong_FromLong(_Alignof(struct Packed4))); +@@ -316,7 +328,8 @@ + int64_t b; + int32_t c; + }; +- struct X86_32EdgeCase value = {0}; ++ struct X86_32EdgeCase value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("X86_32EdgeCase")); + APPEND(PyLong_FromLong(sizeof(struct X86_32EdgeCase))); + APPEND(PyLong_FromLong(_Alignof(struct X86_32EdgeCase))); +@@ -333,7 +346,8 @@ + unsigned int b :5; + unsigned int c :7; + }; +- struct MSBitFieldExample value = {0}; ++ struct MSBitFieldExample value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("MSBitFieldExample")); + APPEND(PyLong_FromLong(sizeof(struct MSBitFieldExample))); + APPEND(PyLong_FromLong(_Alignof(struct MSBitFieldExample))); +@@ -351,7 +365,8 @@ + unsigned int may_straddle :30; + unsigned int last :18; + }; +- struct MSStraddlingExample value = {0}; ++ struct MSStraddlingExample value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("MSStraddlingExample")); + APPEND(PyLong_FromLong(sizeof(struct MSStraddlingExample))); + APPEND(PyLong_FromLong(_Alignof(struct MSStraddlingExample))); +@@ -375,7 +390,8 @@ + int H :8; + int I :9; + }; +- struct IntBits value = {0}; ++ struct IntBits value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("IntBits")); + APPEND(PyLong_FromLong(sizeof(struct IntBits))); + APPEND(PyLong_FromLong(_Alignof(struct IntBits))); +@@ -413,7 +429,8 @@ + short R :6; + short S :7; + }; +- struct Bits value = {0}; ++ struct Bits value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Bits")); + APPEND(PyLong_FromLong(sizeof(struct Bits))); + APPEND(PyLong_FromLong(_Alignof(struct Bits))); +@@ -456,7 +473,8 @@ + int H :8; + int I :9; + }; +- struct IntBits_MSVC value = {0}; ++ struct IntBits_MSVC value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("IntBits_MSVC")); + APPEND(PyLong_FromLong(sizeof(struct IntBits_MSVC))); + APPEND(PyLong_FromLong(_Alignof(struct IntBits_MSVC))); +@@ -499,7 +517,8 @@ + short R :6; + short S :7; + }; +- struct Bits_MSVC value = {0}; ++ struct Bits_MSVC value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Bits_MSVC")); + APPEND(PyLong_FromLong(sizeof(struct Bits_MSVC))); + APPEND(PyLong_FromLong(_Alignof(struct Bits_MSVC))); +@@ -536,7 +555,8 @@ + int64_t b :62; + int64_t c :1; + }; +- struct I64Bits value = {0}; ++ struct I64Bits value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("I64Bits")); + APPEND(PyLong_FromLong(sizeof(struct I64Bits))); + APPEND(PyLong_FromLong(_Alignof(struct I64Bits))); +@@ -560,7 +580,8 @@ + uint64_t b :62; + uint64_t c :1; + }; +- struct U64Bits value = {0}; ++ struct U64Bits value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("U64Bits")); + APPEND(PyLong_FromLong(sizeof(struct U64Bits))); + APPEND(PyLong_FromLong(_Alignof(struct U64Bits))); +@@ -584,7 +605,8 @@ + int8_t b :3; + int8_t c :1; + }; +- struct Struct331_8 value = {0}; ++ struct Struct331_8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_8")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_8))); +@@ -608,7 +630,8 @@ + int8_t b :6; + int8_t c :1; + }; +- struct Struct1x1_8 value = {0}; ++ struct Struct1x1_8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_8")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_8))); +@@ -633,7 +656,8 @@ + int8_t b :6; + int8_t c :1; + }; +- struct Struct1nx1_8 value = {0}; ++ struct Struct1nx1_8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_8")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_8))); +@@ -658,7 +682,8 @@ + int8_t b :6; + int8_t c :6; + }; +- struct Struct3xx_8 value = {0}; ++ struct Struct3xx_8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_8")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_8))); +@@ -682,7 +707,8 @@ + uint8_t b :3; + uint8_t c :1; + }; +- struct Struct331_u8 value = {0}; ++ struct Struct331_u8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_u8")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_u8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_u8))); +@@ -706,7 +732,8 @@ + uint8_t b :6; + uint8_t c :1; + }; +- struct Struct1x1_u8 value = {0}; ++ struct Struct1x1_u8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_u8")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u8))); +@@ -731,7 +758,8 @@ + uint8_t b :6; + uint8_t c :1; + }; +- struct Struct1nx1_u8 value = {0}; ++ struct Struct1nx1_u8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_u8")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u8))); +@@ -756,7 +784,8 @@ + uint8_t b :6; + uint8_t c :6; + }; +- struct Struct3xx_u8 value = {0}; ++ struct Struct3xx_u8 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_u8")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u8))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u8))); +@@ -780,7 +809,8 @@ + int16_t b :3; + int16_t c :1; + }; +- struct Struct331_16 value = {0}; ++ struct Struct331_16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_16")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_16))); +@@ -804,7 +834,8 @@ + int16_t b :14; + int16_t c :1; + }; +- struct Struct1x1_16 value = {0}; ++ struct Struct1x1_16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_16")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_16))); +@@ -829,7 +860,8 @@ + int16_t b :14; + int16_t c :1; + }; +- struct Struct1nx1_16 value = {0}; ++ struct Struct1nx1_16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_16")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_16))); +@@ -854,7 +886,8 @@ + int16_t b :14; + int16_t c :14; + }; +- struct Struct3xx_16 value = {0}; ++ struct Struct3xx_16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_16")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_16))); +@@ -878,7 +911,8 @@ + uint16_t b :3; + uint16_t c :1; + }; +- struct Struct331_u16 value = {0}; ++ struct Struct331_u16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_u16")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_u16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_u16))); +@@ -902,7 +936,8 @@ + uint16_t b :14; + uint16_t c :1; + }; +- struct Struct1x1_u16 value = {0}; ++ struct Struct1x1_u16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_u16")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u16))); +@@ -927,7 +962,8 @@ + uint16_t b :14; + uint16_t c :1; + }; +- struct Struct1nx1_u16 value = {0}; ++ struct Struct1nx1_u16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_u16")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u16))); +@@ -952,7 +988,8 @@ + uint16_t b :14; + uint16_t c :14; + }; +- struct Struct3xx_u16 value = {0}; ++ struct Struct3xx_u16 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_u16")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u16))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u16))); +@@ -976,7 +1013,8 @@ + int32_t b :3; + int32_t c :1; + }; +- struct Struct331_32 value = {0}; ++ struct Struct331_32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_32")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_32))); +@@ -1000,7 +1038,8 @@ + int32_t b :30; + int32_t c :1; + }; +- struct Struct1x1_32 value = {0}; ++ struct Struct1x1_32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_32")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_32))); +@@ -1025,7 +1064,8 @@ + int32_t b :30; + int32_t c :1; + }; +- struct Struct1nx1_32 value = {0}; ++ struct Struct1nx1_32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_32")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_32))); +@@ -1050,7 +1090,8 @@ + int32_t b :30; + int32_t c :30; + }; +- struct Struct3xx_32 value = {0}; ++ struct Struct3xx_32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_32")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_32))); +@@ -1074,7 +1115,8 @@ + uint32_t b :3; + uint32_t c :1; + }; +- struct Struct331_u32 value = {0}; ++ struct Struct331_u32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_u32")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_u32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_u32))); +@@ -1098,7 +1140,8 @@ + uint32_t b :30; + uint32_t c :1; + }; +- struct Struct1x1_u32 value = {0}; ++ struct Struct1x1_u32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_u32")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u32))); +@@ -1123,7 +1166,8 @@ + uint32_t b :30; + uint32_t c :1; + }; +- struct Struct1nx1_u32 value = {0}; ++ struct Struct1nx1_u32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_u32")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u32))); +@@ -1148,7 +1192,8 @@ + uint32_t b :30; + uint32_t c :30; + }; +- struct Struct3xx_u32 value = {0}; ++ struct Struct3xx_u32 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_u32")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u32))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u32))); +@@ -1172,7 +1217,8 @@ + int64_t b :3; + int64_t c :1; + }; +- struct Struct331_64 value = {0}; ++ struct Struct331_64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_64")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_64))); +@@ -1196,7 +1242,8 @@ + int64_t b :62; + int64_t c :1; + }; +- struct Struct1x1_64 value = {0}; ++ struct Struct1x1_64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_64")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_64))); +@@ -1221,7 +1268,8 @@ + int64_t b :62; + int64_t c :1; + }; +- struct Struct1nx1_64 value = {0}; ++ struct Struct1nx1_64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_64")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_64))); +@@ -1246,7 +1294,8 @@ + int64_t b :62; + int64_t c :62; + }; +- struct Struct3xx_64 value = {0}; ++ struct Struct3xx_64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_64")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_64))); +@@ -1270,7 +1319,8 @@ + uint64_t b :3; + uint64_t c :1; + }; +- struct Struct331_u64 value = {0}; ++ struct Struct331_u64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct331_u64")); + APPEND(PyLong_FromLong(sizeof(struct Struct331_u64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct331_u64))); +@@ -1294,7 +1344,8 @@ + uint64_t b :62; + uint64_t c :1; + }; +- struct Struct1x1_u64 value = {0}; ++ struct Struct1x1_u64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1x1_u64")); + APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u64))); +@@ -1319,7 +1370,8 @@ + uint64_t b :62; + uint64_t c :1; + }; +- struct Struct1nx1_u64 value = {0}; ++ struct Struct1nx1_u64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct1nx1_u64")); + APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u64))); +@@ -1344,7 +1396,8 @@ + uint64_t b :62; + uint64_t c :62; + }; +- struct Struct3xx_u64 value = {0}; ++ struct Struct3xx_u64 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Struct3xx_u64")); + APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u64))); + APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u64))); +@@ -1367,7 +1420,8 @@ + signed char a :4; + int b :4; + }; +- struct Mixed1 value = {0}; ++ struct Mixed1 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed1")); + APPEND(PyLong_FromLong(sizeof(struct Mixed1))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed1))); +@@ -1389,7 +1443,8 @@ + signed char a :4; + int32_t b :32; + }; +- struct Mixed2 value = {0}; ++ struct Mixed2 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed2")); + APPEND(PyLong_FromLong(sizeof(struct Mixed2))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed2))); +@@ -1411,7 +1466,8 @@ + signed char a :4; + unsigned char b :4; + }; +- struct Mixed3 value = {0}; ++ struct Mixed3 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed3")); + APPEND(PyLong_FromLong(sizeof(struct Mixed3))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed3))); +@@ -1437,7 +1493,8 @@ + short e :4; + int f :24; + }; +- struct Mixed4 value = {0}; ++ struct Mixed4 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed4")); + APPEND(PyLong_FromLong(sizeof(struct Mixed4))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed4))); +@@ -1463,7 +1520,8 @@ + unsigned int A :1; + unsigned short B :16; + }; +- struct Mixed5 value = {0}; ++ struct Mixed5 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed5")); + APPEND(PyLong_FromLong(sizeof(struct Mixed5))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed5))); +@@ -1485,7 +1543,8 @@ + unsigned long long A :1; + unsigned int B :32; + }; +- struct Mixed6 value = {0}; ++ struct Mixed6 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed6")); + APPEND(PyLong_FromLong(sizeof(struct Mixed6))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed6))); +@@ -1508,7 +1567,8 @@ + uint32_t B :20; + uint64_t C :24; + }; +- struct Mixed7 value = {0}; ++ struct Mixed7 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed7")); + APPEND(PyLong_FromLong(sizeof(struct Mixed7))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed7))); +@@ -1532,7 +1592,8 @@ + uint32_t B :32; + unsigned long long C :1; + }; +- struct Mixed8_a value = {0}; ++ struct Mixed8_a value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed8_a")); + APPEND(PyLong_FromLong(sizeof(struct Mixed8_a))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed8_a))); +@@ -1556,7 +1617,8 @@ + uint32_t B; + unsigned long long C :1; + }; +- struct Mixed8_b value = {0}; ++ struct Mixed8_b value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed8_b")); + APPEND(PyLong_FromLong(sizeof(struct Mixed8_b))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed8_b))); +@@ -1579,7 +1641,8 @@ + uint8_t A; + uint32_t B :1; + }; +- struct Mixed9 value = {0}; ++ struct Mixed9 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed9")); + APPEND(PyLong_FromLong(sizeof(struct Mixed9))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed9))); +@@ -1601,7 +1664,8 @@ + uint32_t A :1; + uint64_t B :1; + }; +- struct Mixed10 value = {0}; ++ struct Mixed10 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Mixed10")); + APPEND(PyLong_FromLong(sizeof(struct Mixed10))); + APPEND(PyLong_FromLong(_Alignof(struct Mixed10))); +@@ -1623,7 +1687,8 @@ + uint32_t A :1; + uint64_t B :1; + }; +- struct Example_gh_95496 value = {0}; ++ struct Example_gh_95496 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_95496")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_95496))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_95496))); +@@ -1655,7 +1720,8 @@ + uint16_t b1 :12; + }; + #pragma pack(pop) +- struct Example_gh_84039_bad value = {0}; ++ struct Example_gh_84039_bad value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_84039_bad")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_bad))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_bad))); +@@ -1693,7 +1759,8 @@ + uint8_t a7 :1; + }; + #pragma pack(pop) +- struct Example_gh_84039_good_a value = {0}; ++ struct Example_gh_84039_good_a value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_84039_good_a")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_good_a))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_good_a))); +@@ -1735,7 +1802,8 @@ + uint16_t b1 :12; + }; + #pragma pack(pop) +- struct Example_gh_84039_good value = {0}; ++ struct Example_gh_84039_good value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_84039_good")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_good))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_good))); +@@ -1775,7 +1843,8 @@ + uint32_t R2 :2; + }; + #pragma pack(pop) +- struct Example_gh_73939 value = {0}; ++ struct Example_gh_73939 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_73939")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_73939))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_73939))); +@@ -1806,7 +1875,8 @@ + uint8_t b :8; + uint32_t c :16; + }; +- struct Example_gh_86098 value = {0}; ++ struct Example_gh_86098 value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_86098")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_86098))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_86098))); +@@ -1832,7 +1902,8 @@ + uint32_t c :16; + }; + #pragma pack(pop) +- struct Example_gh_86098_pack value = {0}; ++ struct Example_gh_86098_pack value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("Example_gh_86098_pack")); + APPEND(PyLong_FromLong(sizeof(struct Example_gh_86098_pack))); + APPEND(PyLong_FromLong(_Alignof(struct Example_gh_86098_pack))); +@@ -1858,7 +1929,8 @@ + }; + signed char y; + }; +- struct AnonBitfields value = {0}; ++ struct AnonBitfields value; ++ memset(&value, 0, sizeof(value)); + APPEND(PyUnicode_FromString("AnonBitfields")); + APPEND(PyLong_FromLong(sizeof(struct AnonBitfields))); + APPEND(PyLong_FromLong(_Alignof(struct AnonBitfields))); diff --git a/python3.14.spec b/python3.14.spec index 89b786d..2a5b3c5 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,10 +14,10 @@ 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}.0 -%global prerel a3 +%global prerel a4 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -351,12 +351,24 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00447 # 79a44c0acfc4c88a1051c133c386da35e10fdee2 -# gh-128089: Bump the PYC magic number for a change in annotate functions +# 00448 # e145ddea32596809c4222b05444c645eed2ea3af +# gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` sockets (GH-128933) # -# The magic number should have been increased in release 3.14a3. Users running -# 3.14a3 with PYC files generated using earlier alphas may run into problems. -Patch447: 00447-gh-128089-bump-the-magic-number.patch +# * gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` sockets +# +# Do not attempt to set ``SO_REUSEPORT`` on sockets of address familifies other +# than ``AF_INET`` and ``AF_INET6``, as it is meaningless with these address +# families, and the call with fail with Linux kernel 6.12.9 and newer. +# +# * Apply suggestions from code review +# +# +# --------- +Patch448: 00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch + +# 00449 # ddd832ac88676343c94b57af00f892928d2c242d +# gh-128889: Zero out memory ctypes for generated struct layout tests (GH-128944) +Patch449: 00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch # (New patches go here ^^^) # @@ -772,6 +784,9 @@ rm -r Modules/_decimal/libmpdec # (This is after patching, so that we can use patches directly from upstream) rm configure pyconfig.h.in +# Patch out the version requirement on autoconf 2.72 +# This can be removed when Fedora 40 goes EOL (2025-05-28) +sed -i "s/AC_PREREQ(\[2\.72\])/AC_PREREQ([2.71])/" configure.ac # ====================================================== # Configuring and building the code: @@ -1246,8 +1261,8 @@ CheckPython() { # 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_*_repeat_respect_immortality and test_immortals failures were reported: - # https://github.com/python/cpython/issues/128058 + # test_init_pyvenv_cfg is failing since 3.14.0a4, the issue is known upstream: + # https://github.com/python/cpython/issues/128690 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1257,6 +1272,7 @@ CheckPython() { %endif -i test_freeze_simple_script \ -i test_check_probes \ + -i test_init_pyvenv_cfg \ %ifarch %{mips64} -x test_ctypes \ %endif @@ -1264,11 +1280,6 @@ CheckPython() { -x test_signal \ -i test_deadlock \ %endif - %ifarch %{ix86} - -i test_tuple_repeat_respect_immortality \ - -i test_list_repeat_respect_immortality \ - -i test_immortals \ - %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1703,6 +1714,9 @@ CheckPython freethreading # ====================================================== %changelog +* Mon Jan 20 2025 Karolina Surma - 3.14.0~a4-1 +- Update to Python 3.14.0a4 + * Sat Jan 18 2025 Fedora Release Engineering - 3.14.0~a3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index e422e4c..d4cbdc0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0a3.tar.xz) = e26c9736f00af680b5f1ff1ba0f06562c48550836088d79dd8b4c97016d52f9f76979de32fa8556e9d750a5dad488643e897807ab6cb0c1424882151fe5f3337 +SHA512 (Python-3.14.0a4.tar.xz) = b70671ebbd9f777fdcb661405c538c733600470ac34992a5b3df99d2f5afecc22cd8325eeec50eeef043181e634da91e535c166b9b5ed421d4e6aa41b79da3ab From 594724cb659fc1803a767f3b1cff939970ee447a Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Thu, 23 Jan 2025 01:50:33 +0100 Subject: [PATCH 08/88] Remove redundant --with-system-ffi configure option The option has been removed since Python 3.12 See: https://github.com/python/cpython/commit/25590eb5dee5176f3ac60916b19450f8198e7ffc --- python3.14.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index 2a5b3c5..f895f61 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -866,7 +866,6 @@ BuildPython() { --with-computed-gotos=%{computed_gotos_flag} \ --with-dbmliborder=gdbm:ndbm:bdb \ --with-system-expat \ - --with-system-ffi \ --with-system-libmpdec \ --enable-loadable-sqlite-extensions \ --with-dtrace \ From 524afa95d3eedf63f3a0b858f2d521f2d8116558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 28 Jan 2025 13:30:16 +0100 Subject: [PATCH 09/88] Drop version constraints from Recommends This makes it easier for the package manager to determine "already broken" weak dependency. When Python is updated, the Recommends now remain identical, rather than being "new". Note that I don't know if dnf currently treats weak dependencies this way, but the assumption is that it *might*. The reverse dependency is versioned anyway, so the constraint is not necessary. Intentionally not bumping the release, this can land with the next update. --- python3.14.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index f895f61..d0019a6 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -513,12 +513,12 @@ Provides: bundled(mimalloc) = 2.12 # We've filtered the automatic requirement out so libs are installable without # the main package. This however makes it pulled in by default. # See https://bugzilla.redhat.com/show_bug.cgi?id=1547131 -Recommends: %{pkgname}%{?_isa} = %{version}-%{release} +Recommends: %{pkgname}%{?_isa} # tkinter is part of the standard library, # but it is torn out to save an unwanted dependency on tk and X11. # we recommend it when tk is already installed (for better UX) -Recommends: (%{pkgname}-tkinter%{?_isa} = %{version}-%{release} if tk%{?_isa}) +Recommends: (%{pkgname}-tkinter%{?_isa} if tk%{?_isa}) # The zoneinfo module needs tzdata Requires: tzdata From a9eff720fabf7b15bcb9316b1ed0067481aa1600 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Tue, 4 Feb 2025 04:26:18 +0100 Subject: [PATCH 10/88] Security fix for CVE-2025-0938 Fixes: rhbz#2343273 --- ...-and-in-domain-names-for-parsed-urls.patch | 119 ++++++++++++++++++ python3.14.spec | 10 +- 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch diff --git a/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch b/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch new file mode 100644 index 0000000..27dee43 --- /dev/null +++ b/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch @@ -0,0 +1,119 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Fri, 31 Jan 2025 11:41:34 -0600 +Subject: [PATCH] 00450: CVE-2025-0938: Disallow square brackets ([ and ]) in + domain names for parsed URLs + +Co-authored-by: Peter Bierma +--- + Lib/test/test_urlparse.py | 37 ++++++++++++++++++- + Lib/urllib/parse.py | 20 +++++++++- + ...-01-28-14-08-03.gh-issue-105704.EnhHxu.rst | 4 ++ + 3 files changed, 58 insertions(+), 3 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst + +diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py +index 4516bdea6a..b51cc006b7 100644 +--- a/Lib/test/test_urlparse.py ++++ b/Lib/test/test_urlparse.py +@@ -1412,16 +1412,51 @@ def test_invalid_bracketed_hosts(self): + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a1') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a1') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:1a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:1a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@prefix.[v6a.ip]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@[v6a.ip].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip[') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix') + + def test_splitting_bracketed_hosts(self): +- p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query') ++ p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query') + self.assertEqual(p1.hostname, 'v6a.ip') + self.assertEqual(p1.username, 'user') + self.assertEqual(p1.path, '/path') ++ self.assertEqual(p1.port, 1234) + p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query') + self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test') + self.assertEqual(p2.username, 'user') + self.assertEqual(p2.path, '/path') ++ self.assertIs(p2.port, None) + p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query') + self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test') + self.assertEqual(p3.username, 'user') +diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py +index c412c72985..9d51f4c681 100644 +--- a/Lib/urllib/parse.py ++++ b/Lib/urllib/parse.py +@@ -439,6 +439,23 @@ def _checknetloc(netloc): + raise ValueError("netloc '" + netloc + "' contains invalid " + + "characters under NFKC normalization") + ++def _check_bracketed_netloc(netloc): ++ # Note that this function must mirror the splitting ++ # done in NetlocResultMixins._hostinfo(). ++ hostname_and_port = netloc.rpartition('@')[2] ++ before_bracket, have_open_br, bracketed = hostname_and_port.partition('[') ++ if have_open_br: ++ # No data is allowed before a bracket. ++ if before_bracket: ++ raise ValueError("Invalid IPv6 URL") ++ hostname, _, port = bracketed.partition(']') ++ # No data is allowed after the bracket but before the port delimiter. ++ if port and not port.startswith(":"): ++ raise ValueError("Invalid IPv6 URL") ++ else: ++ hostname, _, port = hostname_and_port.partition(':') ++ _check_bracketed_host(hostname) ++ + # Valid bracketed hosts are defined in + # https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/ + def _check_bracketed_host(hostname): +@@ -505,8 +522,7 @@ def _urlsplit(url, scheme=None, allow_fragments=True): + (']' in netloc and '[' not in netloc)): + raise ValueError("Invalid IPv6 URL") + if '[' in netloc and ']' in netloc: +- bracketed_host = netloc.partition('[')[2].partition(']')[0] +- _check_bracketed_host(bracketed_host) ++ _check_bracketed_netloc(netloc) + if allow_fragments and '#' in url: + url, fragment = url.split('#', 1) + if '?' in url: +diff --git a/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst +new file mode 100644 +index 0000000000..bff1bc6b0d +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst +@@ -0,0 +1,4 @@ ++When using :func:`urllib.parse.urlsplit` and :func:`urllib.parse.urlparse` host ++parsing would not reject domain names containing square brackets (``[`` and ++``]``). Square brackets are only valid for IPv6 and IPvFuture hosts according to ++`RFC 3986 Section 3.2.2 `__. diff --git a/python3.14.spec b/python3.14.spec index d0019a6..a589200 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel a4 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -370,6 +370,10 @@ Patch448: 00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128 # gh-128889: Zero out memory ctypes for generated struct layout tests (GH-128944) Patch449: 00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch +# 00450 # 4ab8663661748eb994c09e4ae89f59eb84c5d3ea +# CVE-2025-0938: Disallow square brackets ([ and ]) in domain names for parsed URLs +Patch450: 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1713,6 +1717,10 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Feb 04 2025 Charalampos Stratakis - 3.14.0~a4-2 +- Security fix for CVE-2025-0938 +- Fixes: rhbz#2343273 + * Mon Jan 20 2025 Karolina Surma - 3.14.0~a4-1 - Update to Python 3.14.0a4 From 71818464a3f5214e646a5e21b94018496cc2f352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 6 Feb 2025 12:04:28 +0100 Subject: [PATCH 11/88] Rebuilt with mpdecimal 4.0.0 --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index a589200..9fa0ca4 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel a4 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python-2.0.1 @@ -1717,6 +1717,9 @@ CheckPython freethreading # ====================================================== %changelog +* Thu Feb 06 2025 Miro Hrončok - 3.14.0~a4-3 +- Rebuilt with mpdecimal 4.0.0 + * Tue Feb 04 2025 Charalampos Stratakis - 3.14.0~a4-2 - Security fix for CVE-2025-0938 - Fixes: rhbz#2343273 From a6be1658906621789dcc8f395098df176d309637 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 12 Feb 2025 09:14:16 +0100 Subject: [PATCH 12/88] Update to Python 3.14.0a5 --- 00251-change-user-install-location.patch | 16 +- ...rt-on-non--af_inet-sockets-gh-128933.patch | 84 -- ...erated-struct-layout-tests-gh-128944.patch | 758 ------------------ ...-and-in-domain-names-for-parsed-urls.patch | 119 --- ...-linux-with-free-threading-gh-130043.patch | 89 ++ python3.14.spec | 59 +- sources | 2 +- 7 files changed, 123 insertions(+), 1004 deletions(-) delete mode 100644 00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch delete mode 100644 00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch delete mode 100644 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch create mode 100644 00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 264cfdf..ece7bd5 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 92bd1ccdad..951784f3b4 100644 +index 9da8b6724e..b53dd21d51 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -420,8 +420,15 @@ def getsitepackages(prefixes=None): @@ -51,7 +51,7 @@ index 92bd1ccdad..951784f3b4 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index 7a4a8f65a5..c8fca72c01 100644 +index 69f72452c4..6d5d096644 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -67,7 +67,7 @@ index 7a4a8f65a5..c8fca72c01 100644 def _get_implementation(): return 'Python' -@@ -167,6 +173,19 @@ def joinuser(*args): +@@ -169,6 +175,19 @@ def joinuser(*args): }, } @@ -87,7 +87,7 @@ index 7a4a8f65a5..c8fca72c01 100644 _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 'scripts', 'data') -@@ -259,11 +278,40 @@ def _extend_dict(target_dict, other_dict): +@@ -268,11 +287,40 @@ def _extend_dict(target_dict, other_dict): target_dict[key] = value @@ -130,10 +130,10 @@ index 7a4a8f65a5..c8fca72c01 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 ce504dc21a..054e514130 100644 +index 3738914cf1..98da62ff05 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py -@@ -138,8 +138,19 @@ def test_get_path(self): +@@ -131,8 +131,19 @@ def test_get_path(self): for scheme in _INSTALL_SCHEMES: for name in _INSTALL_SCHEMES[scheme]: expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars) @@ -154,7 +154,7 @@ index ce504dc21a..054e514130 100644 os.path.normpath(expected), ) -@@ -394,7 +405,7 @@ def test_get_config_h_filename(self): +@@ -387,7 +398,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 ce504dc21a..054e514130 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -406,6 +417,8 @@ def test_symlink(self): # Issue 7880 +@@ -399,6 +410,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/00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch b/00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch deleted file mode 100644 index afee7af..0000000 --- a/00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= -Date: Sat, 18 Jan 2025 01:49:16 +0100 -Subject: [PATCH] 00448: gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` - sockets (GH-128933) - -* gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` sockets - -Do not attempt to set ``SO_REUSEPORT`` on sockets of address familifies other -than ``AF_INET`` and ``AF_INET6``, as it is meaningless with these address -families, and the call with fail with Linux kernel 6.12.9 and newer. - -* Apply suggestions from code review - -Co-authored-by: Vinay Sajip - ---------- - -Co-authored-by: Vinay Sajip ---- - Lib/asyncio/base_events.py | 4 +++- - Lib/socket.py | 4 +++- - Lib/socketserver.py | 7 ++++++- - .../Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst | 3 +++ - 4 files changed, 15 insertions(+), 3 deletions(-) - create mode 100644 Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst - -diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py -index 6e6e5aaac1..85018797db 100644 ---- a/Lib/asyncio/base_events.py -+++ b/Lib/asyncio/base_events.py -@@ -1593,7 +1593,9 @@ async def create_server( - if reuse_address: - sock.setsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR, True) -- if reuse_port: -+ # Since Linux 6.12.9, SO_REUSEPORT is not allowed -+ # on other address families than AF_INET/AF_INET6. -+ if reuse_port and af in (socket.AF_INET, socket.AF_INET6): - _set_reuseport(sock) - if keep_alive: - sock.setsockopt( -diff --git a/Lib/socket.py b/Lib/socket.py -index be37c24d61..727b0e75f0 100644 ---- a/Lib/socket.py -+++ b/Lib/socket.py -@@ -937,7 +937,9 @@ def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, - # Fail later on bind(), for platforms which may not - # support this option. - pass -- if reuse_port: -+ # Since Linux 6.12.9, SO_REUSEPORT is not allowed -+ # on other address families than AF_INET/AF_INET6. -+ if reuse_port and family in (AF_INET, AF_INET6): - sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1) - if has_ipv6 and family == AF_INET6: - if dualstack_ipv6: -diff --git a/Lib/socketserver.py b/Lib/socketserver.py -index cd028ef1c6..35b2723de3 100644 ---- a/Lib/socketserver.py -+++ b/Lib/socketserver.py -@@ -468,7 +468,12 @@ def server_bind(self): - """ - if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"): - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) -- if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"): -+ # Since Linux 6.12.9, SO_REUSEPORT is not allowed -+ # on other address families than AF_INET/AF_INET6. -+ if ( -+ self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT") -+ and self.address_family in (socket.AF_INET, socket.AF_INET6) -+ ): - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - self.socket.bind(self.server_address) - self.server_address = self.socket.getsockname() -diff --git a/Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst b/Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst -new file mode 100644 -index 0000000000..f2db341ef8 ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2025-01-17-11-46-16.gh-issue-128916.GEePbO.rst -@@ -0,0 +1,3 @@ -+Do not attempt to set ``SO_REUSEPORT`` on sockets of address families -+other than ``AF_INET`` and ``AF_INET6``, as it is meaningless with these -+address families, and the call with fail with Linux kernel 6.12.9 and newer. diff --git a/00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch b/00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch deleted file mode 100644 index 345c562..0000000 --- a/00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch +++ /dev/null @@ -1,758 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Petr Viktorin -Date: Tue, 21 Jan 2025 16:29:02 +0100 -Subject: [PATCH] 00449: gh-128889: Zero out memory ctypes for generated struct - layout tests (GH-128944) - ---- - .../test_ctypes/test_generated_structs.py | 5 +- - Modules/_ctypes/_ctypes_test_generated.c.h | 216 ++++++++++++------ - 2 files changed, 147 insertions(+), 74 deletions(-) - -diff --git a/Lib/test/test_ctypes/test_generated_structs.py b/Lib/test/test_ctypes/test_generated_structs.py -index d61754d6d4..1df9f0dc16 100644 ---- a/Lib/test/test_ctypes/test_generated_structs.py -+++ b/Lib/test/test_ctypes/test_generated_structs.py -@@ -443,7 +443,7 @@ def test_generated_data(self): - - None - - reason to skip the test (str) - -- This does depend on the C compiler keeping padding bits zero. -+ This does depend on the C compiler keeping padding bits unchanged. - Common compilers seem to do so. - """ - for name, cls in TESTCASES.items(): -@@ -696,7 +696,8 @@ def output(string): - output(' ' + line) - typename = f'{struct_or_union(cls)} {name}' - output(f""" -- {typename} value = {{0}}; -+ {typename} value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString({c_str_repr(name)})); - APPEND(PyLong_FromLong(sizeof({typename}))); - APPEND(PyLong_FromLong(_Alignof({typename}))); -diff --git a/Modules/_ctypes/_ctypes_test_generated.c.h b/Modules/_ctypes/_ctypes_test_generated.c.h -index 46a3e4b01e..d70b33eaa8 100644 ---- a/Modules/_ctypes/_ctypes_test_generated.c.h -+++ b/Modules/_ctypes/_ctypes_test_generated.c.h -@@ -56,7 +56,8 @@ - struct SingleInt { - int a; - }; -- struct SingleInt value = {0}; -+ struct SingleInt value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("SingleInt")); - APPEND(PyLong_FromLong(sizeof(struct SingleInt))); - APPEND(PyLong_FromLong(_Alignof(struct SingleInt))); -@@ -69,7 +70,8 @@ - union SingleInt_Union { - int a; - }; -- union SingleInt_Union value = {0}; -+ union SingleInt_Union value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("SingleInt_Union")); - APPEND(PyLong_FromLong(sizeof(union SingleInt_Union))); - APPEND(PyLong_FromLong(_Alignof(union SingleInt_Union))); -@@ -82,7 +84,8 @@ - struct SingleU32 { - uint32_t a; - }; -- struct SingleU32 value = {0}; -+ struct SingleU32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("SingleU32")); - APPEND(PyLong_FromLong(sizeof(struct SingleU32))); - APPEND(PyLong_FromLong(_Alignof(struct SingleU32))); -@@ -97,7 +100,8 @@ - int8_t y; - uint16_t z; - }; -- struct SimpleStruct value = {0}; -+ struct SimpleStruct value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("SimpleStruct")); - APPEND(PyLong_FromLong(sizeof(struct SimpleStruct))); - APPEND(PyLong_FromLong(_Alignof(struct SimpleStruct))); -@@ -114,7 +118,8 @@ - int8_t y; - uint16_t z; - }; -- union SimpleUnion value = {0}; -+ union SimpleUnion value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("SimpleUnion")); - APPEND(PyLong_FromLong(sizeof(union SimpleUnion))); - APPEND(PyLong_FromLong(_Alignof(union SimpleUnion))); -@@ -136,7 +141,8 @@ - int64_t i64; - uint64_t u64; - }; -- struct ManyTypes value = {0}; -+ struct ManyTypes value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("ManyTypes")); - APPEND(PyLong_FromLong(sizeof(struct ManyTypes))); - APPEND(PyLong_FromLong(_Alignof(struct ManyTypes))); -@@ -163,7 +169,8 @@ - int64_t i64; - uint64_t u64; - }; -- union ManyTypesU value = {0}; -+ union ManyTypesU value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("ManyTypesU")); - APPEND(PyLong_FromLong(sizeof(union ManyTypesU))); - APPEND(PyLong_FromLong(_Alignof(union ManyTypesU))); -@@ -197,7 +204,8 @@ - uint16_t z; - }; - }; -- struct Nested value = {0}; -+ struct Nested value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Nested")); - APPEND(PyLong_FromLong(sizeof(struct Nested))); - APPEND(PyLong_FromLong(_Alignof(struct Nested))); -@@ -223,7 +231,8 @@ - int64_t b; - }; - #pragma pack(pop) -- struct Packed1 value = {0}; -+ struct Packed1 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Packed1")); - APPEND(PyLong_FromLong(sizeof(struct Packed1))); - APPEND(PyLong_FromLong(_Alignof(struct Packed1))); -@@ -247,7 +256,8 @@ - int64_t b; - }; - #pragma pack(pop) -- struct Packed2 value = {0}; -+ struct Packed2 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Packed2")); - APPEND(PyLong_FromLong(sizeof(struct Packed2))); - APPEND(PyLong_FromLong(_Alignof(struct Packed2))); -@@ -271,7 +281,8 @@ - int64_t b; - }; - #pragma pack(pop) -- struct Packed3 value = {0}; -+ struct Packed3 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Packed3")); - APPEND(PyLong_FromLong(sizeof(struct Packed3))); - APPEND(PyLong_FromLong(_Alignof(struct Packed3))); -@@ -295,7 +306,8 @@ - int64_t b; - }; - #pragma pack(pop) -- struct Packed4 value = {0}; -+ struct Packed4 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Packed4")); - APPEND(PyLong_FromLong(sizeof(struct Packed4))); - APPEND(PyLong_FromLong(_Alignof(struct Packed4))); -@@ -316,7 +328,8 @@ - int64_t b; - int32_t c; - }; -- struct X86_32EdgeCase value = {0}; -+ struct X86_32EdgeCase value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("X86_32EdgeCase")); - APPEND(PyLong_FromLong(sizeof(struct X86_32EdgeCase))); - APPEND(PyLong_FromLong(_Alignof(struct X86_32EdgeCase))); -@@ -333,7 +346,8 @@ - unsigned int b :5; - unsigned int c :7; - }; -- struct MSBitFieldExample value = {0}; -+ struct MSBitFieldExample value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("MSBitFieldExample")); - APPEND(PyLong_FromLong(sizeof(struct MSBitFieldExample))); - APPEND(PyLong_FromLong(_Alignof(struct MSBitFieldExample))); -@@ -351,7 +365,8 @@ - unsigned int may_straddle :30; - unsigned int last :18; - }; -- struct MSStraddlingExample value = {0}; -+ struct MSStraddlingExample value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("MSStraddlingExample")); - APPEND(PyLong_FromLong(sizeof(struct MSStraddlingExample))); - APPEND(PyLong_FromLong(_Alignof(struct MSStraddlingExample))); -@@ -375,7 +390,8 @@ - int H :8; - int I :9; - }; -- struct IntBits value = {0}; -+ struct IntBits value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("IntBits")); - APPEND(PyLong_FromLong(sizeof(struct IntBits))); - APPEND(PyLong_FromLong(_Alignof(struct IntBits))); -@@ -413,7 +429,8 @@ - short R :6; - short S :7; - }; -- struct Bits value = {0}; -+ struct Bits value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Bits")); - APPEND(PyLong_FromLong(sizeof(struct Bits))); - APPEND(PyLong_FromLong(_Alignof(struct Bits))); -@@ -456,7 +473,8 @@ - int H :8; - int I :9; - }; -- struct IntBits_MSVC value = {0}; -+ struct IntBits_MSVC value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("IntBits_MSVC")); - APPEND(PyLong_FromLong(sizeof(struct IntBits_MSVC))); - APPEND(PyLong_FromLong(_Alignof(struct IntBits_MSVC))); -@@ -499,7 +517,8 @@ - short R :6; - short S :7; - }; -- struct Bits_MSVC value = {0}; -+ struct Bits_MSVC value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Bits_MSVC")); - APPEND(PyLong_FromLong(sizeof(struct Bits_MSVC))); - APPEND(PyLong_FromLong(_Alignof(struct Bits_MSVC))); -@@ -536,7 +555,8 @@ - int64_t b :62; - int64_t c :1; - }; -- struct I64Bits value = {0}; -+ struct I64Bits value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("I64Bits")); - APPEND(PyLong_FromLong(sizeof(struct I64Bits))); - APPEND(PyLong_FromLong(_Alignof(struct I64Bits))); -@@ -560,7 +580,8 @@ - uint64_t b :62; - uint64_t c :1; - }; -- struct U64Bits value = {0}; -+ struct U64Bits value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("U64Bits")); - APPEND(PyLong_FromLong(sizeof(struct U64Bits))); - APPEND(PyLong_FromLong(_Alignof(struct U64Bits))); -@@ -584,7 +605,8 @@ - int8_t b :3; - int8_t c :1; - }; -- struct Struct331_8 value = {0}; -+ struct Struct331_8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_8")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_8))); -@@ -608,7 +630,8 @@ - int8_t b :6; - int8_t c :1; - }; -- struct Struct1x1_8 value = {0}; -+ struct Struct1x1_8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_8")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_8))); -@@ -633,7 +656,8 @@ - int8_t b :6; - int8_t c :1; - }; -- struct Struct1nx1_8 value = {0}; -+ struct Struct1nx1_8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_8")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_8))); -@@ -658,7 +682,8 @@ - int8_t b :6; - int8_t c :6; - }; -- struct Struct3xx_8 value = {0}; -+ struct Struct3xx_8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_8")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_8))); -@@ -682,7 +707,8 @@ - uint8_t b :3; - uint8_t c :1; - }; -- struct Struct331_u8 value = {0}; -+ struct Struct331_u8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_u8")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_u8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_u8))); -@@ -706,7 +732,8 @@ - uint8_t b :6; - uint8_t c :1; - }; -- struct Struct1x1_u8 value = {0}; -+ struct Struct1x1_u8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_u8")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u8))); -@@ -731,7 +758,8 @@ - uint8_t b :6; - uint8_t c :1; - }; -- struct Struct1nx1_u8 value = {0}; -+ struct Struct1nx1_u8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_u8")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u8))); -@@ -756,7 +784,8 @@ - uint8_t b :6; - uint8_t c :6; - }; -- struct Struct3xx_u8 value = {0}; -+ struct Struct3xx_u8 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_u8")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u8))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u8))); -@@ -780,7 +809,8 @@ - int16_t b :3; - int16_t c :1; - }; -- struct Struct331_16 value = {0}; -+ struct Struct331_16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_16")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_16))); -@@ -804,7 +834,8 @@ - int16_t b :14; - int16_t c :1; - }; -- struct Struct1x1_16 value = {0}; -+ struct Struct1x1_16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_16")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_16))); -@@ -829,7 +860,8 @@ - int16_t b :14; - int16_t c :1; - }; -- struct Struct1nx1_16 value = {0}; -+ struct Struct1nx1_16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_16")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_16))); -@@ -854,7 +886,8 @@ - int16_t b :14; - int16_t c :14; - }; -- struct Struct3xx_16 value = {0}; -+ struct Struct3xx_16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_16")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_16))); -@@ -878,7 +911,8 @@ - uint16_t b :3; - uint16_t c :1; - }; -- struct Struct331_u16 value = {0}; -+ struct Struct331_u16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_u16")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_u16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_u16))); -@@ -902,7 +936,8 @@ - uint16_t b :14; - uint16_t c :1; - }; -- struct Struct1x1_u16 value = {0}; -+ struct Struct1x1_u16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_u16")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u16))); -@@ -927,7 +962,8 @@ - uint16_t b :14; - uint16_t c :1; - }; -- struct Struct1nx1_u16 value = {0}; -+ struct Struct1nx1_u16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_u16")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u16))); -@@ -952,7 +988,8 @@ - uint16_t b :14; - uint16_t c :14; - }; -- struct Struct3xx_u16 value = {0}; -+ struct Struct3xx_u16 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_u16")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u16))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u16))); -@@ -976,7 +1013,8 @@ - int32_t b :3; - int32_t c :1; - }; -- struct Struct331_32 value = {0}; -+ struct Struct331_32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_32")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_32))); -@@ -1000,7 +1038,8 @@ - int32_t b :30; - int32_t c :1; - }; -- struct Struct1x1_32 value = {0}; -+ struct Struct1x1_32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_32")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_32))); -@@ -1025,7 +1064,8 @@ - int32_t b :30; - int32_t c :1; - }; -- struct Struct1nx1_32 value = {0}; -+ struct Struct1nx1_32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_32")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_32))); -@@ -1050,7 +1090,8 @@ - int32_t b :30; - int32_t c :30; - }; -- struct Struct3xx_32 value = {0}; -+ struct Struct3xx_32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_32")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_32))); -@@ -1074,7 +1115,8 @@ - uint32_t b :3; - uint32_t c :1; - }; -- struct Struct331_u32 value = {0}; -+ struct Struct331_u32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_u32")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_u32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_u32))); -@@ -1098,7 +1140,8 @@ - uint32_t b :30; - uint32_t c :1; - }; -- struct Struct1x1_u32 value = {0}; -+ struct Struct1x1_u32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_u32")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u32))); -@@ -1123,7 +1166,8 @@ - uint32_t b :30; - uint32_t c :1; - }; -- struct Struct1nx1_u32 value = {0}; -+ struct Struct1nx1_u32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_u32")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u32))); -@@ -1148,7 +1192,8 @@ - uint32_t b :30; - uint32_t c :30; - }; -- struct Struct3xx_u32 value = {0}; -+ struct Struct3xx_u32 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_u32")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u32))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u32))); -@@ -1172,7 +1217,8 @@ - int64_t b :3; - int64_t c :1; - }; -- struct Struct331_64 value = {0}; -+ struct Struct331_64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_64")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_64))); -@@ -1196,7 +1242,8 @@ - int64_t b :62; - int64_t c :1; - }; -- struct Struct1x1_64 value = {0}; -+ struct Struct1x1_64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_64")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_64))); -@@ -1221,7 +1268,8 @@ - int64_t b :62; - int64_t c :1; - }; -- struct Struct1nx1_64 value = {0}; -+ struct Struct1nx1_64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_64")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_64))); -@@ -1246,7 +1294,8 @@ - int64_t b :62; - int64_t c :62; - }; -- struct Struct3xx_64 value = {0}; -+ struct Struct3xx_64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_64")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_64))); -@@ -1270,7 +1319,8 @@ - uint64_t b :3; - uint64_t c :1; - }; -- struct Struct331_u64 value = {0}; -+ struct Struct331_u64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct331_u64")); - APPEND(PyLong_FromLong(sizeof(struct Struct331_u64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct331_u64))); -@@ -1294,7 +1344,8 @@ - uint64_t b :62; - uint64_t c :1; - }; -- struct Struct1x1_u64 value = {0}; -+ struct Struct1x1_u64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1x1_u64")); - APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u64))); -@@ -1319,7 +1370,8 @@ - uint64_t b :62; - uint64_t c :1; - }; -- struct Struct1nx1_u64 value = {0}; -+ struct Struct1nx1_u64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct1nx1_u64")); - APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u64))); -@@ -1344,7 +1396,8 @@ - uint64_t b :62; - uint64_t c :62; - }; -- struct Struct3xx_u64 value = {0}; -+ struct Struct3xx_u64 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Struct3xx_u64")); - APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u64))); - APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u64))); -@@ -1367,7 +1420,8 @@ - signed char a :4; - int b :4; - }; -- struct Mixed1 value = {0}; -+ struct Mixed1 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed1")); - APPEND(PyLong_FromLong(sizeof(struct Mixed1))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed1))); -@@ -1389,7 +1443,8 @@ - signed char a :4; - int32_t b :32; - }; -- struct Mixed2 value = {0}; -+ struct Mixed2 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed2")); - APPEND(PyLong_FromLong(sizeof(struct Mixed2))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed2))); -@@ -1411,7 +1466,8 @@ - signed char a :4; - unsigned char b :4; - }; -- struct Mixed3 value = {0}; -+ struct Mixed3 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed3")); - APPEND(PyLong_FromLong(sizeof(struct Mixed3))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed3))); -@@ -1437,7 +1493,8 @@ - short e :4; - int f :24; - }; -- struct Mixed4 value = {0}; -+ struct Mixed4 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed4")); - APPEND(PyLong_FromLong(sizeof(struct Mixed4))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed4))); -@@ -1463,7 +1520,8 @@ - unsigned int A :1; - unsigned short B :16; - }; -- struct Mixed5 value = {0}; -+ struct Mixed5 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed5")); - APPEND(PyLong_FromLong(sizeof(struct Mixed5))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed5))); -@@ -1485,7 +1543,8 @@ - unsigned long long A :1; - unsigned int B :32; - }; -- struct Mixed6 value = {0}; -+ struct Mixed6 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed6")); - APPEND(PyLong_FromLong(sizeof(struct Mixed6))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed6))); -@@ -1508,7 +1567,8 @@ - uint32_t B :20; - uint64_t C :24; - }; -- struct Mixed7 value = {0}; -+ struct Mixed7 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed7")); - APPEND(PyLong_FromLong(sizeof(struct Mixed7))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed7))); -@@ -1532,7 +1592,8 @@ - uint32_t B :32; - unsigned long long C :1; - }; -- struct Mixed8_a value = {0}; -+ struct Mixed8_a value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed8_a")); - APPEND(PyLong_FromLong(sizeof(struct Mixed8_a))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed8_a))); -@@ -1556,7 +1617,8 @@ - uint32_t B; - unsigned long long C :1; - }; -- struct Mixed8_b value = {0}; -+ struct Mixed8_b value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed8_b")); - APPEND(PyLong_FromLong(sizeof(struct Mixed8_b))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed8_b))); -@@ -1579,7 +1641,8 @@ - uint8_t A; - uint32_t B :1; - }; -- struct Mixed9 value = {0}; -+ struct Mixed9 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed9")); - APPEND(PyLong_FromLong(sizeof(struct Mixed9))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed9))); -@@ -1601,7 +1664,8 @@ - uint32_t A :1; - uint64_t B :1; - }; -- struct Mixed10 value = {0}; -+ struct Mixed10 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Mixed10")); - APPEND(PyLong_FromLong(sizeof(struct Mixed10))); - APPEND(PyLong_FromLong(_Alignof(struct Mixed10))); -@@ -1623,7 +1687,8 @@ - uint32_t A :1; - uint64_t B :1; - }; -- struct Example_gh_95496 value = {0}; -+ struct Example_gh_95496 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_95496")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_95496))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_95496))); -@@ -1655,7 +1720,8 @@ - uint16_t b1 :12; - }; - #pragma pack(pop) -- struct Example_gh_84039_bad value = {0}; -+ struct Example_gh_84039_bad value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_84039_bad")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_bad))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_bad))); -@@ -1693,7 +1759,8 @@ - uint8_t a7 :1; - }; - #pragma pack(pop) -- struct Example_gh_84039_good_a value = {0}; -+ struct Example_gh_84039_good_a value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_84039_good_a")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_good_a))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_good_a))); -@@ -1735,7 +1802,8 @@ - uint16_t b1 :12; - }; - #pragma pack(pop) -- struct Example_gh_84039_good value = {0}; -+ struct Example_gh_84039_good value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_84039_good")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_good))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_good))); -@@ -1775,7 +1843,8 @@ - uint32_t R2 :2; - }; - #pragma pack(pop) -- struct Example_gh_73939 value = {0}; -+ struct Example_gh_73939 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_73939")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_73939))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_73939))); -@@ -1806,7 +1875,8 @@ - uint8_t b :8; - uint32_t c :16; - }; -- struct Example_gh_86098 value = {0}; -+ struct Example_gh_86098 value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_86098")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_86098))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_86098))); -@@ -1832,7 +1902,8 @@ - uint32_t c :16; - }; - #pragma pack(pop) -- struct Example_gh_86098_pack value = {0}; -+ struct Example_gh_86098_pack value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("Example_gh_86098_pack")); - APPEND(PyLong_FromLong(sizeof(struct Example_gh_86098_pack))); - APPEND(PyLong_FromLong(_Alignof(struct Example_gh_86098_pack))); -@@ -1858,7 +1929,8 @@ - }; - signed char y; - }; -- struct AnonBitfields value = {0}; -+ struct AnonBitfields value; -+ memset(&value, 0, sizeof(value)); - APPEND(PyUnicode_FromString("AnonBitfields")); - APPEND(PyLong_FromLong(sizeof(struct AnonBitfields))); - APPEND(PyLong_FromLong(_Alignof(struct AnonBitfields))); diff --git a/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch b/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch deleted file mode 100644 index 27dee43..0000000 --- a/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Fri, 31 Jan 2025 11:41:34 -0600 -Subject: [PATCH] 00450: CVE-2025-0938: Disallow square brackets ([ and ]) in - domain names for parsed URLs - -Co-authored-by: Peter Bierma ---- - Lib/test/test_urlparse.py | 37 ++++++++++++++++++- - Lib/urllib/parse.py | 20 +++++++++- - ...-01-28-14-08-03.gh-issue-105704.EnhHxu.rst | 4 ++ - 3 files changed, 58 insertions(+), 3 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst - -diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py -index 4516bdea6a..b51cc006b7 100644 ---- a/Lib/test/test_urlparse.py -+++ b/Lib/test/test_urlparse.py -@@ -1412,16 +1412,51 @@ def test_invalid_bracketed_hosts(self): - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a1') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a1') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:1a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:1a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@prefix.[v6a.ip]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@[v6a.ip].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip[') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix') - - def test_splitting_bracketed_hosts(self): -- p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query') -+ p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query') - self.assertEqual(p1.hostname, 'v6a.ip') - self.assertEqual(p1.username, 'user') - self.assertEqual(p1.path, '/path') -+ self.assertEqual(p1.port, 1234) - p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query') - self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test') - self.assertEqual(p2.username, 'user') - self.assertEqual(p2.path, '/path') -+ self.assertIs(p2.port, None) - p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query') - self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test') - self.assertEqual(p3.username, 'user') -diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py -index c412c72985..9d51f4c681 100644 ---- a/Lib/urllib/parse.py -+++ b/Lib/urllib/parse.py -@@ -439,6 +439,23 @@ def _checknetloc(netloc): - raise ValueError("netloc '" + netloc + "' contains invalid " + - "characters under NFKC normalization") - -+def _check_bracketed_netloc(netloc): -+ # Note that this function must mirror the splitting -+ # done in NetlocResultMixins._hostinfo(). -+ hostname_and_port = netloc.rpartition('@')[2] -+ before_bracket, have_open_br, bracketed = hostname_and_port.partition('[') -+ if have_open_br: -+ # No data is allowed before a bracket. -+ if before_bracket: -+ raise ValueError("Invalid IPv6 URL") -+ hostname, _, port = bracketed.partition(']') -+ # No data is allowed after the bracket but before the port delimiter. -+ if port and not port.startswith(":"): -+ raise ValueError("Invalid IPv6 URL") -+ else: -+ hostname, _, port = hostname_and_port.partition(':') -+ _check_bracketed_host(hostname) -+ - # Valid bracketed hosts are defined in - # https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/ - def _check_bracketed_host(hostname): -@@ -505,8 +522,7 @@ def _urlsplit(url, scheme=None, allow_fragments=True): - (']' in netloc and '[' not in netloc)): - raise ValueError("Invalid IPv6 URL") - if '[' in netloc and ']' in netloc: -- bracketed_host = netloc.partition('[')[2].partition(']')[0] -- _check_bracketed_host(bracketed_host) -+ _check_bracketed_netloc(netloc) - if allow_fragments and '#' in url: - url, fragment = url.split('#', 1) - if '?' in url: -diff --git a/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst -new file mode 100644 -index 0000000000..bff1bc6b0d ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst -@@ -0,0 +1,4 @@ -+When using :func:`urllib.parse.urlsplit` and :func:`urllib.parse.urlparse` host -+parsing would not reject domain names containing square brackets (``[`` and -+``]``). Square brackets are only valid for IPv6 and IPvFuture hosts according to -+`RFC 3986 Section 3.2.2 `__. diff --git a/00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch b/00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch new file mode 100644 index 0000000..f810a87 --- /dev/null +++ b/00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sam Gross +Date: Wed, 12 Feb 2025 18:09:15 -0500 +Subject: [PATCH] 00451: gh-130030: Fix crash on 32-bit Linux with free + threading (gh-130043) + +The `gc_get_refs` assertion needs to be after we check the alive and +unreachable bits. Otherwise, `ob_tid` may store the actual thread id +instead of the computed `gc_refs`, which may trigger the assertion if +the `ob_tid` looks like a negative value. + +Also fix a few type warnings on 32-bit systems. +--- + Objects/obmalloc.c | 12 ++++++------ + Python/gc_free_threading.c | 12 +++++++----- + 2 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c +index 5688049b02..6341251007 100644 +--- a/Objects/obmalloc.c ++++ b/Objects/obmalloc.c +@@ -3297,12 +3297,12 @@ static bool _collect_alloc_stats( + static void + py_mimalloc_print_stats(FILE *out) + { +- fprintf(out, "Small block threshold = %zd, in %u size classes.\n", +- MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE); +- fprintf(out, "Medium block threshold = %zd\n", +- MI_MEDIUM_OBJ_SIZE_MAX); +- fprintf(out, "Large object max size = %zd\n", +- MI_LARGE_OBJ_SIZE_MAX); ++ fprintf(out, "Small block threshold = %zu, in %u size classes.\n", ++ (size_t)MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE); ++ fprintf(out, "Medium block threshold = %zu\n", ++ (size_t)MI_MEDIUM_OBJ_SIZE_MAX); ++ fprintf(out, "Large object max size = %zu\n", ++ (size_t)MI_LARGE_OBJ_SIZE_MAX); + + mi_heap_t *heap = mi_heap_get_default(); + struct _alloc_stats stats; +diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c +index 9e459da3a4..0d6fddb570 100644 +--- a/Python/gc_free_threading.c ++++ b/Python/gc_free_threading.c +@@ -581,11 +581,13 @@ gc_mark_buffer_len(gc_mark_args_t *args) + } + + // Returns number of free entry slots in buffer ++#ifndef NDEBUG + static inline unsigned int + gc_mark_buffer_avail(gc_mark_args_t *args) + { + return BUFFER_SIZE - gc_mark_buffer_len(args); + } ++#endif + + static inline bool + gc_mark_buffer_is_empty(gc_mark_args_t *args) +@@ -1074,14 +1076,14 @@ mark_heap_visitor(const mi_heap_t *heap, const mi_heap_area_t *area, + return true; + } + +- _PyObject_ASSERT_WITH_MSG(op, gc_get_refs(op) >= 0, +- "refcount is too small"); +- + if (gc_is_alive(op) || !gc_is_unreachable(op)) { + // Object was already marked as reachable. + return true; + } + ++ _PyObject_ASSERT_WITH_MSG(op, gc_get_refs(op) >= 0, ++ "refcount is too small"); ++ + // GH-129236: If we've seen an active frame without a valid stack pointer, + // then we can't collect objects with deferred references because we may + // have missed some reference to the object on the stack. In that case, +@@ -1178,10 +1180,10 @@ move_legacy_finalizer_reachable(struct collection_state *state); + static void + gc_prime_from_spans(gc_mark_args_t *args) + { +- Py_ssize_t space = BUFFER_HI - gc_mark_buffer_len(args); ++ unsigned int space = BUFFER_HI - gc_mark_buffer_len(args); + // there should always be at least this amount of space + assert(space <= gc_mark_buffer_avail(args)); +- assert(space > 0); ++ assert(space <= BUFFER_HI); + gc_span_t entry = args->spans.stack[--args->spans.size]; + // spans on the stack should always have one or more elements + assert(entry.start < entry.end); diff --git a/python3.14.spec b/python3.14.spec index 9fa0ca4..94e78e6 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,10 +14,10 @@ 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}.0 -%global prerel a4 +%global prerel a5 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -57,28 +57,28 @@ 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 24.3.1 +%global pip_version 25.0.1 %global setuptools_version 67.6.1 %global wheel_version 0.43.0 # 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 +Provides: bundled(python3dist(cachecontrol)) = 0.14.1 Provides: bundled(python3dist(certifi)) = 2024.8.30 Provides: bundled(python3dist(distlib)) = 0.3.9 Provides: bundled(python3dist(distro)) = 1.9 -Provides: bundled(python3dist(idna)) = 3.7 -Provides: bundled(python3dist(msgpack)) = 1.0.8 -Provides: bundled(python3dist(packaging)) = 24.1 -Provides: bundled(python3dist(platformdirs)) = 4.2.2 +Provides: bundled(python3dist(idna)) = 3.10 +Provides: bundled(python3dist(msgpack)) = 1.1 +Provides: bundled(python3dist(packaging)) = 24.2 +Provides: bundled(python3dist(platformdirs)) = 4.3.6 Provides: bundled(python3dist(pygments)) = 2.18 -Provides: bundled(python3dist(pyproject-hooks)) = 1 +Provides: bundled(python3dist(pyproject-hooks)) = 1.2 Provides: bundled(python3dist(requests)) = 2.32.3 Provides: bundled(python3dist(resolvelib)) = 1.0.1 -Provides: bundled(python3dist(rich)) = 13.7.1 +Provides: bundled(python3dist(rich)) = 13.9.4 Provides: bundled(python3dist(setuptools)) = 70.3 -Provides: bundled(python3dist(tomli)) = 2.0.1 +Provides: bundled(python3dist(tomli)) = 2.2.1 Provides: bundled(python3dist(truststore)) = 0.10 Provides: bundled(python3dist(typing-extensions)) = 4.12.2 Provides: bundled(python3dist(urllib3)) = 1.26.20 @@ -351,28 +351,16 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00448 # e145ddea32596809c4222b05444c645eed2ea3af -# gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` sockets (GH-128933) +# 00451 # 6b2c3f979219408cc0d48262c31f14a7da418ae2 +# gh-130030: Fix crash on 32-bit Linux with free threading (gh-130043) # -# * gh-128916: Do not set `SO_REUSEPORT` on non-`AF_INET*` sockets +# The `gc_get_refs` assertion needs to be after we check the alive and +# unreachable bits. Otherwise, `ob_tid` may store the actual thread id +# instead of the computed `gc_refs`, which may trigger the assertion if +# the `ob_tid` looks like a negative value. # -# Do not attempt to set ``SO_REUSEPORT`` on sockets of address familifies other -# than ``AF_INET`` and ``AF_INET6``, as it is meaningless with these address -# families, and the call with fail with Linux kernel 6.12.9 and newer. -# -# * Apply suggestions from code review -# -# -# --------- -Patch448: 00448-gh-128916-do-not-set-so_reuseport-on-non--af_inet-sockets-gh-128933.patch - -# 00449 # ddd832ac88676343c94b57af00f892928d2c242d -# gh-128889: Zero out memory ctypes for generated struct layout tests (GH-128944) -Patch449: 00449-gh-128889-zero-out-memory-ctypes-for-generated-struct-layout-tests-gh-128944.patch - -# 00450 # 4ab8663661748eb994c09e4ae89f59eb84c5d3ea -# CVE-2025-0938: Disallow square brackets ([ and ]) in domain names for parsed URLs -Patch450: 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch +# Also fix a few type warnings on 32-bit systems. +Patch451: 00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch # (New patches go here ^^^) # @@ -1264,8 +1252,8 @@ CheckPython() { # 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_init_pyvenv_cfg is failing since 3.14.0a4, the issue is known upstream: - # https://github.com/python/cpython/issues/128690 + # test_external_inspection sometimes fails on freethreading-debug + # see: https://github.com/python/cpython/issues/130035 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1275,7 +1263,7 @@ CheckPython() { %endif -i test_freeze_simple_script \ -i test_check_probes \ - -i test_init_pyvenv_cfg \ + -i test_external_inspection \ %ifarch %{mips64} -x test_ctypes \ %endif @@ -1717,6 +1705,9 @@ CheckPython freethreading # ====================================================== %changelog +* Wed Feb 12 2025 Karolina Surma - 3.14.0~a5-1 +- Update to Python 3.14.0a5 + * Thu Feb 06 2025 Miro Hrončok - 3.14.0~a4-3 - Rebuilt with mpdecimal 4.0.0 diff --git a/sources b/sources index d4cbdc0..e9ab098 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0a4.tar.xz) = b70671ebbd9f777fdcb661405c538c733600470ac34992a5b3df99d2f5afecc22cd8325eeec50eeef043181e634da91e535c166b9b5ed421d4e6aa41b79da3ab +SHA512 (Python-3.14.0a5.tar.xz) = ae34c994f00c36c6ce18091c63eb3469aa545ee391c6879c89f5722f7311f2e97cc997477897969777dfaf98090e3dd01dcdb655c986140e9a7796f963be9df9 From 4490e888a688ee1749f9462b623b3d77cde886aa Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 17 Mar 2025 09:40:04 +0100 Subject: [PATCH 13/88] Update to Python 3.14.0a6 --- 00251-change-user-install-location.patch | 2 +- ...-linux-with-free-threading-gh-130043.patch | 89 ------------------- python3.14.spec | 20 ++--- sources | 2 +- tests/tests.yml | 3 +- 5 files changed, 12 insertions(+), 104 deletions(-) delete mode 100644 00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index ece7bd5..be55264 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -51,7 +51,7 @@ index 9da8b6724e..b53dd21d51 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index 69f72452c4..6d5d096644 100644 +index 18e6b8d25e..42df12fad4 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ diff --git a/00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch b/00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch deleted file mode 100644 index f810a87..0000000 --- a/00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sam Gross -Date: Wed, 12 Feb 2025 18:09:15 -0500 -Subject: [PATCH] 00451: gh-130030: Fix crash on 32-bit Linux with free - threading (gh-130043) - -The `gc_get_refs` assertion needs to be after we check the alive and -unreachable bits. Otherwise, `ob_tid` may store the actual thread id -instead of the computed `gc_refs`, which may trigger the assertion if -the `ob_tid` looks like a negative value. - -Also fix a few type warnings on 32-bit systems. ---- - Objects/obmalloc.c | 12 ++++++------ - Python/gc_free_threading.c | 12 +++++++----- - 2 files changed, 13 insertions(+), 11 deletions(-) - -diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c -index 5688049b02..6341251007 100644 ---- a/Objects/obmalloc.c -+++ b/Objects/obmalloc.c -@@ -3297,12 +3297,12 @@ static bool _collect_alloc_stats( - static void - py_mimalloc_print_stats(FILE *out) - { -- fprintf(out, "Small block threshold = %zd, in %u size classes.\n", -- MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE); -- fprintf(out, "Medium block threshold = %zd\n", -- MI_MEDIUM_OBJ_SIZE_MAX); -- fprintf(out, "Large object max size = %zd\n", -- MI_LARGE_OBJ_SIZE_MAX); -+ fprintf(out, "Small block threshold = %zu, in %u size classes.\n", -+ (size_t)MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE); -+ fprintf(out, "Medium block threshold = %zu\n", -+ (size_t)MI_MEDIUM_OBJ_SIZE_MAX); -+ fprintf(out, "Large object max size = %zu\n", -+ (size_t)MI_LARGE_OBJ_SIZE_MAX); - - mi_heap_t *heap = mi_heap_get_default(); - struct _alloc_stats stats; -diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c -index 9e459da3a4..0d6fddb570 100644 ---- a/Python/gc_free_threading.c -+++ b/Python/gc_free_threading.c -@@ -581,11 +581,13 @@ gc_mark_buffer_len(gc_mark_args_t *args) - } - - // Returns number of free entry slots in buffer -+#ifndef NDEBUG - static inline unsigned int - gc_mark_buffer_avail(gc_mark_args_t *args) - { - return BUFFER_SIZE - gc_mark_buffer_len(args); - } -+#endif - - static inline bool - gc_mark_buffer_is_empty(gc_mark_args_t *args) -@@ -1074,14 +1076,14 @@ mark_heap_visitor(const mi_heap_t *heap, const mi_heap_area_t *area, - return true; - } - -- _PyObject_ASSERT_WITH_MSG(op, gc_get_refs(op) >= 0, -- "refcount is too small"); -- - if (gc_is_alive(op) || !gc_is_unreachable(op)) { - // Object was already marked as reachable. - return true; - } - -+ _PyObject_ASSERT_WITH_MSG(op, gc_get_refs(op) >= 0, -+ "refcount is too small"); -+ - // GH-129236: If we've seen an active frame without a valid stack pointer, - // then we can't collect objects with deferred references because we may - // have missed some reference to the object on the stack. In that case, -@@ -1178,10 +1180,10 @@ move_legacy_finalizer_reachable(struct collection_state *state); - static void - gc_prime_from_spans(gc_mark_args_t *args) - { -- Py_ssize_t space = BUFFER_HI - gc_mark_buffer_len(args); -+ unsigned int space = BUFFER_HI - gc_mark_buffer_len(args); - // there should always be at least this amount of space - assert(space <= gc_mark_buffer_avail(args)); -- assert(space > 0); -+ assert(space <= BUFFER_HI); - gc_span_t entry = args->spans.stack[--args->spans.size]; - // spans on the stack should always have one or more elements - assert(entry.start < entry.end); diff --git a/python3.14.spec b/python3.14.spec index 94e78e6..244a138 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,7 +14,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}.0 -%global prerel a5 +%global prerel a6 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -351,17 +351,6 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00451 # 6b2c3f979219408cc0d48262c31f14a7da418ae2 -# gh-130030: Fix crash on 32-bit Linux with free threading (gh-130043) -# -# The `gc_get_refs` assertion needs to be after we check the alive and -# unreachable bits. Otherwise, `ob_tid` may store the actual thread id -# instead of the computed `gc_refs`, which may trigger the assertion if -# the `ob_tid` looks like a negative value. -# -# Also fix a few type warnings on 32-bit systems. -Patch451: 00451-gh-130030-fix-crash-on-32-bit-linux-with-free-threading-gh-130043.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1379,6 +1368,8 @@ CheckPython freethreading %pure_python_modules %{pylibdir} %{pylibdir}/_sysconfig_vars_%{ABIFLAGS_optimized}_linux_%{platform_triplet}.json +# File defined by PEP 739 since Python 3.14: +%{pylibdir}/build-details.json # This will be in the tkinter package %exclude %{pylibdir}/turtle.py @@ -1628,6 +1619,8 @@ CheckPython freethreading %{pylibdir_freethreading}/turtledemo/ %{pylibdir_freethreading}/_sysconfig_vars_%{ABIFLAGS_freethreading}_linux_%{platform_triplet}.json +# File defined by PEP 739 since Python 3.14: +%{pylibdir_freethreading}/build-details.json # This will be in the -freethreading-debug package %if %{with debug_build} @@ -1705,6 +1698,9 @@ CheckPython freethreading # ====================================================== %changelog +* Mon Mar 17 2025 Karolina Surma - 3.14.0~a6-1 +- Update to Python 3.14.0a6 + * Wed Feb 12 2025 Karolina Surma - 3.14.0~a5-1 - Update to Python 3.14.0a5 diff --git a/sources b/sources index e9ab098..a424a41 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0a5.tar.xz) = ae34c994f00c36c6ce18091c63eb3469aa545ee391c6879c89f5722f7311f2e97cc997477897969777dfaf98090e3dd01dcdb655c986140e9a7796f963be9df9 +SHA512 (Python-3.14.0a6.tar.xz) = 0fca503199bed0744139823aaf3ead30d7876556750b476fa6e1f701ae71fa7fe333cd46c775929c26729cf71bef6ba545fdc0118a0efca17c2434de3cadabe1 diff --git a/tests/tests.yml b/tests/tests.yml index 8af0de4..b1255ce 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -33,7 +33,8 @@ run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - debugtest: dir: python/selftest - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" + # test_base_interpreter: https://github.com/python/cpython/issues/131372 + run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter' ./parallel.sh" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 608ee6ea090483c2eaa66f88720723bb17bb096a Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 8 Apr 2025 17:15:11 +0200 Subject: [PATCH 14/88] Update to Python 3.14.0a7 --- 00251-change-user-install-location.patch | 2 +- ...oken-rst-with-rstfile-as-an-argument.patch | 24 ++++++++++++++++++ ...ame-in-test_group_no_follow_symlinks.patch | 25 +++++++++++++++++++ python3.14.spec | 19 +++++++++++++- sources | 2 +- tests/tests.yml | 5 ++-- 6 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch create mode 100644 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index be55264..5283ffb 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -130,7 +130,7 @@ index 18e6b8d25e..42df12fad4 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 3738914cf1..98da62ff05 100644 +index cc11eade2e..b4f8aabaef 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -131,8 +131,19 @@ def test_get_path(self): diff --git a/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch b/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch new file mode 100644 index 0000000..a456192 --- /dev/null +++ b/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Wed, 9 Apr 2025 10:47:48 +0200 +Subject: [PATCH] 00454: Invoke regen-token rst with rstfile as an argument + +Proposed upstream: https://github.com/python/cpython/pull/132304 +--- + Makefile.pre.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index e10c78d640..5dfde4efcb 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -1960,7 +1960,8 @@ regen-token: + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py rst \ + $(srcdir)/Grammar/Tokens \ +- $(srcdir)/Doc/library/token-list.inc ++ $(srcdir)/Doc/library/token-list.inc \ ++ $(srcdir)/Doc/library/token.rst + # Regenerate Include/internal/pycore_token.h from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py h \ diff --git a/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch b/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch new file mode 100644 index 0000000..3ef6e55 --- /dev/null +++ b/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Thu, 10 Apr 2025 13:46:25 +0200 +Subject: [PATCH] 00456: Find the correct group name in + test_group_no_follow_symlinks + +Reported: https://github.com/python/cpython/issues/132356 +Fix proposed upstream: https://github.com/python/cpython/pull/132357 +--- + Lib/test/test_pathlib/test_pathlib.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py +index b1fcc5f6f0..3cfffc6311 100644 +--- a/Lib/test/test_pathlib/test_pathlib.py ++++ b/Lib/test/test_pathlib/test_pathlib.py +@@ -2065,7 +2065,7 @@ def test_group_no_follow_symlinks(self): + os.chown(link, -1, gid_2, follow_symlinks=False) + + expected_gid = link.stat(follow_symlinks=False).st_gid +- expected_name = self._get_pw_name_or_skip_test(expected_gid) ++ expected_name = self._get_gr_name_or_skip_test(expected_gid) + + self.assertEqual(expected_gid, gid_2) + self.assertEqual(expected_name, link.group(follow_symlinks=False)) diff --git a/python3.14.spec b/python3.14.spec index 244a138..ac88f05 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,7 +14,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}.0 -%global prerel a6 +%global prerel a7 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -351,6 +351,19 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch +# 00454 # 1d5d7e9ce724fbbd89645d637303d12731c2a622 +# Invoke regen-token rst with rstfile as an argument +# +# Proposed upstream: https://github.com/python/cpython/pull/132304 +Patch454: 00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch + +# 00456 # 8f50cf7170e39c02d52cb5f99d647eeefad2f685 +# Find the correct group name in test_group_no_follow_symlinks +# +# Reported: https://github.com/python/cpython/issues/132356 +# Fix proposed upstream: https://github.com/python/cpython/pull/132357 +Patch456: 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1406,6 +1419,7 @@ CheckPython freethreading %{1}/_elementtree.%{2}.so\ %{1}/_hashlib.%{2}.so\ %{1}/_heapq.%{2}.so\ +%{1}/_hmac.%{2}.so\ %{1}/_interpchannels.%{2}.so\ %{1}/_interpqueues.%{2}.so\ %{1}/_interpreters.%{2}.so\ @@ -1698,6 +1712,9 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Apr 08 2025 Karolina Surma - 3.14.0~a7-1 +- Update to Python 3.14.0a7 + * Mon Mar 17 2025 Karolina Surma - 3.14.0~a6-1 - Update to Python 3.14.0a6 diff --git a/sources b/sources index a424a41..e82978e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0a6.tar.xz) = 0fca503199bed0744139823aaf3ead30d7876556750b476fa6e1f701ae71fa7fe333cd46c775929c26729cf71bef6ba545fdc0118a0efca17c2434de3cadabe1 +SHA512 (Python-3.14.0a7.tar.xz) = f7e50c201cb1bbc4779d898e65408147637de7b9d9d85a2e6ad4f8dda758ec150dfb95ee1f12c686a3f46c29a986a75b45323bcbab87b81b319d91236989f6b0 diff --git a/tests/tests.yml b/tests/tests.yml index b1255ce..8db7040 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -30,11 +30,12 @@ run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - selftest: dir: python/selftest - run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" + # test_data_offset_with_exe_prepended and test_data_offset_with_exe_prepended_zip64: https://github.com/python/cpython/issues/84481 + run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json -i test_data_offset_with_exe_prepended -i test_data_offset_with_exe_prepended_zip64' ./parallel.sh" - debugtest: dir: python/selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter' ./parallel.sh" + run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter -i test_data_offset_with_exe_prepended -i test_data_offset_with_exe_prepended_zip64' ./parallel.sh" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 81efe7427b2a0166558c676549d98c8b51b738ed Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 14 Apr 2025 11:39:12 +0200 Subject: [PATCH 15/88] Don't mangle the shebangs of test files Shebangs are mangled from #!/bin/bash to #!/usr/bin/bash, which causes the change in data_offset calculated in tests, resulting in a test_zipfile failure: FAIL: test_data_offset_with_exe_prepended (test.test_zipfile.test_core.TestDataOffsetPrependedZip.test_data_offset_with_exe_prepended) ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/lib64/python3.14/test/test_zipfile/test_core.py", line 3431, in test_data_offset_with_exe_prepended self._test_data_offset(self.exe_zip) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^ File "/usr/lib64/python3.14/test/test_zipfile/test_core.py", line 3428, in _test_data_offset self.assertEqual(zipfp.data_offset, 713) ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 717 != 713 --- python3.14.spec | 4 ++++ tests/tests.yml | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index ac88f05..818289a 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -209,6 +209,10 @@ Provides: bundled(python3dist(packaging)) = 24 # Remove the default -O2 flag, our flags are applied in %%build/%%install %global __global_compiler_flags %(echo '%{__global_compiler_flags}' | sed 's/-O[[:digit:]]//') +# Changing the shebangs of the test files confuses the tests which count with a specific data offset +# We can't remove the executable bit, the files are run directly in other tests +%global __brp_mangle_shebangs_exclude_from ^%{pylibdir}/test/archivetestdata/exe_with_.*$ + # Disable automatic bytecompilation. The python3 binary is not yet be # available in /usr/bin when Python is built. Also, the bytecompilation fails # on files that test invalid syntax. diff --git a/tests/tests.yml b/tests/tests.yml index 8db7040..b1255ce 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -30,12 +30,11 @@ run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - selftest: dir: python/selftest - # test_data_offset_with_exe_prepended and test_data_offset_with_exe_prepended_zip64: https://github.com/python/cpython/issues/84481 - run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json -i test_data_offset_with_exe_prepended -i test_data_offset_with_exe_prepended_zip64' ./parallel.sh" + run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - debugtest: dir: python/selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter -i test_data_offset_with_exe_prepended -i test_data_offset_with_exe_prepended_zip64' ./parallel.sh" + run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter' ./parallel.sh" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 096e4f0d88220dc5ff9c86d30fad9b1c27200c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Thu, 17 Apr 2025 12:24:25 +0200 Subject: [PATCH 16/88] Regenerate patches with updated importpatches script --- 00251-change-user-install-location.patch | 2 +- 00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch | 2 +- ...e-correct-group-name-in-test_group_no_follow_symlinks.patch | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 5283ffb..f18a48e 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 15 Feb 2021 12:19:27 +0100 -Subject: [PATCH] 00251: Change user install location +Subject: 00251: Change user install location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch b/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch index a456192..250072a 100644 --- a/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch +++ b/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 9 Apr 2025 10:47:48 +0200 -Subject: [PATCH] 00454: Invoke regen-token rst with rstfile as an argument +Subject: 00454: Invoke regen-token rst with rstfile as an argument Proposed upstream: https://github.com/python/cpython/pull/132304 --- diff --git a/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch b/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch index 3ef6e55..1577b85 100644 --- a/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch +++ b/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch @@ -1,8 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Thu, 10 Apr 2025 13:46:25 +0200 -Subject: [PATCH] 00456: Find the correct group name in - test_group_no_follow_symlinks +Subject: 00456: Find the correct group name in test_group_no_follow_symlinks Reported: https://github.com/python/cpython/issues/132356 Fix proposed upstream: https://github.com/python/cpython/pull/132357 From eee246a4f22078ab7e7035a3d790983d33ab0b68 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Wed, 23 Apr 2025 00:59:59 +0200 Subject: [PATCH 17/88] Apply Intel's CET for mitigation against control-flow hijacking attacks --- ...l-control-flow-technology-for-x86-64.patch | 68 +++++++++++++++++++ python3.14.spec | 15 +++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 00459-apply-intel-control-flow-technology-for-x86-64.patch diff --git a/00459-apply-intel-control-flow-technology-for-x86-64.patch b/00459-apply-intel-control-flow-technology-for-x86-64.patch new file mode 100644 index 0000000..c6ed738 --- /dev/null +++ b/00459-apply-intel-control-flow-technology-for-x86-64.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Wed, 8 Jan 2025 04:58:22 +0100 +Subject: 00459: Apply Intel Control-flow Technology for x86-64 + +Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks + +Proposed upstream: https://github.com/python/cpython/pull/128606 + +See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html +--- + Python/asm_trampoline.S | 22 ++++++++++++++++++++++ + Python/perf_jit_trampoline.c | 4 ++++ + 2 files changed, 26 insertions(+) + +diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S +index 0a3265dfee..616752459b 100644 +--- a/Python/asm_trampoline.S ++++ b/Python/asm_trampoline.S +@@ -9,6 +9,9 @@ + # } + _Py_trampoline_func_start: + #ifdef __x86_64__ ++#if defined(__CET__) && (__CET__ & 1) ++ endbr64 ++#endif + sub $8, %rsp + call *%rcx + add $8, %rsp +@@ -34,3 +37,22 @@ _Py_trampoline_func_start: + .globl _Py_trampoline_func_end + _Py_trampoline_func_end: + .section .note.GNU-stack,"",@progbits ++# Note for indicating the assembly code supports CET ++#if defined(__x86_64__) && defined(__CET__) && (__CET__ & 1) ++ .section .note.gnu.property,"a" ++ .align 8 ++ .long 1f - 0f ++ .long 4f - 1f ++ .long 5 ++0: ++ .string "GNU" ++1: ++ .align 8 ++ .long 0xc0000002 ++ .long 3f - 2f ++2: ++ .long 0x3 ++3: ++ .align 8 ++4: ++#endif // __x86_64__ +diff --git a/Python/perf_jit_trampoline.c b/Python/perf_jit_trampoline.c +index 1211e0e9f1..da9f887769 100644 +--- a/Python/perf_jit_trampoline.c ++++ b/Python/perf_jit_trampoline.c +@@ -473,7 +473,11 @@ elf_init_ehframe(ELFObjectContext* ctx) + DWRF_U8(0); /* Augmentation data. */ + /* Registers saved in CFRAME. */ + #ifdef __x86_64__ ++# if defined(__CET__) && (__CET__ & 1) ++ DWRF_U8(DWRF_CFA_advance_loc | 8); ++# else + DWRF_U8(DWRF_CFA_advance_loc | 4); ++# endif + DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(16); + DWRF_U8(DWRF_CFA_advance_loc | 6); + DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(8); diff --git a/python3.14.spec b/python3.14.spec index 818289a..899c8d7 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel a7 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -368,6 +368,16 @@ Patch454: 00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch # Fix proposed upstream: https://github.com/python/cpython/pull/132357 Patch456: 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch +# 00459 # 9cf6fed17de184d2e17ace2b5063e782e7e186ba +# Apply Intel Control-flow Technology for x86-64 +# +# Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks +# +# Proposed upstream: https://github.com/python/cpython/pull/128606 +# +# See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html +Patch459: 00459-apply-intel-control-flow-technology-for-x86-64.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1716,6 +1726,9 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Apr 22 2025 Charalampos Stratakis - 3.14.0~a7-2 +- Apply Intel's CET for mitigation against control-flow hijacking attacks + * Tue Apr 08 2025 Karolina Surma - 3.14.0~a7-1 - Update to Python 3.14.0a7 From e3f12dbc36e176ccb6af9b576262a57ceaa4d9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 5 May 2025 09:54:32 +0200 Subject: [PATCH 18/88] Drop requirement on python-wheel-wheel with setuptools >= 71 --- ...red-setuptools-in-lib-test-wheeldata.patch | 120 ++++++++++++++++++ ...eel-in-test-venvs-when-setuptools-71.patch | 33 +++++ python3.14.spec | 25 +++- 3 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch create mode 100644 00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch diff --git a/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch b/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch new file mode 100644 index 0000000..50de614 --- /dev/null +++ b/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch @@ -0,0 +1,120 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> +Date: Fri, 25 Apr 2025 00:46:20 +0100 +Subject: 00460: gh-132415: Update vendored setuptools in + ``Lib/test/wheeldata`` + +(cherry picked from commit c9f3f5b4ed52d7bed6073ffa39717ece47202558) +(actual changes in .whl files removed to make this patch smaller) + +gh-127906: Add missing sys import to test_cppext + +(cherry picked from commit 9cba14881b371b1e95d57877896169c4605f9b75) + +Co-Authored-By: Victor Stinner +--- + Lib/test/support/__init__.py | 14 +++++++------- + Lib/test/test_cext/__init__.py | 2 +- + Lib/test/test_cppext/__init__.py | 2 +- + Lib/test/test_cppext/setup.py | 1 + + Lib/test/test_peg_generator/test_c_parser.py | 2 +- + 5 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py +index 6d670a575b..7f72c689e8 100644 +--- a/Lib/test/support/__init__.py ++++ b/Lib/test/support/__init__.py +@@ -2415,7 +2415,7 @@ def _findwheel(pkgname): + filenames = os.listdir(wheel_dir) + filenames = sorted(filenames, reverse=True) # approximate "newest" first + for filename in filenames: +- # filename is like 'setuptools-67.6.1-py3-none-any.whl' ++ # filename is like 'setuptools-{version}-py3-none-any.whl' + if not filename.endswith(".whl"): + continue + prefix = pkgname + '-' +@@ -2424,16 +2424,16 @@ def _findwheel(pkgname): + raise FileNotFoundError(f"No wheel for {pkgname} found in {wheel_dir}") + + +-# Context manager that creates a virtual environment, install setuptools and wheel in it +-# and returns the path to the venv directory and the path to the python executable ++# Context manager that creates a virtual environment, install setuptools in it, ++# and returns the paths to the venv directory and the python executable + @contextlib.contextmanager +-def setup_venv_with_pip_setuptools_wheel(venv_dir): +- import shlex ++def setup_venv_with_pip_setuptools(venv_dir): + import subprocess + from .os_helper import temp_cwd + + def run_command(cmd): + if verbose: ++ import shlex + print() + print('Run:', ' '.join(map(shlex.quote, cmd))) + subprocess.run(cmd, check=True) +@@ -2457,10 +2457,10 @@ def run_command(cmd): + else: + python = os.path.join(venv, 'bin', python_exe) + +- cmd = [python, '-X', 'dev', ++ cmd = (python, '-X', 'dev', + '-m', 'pip', 'install', + _findwheel('setuptools'), +- _findwheel('wheel')] ++ ) + run_command(cmd) + + yield python +diff --git a/Lib/test/test_cext/__init__.py b/Lib/test/test_cext/__init__.py +index 402a2d04fa..46fde54149 100644 +--- a/Lib/test/test_cext/__init__.py ++++ b/Lib/test/test_cext/__init__.py +@@ -53,7 +53,7 @@ def test_build_limited_c11(self): + + def check_build(self, extension_name, std=None, limited=False): + venv_dir = 'env' +- with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: ++ with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: + self._check_build(extension_name, python_exe, + std=std, limited=limited) + +diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py +index 13f9ea1c56..2b7adac4bc 100644 +--- a/Lib/test/test_cppext/__init__.py ++++ b/Lib/test/test_cppext/__init__.py +@@ -54,7 +54,7 @@ def test_build_limited(self): + + def check_build(self, extension_name, std=None, limited=False): + venv_dir = 'env' +- with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: ++ with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: + self._check_build(extension_name, python_exe, + std=std, limited=limited) + +diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py +index b30c9e2746..ea1ed64bf7 100644 +--- a/Lib/test/test_cppext/setup.py ++++ b/Lib/test/test_cppext/setup.py +@@ -3,6 +3,7 @@ + import os + import platform + import shlex ++import sys + import sysconfig + from test import support + +diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py +index 1411e55dd0..1095e7303c 100644 +--- a/Lib/test/test_peg_generator/test_c_parser.py ++++ b/Lib/test/test_peg_generator/test_c_parser.py +@@ -99,7 +99,7 @@ def setUpClass(cls): + cls.addClassCleanup(shutil.rmtree, cls.library_dir) + + with contextlib.ExitStack() as stack: +- python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools_wheel("venv")) ++ python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools("venv")) + sitepackages = subprocess.check_output( + [python_exe, "-c", "import sysconfig; print(sysconfig.get_path('platlib'))"], + text=True, 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..0689c34 --- /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 7f72c689e8..e15f18c47e 100644 +--- a/Lib/test/support/__init__.py ++++ b/Lib/test/support/__init__.py +@@ -2457,9 +2457,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/python3.14.spec b/python3.14.spec index 899c8d7..a10882d 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel a7 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python-2.0.1 @@ -302,7 +302,7 @@ BuildRequires: libappstream-glib BuildRequires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 %if %{with tests} BuildRequires: %{python_wheel_pkg_prefix}-setuptools-wheel -BuildRequires: %{python_wheel_pkg_prefix}-wheel-wheel +BuildRequires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) %endif %endif @@ -378,6 +378,20 @@ Patch456: 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.pat # See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html Patch459: 00459-apply-intel-control-flow-technology-for-x86-64.patch +# 00460 # f876c748b89770cfee4148c3dd3acbc3dd527eb6 +# gh-132415: Update vendored setuptools in ``Lib/test/wheeldata`` +# +# (actual changes in .whl files removed to make this patch smaller) +# +# gh-127906: Add missing sys import to test_cppext +Patch460: 00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch + +# 00461 # 920175020b21c0aff5edcc4c28d688b5061f591c +# Downstream only: Install wheel in test venvs when setuptools < 71 +# +# 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 + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -635,7 +649,7 @@ Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-setuptools-wheel -Requires: %{python_wheel_pkg_prefix}-wheel-wheel +Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) %else Provides: bundled(python3dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides @@ -700,7 +714,7 @@ Summary: Free Threading (PEP 703) version of the Python runtime %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 Requires: %{python_wheel_pkg_prefix}-setuptools-wheel -Requires: %{python_wheel_pkg_prefix}-wheel-wheel +Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) License: %{libs_license} %else Provides: bundled(python3dist(pip)) = %{pip_version} @@ -1726,6 +1740,9 @@ CheckPython freethreading # ====================================================== %changelog +* Mon May 05 2025 Miro Hrončok - 3.14.0~a7-3 +- Drop requirement on python-wheel-wheel with setuptools >= 71 + * Tue Apr 22 2025 Charalampos Stratakis - 3.14.0~a7-2 - Apply Intel's CET for mitigation against control-flow hijacking attacks From 05411b4c04c36e05ee5df8ea8fe388fd185e4dc1 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 7 May 2025 20:22:24 +0200 Subject: [PATCH 19/88] Update to Python 3.14.0b1 --- 00251-change-user-install-location.patch | 12 +- ...oken-rst-with-rstfile-as-an-argument.patch | 24 ---- ...ame-in-test_group_no_follow_symlinks.patch | 24 ---- ...red-setuptools-in-lib-test-wheeldata.patch | 120 ------------------ ...eel-in-test-venvs-when-setuptools-71.patch | 4 +- python3.14.spec | 114 +++++++---------- sources | 2 +- tests/tests.yml | 3 +- 8 files changed, 59 insertions(+), 244 deletions(-) delete mode 100644 00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch delete mode 100644 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch delete mode 100644 00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index f18a48e..75a897c 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 9da8b6724e..b53dd21d51 100644 +index 5c38b1b17d..862a079ed2 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -420,8 +420,15 @@ def getsitepackages(prefixes=None): @@ -51,7 +51,7 @@ index 9da8b6724e..b53dd21d51 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index 18e6b8d25e..42df12fad4 100644 +index dad715eb08..890b5017d3 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -130,10 +130,10 @@ index 18e6b8d25e..42df12fad4 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 cc11eade2e..b4f8aabaef 100644 +index 53e55383bf..9343c55bd3 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py -@@ -131,8 +131,19 @@ def test_get_path(self): +@@ -132,8 +132,19 @@ def test_get_path(self): for scheme in _INSTALL_SCHEMES: for name in _INSTALL_SCHEMES[scheme]: expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars) @@ -154,7 +154,7 @@ index cc11eade2e..b4f8aabaef 100644 os.path.normpath(expected), ) -@@ -387,7 +398,7 @@ def test_get_config_h_filename(self): +@@ -388,7 +399,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 cc11eade2e..b4f8aabaef 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -399,6 +410,8 @@ def test_symlink(self): # Issue 7880 +@@ -400,6 +411,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/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch b/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch deleted file mode 100644 index 250072a..0000000 --- a/00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Wed, 9 Apr 2025 10:47:48 +0200 -Subject: 00454: Invoke regen-token rst with rstfile as an argument - -Proposed upstream: https://github.com/python/cpython/pull/132304 ---- - Makefile.pre.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/Makefile.pre.in b/Makefile.pre.in -index e10c78d640..5dfde4efcb 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -1960,7 +1960,8 @@ regen-token: - # using Tools/build/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py rst \ - $(srcdir)/Grammar/Tokens \ -- $(srcdir)/Doc/library/token-list.inc -+ $(srcdir)/Doc/library/token-list.inc \ -+ $(srcdir)/Doc/library/token.rst - # Regenerate Include/internal/pycore_token.h from Grammar/Tokens - # using Tools/build/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py h \ diff --git a/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch b/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch deleted file mode 100644 index 1577b85..0000000 --- a/00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Thu, 10 Apr 2025 13:46:25 +0200 -Subject: 00456: Find the correct group name in test_group_no_follow_symlinks - -Reported: https://github.com/python/cpython/issues/132356 -Fix proposed upstream: https://github.com/python/cpython/pull/132357 ---- - Lib/test/test_pathlib/test_pathlib.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py -index b1fcc5f6f0..3cfffc6311 100644 ---- a/Lib/test/test_pathlib/test_pathlib.py -+++ b/Lib/test/test_pathlib/test_pathlib.py -@@ -2065,7 +2065,7 @@ def test_group_no_follow_symlinks(self): - os.chown(link, -1, gid_2, follow_symlinks=False) - - expected_gid = link.stat(follow_symlinks=False).st_gid -- expected_name = self._get_pw_name_or_skip_test(expected_gid) -+ expected_name = self._get_gr_name_or_skip_test(expected_gid) - - self.assertEqual(expected_gid, gid_2) - self.assertEqual(expected_name, link.group(follow_symlinks=False)) diff --git a/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch b/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch deleted file mode 100644 index 50de614..0000000 --- a/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> -Date: Fri, 25 Apr 2025 00:46:20 +0100 -Subject: 00460: gh-132415: Update vendored setuptools in - ``Lib/test/wheeldata`` - -(cherry picked from commit c9f3f5b4ed52d7bed6073ffa39717ece47202558) -(actual changes in .whl files removed to make this patch smaller) - -gh-127906: Add missing sys import to test_cppext - -(cherry picked from commit 9cba14881b371b1e95d57877896169c4605f9b75) - -Co-Authored-By: Victor Stinner ---- - Lib/test/support/__init__.py | 14 +++++++------- - Lib/test/test_cext/__init__.py | 2 +- - Lib/test/test_cppext/__init__.py | 2 +- - Lib/test/test_cppext/setup.py | 1 + - Lib/test/test_peg_generator/test_c_parser.py | 2 +- - 5 files changed, 11 insertions(+), 10 deletions(-) - -diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index 6d670a575b..7f72c689e8 100644 ---- a/Lib/test/support/__init__.py -+++ b/Lib/test/support/__init__.py -@@ -2415,7 +2415,7 @@ def _findwheel(pkgname): - filenames = os.listdir(wheel_dir) - filenames = sorted(filenames, reverse=True) # approximate "newest" first - for filename in filenames: -- # filename is like 'setuptools-67.6.1-py3-none-any.whl' -+ # filename is like 'setuptools-{version}-py3-none-any.whl' - if not filename.endswith(".whl"): - continue - prefix = pkgname + '-' -@@ -2424,16 +2424,16 @@ def _findwheel(pkgname): - raise FileNotFoundError(f"No wheel for {pkgname} found in {wheel_dir}") - - --# Context manager that creates a virtual environment, install setuptools and wheel in it --# and returns the path to the venv directory and the path to the python executable -+# Context manager that creates a virtual environment, install setuptools in it, -+# and returns the paths to the venv directory and the python executable - @contextlib.contextmanager --def setup_venv_with_pip_setuptools_wheel(venv_dir): -- import shlex -+def setup_venv_with_pip_setuptools(venv_dir): - import subprocess - from .os_helper import temp_cwd - - def run_command(cmd): - if verbose: -+ import shlex - print() - print('Run:', ' '.join(map(shlex.quote, cmd))) - subprocess.run(cmd, check=True) -@@ -2457,10 +2457,10 @@ def run_command(cmd): - else: - python = os.path.join(venv, 'bin', python_exe) - -- cmd = [python, '-X', 'dev', -+ cmd = (python, '-X', 'dev', - '-m', 'pip', 'install', - _findwheel('setuptools'), -- _findwheel('wheel')] -+ ) - run_command(cmd) - - yield python -diff --git a/Lib/test/test_cext/__init__.py b/Lib/test/test_cext/__init__.py -index 402a2d04fa..46fde54149 100644 ---- a/Lib/test/test_cext/__init__.py -+++ b/Lib/test/test_cext/__init__.py -@@ -53,7 +53,7 @@ def test_build_limited_c11(self): - - def check_build(self, extension_name, std=None, limited=False): - venv_dir = 'env' -- with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: -+ with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: - self._check_build(extension_name, python_exe, - std=std, limited=limited) - -diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py -index 13f9ea1c56..2b7adac4bc 100644 ---- a/Lib/test/test_cppext/__init__.py -+++ b/Lib/test/test_cppext/__init__.py -@@ -54,7 +54,7 @@ def test_build_limited(self): - - def check_build(self, extension_name, std=None, limited=False): - venv_dir = 'env' -- with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: -+ with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: - self._check_build(extension_name, python_exe, - std=std, limited=limited) - -diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py -index b30c9e2746..ea1ed64bf7 100644 ---- a/Lib/test/test_cppext/setup.py -+++ b/Lib/test/test_cppext/setup.py -@@ -3,6 +3,7 @@ - import os - import platform - import shlex -+import sys - import sysconfig - from test import support - -diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py -index 1411e55dd0..1095e7303c 100644 ---- a/Lib/test/test_peg_generator/test_c_parser.py -+++ b/Lib/test/test_peg_generator/test_c_parser.py -@@ -99,7 +99,7 @@ def setUpClass(cls): - cls.addClassCleanup(shutil.rmtree, cls.library_dir) - - with contextlib.ExitStack() as stack: -- python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools_wheel("venv")) -+ python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools("venv")) - sitepackages = subprocess.check_output( - [python_exe, "-c", "import sysconfig; print(sysconfig.get_path('platlib'))"], - text=True, 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 index 0689c34..1a5e519 100644 --- 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 @@ -10,10 +10,10 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index 7f72c689e8..e15f18c47e 100644 +index c74c3a3190..66433bd17d 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py -@@ -2457,9 +2457,16 @@ def run_command(cmd): +@@ -2466,9 +2466,16 @@ def run_command(cmd): else: python = os.path.join(venv, 'bin', python_exe) diff --git a/python3.14.spec b/python3.14.spec index a10882d..4879a6c 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,10 +14,10 @@ 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}.0 -%global prerel a7 +%global prerel b1 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -57,54 +57,56 @@ 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 25.0.1 -%global setuptools_version 67.6.1 -%global wheel_version 0.43.0 +%global pip_version 25.1.1 +%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.1 -Provides: bundled(python3dist(certifi)) = 2024.8.30 +Provides: bundled(python3dist(cachecontrol)) = 0.14.2 +Provides: bundled(python3dist(certifi)) = 2025.1.31 +Provides: bundled(python3dist(dependency-groups)) = 1.3.1 Provides: bundled(python3dist(distlib)) = 0.3.9 Provides: bundled(python3dist(distro)) = 1.9 Provides: bundled(python3dist(idna)) = 3.10 Provides: bundled(python3dist(msgpack)) = 1.1 -Provides: bundled(python3dist(packaging)) = 24.2 -Provides: bundled(python3dist(platformdirs)) = 4.3.6 -Provides: bundled(python3dist(pygments)) = 2.18 +Provides: bundled(python3dist(packaging)) = 25 +Provides: bundled(python3dist(platformdirs)) = 4.3.7 +Provides: bundled(python3dist(pygments)) = 2.19.1 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 Provides: bundled(python3dist(requests)) = 2.32.3 -Provides: bundled(python3dist(resolvelib)) = 1.0.1 -Provides: bundled(python3dist(rich)) = 13.9.4 +Provides: bundled(python3dist(resolvelib)) = 1.1 +Provides: bundled(python3dist(rich)) = 14 Provides: bundled(python3dist(setuptools)) = 70.3 Provides: bundled(python3dist(tomli)) = 2.2.1 -Provides: bundled(python3dist(truststore)) = 0.10 -Provides: bundled(python3dist(typing-extensions)) = 4.12.2 +Provides: bundled(python3dist(tomli-w)) = 1.2 +Provides: bundled(python3dist(truststore)) = 0.10.1 +Provides: bundled(python3dist(typing-extensions)) = 4.13.2 Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools -# vendor.txt files not in .whl -# $ %%{_rpmconfigdir}/pythonbundles.py \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/setuptools/_vendor/vendored.txt) \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/pkg_resources/_vendor/vendored.txt) +# vendor.txt not in .whl +# Bundled packages are defined in multiple files. Generate the list with: +# git clone https://github.com/pypa/setuptools && git switch v%%{setuptools_version} +# pip freeze --path setuptools/_vendor > vendored.txt +# %%{_rpmconfigdir}/pythonbundles.py vendored.txt %global setuptools_bundled_provides %{expand: -Provides: bundled(python3dist(importlib-metadata)) = 6 -Provides: bundled(python3dist(importlib-resources)) = 5.10.2 -Provides: bundled(python3dist(jaraco-text)) = 3.7 -Provides: bundled(python3dist(more-itertools)) = 8.8 -Provides: bundled(python3dist(ordered-set)) = 3.1.1 -Provides: bundled(python3dist(packaging)) = 23 -Provides: bundled(python3dist(platformdirs)) = 2.6.2 +Provides: bundled(python3dist(autocommand)) = 2.2.2 +Provides: bundled(python3dist(backports-tarfile)) = 1.2 +Provides: bundled(python3dist(importlib-metadata)) = 8 +Provides: bundled(python3dist(inflect)) = 7.3.1 +Provides: bundled(python3dist(jaraco-collections)) = 5.1 +Provides: bundled(python3dist(jaraco-context)) = 5.3 +Provides: bundled(python3dist(jaraco-functools)) = 4.0.1 +Provides: bundled(python3dist(jaraco-text)) = 3.12.1 +Provides: bundled(python3dist(more-itertools)) = 10.3 +Provides: bundled(python3dist(packaging)) = 24.2 +Provides: bundled(python3dist(platformdirs)) = 4.2.2 Provides: bundled(python3dist(tomli)) = 2.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.4 -Provides: bundled(python3dist(zipp)) = 3.7 -} -# wheel -# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt) -%global wheel_bundled_provides %{expand: -Provides: bundled(python3dist(packaging)) = 24 +Provides: bundled(python3dist(typeguard)) = 4.3 +Provides: bundled(python3dist(typing-extensions)) = 4.12.2 +Provides: bundled(python3dist(wheel)) = 0.45.1 +Provides: bundled(python3dist(zipp)) = 3.19.2 } # Expensive optimizations (mainly, profile-guided optimizations) @@ -355,19 +357,6 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00454 # 1d5d7e9ce724fbbd89645d637303d12731c2a622 -# Invoke regen-token rst with rstfile as an argument -# -# Proposed upstream: https://github.com/python/cpython/pull/132304 -Patch454: 00454-invoke-regen-token-rst-with-rstfile-as-an-argument.patch - -# 00456 # 8f50cf7170e39c02d52cb5f99d647eeefad2f685 -# Find the correct group name in test_group_no_follow_symlinks -# -# Reported: https://github.com/python/cpython/issues/132356 -# Fix proposed upstream: https://github.com/python/cpython/pull/132357 -Patch456: 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.patch - # 00459 # 9cf6fed17de184d2e17ace2b5063e782e7e186ba # Apply Intel Control-flow Technology for x86-64 # @@ -378,14 +367,6 @@ Patch456: 00456-find-the-correct-group-name-in-test_group_no_follow_symlinks.pat # See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html Patch459: 00459-apply-intel-control-flow-technology-for-x86-64.patch -# 00460 # f876c748b89770cfee4148c3dd3acbc3dd527eb6 -# gh-132415: Update vendored setuptools in ``Lib/test/wheeldata`` -# -# (actual changes in .whl files removed to make this patch smaller) -# -# gh-127906: Add missing sys import to test_cppext -Patch460: 00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch - # 00461 # 920175020b21c0aff5edcc4c28d688b5061f591c # Downstream only: Install wheel in test venvs when setuptools < 71 # @@ -653,8 +634,6 @@ Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}- %else Provides: bundled(python3dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides -Provides: bundled(python3dist(wheel)) = %{wheel_version} -%wheel_bundled_provides # License manually combined from Python + setuptools + wheel License: Python-2.0.1 AND MIT AND Apache-2.0 AND (Apache-2.0 OR BSD-2-Clause) %endif @@ -721,9 +700,7 @@ Provides: bundled(python3dist(pip)) = %{pip_version} %pip_bundled_provides Provides: bundled(python3dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides -Provides: bundled(python3dist(wheel)) = %{wheel_version} -%wheel_bundled_provides -# License combined from Python libs + pip + setuptools + wheel +# License combined from Python libs + pip + setuptools License: %{libs_license} AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) %endif @@ -784,13 +761,11 @@ extension modules. # setuptools.whl does not contain the vendored.txt files if [ -f %{_rpmconfigdir}/pythonbundles.py ]; then %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) --compare-with '%pip_bundled_provides' - %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt) --compare-with '%wheel_bundled_provides' fi %if %{with rpmwheels} rm Lib/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl rm Lib/test/wheeldata/setuptools-%{setuptools_version}-py3-none-any.whl -rm Lib/test/wheeldata/wheel-%{wheel_version}-py3-none-any.whl %endif # Remove all exe files to ensure we are not shipping prebuilt binaries @@ -1282,8 +1257,9 @@ CheckPython() { # 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_external_inspection sometimes fails on freethreading-debug - # see: https://github.com/python/cpython/issues/130035 + # test_interrupt and test_interrupt_no_handler + # reported in https://github.com/python/cpython/issues/133651 + # test_displays reported https://github.com/python/cpython/issues/133682 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1293,7 +1269,9 @@ CheckPython() { %endif -i test_freeze_simple_script \ -i test_check_probes \ - -i test_external_inspection \ + -i test_interrupt \ + -i test_interrupt_no_handler \ + -i test_displays \ %ifarch %{mips64} -x test_ctypes \ %endif @@ -1362,6 +1340,7 @@ CheckPython freethreading %{1}/_pyrepl/\ %{1}/asyncio/\ %{1}/collections/\ +%{1}/compression/\ %{1}/concurrent/\ %{1}/ctypes/\ %{1}/curses/\ @@ -1377,6 +1356,7 @@ CheckPython freethreading %{1}/pydoc_data/\ %{1}/re/\ %{1}/sqlite3/\ +%{1}/string/\ %{1}/sysconfig/\ %{1}/tomllib/\ %{1}/unittest/\ @@ -1435,7 +1415,6 @@ CheckPython freethreading %{1}/_codecs_jp.%{2}.so\ %{1}/_codecs_kr.%{2}.so\ %{1}/_codecs_tw.%{2}.so\ -%{1}/_contextvars.%{2}.so\ %{1}/_csv.%{2}.so\ %{1}/_ctypes.%{2}.so\ %{1}/_curses.%{2}.so\ @@ -1462,6 +1441,7 @@ CheckPython freethreading %{1}/_posixsubprocess.%{2}.so\ %{1}/_queue.%{2}.so\ %{1}/_random.%{2}.so\ +%{1}/_remote_debugging.%{2}.so\ %{1}/_sha1.%{2}.so\ %{1}/_sha2.%{2}.so\ %{1}/_sha3.%{2}.so\ @@ -1590,7 +1570,6 @@ CheckPython freethreading %{1}/_testcapi.%{2}.so\ %{1}/_testclinic.%{2}.so\ %{1}/_testclinic_limited.%{2}.so\ -%{1}/_testexternalinspection.%{2}.so\ %{1}/_testimportmultiple.%{2}.so\ %{1}/_testinternalcapi.%{2}.so\ %{1}/_testlimitedcapi.%{2}.so\ @@ -1740,6 +1719,9 @@ CheckPython freethreading # ====================================================== %changelog +* Wed May 07 2025 Karolina Surma - 3.14.0~b1-1 +- Update to Python 3.14.0b1 + * Mon May 05 2025 Miro Hrončok - 3.14.0~a7-3 - Drop requirement on python-wheel-wheel with setuptools >= 71 diff --git a/sources b/sources index e82978e..53531ac 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0a7.tar.xz) = f7e50c201cb1bbc4779d898e65408147637de7b9d9d85a2e6ad4f8dda758ec150dfb95ee1f12c686a3f46c29a986a75b45323bcbab87b81b319d91236989f6b0 +SHA512 (Python-3.14.0b1.tar.xz) = 46c0792fe4d7beab13403938e51cc73e4cbc90a1d0367ba106f56353fae6e93697aa08d6389fd5a1fffa71d59376aee0196aba82b2c40d2f0cf642f14eefead8 diff --git a/tests/tests.yml b/tests/tests.yml index b1255ce..7d07cc2 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -34,7 +34,8 @@ - debugtest: dir: python/selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter' ./parallel.sh" + # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651 + run: "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" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 1e24d38cd9daa66a350f96c7955008e36928c660 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Tue, 6 May 2025 03:12:09 +0200 Subject: [PATCH 20/88] Add perf to the testing BuildRequires Perf profiling showing the Python functions is only supported on x86_64 and aarch64 at the moment. Adding perf as a BuildRequires allows tests that utilize the perf binary to run. --- python3.14.spec | 5 +++++ tests/tests.yml | 1 + 2 files changed, 6 insertions(+) diff --git a/python3.14.spec b/python3.14.spec index 4879a6c..4dd89cb 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -282,6 +282,11 @@ BuildRequires: gcc-c++ BuildRequires: gdb BuildRequires: glibc-all-langpacks BuildRequires: tzdata + +# Perf support is only available on x86_64 and aarch64 right now +%ifarch x86_64 aarch64 +BuildRequires: perf +%endif %endif %if %{with jit} diff --git a/tests/tests.yml b/tests/tests.yml index 7d07cc2..4fc8655 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -67,3 +67,4 @@ - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser - rpm # for debugging + - perf # for test_perf_profiler From 143d59d932e3b02c3108550f2188f72d2f81c6aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 13 May 2025 19:29:44 +0200 Subject: [PATCH 21/88] Verify bundled() provides for setuptools.whl --- python3.14.spec | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 4dd89cb..e136fc4 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -86,10 +86,7 @@ Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools # vendor.txt not in .whl -# Bundled packages are defined in multiple files. Generate the list with: -# git clone https://github.com/pypa/setuptools && git switch v%%{setuptools_version} -# pip freeze --path setuptools/_vendor > vendored.txt -# %%{_rpmconfigdir}/pythonbundles.py vendored.txt +# %%{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') %global setuptools_bundled_provides %{expand: Provides: bundled(python3dist(autocommand)) = 2.2.2 Provides: bundled(python3dist(backports-tarfile)) = 1.2 @@ -766,6 +763,7 @@ extension modules. # setuptools.whl does not contain the vendored.txt files if [ -f %{_rpmconfigdir}/pythonbundles.py ]; then %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) --compare-with '%pip_bundled_provides' + %{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') --compare-with '%setuptools_bundled_provides' fi %if %{with rpmwheels} From ef2d703504cf0039fe5dc82e21e20053cc827c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 20 May 2025 13:54:21 +0200 Subject: [PATCH 22/88] Disable JIT on RHEL For now on, until we figure out a way of building the JIT with pre-built stencils, we disable the JIT on RHEL to avoid a dependency on a specific LLVM+clang version. https://discuss.python.org/t/building-the-jit-with-pre-built-stencils/91838 https://src.fedoraproject.org/rpms/python3.14/pull-request/40 https://github.com/fedora-eln/eln/issues/207 --- python3.14.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index e136fc4..4d37fc0 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -125,7 +125,7 @@ Provides: bundled(python3dist(zipp)) = 3.19.2 # 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 %[(0%{?fedora} >= 41 || 0%{?rhel} >= 10) && ("%{_arch}" == "x86_64" || "%{_arch}" == "aarch64")] +%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 From 014f2b2430fc03537d792fa53299291016112ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 26 May 2025 22:15:05 +0200 Subject: [PATCH 23/88] Update to Python 3.14.0b2 --- 00251-change-user-install-location.patch | 8 ++++---- ...y-install-wheel-in-test-venvs-when-setuptools-71.patch | 4 ++-- python3.14.spec | 7 ++++--- sources | 2 +- tests/tests.yml | 5 +++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 75a897c..a672dbf 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -30,10 +30,10 @@ Co-authored-by: Lumír Balhar 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Lib/site.py b/Lib/site.py -index 5c38b1b17d..862a079ed2 100644 +index f932719715..e4ef914ec2 100644 --- a/Lib/site.py +++ b/Lib/site.py -@@ -420,8 +420,15 @@ def getsitepackages(prefixes=None): +@@ -421,8 +421,15 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): @@ -51,7 +51,7 @@ index 5c38b1b17d..862a079ed2 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index dad715eb08..890b5017d3 100644 +index f93b98dd68..f6dbd5f5c3 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -130,7 +130,7 @@ index dad715eb08..890b5017d3 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 53e55383bf..9343c55bd3 100644 +index d30f69ded6..49449c652f 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -132,8 +132,19 @@ def test_get_path(self): 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 index 1a5e519..18633aa 100644 --- 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 @@ -10,10 +10,10 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index c74c3a3190..66433bd17d 100644 +index b7cd7940eb..2237cf345b 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py -@@ -2466,9 +2466,16 @@ def run_command(cmd): +@@ -2468,9 +2468,16 @@ def run_command(cmd): else: python = os.path.join(venv, 'bin', python_exe) diff --git a/python3.14.spec b/python3.14.spec index 4d37fc0..16c97af 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,7 +14,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}.0 -%global prerel b1 +%global prerel b2 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -1262,7 +1262,6 @@ CheckPython() { # see: https://github.com/python/cpython/issues/121719 # test_interrupt and test_interrupt_no_handler # reported in https://github.com/python/cpython/issues/133651 - # test_displays reported https://github.com/python/cpython/issues/133682 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1274,7 +1273,6 @@ CheckPython() { -i test_check_probes \ -i test_interrupt \ -i test_interrupt_no_handler \ - -i test_displays \ %ifarch %{mips64} -x test_ctypes \ %endif @@ -1722,6 +1720,9 @@ CheckPython freethreading # ====================================================== %changelog +* Mon May 26 2025 Miro Hrončok - 3.14.0~b2-1 +- Update to Python 3.14.0b2 + * Wed May 07 2025 Karolina Surma - 3.14.0~b1-1 - Update to Python 3.14.0b1 diff --git a/sources b/sources index 53531ac..eaef709 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0b1.tar.xz) = 46c0792fe4d7beab13403938e51cc73e4cbc90a1d0367ba106f56353fae6e93697aa08d6389fd5a1fffa71d59376aee0196aba82b2c40d2f0cf642f14eefead8 +SHA512 (Python-3.14.0b2.tar.xz) = cdd37f8a982e6194d5afa80a2eb94c899080809749d59a50a2ce3eed37f720a1fd9a7977f0dd3992650d173a7070b15610077d97cb499bd16a7500c56ef1f8dd diff --git a/tests/tests.yml b/tests/tests.yml index 4fc8655..6225911 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -30,12 +30,13 @@ run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - selftest: dir: python/selftest - run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" + # test_alias_modules_exist: https://github.com/python/cpython/pull/134777 + run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json -i test_alias_modules_exist' ./parallel.sh" - debugtest: dir: python/selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651 - run: "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" + run: "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 -i test_alias_modules_exist' ./parallel.sh" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 09b6af795138e74fa02a27f8ce758c3abd3b2e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 27 May 2025 10:22:03 +0200 Subject: [PATCH 24/88] Build the _zstd module --- python3.14.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python3.14.spec b/python3.14.spec index 16c97af..44cea3f 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -258,6 +258,7 @@ BuildRequires: gnupg2 BuildRequires: libX11-devel BuildRequires: libffi-devel BuildRequires: libuuid-devel +BuildRequires: libzstd-devel BuildRequires: make BuildRequires: mpdecimal-devel BuildRequires: ncurses-devel @@ -1453,6 +1454,7 @@ CheckPython freethreading %{1}/_struct.%{2}.so\ %{1}/_uuid.%{2}.so\ %{1}/_zoneinfo.%{2}.so\ +%{1}/_zstd.%{2}.so\ %{1}/array.%{2}.so\ %{1}/binascii.%{2}.so\ %{1}/cmath.%{2}.so\ From b06a2a26f3467277c8878fdb275564ed2693eabc Mon Sep 17 00:00:00 2001 From: Python Maint Date: Mon, 2 Jun 2025 10:51:01 +0200 Subject: [PATCH 25/88] Bootstrap for Python 3.14 --- python3.14.spec | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 44cea3f..dffb1c3 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel b2 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -47,11 +47,11 @@ License: Python-2.0.1 # IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is # not available. Turn off the rpmwheels bcond until # python-pip is built with a wheel to get around the issue. -%bcond bootstrap 0 +%bcond bootstrap 1 # Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages # Uses upstream bundled prebuilt wheels otherwise -%bcond rpmwheels 1 +%bcond rpmwheels 0 # If the rpmwheels condition is disabled, we use the bundled wheel packages # from Python with the versions below. # This needs to be manually updated when we update Python. @@ -107,10 +107,10 @@ Provides: bundled(python3dist(zipp)) = 3.19.2 } # Expensive optimizations (mainly, profile-guided optimizations) -%bcond optimizations 1 +%bcond optimizations 0 # Run the test suite in %%check -%bcond tests 1 +%bcond tests 0 # Extra build for debugging the interpreter or C-API extensions # (the -debug subpackages) @@ -1722,6 +1722,9 @@ CheckPython freethreading # ====================================================== %changelog +* Mon Jun 02 2025 Python Maint - 3.14.0~b2-2 +- Bootstrap for Python 3.14 + * Mon May 26 2025 Miro Hrončok - 3.14.0~b2-1 - Update to Python 3.14.0b2 From e3c3cbe96ef4f49dc48fe6ece049c64ee6c22473 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Mon, 2 Jun 2025 17:45:07 +0200 Subject: [PATCH 26/88] Rebuilt for Python 3.14 --- python3.14.spec | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index dffb1c3..713dc44 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel b2 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python-2.0.1 @@ -47,11 +47,11 @@ License: Python-2.0.1 # IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is # not available. Turn off the rpmwheels bcond until # python-pip is built with a wheel to get around the issue. -%bcond bootstrap 1 +%bcond bootstrap 0 # Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages # Uses upstream bundled prebuilt wheels otherwise -%bcond rpmwheels 0 +%bcond rpmwheels 1 # If the rpmwheels condition is disabled, we use the bundled wheel packages # from Python with the versions below. # This needs to be manually updated when we update Python. @@ -107,10 +107,10 @@ Provides: bundled(python3dist(zipp)) = 3.19.2 } # Expensive optimizations (mainly, profile-guided optimizations) -%bcond optimizations 0 +%bcond optimizations 1 # Run the test suite in %%check -%bcond tests 0 +%bcond tests 1 # Extra build for debugging the interpreter or C-API extensions # (the -debug subpackages) @@ -1722,6 +1722,9 @@ CheckPython freethreading # ====================================================== %changelog +* Mon Jun 02 2025 Python Maint - 3.14.0~b2-3 +- Rebuilt for Python 3.14 + * Mon Jun 02 2025 Python Maint - 3.14.0~b2-2 - Bootstrap for Python 3.14 From eda37b70f49c903615f29e3e09851db5bf61e2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 17 Jun 2025 21:16:32 +0200 Subject: [PATCH 27/88] Update to Python 3.14.0b3 - The .pyc magic number was bumped - python3.14-freethreading is no longer provisional --- ...l-control-flow-technology-for-x86-64.patch | 68 ------------------- ...eel-in-test-venvs-when-setuptools-71.patch | 4 +- python3.14.spec | 27 +++----- sources | 2 +- 4 files changed, 14 insertions(+), 87 deletions(-) delete mode 100644 00459-apply-intel-control-flow-technology-for-x86-64.patch diff --git a/00459-apply-intel-control-flow-technology-for-x86-64.patch b/00459-apply-intel-control-flow-technology-for-x86-64.patch deleted file mode 100644 index c6ed738..0000000 --- a/00459-apply-intel-control-flow-technology-for-x86-64.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Charalampos Stratakis -Date: Wed, 8 Jan 2025 04:58:22 +0100 -Subject: 00459: Apply Intel Control-flow Technology for x86-64 - -Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks - -Proposed upstream: https://github.com/python/cpython/pull/128606 - -See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html ---- - Python/asm_trampoline.S | 22 ++++++++++++++++++++++ - Python/perf_jit_trampoline.c | 4 ++++ - 2 files changed, 26 insertions(+) - -diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S -index 0a3265dfee..616752459b 100644 ---- a/Python/asm_trampoline.S -+++ b/Python/asm_trampoline.S -@@ -9,6 +9,9 @@ - # } - _Py_trampoline_func_start: - #ifdef __x86_64__ -+#if defined(__CET__) && (__CET__ & 1) -+ endbr64 -+#endif - sub $8, %rsp - call *%rcx - add $8, %rsp -@@ -34,3 +37,22 @@ _Py_trampoline_func_start: - .globl _Py_trampoline_func_end - _Py_trampoline_func_end: - .section .note.GNU-stack,"",@progbits -+# Note for indicating the assembly code supports CET -+#if defined(__x86_64__) && defined(__CET__) && (__CET__ & 1) -+ .section .note.gnu.property,"a" -+ .align 8 -+ .long 1f - 0f -+ .long 4f - 1f -+ .long 5 -+0: -+ .string "GNU" -+1: -+ .align 8 -+ .long 0xc0000002 -+ .long 3f - 2f -+2: -+ .long 0x3 -+3: -+ .align 8 -+4: -+#endif // __x86_64__ -diff --git a/Python/perf_jit_trampoline.c b/Python/perf_jit_trampoline.c -index 1211e0e9f1..da9f887769 100644 ---- a/Python/perf_jit_trampoline.c -+++ b/Python/perf_jit_trampoline.c -@@ -473,7 +473,11 @@ elf_init_ehframe(ELFObjectContext* ctx) - DWRF_U8(0); /* Augmentation data. */ - /* Registers saved in CFRAME. */ - #ifdef __x86_64__ -+# if defined(__CET__) && (__CET__ & 1) -+ DWRF_U8(DWRF_CFA_advance_loc | 8); -+# else - DWRF_U8(DWRF_CFA_advance_loc | 4); -+# endif - DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(16); - DWRF_U8(DWRF_CFA_advance_loc | 6); - DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(8); 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 index 18633aa..0c16989 100644 --- 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 @@ -10,10 +10,10 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index b7cd7940eb..2237cf345b 100644 +index 7ac95f0780..4eaf37be17 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py -@@ -2468,9 +2468,16 @@ def run_command(cmd): +@@ -2493,9 +2493,16 @@ def run_command(cmd): else: python = os.path.join(venv, 'bin', python_exe) diff --git a/python3.14.spec b/python3.14.spec index 713dc44..423095b 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -14,10 +14,10 @@ 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}.0 -%global prerel b2 +%global prerel b3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -116,7 +116,7 @@ Provides: bundled(python3dist(zipp)) = 3.19.2 # (the -debug subpackages) %bcond debug_build 1 -# Extra build without GIL, the freethreading PEP 703 provisional way +# Extra build without GIL, the freethreading PEP 703 way # (the -freethreading subpackage) %bcond freethreading_build 1 @@ -360,16 +360,6 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00459 # 9cf6fed17de184d2e17ace2b5063e782e7e186ba -# Apply Intel Control-flow Technology for x86-64 -# -# Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks -# -# Proposed upstream: https://github.com/python/cpython/pull/128606 -# -# See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html -Patch459: 00459-apply-intel-control-flow-technology-for-x86-64.patch - # 00461 # 920175020b21c0aff5edcc4c28d688b5061f591c # Downstream only: Install wheel in test venvs when setuptools < 71 # @@ -689,7 +679,7 @@ The debug runtime additionally supports debug builds of C-API extensions %if %{with freethreading_build} # This deliberately does not use the %%{pkgname}- prefix, # we want to call this python3.X-threading even when built as a main Python. -# At least until the PEP 703 build remains provisional. +# This build of Python is not "the main freethreading Python", there's no such thing (yet?) %package -n python%{pybasever}-freethreading Summary: Free Threading (PEP 703) version of the Python runtime @@ -715,7 +705,7 @@ Requires: tzdata Requires: expat >= 2.6 %description -n python%{pybasever}-freethreading -The provisional Free Threading (PEP 703) build of Python. +The Free Threading (PEP 703) build of Python. CPython’s global interpreter lock (“GIL”) prevents multiple threads from executing Python code at the same time. The GIL is an obstacle to using @@ -736,7 +726,7 @@ License: %{libs_license} Requires: python%{pybasever}-freethreading%{?_isa} = %{version}-%{release} %description -n python%{pybasever}-freethreading-debug -The provisional Free Threading (PEP 703) build of Python. Debug build. +The Free Threading (PEP 703) build of Python. Debug build. CPython’s global interpreter lock (“GIL”) prevents multiple threads from executing Python code at the same time. The GIL is an obstacle to using @@ -1722,6 +1712,11 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Jun 17 2025 Miro Hrončok - 3.14.0~b3-1 +- Update to Python 3.14.0b3 +- The .pyc magic number was bumped +- python3.14-freethreading is no longer provisional + * Mon Jun 02 2025 Python Maint - 3.14.0~b2-3 - Rebuilt for Python 3.14 diff --git a/sources b/sources index eaef709..f93997d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0b2.tar.xz) = cdd37f8a982e6194d5afa80a2eb94c899080809749d59a50a2ce3eed37f720a1fd9a7977f0dd3992650d173a7070b15610077d97cb499bd16a7500c56ef1f8dd +SHA512 (Python-3.14.0b3.tar.xz) = 621bcaf2ae4b6f0ba6c95ef74b5ffb78d8a2a0bb10415fb4c5eab1cad26c63098237944713a7f0812ec3e014ff62cd0f9bd5663e87799fcf1856aa4b937be914 From 64000497af10d72feb11d50fce124ab7bca7efdf Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Wed, 18 Jun 2025 17:25:37 +0200 Subject: [PATCH 28/88] Revert "Add perf to the testing BuildRequires" This reverts commit 1e24d38cd9daa66a350f96c7955008e36928c660. --- python3.14.spec | 5 ----- tests/tests.yml | 1 - 2 files changed, 6 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 423095b..c894436 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -280,11 +280,6 @@ BuildRequires: gcc-c++ BuildRequires: gdb BuildRequires: glibc-all-langpacks BuildRequires: tzdata - -# Perf support is only available on x86_64 and aarch64 right now -%ifarch x86_64 aarch64 -BuildRequires: perf -%endif %endif %if %{with jit} diff --git a/tests/tests.yml b/tests/tests.yml index 6225911..197a796 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -68,4 +68,3 @@ - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser - rpm # for debugging - - perf # for test_perf_profiler From eb9909215ca53349fd78a88d3b88aaeb0b5e8c1f Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Wed, 18 Jun 2025 17:29:39 +0200 Subject: [PATCH 29/88] Enable PAC and BTI hardware protections for aarch64 --- ...-pac-and-bti-protections-for-aarch64.patch | 102 ++++++++++++++++++ python3.14.spec | 22 +++- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 00464-enable-pac-and-bti-protections-for-aarch64.patch 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..9404072 --- /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 616752459b..ec205a08ef 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: +@@ -20,10 +22,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/python3.14.spec b/python3.14.spec index c894436..c5d9bc4 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel b3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -361,6 +361,23 @@ Patch251: 00251-change-user-install-location.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 +# 00464 # 292acffec7a379cb6d1f3c47b9e5a2f170bbadb6 +# 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. +Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1707,6 +1724,9 @@ CheckPython freethreading # ====================================================== %changelog +* Wed Jun 18 2025 Charalampos Stratakis - 3.14.0~b3-2 +- Enable PAC and BTI hardware protections for aarch64 + * Tue Jun 17 2025 Miro Hrončok - 3.14.0~b3-1 - Update to Python 3.14.0b3 - The .pyc magic number was bumped From 4041c8a86ed43834c1b31fe6b644db476adf3056 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 24 Jun 2025 14:25:40 +0200 Subject: [PATCH 30/88] Remove the upper version bound from expat library It's already greater than 2.6 in all Fedoras. --- python3.14.spec | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index c5d9bc4..75bb7b0 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -247,8 +247,7 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\ BuildRequires: autoconf BuildRequires: bluez-libs-devel BuildRequires: bzip2-devel -# See the runtime requirement in the -libs subpackage -BuildRequires: expat-devel >= 2.6 +BuildRequires: expat-devel BuildRequires: findutils BuildRequires: gcc BuildRequires: gdbm-devel @@ -531,13 +530,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 expat >= 2.6, but installed with older expat, we get: -# ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so: -# undefined symbol: XML_SetReparseDeferralEnabled -# This breaks many things, including python -m venv. -# Other subpackages (like -debug) also need this, but they all depend on -libs. -Requires: expat >= 2.6 %description -n %{pkgname}-libs This package contains runtime libraries for use by Python: @@ -714,7 +706,6 @@ License: %{libs_license} AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND IS # See the comments in the definition of -libs subpackage for detailed explanations Provides: bundled(mimalloc) = 2.12 Requires: tzdata -Requires: expat >= 2.6 %description -n python%{pybasever}-freethreading The Free Threading (PEP 703) build of Python. From 1521b586f03ffaeac28c49acfe5bbfc902cfaa33 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 24 Jun 2025 14:26:44 +0200 Subject: [PATCH 31/88] Define %python3_pkgversion based on the Python's status Main Python should retain the value '3', non-main the major-minor one. We need that to request the correctly versioned wheels for EPEL builds. --- python3.14.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python3.14.spec b/python3.14.spec index 75bb7b0..01493dd 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -140,9 +140,11 @@ Provides: bundled(python3dist(zipp)) = 3.19.2 %if %{with main_python} %global pkgname python3 %global exename python3 +%global python3_pkgversion 3 %else %global pkgname python%{pybasever} %global exename python%{pybasever} +%global python3_pkgversion %{pybasever} %endif # ABIFLAGS, LDVERSION and SOABI are in the upstream configure.ac From 48ee6e9c72208ed72ec2104b1f258a03adac86cd Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 25 Jun 2025 11:23:45 +0200 Subject: [PATCH 32/88] Downstream patch: Skip tests not working with older expat version This will ensure the tests run in Fedoras and EPEL 10, but are skipped for EPEL 9. --- ...not-working-with-older-expat-version.patch | 69 +++++++++++++++++++ python3.14.spec | 14 +++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch 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..6015a1a --- /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 1d56ccd71c..5ef5517828 100644 +--- a/Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -790,6 +790,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 38be2cd437..e62ff6fcc4 100644 +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -1520,9 +1520,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) + +@@ -1747,6 +1751,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/python3.14.spec b/python3.14.spec index 01493dd..961213d 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel b3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python-2.0.1 @@ -379,6 +379,15 @@ Patch461: 00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.p # hardware protections can be enabled without losing Perf unwinding. Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch +# 00466 # e10760fb955ee33d2917f8a57bb4e24d71e5341c +# 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. +Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1717,6 +1726,9 @@ CheckPython freethreading # ====================================================== %changelog +* Wed Jun 25 2025 Karolina Surma - 3.14.0~b3-3 +- Conditionally skip tests not working with the older expat version + * Wed Jun 18 2025 Charalampos Stratakis - 3.14.0~b3-2 - Enable PAC and BTI hardware protections for aarch64 From ed3fc5a80bd80510ca62aae1a189dd030479aac5 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 25 Jun 2025 12:48:50 +0200 Subject: [PATCH 33/88] Move the bootstrapping conditionals above the global metadata We need to have it above the Release field, in order for the build NVR to contain the ~bootstrap suffix and sort correctly (lower than the main build). This enables bootstrapping the package directly in Koji side tag. --- python3.14.spec | 118 +++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 961213d..de81859 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1,3 +1,30 @@ +# ====================== +# Bootstrap conditionals +# ====================== + +# When bootstrapping python3, we need to build python3-packaging. +# but packaging BR python3-devel and that brings in python3-rpm-generators; +# python3-rpm-generators needs python3-packaging, so we cannot have it yet. +# +# We also use the previous build of Python in "make regen-all". +# +# Procedure: https://fedoraproject.org/wiki/SIGs/Python/UpgradingPython +# +# IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is +# not available. Turn off the rpmwheels bcond until +# python-pip is built with a wheel to get around the issue. +%bcond bootstrap 0 + +# Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages +# Uses upstream bundled prebuilt wheels otherwise +%bcond rpmwheels 1 + +# Expensive optimizations (mainly, profile-guided optimizations) +%bcond optimizations 1 + +# Run the test suite in %%check +%bcond tests 1 + # ================== # Top-level metadata # ================== @@ -36,22 +63,42 @@ License: Python-2.0.1 # In ELN/RHEL/CentOS we want to allow building against alternative stacks, so the Provide is enabled. %bcond python_abi_provides_for_alt_pythons %{undefined fedora} -# When bootstrapping python3, we need to build python3-packaging. -# but packaging BR python3-devel and that brings in python3-rpm-generators; -# python3-rpm-generators needs python3-packaging, so we cannot have it yet. -# -# We also use the previous build of Python in "make regen-all". -# -# Procedure: https://fedoraproject.org/wiki/SIGs/Python/UpgradingPython -# -# IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is -# not available. Turn off the rpmwheels bcond until -# python-pip is built with a wheel to get around the issue. -%bcond bootstrap 0 +# Extra build for debugging the interpreter or C-API extensions +# (the -debug subpackages) +%bcond debug_build 1 + +# Extra build without GIL, the freethreading PEP 703 way +# (the -freethreading subpackage) +%bcond freethreading_build 1 + +# PEP 744: JIT Compilation +# Whether to build with the experimental JIT compiler +# 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 %[(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 +%endif + +# Main interpreter loop optimization +%bcond computed_gotos 1 + +# ===================== +# General global macros +# ===================== + +%if %{with main_python} +%global pkgname python3 +%global exename python3 +%global python3_pkgversion 3 +%else +%global pkgname python%{pybasever} +%global exename python%{pybasever} +%global python3_pkgversion %{pybasever} +%endif -# Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages -# Uses upstream bundled prebuilt wheels otherwise -%bcond rpmwheels 1 # If the rpmwheels condition is disabled, we use the bundled wheel packages # from Python with the versions below. # This needs to be manually updated when we update Python. @@ -106,47 +153,6 @@ Provides: bundled(python3dist(wheel)) = 0.45.1 Provides: bundled(python3dist(zipp)) = 3.19.2 } -# Expensive optimizations (mainly, profile-guided optimizations) -%bcond optimizations 1 - -# Run the test suite in %%check -%bcond tests 1 - -# Extra build for debugging the interpreter or C-API extensions -# (the -debug subpackages) -%bcond debug_build 1 - -# Extra build without GIL, the freethreading PEP 703 way -# (the -freethreading subpackage) -%bcond freethreading_build 1 - -# PEP 744: JIT Compilation -# Whether to build with the experimental JIT compiler -# 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 %[(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 -%endif - -# Main interpreter loop optimization -%bcond computed_gotos 1 - -# ===================== -# General global macros -# ===================== -%if %{with main_python} -%global pkgname python3 -%global exename python3 -%global python3_pkgversion 3 -%else -%global pkgname python%{pybasever} -%global exename python%{pybasever} -%global python3_pkgversion %{pybasever} -%endif - # ABIFLAGS, LDVERSION and SOABI are in the upstream configure.ac # See PEP 3149 for some background: http://www.python.org/dev/peps/pep-3149/ %global ABIFLAGS_optimized %{nil} From a419176c4c2f03ee64edc9ead62cdf6cf19f13a6 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 25 Jun 2025 12:50:00 +0200 Subject: [PATCH 34/88] Switch the basic conditionals based on the bootstrap's value We always switch rpmswheels, optimizations and tests when bootstrapping new Python version, so they can be tied to the bootstrap conditional. With that, switching the bootstrap in Koji side tag will be possible, letting us to avoid separate "bootstrap" and "rebuild" commits. --- python3.14.spec | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index de81859..bb1128d 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -10,20 +10,25 @@ # # Procedure: https://fedoraproject.org/wiki/SIGs/Python/UpgradingPython # -# IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is -# not available. Turn off the rpmwheels bcond until -# python-pip is built with a wheel to get around the issue. +# Bootstrap enabled: +# - disables regen-all with the same Python version +# - disables dependency on python3-rpm-generators if we build with main_python +# - disables rpmwheels, optimizations and tests by default %bcond bootstrap 0 # Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages # Uses upstream bundled prebuilt wheels otherwise -%bcond rpmwheels 1 +%bcond rpmwheels %{without bootstrap} # Expensive optimizations (mainly, profile-guided optimizations) -%bcond optimizations 1 +# We don't have to switch it off for bootstrap, but it speeds up the first build, +# so we opt to only run them during the "full" build +%bcond optimizations %{without bootstrap} # Run the test suite in %%check -%bcond tests 1 +# Technically, we can run the tests even during the bootstrap build, but since +# we build Python 2x, it's better to just run it once with the "full" build +%bcond tests %{without bootstrap} # ================== # Top-level metadata From c0c82aa7718b14026a686597af61138a60f7d2e8 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Fri, 27 Jun 2025 08:38:41 +0200 Subject: [PATCH 35/88] Lower the minimal required autoconf version for EPEL 9 build --- python3.14.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index bb1128d..d666832 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -801,8 +801,8 @@ rm -r Modules/_decimal/libmpdec rm configure pyconfig.h.in # Patch out the version requirement on autoconf 2.72 -# This can be removed when Fedora 40 goes EOL (2025-05-28) -sed -i "s/AC_PREREQ(\[2\.72\])/AC_PREREQ([2.71])/" configure.ac +# We need it to allow the version available in RHEL 9 +sed -i "s/AC_PREREQ(\[2\.72\])/AC_PREREQ([2.69])/" configure.ac # ====================================================== # Configuring and building the code: From 797b97aa4d7a81a2605c606fc545f3716b92d75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 8 Jul 2025 20:54:38 +0200 Subject: [PATCH 36/88] CI: Unskip a fixed test --- tests/tests.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/tests.yml b/tests/tests.yml index 197a796..93b6b3b 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -30,13 +30,12 @@ run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - selftest: dir: python/selftest - # test_alias_modules_exist: https://github.com/python/cpython/pull/134777 - run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json -i test_alias_modules_exist' ./parallel.sh" + run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - debugtest: dir: python/selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651 - run: "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 -i test_alias_modules_exist' ./parallel.sh" + # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651https://github.com/python/cpython/issues/133651 + run: "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" - optimizedflags: dir: python/flags run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" From 278f3033f31a309c3216051890fa6b85213af7b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 8 Jul 2025 20:54:23 +0200 Subject: [PATCH 37/88] Update to Python 3.14.0b4 --- 00251-change-user-install-location.patch | 2 +- ...ly-install-wheel-in-test-venvs-when-setuptools-71.patch | 4 ++-- ...y-skip-tests-not-working-with-older-expat-version.patch | 6 +++--- python3.14.spec | 7 +++++-- sources | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index a672dbf..548a8ba 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -130,7 +130,7 @@ index f93b98dd68..f6dbd5f5c3 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 d30f69ded6..49449c652f 100644 +index 7af3144d69..721017a1f8 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -132,8 +132,19 @@ def test_get_path(self): 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 index 0c16989..8a59085 100644 --- 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 @@ -10,10 +10,10 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index 7ac95f0780..4eaf37be17 100644 +index ce18518bb8..7836bb37c4 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py -@@ -2493,9 +2493,16 @@ def run_command(cmd): +@@ -2495,9 +2495,16 @@ def run_command(cmd): else: python = os.path.join(venv, 'bin', python_exe) 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 index 6015a1a..2ae139a 100644 --- 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 @@ -41,10 +41,10 @@ index 5c10bcedc6..1fd7a273b5 100644 result = BytesIO() xmlgen = XMLGenerator(result) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 38be2cd437..e62ff6fcc4 100644 +index bf6d5074fd..6f8ef34590 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py -@@ -1520,9 +1520,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): +@@ -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()) @@ -58,7 +58,7 @@ index 38be2cd437..e62ff6fcc4 100644 def test_simple_xml_chunk_5(self): self.test_simple_xml(chunk_size=5, flush=True) -@@ -1747,6 +1751,8 @@ def test_flush_reparse_deferral_enabled(self): +@@ -1774,6 +1778,8 @@ def test_flush_reparse_deferral_enabled(self): self.assert_event_tags(parser, [('end', 'doc')]) diff --git a/python3.14.spec b/python3.14.spec index d666832..08feeeb 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -46,10 +46,10 @@ 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}.0 -%global prerel b3 +%global prerel b4 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -1737,6 +1737,9 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Jul 08 2025 Miro Hrončok - 3.14.0~b4-1 +- Update to Python 3.14.0b4 + * Wed Jun 25 2025 Karolina Surma - 3.14.0~b3-3 - Conditionally skip tests not working with the older expat version diff --git a/sources b/sources index f93997d..7b805ec 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0b3.tar.xz) = 621bcaf2ae4b6f0ba6c95ef74b5ffb78d8a2a0bb10415fb4c5eab1cad26c63098237944713a7f0812ec3e014ff62cd0f9bd5663e87799fcf1856aa4b937be914 +SHA512 (Python-3.14.0b4.tar.xz) = faaea000a474430a4ee41bdc95f9a77aa6573354698bc987a7617a6d36eae4b8e7f02ac945eb5b97df8dc62a256725ccd59fec08d4af2bd7b6e8a31ef4f92e2a From 482bb556a984a90d4d3130d2c01caf76f628c470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 22 Jul 2025 21:52:49 +0200 Subject: [PATCH 38/88] Update to Python 3.14.0rc1 _datetime was removed from installed files via https://github.com/python/cpython/commit/ecd97caaf5923764d22f6bd29339b8416c0c1917 --- 00251-change-user-install-location.patch | 2 +- ...nly-install-wheel-in-test-venvs-when-setuptools-71.patch | 2 +- 00464-enable-pac-and-bti-protections-for-aarch64.patch | 4 ++-- python3.14.spec | 6 ++++-- sources | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 548a8ba..a207721 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -130,7 +130,7 @@ index f93b98dd68..f6dbd5f5c3 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 7af3144d69..721017a1f8 100644 +index 9faabc2e25..b1532ad90b 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -132,8 +132,19 @@ def test_get_path(self): 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 index 8a59085..1a1a9d3 100644 --- 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 @@ -10,7 +10,7 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index ce18518bb8..7836bb37c4 100644 +index 001ecec4dc..f3338439b7 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2495,9 +2495,16 @@ def 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 index 9404072..1a7acf3 100644 --- a/00464-enable-pac-and-bti-protections-for-aarch64.patch +++ b/00464-enable-pac-and-bti-protections-for-aarch64.patch @@ -22,7 +22,7 @@ hardware protections can be enabled without losing Perf unwinding. create mode 100644 Python/asm_trampoline_aarch64.h diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S -index 616752459b..ec205a08ef 100644 +index a14e68c0e8..2513cde4e7 100644 --- a/Python/asm_trampoline.S +++ b/Python/asm_trampoline.S @@ -1,3 +1,5 @@ @@ -31,7 +31,7 @@ index 616752459b..ec205a08ef 100644 .text .globl _Py_trampoline_func_start # The following assembly is equivalent to: -@@ -20,10 +22,12 @@ _Py_trampoline_func_start: +@@ -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 diff --git a/python3.14.spec b/python3.14.spec index 08feeeb..c4f8ba2 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -46,7 +46,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}.0 -%global prerel b4 +%global prerel rc1 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -1436,7 +1436,6 @@ CheckPython freethreading %{1}/_ctypes.%{2}.so\ %{1}/_curses.%{2}.so\ %{1}/_curses_panel.%{2}.so\ -%{1}/_datetime.%{2}.so\ %{1}/_dbm.%{2}.so\ %{1}/_gdbm.%{2}.so\ %{1}/_decimal.%{2}.so\ @@ -1737,6 +1736,9 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Jul 22 2025 Miro Hrončok - 3.14.0~rc1-1 +- Update to Python 3.14.0rc1 + * Tue Jul 08 2025 Miro Hrončok - 3.14.0~b4-1 - Update to Python 3.14.0b4 diff --git a/sources b/sources index 7b805ec..4489574 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0b4.tar.xz) = faaea000a474430a4ee41bdc95f9a77aa6573354698bc987a7617a6d36eae4b8e7f02ac945eb5b97df8dc62a256725ccd59fec08d4af2bd7b6e8a31ef4f92e2a +SHA512 (Python-3.14.0rc1.tar.xz) = 6f34f593713282e105f9cf0396c523f738f3e4e8c2d4bcc4051c9febff96ab521e67abfe5fd072d7f584c3afcc7acb96a42939f51259ea411308a48468f7fd4e From 8c03c574c2525c7b48fb3422cbadcf0356dc7c57 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 25 Jul 2025 11:19:30 +0000 Subject: [PATCH 39/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index c4f8ba2..d78bfae 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ %global prerel rc1 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -1736,6 +1736,9 @@ CheckPython freethreading # ====================================================== %changelog +* Fri Jul 25 2025 Fedora Release Engineering - 3.14.0~rc1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Tue Jul 22 2025 Miro Hrončok - 3.14.0~rc1-1 - Update to Python 3.14.0rc1 From e8a3251a5e1e133bccb7ae78488ddc4b55ee8b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zachar?= Date: Mon, 28 Jul 2025 13:14:55 +0200 Subject: [PATCH 40/88] Drop STI and use tmt instead Resolves: rhbz#2383060 --- {tests/.fmf => .fmf}/version | 0 plan.fmf | 75 ++++++++++++++++++++++++++++++++++++ tests/provision.fmf | 4 -- tests/tests.yml | 69 --------------------------------- 4 files changed, 75 insertions(+), 73 deletions(-) rename {tests/.fmf => .fmf}/version (100%) create mode 100644 plan.fmf delete mode 100644 tests/provision.fmf delete mode 100644 tests/tests.yml diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/plan.fmf b/plan.fmf new file mode 100644 index 0000000..57bc44c --- /dev/null +++ b/plan.fmf @@ -0,0 +1,75 @@ +execute: + how: tmt + +provision: + hardware: + memory: '>= 3 GB' + +environment: + pybasever: '3.14' + +discover: + - name: tests_python + how: shell + url: https://src.fedoraproject.org/tests/python.git + tests: + - name: smoke + path: /smoke + test: "VERSION=${pybasever} CYTHON=false ./venv.sh" + - name: smoke_virtualenv + path: /smoke + test: "VERSION=${pybasever} METHOD=virtualenv CYTHON=false ./venv.sh" + - name: debugsmoke + path: /smoke + test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} CYTHON=false ./venv.sh" + - name: selftest + path: /selftest + 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_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651https://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: 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" + - name: debugflags + path: /flags + test: "python${pybasever}d ./assertflags.py -O0 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: freethreadingflags + path: /flags + test: "python${pybasever}t ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: freethreadingdebugflags + path: /flags + test: "python${pybasever}td ./assertflags.py -O0 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: marshalparser + path: /marshalparser + test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh" + +prepare: + - name: Install dependencies + how: install + package: + - gcc # for extension building in venv and selftest + - gcc-c++ # for test_cppext + - gdb # for test_gdb + - "python${pybasever}" # the test subject + - "python${pybasever}-debug" # for leak testing + - "python${pybasever}-devel" # for extension building in venv and selftest + - "python${pybasever}-tkinter" # for selftest + - "python${pybasever}-test" # for selftest + - "python${pybasever}-freethreading" # for -O... flag test + - "python${pybasever}-freethreading-debug" # for -O... flag test + - tox # for venv tests + - virtualenv # for virtualenv tests + - glibc-all-langpacks # for locale tests + - marshalparser # for testing compatibility (magic numbers) with marshalparser + - rpm # for debugging + - dnf # for upgrade + - name: Update packages + how: shell + script: dnf upgrade -y + - name: rpm_qa + order: 100 + how: shell + script: rpm -qa | sort | tee $TMT_PLAN_DATA/rpmqa.txt diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 1a4f0f0..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,4 +0,0 @@ ---- -standard-inventory-qcow2: - qemu: - m: 3G # Amount of VM memory diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 93b6b3b..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,69 +0,0 @@ ---- -- hosts: localhost - tags: - - classic - tasks: - - dnf: - name: "*" - state: latest - -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - repositories: - - repo: "https://src.fedoraproject.org/tests/python.git" - dest: "python" - pybasever: "3.14" - tests: - - rpm_qa: - run: rpm -qa - - smoke: - dir: python/smoke - run: "VERSION={{ pybasever }} CYTHON=false ./venv.sh" - - smoke_virtualenv: - dir: python/smoke - run: "VERSION={{ pybasever }} METHOD=virtualenv CYTHON=false ./venv.sh" - - debugsmoke: - dir: python/smoke - run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - - selftest: - dir: python/selftest - run: "VERSION={{ pybasever }} X='-i test_check_probes -i test_sysconfigdata_json' ./parallel.sh" - - debugtest: - dir: python/selftest - # test_base_interpreter: https://github.com/python/cpython/issues/131372 - # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651https://github.com/python/cpython/issues/133651 - run: "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" - - optimizedflags: - dir: python/flags - run: "python{{ pybasever }} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" - - debugflags: - dir: python/flags - run: "python{{ pybasever }}d ./assertflags.py -O0 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" - - freethreadingflags: - dir: python/flags - run: "python{{ pybasever }}t ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" - - freethreadingdebugflags: - dir: python/flags - run: "python{{ pybasever }}td ./assertflags.py -O0 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" - - marshalparser: - dir: python/marshalparser - run: "VERSION={{ pybasever }} SAMPLE=10 test_marshalparser_compatibility.sh" - required_packages: - - gcc # for extension building in venv and selftest - - gcc-c++ # for test_cppext - - gdb # for test_gdb - - "python{{ pybasever }}" # the test subject - - "python{{ pybasever }}-debug" # for leak testing - - "python{{ pybasever }}-devel" # for extension building in venv and selftest - - "python{{ pybasever }}-tkinter" # for selftest - - "python{{ pybasever }}-test" # for selftest - - "python{{ pybasever }}-freethreading" # for -O... flag test - - "python{{ pybasever }}-freethreading-debug" # for -O... flag test - - tox # for venv tests - - virtualenv # for virtualenv tests - - glibc-all-langpacks # for locale tests - - marshalparser # for testing compatibility (magic numbers) with marshalparser - - rpm # for debugging From 56f34b9695e250e2a36231f4f4f3b664d1edc8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 14 Aug 2025 18:20:41 +0200 Subject: [PATCH 41/88] Update to Python 3.14.0rc2 - The .pyc magic number was bumped --- python3.14.spec | 29 ++++++++++++++++------------- sources | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index d78bfae..50fbaf5 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -46,10 +46,10 @@ 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}.0 -%global prerel rc1 +%global prerel rc2 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -109,31 +109,30 @@ 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 25.1.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.2 -Provides: bundled(python3dist(certifi)) = 2025.1.31 +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.3.9 +Provides: bundled(python3dist(distlib)) = 0.4 Provides: bundled(python3dist(distro)) = 1.9 Provides: bundled(python3dist(idna)) = 3.10 -Provides: bundled(python3dist(msgpack)) = 1.1 +Provides: bundled(python3dist(msgpack)) = 1.1.1 Provides: bundled(python3dist(packaging)) = 25 -Provides: bundled(python3dist(platformdirs)) = 4.3.7 -Provides: bundled(python3dist(pygments)) = 2.19.1 +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.32.3 -Provides: bundled(python3dist(resolvelib)) = 1.1 -Provides: bundled(python3dist(rich)) = 14 +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.2.1 Provides: bundled(python3dist(tomli-w)) = 1.2 Provides: bundled(python3dist(truststore)) = 0.10.1 -Provides: bundled(python3dist(typing-extensions)) = 4.13.2 Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools @@ -1736,6 +1735,10 @@ CheckPython freethreading # ====================================================== %changelog +* Thu Aug 14 2025 Miro Hrončok - 3.14.0~rc2-1 +- Update to Python 3.14.0rc2 +- The .pyc magic number was bumped + * Fri Jul 25 2025 Fedora Release Engineering - 3.14.0~rc1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 4489574..43ae6bc 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0rc1.tar.xz) = 6f34f593713282e105f9cf0396c523f738f3e4e8c2d4bcc4051c9febff96ab521e67abfe5fd072d7f584c3afcc7acb96a42939f51259ea411308a48468f7fd4e +SHA512 (Python-3.14.0rc2.tar.xz) = 8021dc8e23239fd9e53fafd1fcaa1108da41ef376ee5b5e9c8dfd74995537131990239cd83de45b8bd5fb52b44c4dc08df1c837f69ce82c5b2d99ddf3ea5ef77 From cfc37cd117b4501d66842d17fc3d654d6299783f Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Tue, 26 Aug 2025 10:01:22 +0200 Subject: [PATCH 42/88] rpminspect: Wrap strings with globs with single quotes It seems to be required since rpminspect 2.0: https://github.com/rpminspect/rpminspect/commit/1593c38ce46980e0279150706d1f7c7bdd82de28 --- rpminspect.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rpminspect.yaml b/rpminspect.yaml index 83dfb5e..8cc18cb 100644 --- a/rpminspect.yaml +++ b/rpminspect.yaml @@ -1,22 +1,22 @@ # exclude test XML data (not always valid) from XML validity check: xml: ignore: - - /usr/lib*/python*/test/xmltestdata/* - - /usr/lib*/python*/test/xmltestdata/*/* + - '/usr/lib*/python*/test/xmltestdata/*' + - '/usr/lib*/python*/test/xmltestdata/*/*' # exclude _socket from ipv4 only functions check, it has both ipv4 and ipv6 only badfuncs: allowed: - /usr/lib*/python*/lib-dynload/_socket.*: + '/usr/lib*/python*/lib-dynload/_socket.*': - inet_aton - inet_ntoa # exclude the debug build from annocheck entirely annocheck: ignore: - - /usr/bin/python*d - - /usr/lib*/libpython*d.so.1.0 - - /usr/lib*/python*/lib-dynload/*.cpython-*d-*-*-*.so + - '/usr/bin/python*d' + - '/usr/lib*/libpython*d.so.1.0' + - '/usr/lib*/python*/lib-dynload/*.cpython-*d-*-*-*.so' # don't report changed content of compiled files # that is expected with every toolchain update and not reproducible yet From 0ca0aa8525773cb91961c637f136ccd0013363be Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Thu, 18 Sep 2025 15:06:56 +0200 Subject: [PATCH 43/88] Update to Python 3.14.0rc3 --- ...nly-install-wheel-in-test-venvs-when-setuptools-71.patch | 4 ++-- python3.14.spec | 6 +++++- sources | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) 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 index 1a1a9d3..b59776b 100644 --- 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 @@ -10,10 +10,10 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index 001ecec4dc..f3338439b7 100644 +index a719e49ef3..209f77d52d 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py -@@ -2495,9 +2495,16 @@ def run_command(cmd): +@@ -2502,9 +2502,16 @@ def run_command(cmd): else: python = os.path.join(venv, 'bin', python_exe) diff --git a/python3.14.spec b/python3.14.spec index 50fbaf5..f97ab2f 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -46,7 +46,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}.0 -%global prerel rc2 +%global prerel rc3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -1735,6 +1735,10 @@ CheckPython freethreading # ====================================================== %changelog +* Thu Sep 18 2025 Karolina Surma - 3.14.0~rc3-1 +- Update to Python 3.14.0rc3 +- The .pyc magic number was bumped again + * Thu Aug 14 2025 Miro Hrončok - 3.14.0~rc2-1 - Update to Python 3.14.0rc2 - The .pyc magic number was bumped diff --git a/sources b/sources index 43ae6bc..20f5496 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0rc2.tar.xz) = 8021dc8e23239fd9e53fafd1fcaa1108da41ef376ee5b5e9c8dfd74995537131990239cd83de45b8bd5fb52b44c4dc08df1c837f69ce82c5b2d99ddf3ea5ef77 +SHA512 (Python-3.14.0rc3.tar.xz) = 15c55660fc0168bd0f2348fa6d669352b422a626b151b7a7131eb338459e552a15908874ad872eea0eea48801d5a489647e1643bf00548fd6d9c1aff6fc2044f From 937d86cf62c4e47975d7544025ffdeb794d95ed3 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 23 Sep 2025 12:51:08 +0200 Subject: [PATCH 44/88] Include licenses of incorporated software (rhbz#2133426) Python includes a lot of differently licensed functions and modules. We gather the list from https://docs.python.org/3.14/license.html. Detect changes to Doc/license.rst with file hash automatically in %prep. --- python3.14.spec | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index f97ab2f..6fa4862 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -518,8 +518,36 @@ This package contains /usr/bin/python - the "python" command that runs Python 3. %package -n %{pkgname}-libs Summary: Python runtime libraries -# Bundled mimalloc is MIT -%global libs_license Python-2.0.1 AND MIT +# Python is generally licensed as Python-2.0.1 but also includes incorporated software +# 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 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 +# test.support.asynchat and test.support.asyncore are MIT-CMU +# http.cookies is MIT-CMU +# trace is under temporary SPDX ref: https://gitlab.com/fedora/legal/fedora-license-data/-/issues/657 +# trace: LicenseRef-Fedora-Temporary-Python-trace +# uu is MIT-CMU +# xmlrpc.client is MIT-CMU +# test.test_epoll is MIT +# select kqueue interface is BSD-2-Clause +# SipHash algorithm in Python/pyhash.c is MIT +# strtod and dtoa are dtoa +# OpenSSL is not bundled +# expat is not bundled +# libffi is not bundled +# zlib is not bundled +# cfuhash used by tracemalloc is BSD-3-Clause +# libmpdec is not bundled +# C14N test suite in Lib/test/xmltestdata/c14n-20/ is BSD-3-Clause +# mimalloc is MIT +# 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 +%global libs_license Python-2.0.1 AND MIT AND BSD-3-Clause AND MIT-CMU AND LicenseRef-Fedora-Temporary-Python-trace AND BSD-2-Clause AND dtoa %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 License: %{libs_license} @@ -527,7 +555,7 @@ License: %{libs_license} Provides: bundled(python3dist(pip)) = %{pip_version} %pip_bundled_provides # License combined from Python libs + pip -License: %{libs_license} AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) %endif %unversioned_obsoletes_of_python3_X_if_main libs @@ -719,7 +747,7 @@ Provides: bundled(python3dist(pip)) = %{pip_version} Provides: bundled(python3dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides # License combined from Python libs + pip + setuptools -License: %{libs_license} AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) %endif # This package doesn't depend on python3-libs, so we need to explicitly @@ -786,6 +814,14 @@ rm Lib/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl rm Lib/test/wheeldata/setuptools-%{setuptools_version}-py3-none-any.whl %endif +# check if there were any changes to Doc/license.rst +# if so, a review of %%libs_license and %%license_file_hash is needed +found_hash=$(sha256sum Doc/license.rst | cut -f1 -d" ") +if [ "$found_hash" != %{license_file_hash} ]; then + echo "File hash mismatch: review Doc/license.rst for changes" + exit 1 +fi + # Remove all exe files to ensure we are not shipping prebuilt binaries # note that those are only used to create Microsoft Windows installers # and that functionality is broken on Linux anyway From c6a9f6fe3baf1c01b3fc42f1ef1ad2919c2e370f Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 7 Oct 2025 17:07:19 +0200 Subject: [PATCH 45/88] Update to Python 3.14.0 --- 00251-change-user-install-location.patch | 8 ++++---- ...y-install-wheel-in-test-venvs-when-setuptools-71.patch | 4 ++-- ...-skip-tests-not-working-with-older-expat-version.patch | 4 ++-- python3.14.spec | 5 ++++- sources | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index a207721..ff9c69b 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -51,7 +51,7 @@ index f932719715..e4ef914ec2 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index f93b98dd68..f6dbd5f5c3 100644 +index 2ecbff222f..7211773bad 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -130,7 +130,7 @@ index f93b98dd68..f6dbd5f5c3 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 9faabc2e25..b1532ad90b 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 9faabc2e25..b1532ad90b 100644 os.path.normpath(expected), ) -@@ -388,7 +399,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 9faabc2e25..b1532ad90b 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -400,6 +411,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 index b59776b..aea27d9 100644 --- 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 @@ -10,10 +10,10 @@ This can be removed when Fedora 41 goes EOL (or updates setuptools). 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py -index a719e49ef3..209f77d52d 100644 +index 88f6110351..210ddcdbe3 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py -@@ -2502,9 +2502,16 @@ def run_command(cmd): +@@ -2512,9 +2512,16 @@ def run_command(cmd): else: python = os.path.join(venv, 'bin', python_exe) 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 index 2ae139a..953c18d 100644 --- 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 @@ -15,10 +15,10 @@ which is tested as working. 3 files changed, 10 insertions(+) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index 1d56ccd71c..5ef5517828 100644 +index a091430463..55ebf34c52 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py -@@ -790,6 +790,8 @@ def start_element(name, _): +@@ -826,6 +826,8 @@ def start_element(name, _): self.assertEqual(started, ['doc']) diff --git a/python3.14.spec b/python3.14.spec index 6fa4862..46f9134 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -46,7 +46,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}.0 -%global prerel rc3 +#global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -1771,6 +1771,9 @@ CheckPython freethreading # ====================================================== %changelog +* Tue Oct 07 2025 Karolina Surma - 3.14.0-1 +- Update to Python 3.14.0 + * Thu Sep 18 2025 Karolina Surma - 3.14.0~rc3-1 - Update to Python 3.14.0rc3 - The .pyc magic number was bumped again diff --git a/sources b/sources index 20f5496..3a6d2f0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Python-3.14.0rc3.tar.xz) = 15c55660fc0168bd0f2348fa6d669352b422a626b151b7a7131eb338459e552a15908874ad872eea0eea48801d5a489647e1643bf00548fd6d9c1aff6fc2044f +SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53 From 0bef7f1c35c1cf9a1b8a8823df31f758cf7c882c Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 13 Oct 2025 10:16:25 +0200 Subject: [PATCH 46/88] trace is officially licensed as HPND-SMC https://gitlab.com/fedora/legal/fedora-license-data/-/issues/657#note_2815942473 --- python3.14.spec | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 46f9134..33e3a15 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -528,8 +528,7 @@ Summary: Python runtime libraries # socket.getaddrinfo() and socket.getnameinfo() are BSD-3-Clause # test.support.asynchat and test.support.asyncore are MIT-CMU # http.cookies is MIT-CMU -# trace is under temporary SPDX ref: https://gitlab.com/fedora/legal/fedora-license-data/-/issues/657 -# trace: LicenseRef-Fedora-Temporary-Python-trace +# trace is HPND-SMC # uu is MIT-CMU # xmlrpc.client is MIT-CMU # test.test_epoll is MIT @@ -547,7 +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 -%global libs_license Python-2.0.1 AND MIT AND BSD-3-Clause AND MIT-CMU AND LicenseRef-Fedora-Temporary-Python-trace AND BSD-2-Clause AND dtoa +%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} From 041b6663c5928d6b0012aab1a04ac84e62c240bf Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Fri, 17 Oct 2025 10:16:29 +0200 Subject: [PATCH 47/88] Split freethreading package into analogs of the main Python Assisted-By: Claude Sonnet 4.5 --- python3.14.spec | 246 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 206 insertions(+), 40 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 33e3a15..d6cae5b 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -733,48 +733,159 @@ The debug runtime additionally supports debug builds of C-API extensions # we want to call this python3.X-threading even when built as a main Python. # This build of Python is not "the main freethreading Python", there's no such thing (yet?) %package -n python%{pybasever}-freethreading -Summary: Free Threading (PEP 703) version of the Python runtime +Summary: Free Threading (PEP 703) version of the Python interpreter -%if %{with rpmwheels} -Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 -Requires: %{python_wheel_pkg_prefix}-setuptools-wheel -Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) -License: %{libs_license} -%else -Provides: bundled(python3dist(pip)) = %{pip_version} -%pip_bundled_provides -Provides: bundled(python3dist(setuptools)) = %{setuptools_version} -%setuptools_bundled_provides -# License combined from Python libs + pip + setuptools -License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) -%endif +Requires: python%{pybasever}-freethreading-libs%{?_isa} = %{version}-%{release} -# This package doesn't depend on python3-libs, so we need to explicitly -# define the same Provides and Requires. -# See the comments in the definition of -libs subpackage for detailed explanations -Provides: bundled(mimalloc) = 2.12 -Requires: tzdata +Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 %description -n python%{pybasever}-freethreading -The Free Threading (PEP 703) build of Python. +The Free Threading (PEP 703) build of Python interpreter. -CPython’s global interpreter lock (“GIL”) prevents multiple threads from +CPython's global interpreter lock ("GIL") prevents multiple threads from executing Python code at the same time. The GIL is an obstacle to using multi-core CPUs from Python efficiently. This build of Python is built with the --disable-gil option. It lets the interpreter run Python code without the global interpreter lock and with the necessary changes needed to make the interpreter thread-safe. -%endif # with freethreading_build +The %{pkgname}-freethreading package provides the "python%{pybasever}t" executable. +The majority of its standard library is provided in the +python%{pybasever}-freethreading-libs package, which should be installed +automatically along with python%{pybasever}-freethreading. +The remaining parts of the Python standard library are broken out into the +python%{pybasever}-freethreading-tkinter and +python%{pybasever}-freethreading-test packages, +which may need to be installed separately. + + +%package -n python%{pybasever}-freethreading-libs +Summary: Free Threading Python runtime libraries +%if %{with rpmwheels} +Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 +License: %{libs_license} +%else +Provides: bundled(python3dist(pip)) = %{pip_version} +%pip_bundled_provides +# License combined from Python libs + pip +License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +%endif + +# See the comments in the definition of main -libs subpackage for detailed explanations +Provides: bundled(mimalloc) = 2.12 +Requires: tzdata + +# There are files in the standard library that have python shebang. +# We've filtered the automatic requirement out so libs are installable without +# the main package. This however makes it pulled in by default. +Recommends: python%{pybasever}-freethreading%{?_isa} + +# tkinter is part of the standard library, +# but it is torn out to save an unwanted dependency on tk and X11. +# we recommend it when tk is already installed (for better UX) +Recommends: (python%{pybasever}-freethreading-tkinter%{?_isa} if tk%{?_isa}) + +Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 + +%description -n python%{pybasever}-freethreading-libs +This package contains runtime libraries for use by Free Threading Python: +- the majority of the Python standard library +- a dynamically linked library for use by applications that embed Python as + a scripting language, and by the main "python%{pybasever}t" executable + + +%package -n python%{pybasever}-freethreading-devel +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} +Requires: python%{pybasever}-freethreading-libs%{?_isa} = %{version}-%{release} + +Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 + +%description -n python%{pybasever}-freethreading-devel +This package contains the header files and configuration needed to compile +Python extension modules (typically written in C or C++) for the Free hreading +build, to embed Free Threading Python into other programs, and to make binary +distributions for Free Threading Python libraries. + + +%package -n python%{pybasever}-freethreading-idle +Summary: A basic graphical development environment for Free Threading Python +Requires: python%{pybasever}-freethreading = %{version}-%{release} +Requires: python%{pybasever}-freethreading-tkinter = %{version}-%{release} + +Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 + +%description -n python%{pybasever}-freethreading-idle +IDLE is Python's Integrated Development and Learning Environment for +the Free Threading build. + +IDLE has the following features: Python shell window (interactive +interpreter) with colorizing of code input, output, and error messages; +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); debugger with persistent +breakpoints, stepping, and viewing of global and local namespaces; +configuration, browsers, and other dialogs. +Run with `python%{pybasever}t -m idlelib`. + + +%package -n python%{pybasever}-freethreading-tkinter +Summary: A GUI toolkit for Free Threading Python +Requires: python%{pybasever}-freethreading = %{version}-%{release} + +# The importable module "turtle" is here, so provide python3.x-freethreading-turtle. +%py_provides python%{pybasever}-freethreading-turtle + +Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 + +%description -n python%{pybasever}-freethreading-tkinter +The Tkinter (Tk interface) library is a graphical user interface toolkit for +the Free Threading Python interpreter. + + +%package -n python%{pybasever}-freethreading-test +Summary: The self-test suite for the Free Threading Python package +Requires: python%{pybasever}-freethreading = %{version}-%{release} +Requires: python%{pybasever}-freethreading-libs%{?_isa} = %{version}-%{release} + +%if %{with rpmwheels} +Requires: %{python_wheel_pkg_prefix}-setuptools-wheel +Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) +%else +Provides: bundled(python3dist(setuptools)) = %{setuptools_version} +%setuptools_bundled_provides +# License manually combined from Python + setuptools + wheel +License: Python-2.0.1 AND MIT AND Apache-2.0 AND (Apache-2.0 OR BSD-2-Clause) +%endif + +Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 + +%description -n python%{pybasever}-freethreading-test +The self-test suite for the Free Threading Python interpreter. + +This is only useful to test Free Threading Python itself. For testing general +Python code with the Free Threading build, you should use the unittest module +from python%{pybasever}-freethreading-libs, or a library such as pytest. +%endif # with freethreading_build %if %{with freethreading_build} && %{with debug_build} %package -n python%{pybasever}-freethreading-debug Summary: Free Threading (PEP 703) version of the Python runtime (debug build) License: %{libs_license} -# This uses the pure Python modules from the freethreading package +# The debug build is an all-in-one package version of the regular build, and +# shares the same .py/.pyc files and directories as the regular build. Hence +# we depend on all of the subpackages of the regular build: Requires: python%{pybasever}-freethreading%{?_isa} = %{version}-%{release} +Requires: python%{pybasever}-freethreading-libs%{?_isa} = %{version}-%{release} +Requires: python%{pybasever}-freethreading-devel%{?_isa} = %{version}-%{release} +Requires: python%{pybasever}-freethreading-test%{?_isa} = %{version}-%{release} +Requires: python%{pybasever}-freethreading-tkinter%{?_isa} = %{version}-%{release} +Requires: python%{pybasever}-freethreading-idle%{?_isa} = %{version}-%{release} %description -n python%{pybasever}-freethreading-debug The Free Threading (PEP 703) build of Python. Debug build. @@ -1100,6 +1211,9 @@ InstallPython optimized \ # Install directories for additional packages install -d -m 0755 %{buildroot}%{pylibdir}/site-packages/__pycache__ +%if %{with freethreading_build} +install -d -m 0755 %{buildroot}%{pylibdir_freethreading}/site-packages/__pycache__ +%endif %if "%{_lib}" == "lib64" # The 64-bit version needs to create "site-packages" in /usr/lib/ (for # pure-Python modules) as well as in /usr/lib64/ (for packages with extension @@ -1674,6 +1788,13 @@ CheckPython freethreading %if %{with freethreading_build} %files -n python%{pybasever}-freethreading +%{_bindir}/python%{LDVERSION_freethreading} +%doc README.rst + + +%files -n python%{pybasever}-freethreading-libs +%doc README.rst + %dir %{pylibdir_freethreading} %dir %{dynload_dir_freethreading} @@ -1683,42 +1804,84 @@ CheckPython freethreading # Pure Python modules %pure_python_modules %{pylibdir_freethreading} -# Modules that we separate from python3-libs, but want to ship in -freethreading -%{pylibdir_freethreading}/__phello__/ -%{pylibdir_freethreading}/idlelib/ -%{pylibdir_freethreading}/test/ -%{pylibdir_freethreading}/tkinter/ -%{pylibdir_freethreading}/turtledemo/ - %{pylibdir_freethreading}/_sysconfig_vars_%{ABIFLAGS_freethreading}_linux_%{platform_triplet}.json # File defined by PEP 739 since Python 3.14: %{pylibdir_freethreading}/build-details.json +# This will be in the -freethreading-tkinter package +%exclude %{pylibdir_freethreading}/turtle.py +%exclude %{pylibdir_freethreading}/__pycache__/turtle*%{bytecode_suffixes} + # This will be in the -freethreading-debug package %if %{with debug_build} %exclude %{pylibdir_freethreading}/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}.py %exclude %{pylibdir_freethreading}/__pycache__/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}%{bytecode_suffixes} %endif -# Analog of the core subpackage's files: -%{_bindir}/python%{LDVERSION_freethreading} +# Extension modules +%extension_modules %{dynload_dir_freethreading} %{SOABI_freethreading} -# Analog to the -libs subpackage's files: +%dir %{pylibdir_freethreading}/site-packages/ +%dir %{pylibdir_freethreading}/site-packages/__pycache__/ + +%if "%{_lib}" == "lib64" +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}%{ABIFLAGS_freethreading}/ +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}%{ABIFLAGS_freethreading}/site-packages/ +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}%{ABIFLAGS_freethreading}/site-packages/__pycache__/ +%endif + +# "Makefile" and the config-32/64.h file are needed by +# sysconfig.get_config_vars(), so we include them in the core +# package, along with their parent directories: +%dir %{pylibdir_freethreading}/config-%{LDVERSION_freethreading}-%{platform_triplet}/ +%{pylibdir_freethreading}/config-%{LDVERSION_freethreading}-%{platform_triplet}/Makefile +%dir %{_includedir}/python%{LDVERSION_freethreading}/ +%{_includedir}/python%{LDVERSION_freethreading}/%{_pyconfig_h} + +# Finally, libpython %{_libdir}/%{py_INSTSONAME_freethreading} -%extension_modules %{dynload_dir_freethreading} %{SOABI_freethreading} -%extension_modules_test %{dynload_dir_freethreading} %{SOABI_freethreading} -%{dynload_dir_freethreading}/_tkinter.%{SOABI_freethreading}.so -# Analog of the -devel subpackage's files: -%{pylibdir_freethreading}/config-%{LDVERSION_freethreading}-%{platform_triplet}/ -%{_includedir}/python%{LDVERSION_freethreading}/ +%files -n python%{pybasever}-freethreading-devel +%{pylibdir_freethreading}/config-%{LDVERSION_freethreading}-%{platform_triplet}/* +%exclude %{pylibdir_freethreading}/config-%{LDVERSION_freethreading}-%{platform_triplet}/Makefile +%exclude %{_includedir}/python%{LDVERSION_freethreading}/%{_pyconfig_h} +%{_includedir}/python%{LDVERSION_freethreading}/*.h +%{_includedir}/python%{LDVERSION_freethreading}/internal/ +%{_includedir}/python%{LDVERSION_freethreading}/cpython/ + %{_bindir}/python%{LDVERSION_freethreading}-config %{_bindir}/python%{LDVERSION_freethreading}-*-config %{_libdir}/libpython%{LDVERSION_freethreading}.so %{_libdir}/pkgconfig/python-%{LDVERSION_freethreading}.pc %{_libdir}/pkgconfig/python-%{LDVERSION_freethreading}-embed.pc + +%files -n python%{pybasever}-freethreading-idle +%{pylibdir_freethreading}/idlelib/ + + +%files -n python%{pybasever}-freethreading-tkinter +%{pylibdir_freethreading}/tkinter/ +%{dynload_dir_freethreading}/_tkinter.%{SOABI_freethreading}.so +%{pylibdir_freethreading}/turtle.py +%{pylibdir_freethreading}/__pycache__/turtle*%{bytecode_suffixes} +%dir %{pylibdir_freethreading}/turtledemo/ +%{pylibdir_freethreading}/turtledemo/*.py +%{pylibdir_freethreading}/turtledemo/*.cfg +%dir %{pylibdir_freethreading}/turtledemo/__pycache__/ +%{pylibdir_freethreading}/turtledemo/__pycache__/*%{bytecode_suffixes} + + +%files -n python%{pybasever}-freethreading-test +%{pylibdir_freethreading}/test/ + +# Pure Python modules +%{pylibdir_freethreading}/__phello__/ + +# Extension modules +%extension_modules_test %{dynload_dir_freethreading} %{SOABI_freethreading} + %endif # with freethreading_build %if %{with freethreading_build} && %{with debug_build} @@ -1770,6 +1933,9 @@ CheckPython freethreading # ====================================================== %changelog +* Fri Oct 17 2025 Karolina Surma - 3.14.0-2 +- Split -freethreading package into analogs of the main Python + * Tue Oct 07 2025 Karolina Surma - 3.14.0-1 - Update to Python 3.14.0 From a7297274d1207527645a2dbc59b3cb54cd505ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 22 Oct 2025 14:55:01 +0200 Subject: [PATCH 48/88] Revert "CI: Disable Cython checks on the smoke test for now" Cython supports 3.14. This should have been enabled a long time ago. This reverts commit 204e750d2e37ea1dd1d90c2da3b63b6f771b0f26. --- plan.fmf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plan.fmf b/plan.fmf index 57bc44c..5f8d0d7 100644 --- a/plan.fmf +++ b/plan.fmf @@ -15,13 +15,13 @@ discover: tests: - name: smoke path: /smoke - test: "VERSION=${pybasever} CYTHON=false ./venv.sh" + test: "VERSION=${pybasever} CYTHON=true ./venv.sh" - name: smoke_virtualenv path: /smoke - test: "VERSION=${pybasever} METHOD=virtualenv CYTHON=false ./venv.sh" + test: "VERSION=${pybasever} METHOD=virtualenv CYTHON=true ./venv.sh" - name: debugsmoke path: /smoke - test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} CYTHON=false ./venv.sh" + 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 -i test_sysconfigdata_json' ./parallel.sh" From d60c500d01032e0db7957469b16c47c535d03996 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Fri, 24 Oct 2025 13:06:09 +0200 Subject: [PATCH 49/88] Supplement tox from -freethreading-devel package --- python3.14.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python3.14.spec b/python3.14.spec index d6cae5b..1649c29 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -802,6 +802,9 @@ License: Python-2.0.1 AND MIT Requires: python%{pybasever}-freethreading = %{version}-%{release} Requires: python%{pybasever}-freethreading-libs%{?_isa} = %{version}-%{release} +# tox users are likely to need the devel subpackage +Supplements: tox + Obsoletes: python%{pybasever}-freethreading < 3.14.0-2 %description -n python%{pybasever}-freethreading-devel From e365cd89b9bf36673832102ff11275a0271477d3 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 20 Oct 2025 10:36:04 +0200 Subject: [PATCH 50/88] CI: Fix duplicate link in a comment --- plan.fmf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plan.fmf b/plan.fmf index 5f8d0d7..35fb994 100644 --- a/plan.fmf +++ b/plan.fmf @@ -28,7 +28,7 @@ discover: - name: debugtest path: /selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651https://github.com/python/cpython/issues/133651 + # 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: optimizedflags path: /flags From 56eb7aad4b526499062b8a1eaf474a5cfa56a373 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 20 Oct 2025 10:36:15 +0200 Subject: [PATCH 51/88] CI: Run selftest on freethreading build --- plan.fmf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plan.fmf b/plan.fmf index 35fb994..f681007 100644 --- a/plan.fmf +++ b/plan.fmf @@ -30,6 +30,9 @@ discover: # test_base_interpreter: https://github.com/python/cpython/issues/131372 # 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_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" @@ -60,6 +63,8 @@ prepare: - "python${pybasever}-test" # for selftest - "python${pybasever}-freethreading" # for -O... flag test - "python${pybasever}-freethreading-debug" # for -O... flag test + - "python${pybasever}-freethreading-tkinter" # for freethreadingtest + - "python${pybasever}-freethreading-test" # for freethreadingtest - tox # for venv tests - virtualenv # for virtualenv tests - glibc-all-langpacks # for locale tests From 2986781bf7a85ebee75280bf6262a1aa5b6c57f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 27 Mar 2025 12:08:00 +0000 Subject: [PATCH 52/88] Use prebuilt JIT stencils on platforms without LLVM 19 (cherry picked from python3.15 commit f3045380bba4fd8047571a76b233c5d955eb2577) --- .gitignore | 1 + download-jit-stencils-from-koji.sh | 23 ++++++++++++++ python3.14.spec | 49 +++++++++++++++++++++++++++--- rpmlint.toml | 3 ++ sources | 4 +++ 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 download-jit-stencils-from-koji.sh diff --git a/.gitignore b/.gitignore index 1107137..67901af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /*.tar.* +/*-jit_stencils.h /*.src.rpm /results_python3* diff --git a/download-jit-stencils-from-koji.sh b/download-jit-stencils-from-koji.sh new file mode 100644 index 0000000..296af97 --- /dev/null +++ b/download-jit-stencils-from-koji.sh @@ -0,0 +1,23 @@ +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/python3.14.spec b/python3.14.spec index 1649c29..11dc475 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -78,10 +78,13 @@ License: Python-2.0.1 # PEP 744: JIT Compilation # Whether to build with the experimental JIT compiler -# 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 +# Only possible on certain architectures: https://peps.python.org/pep-0744/#support # The freethreading build (when enabled) does not support JIT yet -%bcond jit %[(0%{?fedora} >= 41) && ("%{_arch}" == "x86_64" || "%{_arch}" == "aarch64")] +%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] %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 @@ -293,7 +296,7 @@ BuildRequires: glibc-all-langpacks BuildRequires: tzdata %endif -%if %{with jit} +%if %{with jit_build_stencils} BuildRequires: clang(major) = 19 BuildRequires: llvm(major) = 19 %endif @@ -347,6 +350,24 @@ 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. touch the .h files (create them empty) +# 2. scratch build Python on platform with required LLVM version (usually rawhide) +# 3. download the files from Koji: +# $ bash download-jit-stencils-from-koji.sh KOJI_TASK_URL|KOJI_TASK_ID +# 4. add the files to lookaside cache with fedpkg new-sources +Source30: download-jit-stencils-from-koji.sh +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 +%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 @@ -1045,6 +1066,16 @@ BuildPython() { $ExtraConfigArgs \ %{nil} +%if %{with jit} && %{without jit_build_stencils} + if [[ ! "$ConfName" =~ ^freethreading ]]; then + cp -a %{jit_stencils_source} %{jit_stencils_filename} + # Hackish way of preventing PGO task to delete the stencils. + # Upstream issue: https://github.com/python/cpython/issues/141808 + # Upstream PR: https://github.com/python/cpython/pull/141809 + sed -i '/rm -f jit_stencils.h/d' Makefile + fi +%endif + %global flags_override EXTRA_CFLAGS="$MoreCFlags" CFLAGS_NODIST="$CFLAGS_NODIST $MoreCFlags" %if %{without bootstrap} @@ -1397,6 +1428,16 @@ 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 + diff -u %{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 diff --git a/rpmlint.toml b/rpmlint.toml index 0864a1c..9ddef32 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -37,6 +37,9 @@ 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__)/', diff --git a/sources b/sources index 3a6d2f0..8aaba44 100644 --- a/sources +++ b/sources @@ -1 +1,5 @@ SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53 +SHA512 (Python-3.14.0-aarch64-debug-jit_stencils.h) = 850952abc9ee83be51a67d64d013e31abd6a9e4331045ae169f684107d98fba9c91ef28fd1bf60e75c8975b600665afc9aec258b7e5b61abafa834996b16fb18 +SHA512 (Python-3.14.0-aarch64-optimized-jit_stencils.h) = d7b50e8bb2341f0404781f3f17dca9ac489efd8e25b832eb34346e4b88f3084e9c4482f981e51db4a9596df05c4138642252f52d0712dac9dda15cee21db196c +SHA512 (Python-3.14.0-x86_64-debug-jit_stencils.h) = 51484d6b19a2483f67589c4d57f2df25f28d089a591f19c5eef6564006db5f7d5afa52181df2cd925a550e358ee5562c8f02ef0f8de7628f5f1fa242fd89a56a +SHA512 (Python-3.14.0-x86_64-optimized-jit_stencils.h) = c84dda9956690faf372a09d9a532311d975ae69c4bf2a91102c30086dca16bef9a2c0ebb2f372437cfad64585e7a872db74476f5c502dc9635a25dd9e0b710d4 From 6d982d0a19e045036e56074e7a101cd93ddf7550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 28 Mar 2025 11:21:19 +0000 Subject: [PATCH 53/88] CI: Run tests with JIT enabled, assert JIT is enabled/disabled correctly (cherry picked from python3.15 commit 687c6ece6f633bbd9e65a680bba3e3ea80eb122c) --- plan.fmf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plan.fmf b/plan.fmf index f681007..f956e08 100644 --- a/plan.fmf +++ b/plan.fmf @@ -33,6 +33,16 @@ discover: - name: freethreadingtest path: /selftest test: "VERSION=${pybasever}t X='-i test_check_probes -i test_sysconfigdata_json -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_sysconfigdata_json -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()'" - 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" From e0af09b7c20b92ae76ee8e1deda897be33e62299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 5 Sep 2025 13:26:16 +0000 Subject: [PATCH 54/88] Inject SBOM into the installed wheels (when using the bundled ones) --- python3.14.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python3.14.spec b/python3.14.spec index 11dc475..866f5d4 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1393,6 +1393,11 @@ 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 # ====================================================== From d849d8f12715320b2e1713e414d665f1a8347a9d Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 3 Dec 2025 09:21:58 +0100 Subject: [PATCH 55/88] Update to Python 3.14.1 --- 00251-change-user-install-location.patch | 2 +- ...eel-in-test-venvs-when-setuptools-71.patch | 33 ------------------ ...not-working-with-older-expat-version.patch | 10 +++--- plan.fmf | 9 ++--- python3.14.spec | 34 +++++++++---------- sources | 10 +++--- 6 files changed, 33 insertions(+), 65 deletions(-) delete mode 100644 00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index ff9c69b..41995c3 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 f932719715..e4ef914ec2 100644 +index aeb7c6cfc7..86f9ae9e76 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -421,8 +421,15 @@ def getsitepackages(prefixes=None): 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 deleted file mode 100644 index aea27d9..0000000 --- a/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch +++ /dev/null @@ -1,33 +0,0 @@ -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/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 index 953c18d..1b36e9b 100644 --- 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 @@ -15,10 +15,10 @@ which is tested as working. 3 files changed, 10 insertions(+) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index a091430463..55ebf34c52 100644 +index daeaa38a3c..b243f1da14 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py -@@ -826,6 +826,8 @@ def start_element(name, _): +@@ -847,6 +847,8 @@ def start_element(name, _): self.assertEqual(started, ['doc']) @@ -41,10 +41,10 @@ index 5c10bcedc6..1fd7a273b5 100644 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 +index 25c084c8b9..e26e6e0c26 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): +@@ -1573,9 +1573,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): self.assert_event_tags(parser, [('end', 'root')]) self.assertIsNone(parser.close()) @@ -58,7 +58,7 @@ index bf6d5074fd..6f8ef34590 100644 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): +@@ -1802,6 +1806,8 @@ def test_flush_reparse_deferral_enabled(self): self.assert_event_tags(parser, [('end', 'doc')]) diff --git a/plan.fmf b/plan.fmf index f956e08..c7d158a 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,19 +24,20 @@ 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 -i test_sysconfigdata_json' ./parallel.sh" + test: "VERSION=${pybasever} X='-i test_check_probes -i test_sysconfigdata_json -i test_margin_is_sufficient' ./parallel.sh" - name: debugtest path: /selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 # 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" + # test_margin_is_sufficient: https://github.com/python/cpython/issues/140222 + 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 -i test_margin_is_sufficient' ./parallel.sh" - name: freethreadingtest path: /selftest - test: "VERSION=${pybasever}t X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter' ./parallel.sh" + test: "VERSION=${pybasever}t X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter -i test_margin_is_sufficient' ./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_sysconfigdata_json -i test_attr_promotion_failure' ./parallel.sh" + test: "VERSION=${pybasever} PYTHON_JIT=1 X='-i test_check_probes -i test_sysconfigdata_json -i test_attr_promotion_failure -i test_margin_is_sufficient' ./parallel.sh" - name: jit_disabled_by_default test: "python${pybasever} -c 'import sys; assert not sys._jit.is_enabled()'" - name: jit_disabled_explicitly diff --git a/python3.14.spec b/python3.14.spec index 866f5d4..2d6158a 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,11 +45,11 @@ 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}.0 +%global general_version %{pybasever}.1 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -112,30 +112,30 @@ 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 25.2 +%global pip_version 25.3 %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.3 -Provides: bundled(python3dist(certifi)) = 2025.7.14 +Provides: bundled(python3dist(certifi)) = 2025.10.5 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.10 -Provides: bundled(python3dist(msgpack)) = 1.1.1 +Provides: bundled(python3dist(msgpack)) = 1.1.2 Provides: bundled(python3dist(packaging)) = 25 -Provides: bundled(python3dist(platformdirs)) = 4.3.8 +Provides: bundled(python3dist(platformdirs)) = 4.5 Provides: bundled(python3dist(pygments)) = 2.19.2 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 -Provides: bundled(python3dist(requests)) = 2.32.4 -Provides: bundled(python3dist(resolvelib)) = 1.2 -Provides: bundled(python3dist(rich)) = 14.1 +Provides: bundled(python3dist(requests)) = 2.32.5 +Provides: bundled(python3dist(resolvelib)) = 1.2.1 +Provides: bundled(python3dist(rich)) = 14.2 Provides: bundled(python3dist(setuptools)) = 70.3 -Provides: bundled(python3dist(tomli)) = 2.2.1 +Provides: bundled(python3dist(tomli)) = 2.3 Provides: bundled(python3dist(tomli-w)) = 1.2 -Provides: bundled(python3dist(truststore)) = 0.10.1 +Provides: bundled(python3dist(truststore)) = 0.10.4 Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools @@ -387,12 +387,6 @@ 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 -# 00461 # 920175020b21c0aff5edcc4c28d688b5061f591c -# Downstream only: Install wheel in test venvs when setuptools < 71 -# -# 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 - # 00464 # 292acffec7a379cb6d1f3c47b9e5a2f170bbadb6 # Enable PAC and BTI protections for aarch64 # @@ -1475,6 +1469,8 @@ CheckPython() { # see: https://github.com/python/cpython/issues/121719 # test_interrupt and test_interrupt_no_handler # reported in https://github.com/python/cpython/issues/133651 + # test_margin_is_sufficient + # reported in https://github.com/python/cpython/issues/140222 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1486,6 +1482,7 @@ CheckPython() { -i test_check_probes \ -i test_interrupt \ -i test_interrupt_no_handler \ + -i test_margin_is_sufficient \ %ifarch %{mips64} -x test_ctypes \ %endif @@ -1982,6 +1979,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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/sources b/sources index 8aaba44..0db8db1 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53 -SHA512 (Python-3.14.0-aarch64-debug-jit_stencils.h) = 850952abc9ee83be51a67d64d013e31abd6a9e4331045ae169f684107d98fba9c91ef28fd1bf60e75c8975b600665afc9aec258b7e5b61abafa834996b16fb18 -SHA512 (Python-3.14.0-aarch64-optimized-jit_stencils.h) = d7b50e8bb2341f0404781f3f17dca9ac489efd8e25b832eb34346e4b88f3084e9c4482f981e51db4a9596df05c4138642252f52d0712dac9dda15cee21db196c -SHA512 (Python-3.14.0-x86_64-debug-jit_stencils.h) = 51484d6b19a2483f67589c4d57f2df25f28d089a591f19c5eef6564006db5f7d5afa52181df2cd925a550e358ee5562c8f02ef0f8de7628f5f1fa242fd89a56a -SHA512 (Python-3.14.0-x86_64-optimized-jit_stencils.h) = c84dda9956690faf372a09d9a532311d975ae69c4bf2a91102c30086dca16bef9a2c0ebb2f372437cfad64585e7a872db74476f5c502dc9635a25dd9e0b710d4 +SHA512 (Python-3.14.1-aarch64-debug-jit_stencils.h) = 158a259a89b86d5456f4e07d41132644698d40783fb6cd3c6aba231da4ac428c1588c3c1e665430ee6909f7b6c29c7924ff0e37adf0470679c120faaf169f07a +SHA512 (Python-3.14.1-aarch64-optimized-jit_stencils.h) = 45ac03531984fcd0c1366563649510e6b0c6760e76e4c8ce675291202b4e1bcd78ed038c312bc66c7ab8b8cd26a6bae7804e7b87b327d1e67c901b93194c4fc1 +SHA512 (Python-3.14.1-x86_64-debug-jit_stencils.h) = bfacfb2fe7fc32dd239b7a533f1e86364d687d46dbc6c7170bdd39c1660deda72f3fa2d5e26bd9a27f009f487e248e0426614fcb8dcefd42be1e71d5ef0f0523 +SHA512 (Python-3.14.1-x86_64-optimized-jit_stencils.h) = ecf76a904c7f686c01fea4ecfd498ef07fef226e62b792c97dcbb45c76f54351e5ecc02554fa21a3a82d55e5b6255b80c73f67538929d69c1c326f81ac8bd7b2 +SHA512 (Python-3.14.1.tar.xz) = b5ec011190536126fedade5c33a4afabc081a133ad5c734f4b872769d376735775219d63a482812d139fdd90c46707927065ab9dc733d0bce2d1ebc59fe705a2 From 1f64e4dcdb5d11d015fddf200e30dc8f63c2a59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 5 Dec 2025 22:30:26 +0100 Subject: [PATCH 56/88] Update to Python 3.14.2 --- python3.14.spec | 5 ++++- sources | 10 +++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 2d6158a..83cb290 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}.1 +%global general_version %{pybasever}.2 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1979,6 +1979,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 diff --git a/sources b/sources index 0db8db1..8cead99 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.1-aarch64-debug-jit_stencils.h) = 158a259a89b86d5456f4e07d41132644698d40783fb6cd3c6aba231da4ac428c1588c3c1e665430ee6909f7b6c29c7924ff0e37adf0470679c120faaf169f07a -SHA512 (Python-3.14.1-aarch64-optimized-jit_stencils.h) = 45ac03531984fcd0c1366563649510e6b0c6760e76e4c8ce675291202b4e1bcd78ed038c312bc66c7ab8b8cd26a6bae7804e7b87b327d1e67c901b93194c4fc1 -SHA512 (Python-3.14.1-x86_64-debug-jit_stencils.h) = bfacfb2fe7fc32dd239b7a533f1e86364d687d46dbc6c7170bdd39c1660deda72f3fa2d5e26bd9a27f009f487e248e0426614fcb8dcefd42be1e71d5ef0f0523 -SHA512 (Python-3.14.1-x86_64-optimized-jit_stencils.h) = ecf76a904c7f686c01fea4ecfd498ef07fef226e62b792c97dcbb45c76f54351e5ecc02554fa21a3a82d55e5b6255b80c73f67538929d69c1c326f81ac8bd7b2 -SHA512 (Python-3.14.1.tar.xz) = b5ec011190536126fedade5c33a4afabc081a133ad5c734f4b872769d376735775219d63a482812d139fdd90c46707927065ab9dc733d0bce2d1ebc59fe705a2 +SHA512 (Python-3.14.2.tar.xz) = 165256b4c713e0262767cd7a2c65622f3f086423524646a39bfa64912376be9e5b70863d5a3c95224b516152d0b79e7ccbfe2f2cf35b809d132f2c38ebb3ab3b +SHA512 (Python-3.14.2-aarch64-debug-jit_stencils.h) = c4d14860576768e24d15b9b1c8fbb9878403710126188e39265726fefcfe7336339bc863320a79b535516669101e7486051f37c0e797857adbc60073ed340ac1 +SHA512 (Python-3.14.2-aarch64-optimized-jit_stencils.h) = 64a23be3f2bd1e45b487d9e9e9010c3caa08ca2102d733ab54031c6fca5bcd6881b34ce9c6cc3cab58fd640f7b3af24d32ac828ee1fd3f44edbc276c98dd1596 +SHA512 (Python-3.14.2-x86_64-debug-jit_stencils.h) = 25e9a7e5867fa4c91d95c82dc63aeea19072a82a1bffe402554cf4abf7569c7510ab72815bb1c9ff7a4303192d65082f6d97bb5a334968ee7c06a360d9dac2cd +SHA512 (Python-3.14.2-x86_64-optimized-jit_stencils.h) = 52182daa5c50c60cc649a391a80f27e69e0eb86b5327c15a0af37657095e3e72916290106bd7dc640d5c5fdb71ad8c492a24ba4fa73411fd0b4ed248c75d3a81 From e0d3024961344564ab5f0bb34a87b7fe881be640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 9 Dec 2025 19:48:18 +0100 Subject: [PATCH 57/88] Remove a hack that was not needed on 3.14 When discussing whether to backport https://github.com/python/cpython/pull/141809 I discovered that this hack was not needed on this Python version. --- python3.14.spec | 4 ---- 1 file changed, 4 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 83cb290..6e9f073 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1063,10 +1063,6 @@ BuildPython() { %if %{with jit} && %{without jit_build_stencils} if [[ ! "$ConfName" =~ ^freethreading ]]; then cp -a %{jit_stencils_source} %{jit_stencils_filename} - # Hackish way of preventing PGO task to delete the stencils. - # Upstream issue: https://github.com/python/cpython/issues/141808 - # Upstream PR: https://github.com/python/cpython/pull/141809 - sed -i '/rm -f jit_stencils.h/d' Makefile fi %endif From 78e3110af1b0ec6fc66908f0de4a7ddbf045ec82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 3 Dec 2025 11:51:32 +0100 Subject: [PATCH 58/88] Make it easier to bootstrap new JIT stencils Only define the JIT stencils sources when we must (i.e. when building --wihtout jit_build_stencils) or when the files already exist. This allows to run rawhide CI scratch builds without the stencils, but it also ensures the final SRPM contains them even when built --with jit_build_stencils. (cherry picked from python3.15 commit b2312d171d6a3280744a549f2c4daee492b66f44) --- python3.14.spec | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 6e9f073..e1f1485 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -355,16 +355,19 @@ Source11: idle3.appdata.xml # Only used on platforms without the required LLVM version. # # When updating Python: -# 1. touch the .h files (create them empty) -# 2. scratch build Python on platform with required LLVM version (usually rawhide) -# 3. download the files from Koji: +# 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 -# 4. add the files to lookaside cache with fedpkg new-sources +# 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 %{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 From 8236063d9f0539e2ac7df38c8d0313c37bc7d39a Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Tue, 6 Jan 2026 16:18:59 +0100 Subject: [PATCH 59/88] Require at least the same expat version as used during the build In the past we have had a versioned requirement on expat, e.g.: https://src.fedoraproject.org/rpms/python3.13/c/c686992b6c25a39d0e4117053ddb669fd5998723 The explanation is still valid: if Python is built with an expat version with new symbols, and used with an installed older expat, it won't work, preventing crating new venvs, and many more. This has happened again now with expat 2.7.2 introducing new symbols. Reintroduce the versioned requirement and make it future-proof - the generated version will always match at least the one present in the buildroot during the Python build. --- python3.14.spec | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index e1f1485..c4ce5c3 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -596,6 +596,21 @@ 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. +# Other subpackages (like -debug) also need this, but they all depend on -libs. +%global expat_version %(LANG=C rpm -q --qf '%%{version}' expat.%{_target_cpu} | sed 's/.*not installed/0/') +Requires: expat >= %{expat_version} + %description -n %{pkgname}-libs This package contains runtime libraries for use by Python: @@ -793,6 +808,7 @@ 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 +Requires: expat >= %{expat_version} # There are files in the standard library that have python shebang. # We've filtered the automatic requirement out so libs are installable without @@ -1978,6 +1994,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 From 5ce9d27cf1e3c92ccba70c301aea5c72e9be0735 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 12 Jan 2026 11:55:39 +0100 Subject: [PATCH 60/88] Extend the expat requirement to differentiate between 32 and 64 arches (cherry picked from python3.15 commit a5ca170d3f1e6e19f5df66f21482c2b10593af42) --- python3.14.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index c4ce5c3..2db5e92 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -609,7 +609,7 @@ Requires: tzdata # was used during the build time. # Other subpackages (like -debug) also need this, but they all depend on -libs. %global expat_version %(LANG=C rpm -q --qf '%%{version}' expat.%{_target_cpu} | sed 's/.*not installed/0/') -Requires: expat >= %{expat_version} +Requires: expat%{?_isa} >= %{expat_version} %description -n %{pkgname}-libs @@ -808,7 +808,7 @@ 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 -Requires: expat >= %{expat_version} +Requires: expat%{?_isa} >= %{expat_version} # There are files in the standard library that have python shebang. # We've filtered the automatic requirement out so libs are installable without From 8f8849fb7c7f087d68cc1365f4bb201b3ba7b6a2 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 17 Jan 2026 10:40:18 +0000 Subject: [PATCH 61/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index 2db5e92..f028b08 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python-2.0.1 @@ -1994,6 +1994,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 From b4fbfd93352952689538d88c09da3927bce14584 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 26 Jan 2026 11:12:41 +0100 Subject: [PATCH 62/88] Reenable passing tests --- plan.fmf | 9 ++++----- python3.14.spec | 19 ------------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/plan.fmf b/plan.fmf index c7d158a..2253feb 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,20 +24,19 @@ 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 -i test_sysconfigdata_json -i test_margin_is_sufficient' ./parallel.sh" + test: "VERSION=${pybasever} X='-i test_check_probes -i test_margin_is_sufficient' ./parallel.sh" - name: debugtest path: /selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - # test_interrupt and test_interrupt_no_handler: https://github.com/python/cpython/issues/133651 # test_margin_is_sufficient: https://github.com/python/cpython/issues/140222 - 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 -i test_margin_is_sufficient' ./parallel.sh" + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_base_interpreter -i test_margin_is_sufficient' ./parallel.sh" - name: freethreadingtest path: /selftest - test: "VERSION=${pybasever}t X='-i test_check_probes -i test_sysconfigdata_json -i test_base_interpreter -i test_margin_is_sufficient' ./parallel.sh" + test: "VERSION=${pybasever}t X='-i test_check_probes -i test_base_interpreter -i test_margin_is_sufficient' ./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_sysconfigdata_json -i test_attr_promotion_failure -i test_margin_is_sufficient' ./parallel.sh" + test: "VERSION=${pybasever} PYTHON_JIT=1 X='-i test_check_probes -i test_attr_promotion_failure -i test_margin_is_sufficient' ./parallel.sh" - name: jit_disabled_by_default test: "python${pybasever} -c 'import sys; assert not sys._jit.is_enabled()'" - name: jit_disabled_explicitly diff --git a/python3.14.spec b/python3.14.spec index f028b08..9da94a3 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1472,18 +1472,9 @@ 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 # test_margin_is_sufficient # reported in https://github.com/python/cpython/issues/140222 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ @@ -1493,18 +1484,8 @@ CheckPython() { %else --timeout=2700 \ %endif - -i test_freeze_simple_script \ -i test_check_probes \ - -i test_interrupt \ - -i test_interrupt_no_handler \ -i test_margin_is_sufficient \ - %ifarch %{mips64} - -x test_ctypes \ - %endif - %ifarch s390x ppc64le - -x test_signal \ - -i test_deadlock \ - %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName From 6e767cf9f455bf9eab8dfc93480f95f857b8a563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 26 Jan 2026 11:14:03 +0100 Subject: [PATCH 63/88] Don't require the JIT stencils sources when the SRPM is built on other arch When the SRPM is built in Koji on non-JIT architecture (such as ppc64le or s390x), the jit_build_stencils bcond is set to false. When we don't have the JIT stencils sources yet and we do a scratch build to generate them, we want the SRPM creation to succeed, regardless of architecture. This way, the sources are only defined when they are required or when they exist. An alternative would be to set jit_build_stencils to true/false in an arch-independent way, and later always check for: %{with jit} && %{with jit_build_stencils} But I think that might be confusing. --- python3.14.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index 9da94a3..473529a 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -362,7 +362,7 @@ Source11: idle3.appdata.xml 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 %{without jit_build_stencils} || %{exists:%{_sourcedir}/Python-%{upstream_version}-x86_64-optimized-jit_stencils.h} +%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 From dd282ac7f3ea1e15e7920b1b3c5b3acaecfd0304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 26 Jan 2026 11:15:47 +0100 Subject: [PATCH 64/88] Remove an outdated workaround This fix landed 6 years ago in 3.9.0a5. https://github.com/python/cpython/commit/3c97e1e457033bbb8bbe0b7198bd13fc794a12b0 --- python3.14.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 473529a..1a46e39 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1054,9 +1054,6 @@ 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 \ From 406c34b53ba30ce7f9a7bd75060c1d9284c1aa49 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 9 Feb 2026 10:10:12 +0100 Subject: [PATCH 65/88] Update to Python 3.14.3 --- ...not-working-with-older-expat-version.patch | 2 +- ...piled-for-a-different-python-version.patch | 156 ++++++++++++++++++ plan.fmf | 9 +- python3.14.spec | 26 ++- sources | 10 +- 5 files changed, 187 insertions(+), 16 deletions(-) create mode 100644 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch 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 index 1b36e9b..92c451e 100644 --- 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 @@ -41,7 +41,7 @@ index 5c10bcedc6..1fd7a273b5 100644 result = BytesIO() xmlgen = XMLGenerator(result) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 25c084c8b9..e26e6e0c26 100644 +index 0b343cc4bb..145ecacd21 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1573,9 +1573,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): 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 new file mode 100644 index 0000000..808dac8 --- /dev/null +++ b/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch @@ -0,0 +1,156 @@ +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 38a355a23f..67c19c329e 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -3415,3 +3415,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 2216de509e..a640496f7f 100644 +--- a/Modules/_tkinter.c ++++ b/Modules/_tkinter.c +@@ -3489,6 +3489,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 8475846eef..b3f5eb3a1f 100644 +--- a/Modules/readline.c ++++ b/Modules/readline.c +@@ -1604,6 +1604,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/plan.fmf b/plan.fmf index 2253feb..f904b17 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,19 +24,18 @@ 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 -i test_margin_is_sufficient' ./parallel.sh" + test: "VERSION=${pybasever} X='-i test_check_probes' ./parallel.sh" - name: debugtest path: /selftest # test_base_interpreter: https://github.com/python/cpython/issues/131372 - # test_margin_is_sufficient: https://github.com/python/cpython/issues/140222 - test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_base_interpreter -i test_margin_is_sufficient' ./parallel.sh" + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_base_interpreter' ./parallel.sh" - name: freethreadingtest path: /selftest - test: "VERSION=${pybasever}t X='-i test_check_probes -i test_base_interpreter -i test_margin_is_sufficient' ./parallel.sh" + 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 -i test_margin_is_sufficient' ./parallel.sh" + 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 diff --git a/python3.14.spec b/python3.14.spec index 1a46e39..ed07de8 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,11 +45,11 @@ 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}.2 +%global general_version %{pybasever}.3 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -416,6 +416,22 @@ Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch # which is tested as working. Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch +# 00477 # f9f53e560d161531a0c3476c08ee26b89a628bde +# 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. +Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1472,8 +1488,6 @@ CheckPython() { # 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_margin_is_sufficient - # reported in https://github.com/python/cpython/issues/140222 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1482,7 +1496,6 @@ CheckPython() { --timeout=2700 \ %endif -i test_check_probes \ - -i test_margin_is_sufficient \ echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1972,6 +1985,9 @@ CheckPython freethreading # ====================================================== %changelog +* Wed Feb 04 2026 Karolina Surma - 3.14.3-1 +- Update to Python 3.14.3 + * Sat Jan 17 2026 Fedora Release Engineering - 3.14.2-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild diff --git a/sources b/sources index 8cead99..052ef5a 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.2.tar.xz) = 165256b4c713e0262767cd7a2c65622f3f086423524646a39bfa64912376be9e5b70863d5a3c95224b516152d0b79e7ccbfe2f2cf35b809d132f2c38ebb3ab3b -SHA512 (Python-3.14.2-aarch64-debug-jit_stencils.h) = c4d14860576768e24d15b9b1c8fbb9878403710126188e39265726fefcfe7336339bc863320a79b535516669101e7486051f37c0e797857adbc60073ed340ac1 -SHA512 (Python-3.14.2-aarch64-optimized-jit_stencils.h) = 64a23be3f2bd1e45b487d9e9e9010c3caa08ca2102d733ab54031c6fca5bcd6881b34ce9c6cc3cab58fd640f7b3af24d32ac828ee1fd3f44edbc276c98dd1596 -SHA512 (Python-3.14.2-x86_64-debug-jit_stencils.h) = 25e9a7e5867fa4c91d95c82dc63aeea19072a82a1bffe402554cf4abf7569c7510ab72815bb1c9ff7a4303192d65082f6d97bb5a334968ee7c06a360d9dac2cd -SHA512 (Python-3.14.2-x86_64-optimized-jit_stencils.h) = 52182daa5c50c60cc649a391a80f27e69e0eb86b5327c15a0af37657095e3e72916290106bd7dc640d5c5fdb71ad8c492a24ba4fa73411fd0b4ed248c75d3a81 +SHA512 (Python-3.14.3.tar.xz) = 9fd875f7a1d96d64e7150913ef38b72b0aeecfcbc24ba46967e57b6495146b0cba6b940c273561fc4d656b6d0ce2e23ffb7bd32bcd0b61fd59a6d90585998c07 +SHA512 (Python-3.14.3-aarch64-debug-jit_stencils.h) = 31cd37ee2c788e63867deb3cc40d34be3100a191dbc42a41c30b1de5e23c5dff2aa27e6927baaf2d0a220f32079c5c650b10f72d79939975845c3977508fd4b1 +SHA512 (Python-3.14.3-aarch64-optimized-jit_stencils.h) = 504af12fda768c819954367ccb3cdd5af45a473bd311d1b884ef54263248c036cd6722dada013bc060231274c9bfaa20c65958cf4f546e363fe0a8b9ec0e4a93 +SHA512 (Python-3.14.3-x86_64-debug-jit_stencils.h) = 0a4a5ba7a48177c0ee66f9eb5215b0287a28d7b0c1943d6a2590921f5e12507eea041f43985c4321d6bf9a2573f70d94c15ef5fee0df2227af1fd45f09409552 +SHA512 (Python-3.14.3-x86_64-optimized-jit_stencils.h) = f9e126f66a8c7650ea26c92e4190dee613c5b899dd231ee8d43173e040f29a217d0298675f7ec75df37da340b39af9fc21a7e1711722876ad5830e52b517baea From aaf6ec2cca44f9bf9fb7245f23c640bd3b0e0b7f Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 9 Feb 2026 10:10:54 +0100 Subject: [PATCH 66/88] Fix CVE-2025-15366, CVE-2025-15367 --- 00474-cve-2025-15366.patch | 59 ++++++++++++++++++++++++++++++++++++++ 00475-cve-2025-15367.patch | 59 ++++++++++++++++++++++++++++++++++++++ python3.14.spec | 13 +++++++++ 3 files changed, 131 insertions(+) create mode 100644 00474-cve-2025-15366.patch create mode 100644 00475-cve-2025-15367.patch diff --git a/00474-cve-2025-15366.patch b/00474-cve-2025-15366.patch new file mode 100644 index 0000000..985adbb --- /dev/null +++ b/00474-cve-2025-15366.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Tue, 20 Jan 2026 14:45:42 -0600 +Subject: 00474: CVE-2025-15366 + +Downstream only: Reject control characters in IMAP commands +--- + Lib/imaplib.py | 4 +++- + Lib/test/test_imaplib.py | 6 ++++++ + .../Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 + + 3 files changed, 10 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst + +diff --git a/Lib/imaplib.py b/Lib/imaplib.py +index cbe129b3e7..b9c691aacd 100644 +--- a/Lib/imaplib.py ++++ b/Lib/imaplib.py +@@ -131,7 +131,7 @@ + # We compile these in _mode_xxx. + _Literal = br'.*{(?P\d+)}$' + _Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' +- ++_control_chars = re.compile(b'[\x00-\x1F\x7F]') + + + class IMAP4: +@@ -1108,6 +1108,8 @@ def _command(self, name, *args): + if arg is None: continue + if isinstance(arg, str): + arg = bytes(arg, self._encoding) ++ if _control_chars.search(arg): ++ raise ValueError("Control characters not allowed in commands") + data = data + b' ' + arg + + literal = self.literal +diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py +index a03d7b8bb2..e26400b588 100644 +--- a/Lib/test/test_imaplib.py ++++ b/Lib/test/test_imaplib.py +@@ -663,6 +663,12 @@ def test_unselect(self): + self.assertEqual(data[0], b'Returned to authenticated state. (Success)') + self.assertEqual(client.state, 'AUTH') + ++ def test_control_characters(self): ++ client, _ = self._setup(SimpleIMAPHandler) ++ for c0 in support.control_characters_c0(): ++ with self.assertRaises(ValueError): ++ client.login(f'user{c0}', 'pass') ++ + # property tests + + def test_file_property_should_not_be_accessed(self): +diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +new file mode 100644 +index 0000000000..4e13fe92bc +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +@@ -0,0 +1 @@ ++Reject control characters in IMAP commands. diff --git a/00475-cve-2025-15367.patch b/00475-cve-2025-15367.patch new file mode 100644 index 0000000..71c71c2 --- /dev/null +++ b/00475-cve-2025-15367.patch @@ -0,0 +1,59 @@ +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/python3.14.spec b/python3.14.spec index ed07de8..718fd69 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -416,6 +416,18 @@ Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch # which is tested as working. Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch +# 00474 # 0d9da266d5ecb31d8a417a0a5daa251a2d99389f +# CVE-2025-15366 +# +# Downstream only: Reject control characters in IMAP commands +Patch474: 00474-cve-2025-15366.patch + +# 00475 # 91e12ebfb2a88b265f3764a0d852b6fa53b2386a +# CVE-2025-15367 +# +# Downstream only: Reject control characters in POP3 commands +Patch475: 00475-cve-2025-15367.patch + # 00477 # f9f53e560d161531a0c3476c08ee26b89a628bde # Raise an error when importing stdlib modules compiled for a different Python version # @@ -1987,6 +1999,7 @@ CheckPython freethreading %changelog * 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 From ca8cc60bc459e379e0229eb770b8d51272e3160f Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Thu, 26 Mar 2026 09:12:33 +0100 Subject: [PATCH 67/88] Security fix for CVE-2026-4519 (rhbz#2449730) --- 00478-cve-2026-4519.patch | 114 ++++++++++++++++++++++++++++++++++++++ python3.14.spec | 11 +++- 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 00478-cve-2026-4519.patch diff --git a/00478-cve-2026-4519.patch b/00478-cve-2026-4519.patch new file mode 100644 index 0000000..ca5603c --- /dev/null +++ b/00478-cve-2026-4519.patch @@ -0,0 +1,114 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Tue, 24 Mar 2026 00:16:27 +0100 +Subject: 00478: CVE-2026-4519 + +Reject leading dashes in webbrowser URLs (GH-146214) + +(cherry picked from commit 82a24a4442312bdcfc4c799885e8b3e00990f02b) + +Co-authored-by: Seth Michael Larson +--- + Lib/test/test_webbrowser.py | 5 +++++ + Lib/webbrowser.py | 13 +++++++++++++ + .../2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst | 1 + + 3 files changed, 19 insertions(+) + create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst + +diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py +index 4c3ea1cd8d..22e9d7493a 100644 +--- a/Lib/test/test_webbrowser.py ++++ b/Lib/test/test_webbrowser.py +@@ -67,6 +67,11 @@ def test_open(self): + options=[], + arguments=[URL]) + ++ def test_reject_dash_prefixes(self): ++ browser = self.browser_class(name=CMD_NAME) ++ with self.assertRaises(ValueError): ++ browser.open(f"--key=val {URL}") ++ + + class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase): + +diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py +index f2e2394089..9ead2990e8 100644 +--- a/Lib/webbrowser.py ++++ b/Lib/webbrowser.py +@@ -163,6 +163,12 @@ def open_new(self, url): + def open_new_tab(self, url): + return self.open(url, 2) + ++ @staticmethod ++ def _check_url(url): ++ """Ensures that the URL is safe to pass to subprocesses as a parameter""" ++ if url and url.lstrip().startswith("-"): ++ raise ValueError(f"Invalid URL: {url}") ++ + + class GenericBrowser(BaseBrowser): + """Class for all browsers started with a command +@@ -180,6 +186,7 @@ def __init__(self, name): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + cmdline = [self.name] + [arg.replace("%s", url) + for arg in self.args] + try: +@@ -200,6 +207,7 @@ def open(self, url, new=0, autoraise=True): + cmdline = [self.name] + [arg.replace("%s", url) + for arg in self.args] + sys.audit("webbrowser.open", url) ++ self._check_url(url) + try: + if sys.platform[:3] == 'win': + p = subprocess.Popen(cmdline) +@@ -266,6 +274,7 @@ def _invoke(self, args, remote, autoraise, url=None): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + if new == 0: + action = self.remote_action + elif new == 1: +@@ -357,6 +366,7 @@ class Konqueror(BaseBrowser): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + # XXX Currently I know no way to prevent KFM from opening a new win. + if new == 2: + action = "newTab" +@@ -588,6 +598,7 @@ def register_standard_browsers(): + class WindowsDefault(BaseBrowser): + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + try: + os.startfile(url) + except OSError: +@@ -608,6 +619,7 @@ def __init__(self, name='default'): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + url = url.replace('"', '%22') + if self.name == 'default': + proto, _sep, _rest = url.partition(":") +@@ -664,6 +676,7 @@ def open(self, url, new=0, autoraise=True): + class IOSBrowser(BaseBrowser): + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + # If ctypes isn't available, we can't open a browser + if objc is None: + return False +diff --git a/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst b/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst +new file mode 100644 +index 0000000000..0f27eae99a +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst +@@ -0,0 +1 @@ ++Reject leading dashes in URLs passed to :func:`webbrowser.open` diff --git a/python3.14.spec b/python3.14.spec index 718fd69..30c4dc8 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -444,6 +444,12 @@ Patch475: 00475-cve-2025-15367.patch # direct call to the check function. Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch +# 00478 # d9d794656850591a4e6aeddcf853505aeea08028 +# CVE-2026-4519 +# +# Reject leading dashes in webbrowser URLs (GH-146214) +Patch478: 00478-cve-2026-4519.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1997,6 +2003,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 From cf66620612848516dd5c3e151db575b24450dd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 11 Mar 2026 13:00:14 +0100 Subject: [PATCH 68/88] Remove a no longer needed workaround https://github.com/python/cpython/issues/98782 was fixed in 3.12.0a6+ (cherry picked from python3.15 commit 8b2d02a1ede90cfe0392a79a4e65d5a9240b14ee) --- python3.14.spec | 6 ------ 1 file changed, 6 deletions(-) diff --git a/python3.14.spec b/python3.14.spec index 30c4dc8..63ec457 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1189,12 +1189,6 @@ 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), From fee84f7c5582a0f89a5ec954d3d6c34b9f4418de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 11 Mar 2026 19:39:18 +0100 Subject: [PATCH 69/88] Only explicitly require expat >= installed version when expat < 2.7.4 See https://src.fedoraproject.org/rpms/expat/c/4da0543472 (cherry picked from python3.15 commit ce1bde3e67443b7cf5df33bf58cb2ec75cc2c8e2) --- python3.14.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python3.14.spec b/python3.14.spec index 63ec457..d583e06 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -642,8 +642,12 @@ Requires: tzdata # We avoid this problem by requiring at least the same version of expat that # was used during the build time. # 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}' 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 @@ -842,7 +846,9 @@ 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 From e9c5c0c3c4338aab92d74a75f85510ecccfc4f98 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 8 Apr 2026 13:03:09 +0200 Subject: [PATCH 70/88] Update to Python 3.14.4 --- 00251-change-user-install-location.patch | 8 +- ...not-working-with-older-expat-version.patch | 4 +- ...piled-for-a-different-python-version.patch | 2 +- 00478-cve-2026-4519.patch | 114 ------------------ python3.14.spec | 25 ++-- sources | 10 +- 6 files changed, 23 insertions(+), 140 deletions(-) delete mode 100644 00478-cve-2026-4519.patch diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 41995c3..b35197d 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -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 2ecbff222f..7211773bad 100644 +index faf8273bd0..d7667bbc77 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -106,6 +106,12 @@ @@ -130,7 +130,7 @@ index 2ecbff222f..7211773bad 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 09eff11179..c227815ebd 100644 +index 1fe4b6849f..e0cb3ec23a 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 09eff11179..c227815ebd 100644 os.path.normpath(expected), ) -@@ -395,7 +406,7 @@ def test_get_config_h_filename(self): +@@ -397,7 +408,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 09eff11179..c227815ebd 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -407,6 +418,8 @@ def test_symlink(self): # Issue 7880 +@@ -409,6 +420,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/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 index 92c451e..ce1c39d 100644 --- 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 @@ -15,10 +15,10 @@ which is tested as working. 3 files changed, 10 insertions(+) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index daeaa38a3c..b243f1da14 100644 +index 465f65a03b..3379ab8aa9 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py -@@ -847,6 +847,8 @@ def start_element(name, _): +@@ -905,6 +905,8 @@ def start_element(name, _): self.assertEqual(started, ['doc']) 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 index 808dac8..5fd303c 100644 --- 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 @@ -81,7 +81,7 @@ index 2a17c891dd..64017c666c 100644 } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in -index 38a355a23f..67c19c329e 100644 +index 80a1b590c2..f28f562930 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -3415,3 +3415,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h diff --git a/00478-cve-2026-4519.patch b/00478-cve-2026-4519.patch deleted file mode 100644 index ca5603c..0000000 --- a/00478-cve-2026-4519.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Tue, 24 Mar 2026 00:16:27 +0100 -Subject: 00478: CVE-2026-4519 - -Reject leading dashes in webbrowser URLs (GH-146214) - -(cherry picked from commit 82a24a4442312bdcfc4c799885e8b3e00990f02b) - -Co-authored-by: Seth Michael Larson ---- - Lib/test/test_webbrowser.py | 5 +++++ - Lib/webbrowser.py | 13 +++++++++++++ - .../2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst | 1 + - 3 files changed, 19 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst - -diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py -index 4c3ea1cd8d..22e9d7493a 100644 ---- a/Lib/test/test_webbrowser.py -+++ b/Lib/test/test_webbrowser.py -@@ -67,6 +67,11 @@ def test_open(self): - options=[], - arguments=[URL]) - -+ def test_reject_dash_prefixes(self): -+ browser = self.browser_class(name=CMD_NAME) -+ with self.assertRaises(ValueError): -+ browser.open(f"--key=val {URL}") -+ - - class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase): - -diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py -index f2e2394089..9ead2990e8 100644 ---- a/Lib/webbrowser.py -+++ b/Lib/webbrowser.py -@@ -163,6 +163,12 @@ def open_new(self, url): - def open_new_tab(self, url): - return self.open(url, 2) - -+ @staticmethod -+ def _check_url(url): -+ """Ensures that the URL is safe to pass to subprocesses as a parameter""" -+ if url and url.lstrip().startswith("-"): -+ raise ValueError(f"Invalid URL: {url}") -+ - - class GenericBrowser(BaseBrowser): - """Class for all browsers started with a command -@@ -180,6 +186,7 @@ def __init__(self, name): - - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -+ self._check_url(url) - cmdline = [self.name] + [arg.replace("%s", url) - for arg in self.args] - try: -@@ -200,6 +207,7 @@ def open(self, url, new=0, autoraise=True): - cmdline = [self.name] + [arg.replace("%s", url) - for arg in self.args] - sys.audit("webbrowser.open", url) -+ self._check_url(url) - try: - if sys.platform[:3] == 'win': - p = subprocess.Popen(cmdline) -@@ -266,6 +274,7 @@ def _invoke(self, args, remote, autoraise, url=None): - - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -+ self._check_url(url) - if new == 0: - action = self.remote_action - elif new == 1: -@@ -357,6 +366,7 @@ class Konqueror(BaseBrowser): - - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -+ self._check_url(url) - # XXX Currently I know no way to prevent KFM from opening a new win. - if new == 2: - action = "newTab" -@@ -588,6 +598,7 @@ def register_standard_browsers(): - class WindowsDefault(BaseBrowser): - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -+ self._check_url(url) - try: - os.startfile(url) - except OSError: -@@ -608,6 +619,7 @@ def __init__(self, name='default'): - - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -+ self._check_url(url) - url = url.replace('"', '%22') - if self.name == 'default': - proto, _sep, _rest = url.partition(":") -@@ -664,6 +676,7 @@ def open(self, url, new=0, autoraise=True): - class IOSBrowser(BaseBrowser): - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -+ self._check_url(url) - # If ctypes isn't available, we can't open a browser - if objc is None: - return False -diff --git a/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst b/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst -new file mode 100644 -index 0000000000..0f27eae99a ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst -@@ -0,0 +1 @@ -+Reject leading dashes in URLs passed to :func:`webbrowser.open` diff --git a/python3.14.spec b/python3.14.spec index d583e06..aac4145 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,11 +45,11 @@ 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}.3 +%global general_version %{pybasever}.4 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -112,21 +112,21 @@ 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 25.3 +%global pip_version 26.0.1 %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.3 -Provides: bundled(python3dist(certifi)) = 2025.10.5 +Provides: bundled(python3dist(cachecontrol)) = 0.14.4 +Provides: bundled(python3dist(certifi)) = 2026.1.4 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.10 +Provides: bundled(python3dist(idna)) = 3.11 Provides: bundled(python3dist(msgpack)) = 1.1.2 -Provides: bundled(python3dist(packaging)) = 25 -Provides: bundled(python3dist(platformdirs)) = 4.5 +Provides: bundled(python3dist(packaging)) = 26 +Provides: bundled(python3dist(platformdirs)) = 4.5.1 Provides: bundled(python3dist(pygments)) = 2.19.2 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 Provides: bundled(python3dist(requests)) = 2.32.5 @@ -444,12 +444,6 @@ Patch475: 00475-cve-2025-15367.patch # direct call to the check function. Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch -# 00478 # d9d794656850591a4e6aeddcf853505aeea08028 -# CVE-2026-4519 -# -# Reject leading dashes in webbrowser URLs (GH-146214) -Patch478: 00478-cve-2026-4519.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -2003,6 +1997,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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) diff --git a/sources b/sources index 052ef5a..d2b1483 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.3.tar.xz) = 9fd875f7a1d96d64e7150913ef38b72b0aeecfcbc24ba46967e57b6495146b0cba6b940c273561fc4d656b6d0ce2e23ffb7bd32bcd0b61fd59a6d90585998c07 -SHA512 (Python-3.14.3-aarch64-debug-jit_stencils.h) = 31cd37ee2c788e63867deb3cc40d34be3100a191dbc42a41c30b1de5e23c5dff2aa27e6927baaf2d0a220f32079c5c650b10f72d79939975845c3977508fd4b1 -SHA512 (Python-3.14.3-aarch64-optimized-jit_stencils.h) = 504af12fda768c819954367ccb3cdd5af45a473bd311d1b884ef54263248c036cd6722dada013bc060231274c9bfaa20c65958cf4f546e363fe0a8b9ec0e4a93 -SHA512 (Python-3.14.3-x86_64-debug-jit_stencils.h) = 0a4a5ba7a48177c0ee66f9eb5215b0287a28d7b0c1943d6a2590921f5e12507eea041f43985c4321d6bf9a2573f70d94c15ef5fee0df2227af1fd45f09409552 -SHA512 (Python-3.14.3-x86_64-optimized-jit_stencils.h) = f9e126f66a8c7650ea26c92e4190dee613c5b899dd231ee8d43173e040f29a217d0298675f7ec75df37da340b39af9fc21a7e1711722876ad5830e52b517baea +SHA512 (Python-3.14.4.tar.xz) = 89a7f8b8a31f48d150badb4751df137d47d9014c9c422649a1a55aef5618aa7f0259dd18c151e6804fa8312c6a21544332a9f630ee81150dc00505637e62bb8c +SHA512 (Python-3.14.4-aarch64-debug-jit_stencils.h) = a3dd821a955043a45b03fa03db2492eea9333bf618df17154fe8c6626c5021d992b5bcd3143791526fdbc5ae16381de5a3966477669fa560278527279ba8687e +SHA512 (Python-3.14.4-aarch64-optimized-jit_stencils.h) = ee0d225a555fe340395ebf63e3816fae90be87e9eed12310b130d19149182aafb17d38c3853ada20480b18b1854666523b99de0ab4df196bcef18cde92817a05 +SHA512 (Python-3.14.4-x86_64-debug-jit_stencils.h) = 1e1770b1053e5c1504c3cfc246e970123f05366ff460383a902857f10afdc010d0bccaa1b5d48547c50840c3939ee2e4a6d153a67278a7bd4d5bfe5d16d947b5 +SHA512 (Python-3.14.4-x86_64-optimized-jit_stencils.h) = 6f41b130d47b6489db909bcd922a26f92ad62153bffcbf169c6137362877797c1efe8eca6811628429b599db962e14933fdbb24c4faa25b57e0d873d9124c7fb From 25248beb9951931f104362b9e8e233af7ee6588b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 9 Apr 2026 13:16:25 +0200 Subject: [PATCH 71/88] Explicitly build with OpenSSL 3 for now https://fedoraproject.org/wiki/Changes/OpenSSL40 --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index aac4145..2fa74e6 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -276,7 +276,6 @@ BuildRequires: libzstd-devel BuildRequires: make BuildRequires: mpdecimal-devel BuildRequires: ncurses-devel -BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: readline-devel @@ -289,6 +288,10 @@ 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 From 94e3c06cd790b610ce72697c66293575b1b856e1 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Thu, 16 Apr 2026 03:25:31 +0200 Subject: [PATCH 72/88] Security fixes for CVE-2026-1502, CVE-2026-4786, CVE-2026-5713, CVE-2026-6100 Resolves: rhbz#2457944, rhbz#2458224, rhbz#2458488, rhbz#2458016 --- 00479-cve-2026-1502.patch | 107 +++++++ 00480-cve-2026-4786.patch | 64 +++++ 00481-cve-2026-5713.patch | 587 ++++++++++++++++++++++++++++++++++++++ 00482-cve-2026-6100.patch | 64 +++++ python3.14.spec | 30 +- 5 files changed, 851 insertions(+), 1 deletion(-) create mode 100644 00479-cve-2026-1502.patch create mode 100644 00480-cve-2026-4786.patch create mode 100644 00481-cve-2026-5713.patch create mode 100644 00482-cve-2026-6100.patch diff --git a/00479-cve-2026-1502.patch b/00479-cve-2026-1502.patch new file mode 100644 index 0000000..c820171 --- /dev/null +++ b/00479-cve-2026-1502.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Larson +Date: Fri, 10 Apr 2026 10:21:42 -0500 +Subject: 00479: CVE-2026-1502 + +Reject CR/LF in HTTP tunnel request headers + +Co-authored-by: Illia Volochii +--- + Lib/http/client.py | 11 ++++- + Lib/test/test_httplib.py | 45 +++++++++++++++++++ + ...-03-20-09-29-42.gh-issue-146211.PQVbs7.rst | 2 + + 3 files changed, 57 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst + +diff --git a/Lib/http/client.py b/Lib/http/client.py +index 77f8d26291..6fb7d254ea 100644 +--- a/Lib/http/client.py ++++ b/Lib/http/client.py +@@ -972,13 +972,22 @@ def _wrap_ipv6(self, ip): + return ip + + def _tunnel(self): ++ if _contains_disallowed_url_pchar_re.search(self._tunnel_host): ++ raise ValueError('Tunnel host can\'t contain control characters %r' ++ % (self._tunnel_host,)) + connect = b"CONNECT %s:%d %s\r\n" % ( + self._wrap_ipv6(self._tunnel_host.encode("idna")), + self._tunnel_port, + self._http_vsn_str.encode("ascii")) + headers = [connect] + for header, value in self._tunnel_headers.items(): +- headers.append(f"{header}: {value}\r\n".encode("latin-1")) ++ header_bytes = header.encode("latin-1") ++ value_bytes = value.encode("latin-1") ++ if not _is_legal_header_name(header_bytes): ++ raise ValueError('Invalid header name %r' % (header_bytes,)) ++ if _is_illegal_header_value(value_bytes): ++ raise ValueError('Invalid header value %r' % (value_bytes,)) ++ headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes)) + headers.append(b"\r\n") + # Making a single send() call instead of one per line encourages + # the host OS to use a more optimal packet size instead of +diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py +index bcb828edec..6f3eac6b98 100644 +--- a/Lib/test/test_httplib.py ++++ b/Lib/test/test_httplib.py +@@ -369,6 +369,51 @@ def test_invalid_headers(self): + with self.assertRaisesRegex(ValueError, 'Invalid header'): + conn.putheader(name, value) + ++ def test_invalid_tunnel_headers(self): ++ cases = ( ++ ('Invalid\r\nName', 'ValidValue'), ++ ('Invalid\rName', 'ValidValue'), ++ ('Invalid\nName', 'ValidValue'), ++ ('\r\nInvalidName', 'ValidValue'), ++ ('\rInvalidName', 'ValidValue'), ++ ('\nInvalidName', 'ValidValue'), ++ (' InvalidName', 'ValidValue'), ++ ('\tInvalidName', 'ValidValue'), ++ ('Invalid:Name', 'ValidValue'), ++ (':InvalidName', 'ValidValue'), ++ ('ValidName', 'Invalid\r\nValue'), ++ ('ValidName', 'Invalid\rValue'), ++ ('ValidName', 'Invalid\nValue'), ++ ('ValidName', 'InvalidValue\r\n'), ++ ('ValidName', 'InvalidValue\r'), ++ ('ValidName', 'InvalidValue\n'), ++ ) ++ for name, value in cases: ++ with self.subTest((name, value)): ++ conn = client.HTTPConnection('example.com') ++ conn.set_tunnel('tunnel', headers={ ++ name: value ++ }) ++ conn.sock = FakeSocket('') ++ with self.assertRaisesRegex(ValueError, 'Invalid header'): ++ conn._tunnel() # Called in .connect() ++ ++ def test_invalid_tunnel_host(self): ++ cases = ( ++ 'invalid\r.host', ++ '\ninvalid.host', ++ 'invalid.host\r\n', ++ 'invalid.host\x00', ++ 'invalid host', ++ ) ++ for tunnel_host in cases: ++ with self.subTest(tunnel_host): ++ conn = client.HTTPConnection('example.com') ++ conn.set_tunnel(tunnel_host) ++ conn.sock = FakeSocket('') ++ with self.assertRaisesRegex(ValueError, 'Tunnel host can\'t contain control characters'): ++ conn._tunnel() # Called in .connect() ++ + def test_headers_debuglevel(self): + body = ( + b'HTTP/1.1 200 OK\r\n' +diff --git a/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst b/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst +new file mode 100644 +index 0000000000..4993633b8e +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst +@@ -0,0 +1,2 @@ ++Reject CR/LF characters in tunnel request headers for the ++HTTPConnection.set_tunnel() method. diff --git a/00480-cve-2026-4786.patch b/00480-cve-2026-4786.patch new file mode 100644 index 0000000..1b51d5a --- /dev/null +++ b/00480-cve-2026-4786.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Stan Ulbrych +Date: Mon, 13 Apr 2026 20:02:52 +0100 +Subject: 00480: CVE-2026-4786 + +Fix webbrowser `%action` substitution bypass of dash-prefix check +--- + Lib/test/test_webbrowser.py | 9 +++++++++ + Lib/webbrowser.py | 5 +++-- + .../2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst | 2 ++ + 3 files changed, 14 insertions(+), 2 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst + +diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py +index 404b3a31a5..bfbcf112b0 100644 +--- a/Lib/test/test_webbrowser.py ++++ b/Lib/test/test_webbrowser.py +@@ -119,6 +119,15 @@ def test_open_bad_new_parameter(self): + arguments=[URL], + kw=dict(new=999)) + ++ def test_reject_action_dash_prefixes(self): ++ browser = self.browser_class(name=CMD_NAME) ++ with self.assertRaises(ValueError): ++ browser.open('%action--incognito') ++ # new=1: action is "--new-window", so "%action" itself expands to ++ # a dash-prefixed flag even with no dash in the original URL. ++ with self.assertRaises(ValueError): ++ browser.open('%action', new=1) ++ + + class EdgeCommandTest(CommandTestMixin, unittest.TestCase): + +diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py +index 0e0b5034e5..97aad6eea5 100644 +--- a/Lib/webbrowser.py ++++ b/Lib/webbrowser.py +@@ -274,7 +274,6 @@ def _invoke(self, args, remote, autoraise, url=None): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) +- self._check_url(url) + if new == 0: + action = self.remote_action + elif new == 1: +@@ -288,7 +287,9 @@ def open(self, url, new=0, autoraise=True): + raise Error("Bad 'new' parameter to open(); " + f"expected 0, 1, or 2, got {new}") + +- args = [arg.replace("%s", url).replace("%action", action) ++ self._check_url(url.replace("%action", action)) ++ ++ args = [arg.replace("%action", action).replace("%s", url) + for arg in self.remote_args] + args = [arg for arg in args if arg] + success = self._invoke(args, True, autoraise, url) +diff --git a/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst +new file mode 100644 +index 0000000000..45cdeebe1b +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst +@@ -0,0 +1,2 @@ ++A bypass in :mod:`webbrowser` allowed URLs prefixed with ``%action`` to pass ++the dash-prefix safety check. diff --git a/00481-cve-2026-5713.patch b/00481-cve-2026-5713.patch new file mode 100644 index 0000000..d5b0551 --- /dev/null +++ b/00481-cve-2026-5713.patch @@ -0,0 +1,587 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Pablo Galindo Salgado +Date: Mon, 13 Apr 2026 23:22:23 +0100 +Subject: 00481: CVE-2026-5713 + +Validate remote debug offset tables on load +--- + ...-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst | 2 + + Modules/_remote_debugging_module.c | 509 +++++++++++++++++- + 2 files changed, 505 insertions(+), 6 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst + +diff --git a/Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst b/Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst +new file mode 100644 +index 0000000000..ed138a54a8 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst +@@ -0,0 +1,2 @@ ++Hardened :mod:`!_remote_debugging` by validating remote debug offset tables ++before using them to size memory reads or interpret remote layouts. +diff --git a/Modules/_remote_debugging_module.c b/Modules/_remote_debugging_module.c +index a327772258..d756ac326f 100644 +--- a/Modules/_remote_debugging_module.c ++++ b/Modules/_remote_debugging_module.c +@@ -20,6 +20,7 @@ + #include // FRAME_OWNED_BY_CSTACK + #include // struct llist_node + #include // Py_TAG_BITS ++#include // _PyThreadStateImpl + #include "../Python/remote_debug.h" + + // gh-141784: Python.h header must be included first, before system headers. +@@ -41,9 +42,11 @@ + * TYPE DEFINITIONS AND STRUCTURES + * ============================================================================ */ + +-#define GET_MEMBER(type, obj, offset) (*(type*)((char*)(obj) + (offset))) ++#define GET_MEMBER(type, obj, offset) \ ++ (*(type *)memcpy(&(type){0}, (const char *)(obj) + (offset), sizeof(type))) + #define CLEAR_PTR_TAG(ptr) (((uintptr_t)(ptr) & ~Py_TAG_BITS)) +-#define GET_MEMBER_NO_TAG(type, obj, offset) (type)(CLEAR_PTR_TAG(*(type*)((char*)(obj) + (offset)))) ++#define GET_MEMBER_NO_TAG(type, obj, offset) \ ++ (type)(CLEAR_PTR_TAG(GET_MEMBER(type, obj, offset))) + + /* Size macros for opaque buffers */ + #define SIZEOF_BYTES_OBJ sizeof(PyBytesObject) +@@ -107,6 +110,486 @@ struct _Py_AsyncioModuleDebugOffsets { + } asyncio_thread_state; + }; + ++/* Treat the remote debug tables as untrusted input and validate every ++ * size/offset we later dereference against a fixed local buffer or object ++ * layout before the unwinder starts using them. */ ++#define FIELD_SIZE(type, member) sizeof(((type *)0)->member) ++#define PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS (-2) ++ ++static inline int ++validate_section_size(const char *section_name, uint64_t size) ++{ ++ if (size == 0) { ++ PyErr_Format( ++ PyExc_RuntimeError, ++ "Invalid debug offsets: %s.size must be greater than zero", ++ section_name); ++ return -1; ++ } ++ return 0; ++} ++ ++static inline int ++validate_read_size(const char *section_name, uint64_t size, size_t buffer_size) ++{ ++ if (validate_section_size(section_name, size) < 0) { ++ return -1; ++ } ++ if (size > buffer_size) { ++ PyErr_Format( ++ PyExc_RuntimeError, ++ "Invalid debug offsets: %s.size=%llu exceeds local buffer size %zu", ++ section_name, ++ (unsigned long long)size, ++ buffer_size); ++ return -1; ++ } ++ return 0; ++} ++ ++static inline int ++validate_span( ++ const char *field_name, ++ uint64_t offset, ++ size_t width, ++ uint64_t limit, ++ const char *limit_name) ++{ ++ uint64_t span = (uint64_t)width; ++ if (span > limit || offset > limit - span) { ++ PyErr_Format( ++ PyExc_RuntimeError, ++ "Invalid debug offsets: %s=%llu with width %zu exceeds %s %llu", ++ field_name, ++ (unsigned long long)offset, ++ width, ++ limit_name, ++ (unsigned long long)limit); ++ return -1; ++ } ++ return 0; ++} ++ ++static inline int ++validate_alignment( ++ const char *field_name, ++ uint64_t offset, ++ size_t alignment) ++{ ++ if (alignment > 1 && offset % alignment != 0) { ++ PyErr_Format( ++ PyExc_RuntimeError, ++ "Invalid debug offsets: %s=%llu is not aligned to %zu bytes", ++ field_name, ++ (unsigned long long)offset, ++ alignment); ++ return -1; ++ } ++ return 0; ++} ++ ++static inline int ++validate_field( ++ const char *field_name, ++ uint64_t offset, ++ uint64_t reported_size, ++ size_t width, ++ size_t alignment, ++ size_t buffer_size) ++{ ++ if (validate_alignment(field_name, offset, alignment) < 0) { ++ return -1; ++ } ++ if (validate_span(field_name, offset, width, reported_size, "reported size") < 0) { ++ return -1; ++ } ++ return validate_span(field_name, offset, width, buffer_size, "local buffer size"); ++} ++ ++static inline int ++validate_fixed_field( ++ const char *field_name, ++ uint64_t offset, ++ size_t width, ++ size_t alignment, ++ size_t buffer_size) ++{ ++ if (validate_alignment(field_name, offset, alignment) < 0) { ++ return -1; ++ } ++ return validate_span(field_name, offset, width, buffer_size, "local buffer size"); ++} ++ ++#define PY_REMOTE_DEBUG_VALIDATE_SECTION(section) \ ++ do { \ ++ if (validate_section_size(#section, debug_offsets->section.size) < 0) { \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++#define PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(section, buffer_size) \ ++ do { \ ++ if (validate_read_size(#section, debug_offsets->section.size, buffer_size) < 0) { \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++#define PY_REMOTE_DEBUG_VALIDATE_FIELD(section, field, field_size, field_alignment, buffer_size) \ ++ do { \ ++ if (validate_field( \ ++ #section "." #field, \ ++ debug_offsets->section.field, \ ++ debug_offsets->section.size, \ ++ field_size, \ ++ field_alignment, \ ++ buffer_size) < 0) { \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++#define PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD(section, field, field_size, field_alignment, buffer_size) \ ++ do { \ ++ if (validate_fixed_field( \ ++ #section "." #field, \ ++ debug_offsets->section.field, \ ++ field_size, \ ++ field_alignment, \ ++ buffer_size) < 0) { \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++static inline int ++validate_debug_offsets_layout(struct _Py_DebugOffsets *debug_offsets) ++{ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(runtime_state); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ runtime_state, ++ interpreters_head, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ sizeof(_PyRuntimeState)); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(interpreter_state); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_state, ++ threads_head, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ INTERP_STATE_BUFFER_SIZE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_state, ++ threads_main, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ INTERP_STATE_BUFFER_SIZE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_state, ++ gil_runtime_state_locked, ++ sizeof(int), ++ _Alignof(int), ++ INTERP_STATE_BUFFER_SIZE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_state, ++ gil_runtime_state_holder, ++ sizeof(PyThreadState *), ++ _Alignof(PyThreadState *), ++ INTERP_STATE_BUFFER_SIZE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_state, ++ code_object_generation, ++ sizeof(uint64_t), ++ _Alignof(uint64_t), ++ INTERP_STATE_BUFFER_SIZE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_state, ++ tlbc_generation, ++ sizeof(uint32_t), ++ _Alignof(uint32_t), ++ INTERP_STATE_BUFFER_SIZE); ++ ++ PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(thread_state, SIZEOF_THREAD_STATE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ thread_state, ++ next, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_THREAD_STATE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ thread_state, ++ current_frame, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_THREAD_STATE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ thread_state, ++ native_thread_id, ++ sizeof(unsigned long), ++ _Alignof(unsigned long), ++ SIZEOF_THREAD_STATE); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ thread_state, ++ datastack_chunk, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_THREAD_STATE); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(interpreter_frame); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_frame, ++ previous, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_INTERP_FRAME); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_frame, ++ executable, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_INTERP_FRAME); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_frame, ++ instr_ptr, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_INTERP_FRAME); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_frame, ++ owner, ++ sizeof(char), ++ _Alignof(char), ++ SIZEOF_INTERP_FRAME); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_frame, ++ stackpointer, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_INTERP_FRAME); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ interpreter_frame, ++ tlbc_index, ++ sizeof(int32_t), ++ _Alignof(int32_t), ++ SIZEOF_INTERP_FRAME); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(code_object); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ code_object, ++ qualname, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_CODE_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ code_object, ++ filename, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_CODE_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ code_object, ++ linetable, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_CODE_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ code_object, ++ firstlineno, ++ sizeof(int), ++ _Alignof(int), ++ SIZEOF_CODE_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ code_object, ++ co_code_adaptive, ++ sizeof(char), ++ _Alignof(char), ++ SIZEOF_CODE_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ code_object, ++ co_tlbc, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_CODE_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(pyobject); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ pyobject, ++ ob_type, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_PYOBJECT); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(type_object); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ type_object, ++ tp_flags, ++ sizeof(unsigned long), ++ _Alignof(unsigned long), ++ SIZEOF_TYPE_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(set_object); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ set_object, ++ used, ++ sizeof(Py_ssize_t), ++ _Alignof(Py_ssize_t), ++ SIZEOF_SET_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ set_object, ++ mask, ++ sizeof(Py_ssize_t), ++ _Alignof(Py_ssize_t), ++ SIZEOF_SET_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ set_object, ++ table, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_SET_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(long_object, SIZEOF_LONG_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ long_object, ++ lv_tag, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_LONG_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ long_object, ++ ob_digit, ++ sizeof(digit), ++ _Alignof(digit), ++ SIZEOF_LONG_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(bytes_object); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ bytes_object, ++ ob_size, ++ sizeof(Py_ssize_t), ++ _Alignof(Py_ssize_t), ++ SIZEOF_BYTES_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ bytes_object, ++ ob_sval, ++ sizeof(char), ++ _Alignof(char), ++ SIZEOF_BYTES_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(unicode_object); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ unicode_object, ++ length, ++ sizeof(Py_ssize_t), ++ _Alignof(Py_ssize_t), ++ SIZEOF_UNICODE_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ unicode_object, ++ asciiobject_size, ++ sizeof(char), ++ _Alignof(char), ++ SIZEOF_UNICODE_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(gen_object); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ gen_object, ++ gi_frame_state, ++ sizeof(int8_t), ++ _Alignof(int8_t), ++ SIZEOF_GEN_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ gen_object, ++ gi_iframe, ++ FIELD_SIZE(PyGenObject, gi_iframe), ++ _Alignof(_PyInterpreterFrame), ++ SIZEOF_GEN_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD( ++ llist_node, ++ next, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_LLIST_NODE); ++ ++ return 0; ++} ++ ++static inline int ++validate_async_debug_offsets_layout(struct _Py_AsyncioModuleDebugOffsets *debug_offsets) ++{ ++ PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(asyncio_task_object, SIZEOF_TASK_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_task_object, ++ task_name, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_TASK_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_task_object, ++ task_awaited_by, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_TASK_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_task_object, ++ task_is_task, ++ sizeof(char), ++ _Alignof(char), ++ SIZEOF_TASK_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_task_object, ++ task_awaited_by_is_set, ++ sizeof(char), ++ _Alignof(char), ++ SIZEOF_TASK_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_task_object, ++ task_coro, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ SIZEOF_TASK_OBJ); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_task_object, ++ task_node, ++ SIZEOF_LLIST_NODE, ++ _Alignof(struct llist_node), ++ SIZEOF_TASK_OBJ); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(asyncio_interpreter_state); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_interpreter_state, ++ asyncio_tasks_head, ++ SIZEOF_LLIST_NODE, ++ _Alignof(struct llist_node), ++ sizeof(PyInterpreterState)); ++ ++ PY_REMOTE_DEBUG_VALIDATE_SECTION(asyncio_thread_state); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_thread_state, ++ asyncio_running_loop, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ sizeof(_PyThreadStateImpl)); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_thread_state, ++ asyncio_running_task, ++ sizeof(uintptr_t), ++ _Alignof(uintptr_t), ++ sizeof(_PyThreadStateImpl)); ++ PY_REMOTE_DEBUG_VALIDATE_FIELD( ++ asyncio_thread_state, ++ asyncio_tasks_head, ++ SIZEOF_LLIST_NODE, ++ _Alignof(struct llist_node), ++ sizeof(_PyThreadStateImpl)); ++ ++ return 0; ++} ++ ++#undef PY_REMOTE_DEBUG_VALIDATE_SECTION ++#undef PY_REMOTE_DEBUG_VALIDATE_READ_SECTION ++#undef PY_REMOTE_DEBUG_VALIDATE_FIELD ++#undef PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD ++#undef FIELD_SIZE ++ + /* ============================================================================ + * STRUCTSEQ TYPE DEFINITIONS + * ============================================================================ */ +@@ -434,7 +917,7 @@ validate_debug_offsets(struct _Py_DebugOffsets *debug_offsets) + return -1; + } + +- return 0; ++ return validate_debug_offsets_layout(debug_offsets); + } + + // Generic function to iterate through all threads +@@ -877,8 +1360,13 @@ read_async_debug( + int result = _Py_RemoteDebug_PagedReadRemoteMemory(&unwinder->handle, async_debug_addr, size, &unwinder->async_debug_offsets); + if (result < 0) { + set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read AsyncioDebug offsets"); ++ return result; + } +- return result; ++ if (validate_async_debug_offsets_layout(&unwinder->async_debug_offsets) < 0) { ++ set_exception_cause(unwinder, PyExc_RuntimeError, "Invalid AsyncioDebug offsets"); ++ return PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS; ++ } ++ return 0; + } + + /* ============================================================================ +@@ -2054,10 +2542,15 @@ static void * + find_frame_in_chunks(StackChunkList *chunks, uintptr_t remote_ptr) + { + for (size_t i = 0; i < chunks->count; ++i) { ++ if (chunks->chunks[i].size <= offsetof(_PyStackChunk, data)) { ++ continue; ++ } + uintptr_t base = chunks->chunks[i].remote_addr + offsetof(_PyStackChunk, data); + size_t payload = chunks->chunks[i].size - offsetof(_PyStackChunk, data); + +- if (remote_ptr >= base && remote_ptr < base + payload) { ++ if (payload >= SIZEOF_INTERP_FRAME && ++ remote_ptr >= base && ++ remote_ptr <= base + payload - SIZEOF_INTERP_FRAME) { + return (char *)chunks->chunks[i].local_copy + (remote_ptr - chunks->chunks[i].remote_addr); + } + } +@@ -2624,7 +3117,11 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self, + + // Try to read async debug offsets, but don't fail if they're not available + self->async_debug_offsets_available = 1; +- if (read_async_debug(self) < 0) { ++ int async_debug_result = read_async_debug(self); ++ if (async_debug_result == PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS) { ++ return -1; ++ } ++ if (async_debug_result < 0) { + PyErr_Clear(); + memset(&self->async_debug_offsets, 0, sizeof(self->async_debug_offsets)); + self->async_debug_offsets_available = 0; diff --git a/00482-cve-2026-6100.patch b/00482-cve-2026-6100.patch new file mode 100644 index 0000000..0c42470 --- /dev/null +++ b/00482-cve-2026-6100.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Mon, 13 Apr 2026 03:40:54 +0200 +Subject: 00482: CVE-2026-6100 + +Fix a possible UAF in {LZMA,BZ2,_Zlib}Decompressor + +Co-authored-by: Stan Ulbrych +--- + .../Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst | 5 +++++ + Modules/_bz2module.c | 1 + + Modules/_lzmamodule.c | 1 + + Modules/zlibmodule.c | 1 + + 4 files changed, 8 insertions(+) + create mode 100644 Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst + +diff --git a/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst b/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst +new file mode 100644 +index 0000000000..9502189ab1 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst +@@ -0,0 +1,5 @@ ++Fix a dangling input pointer in :class:`lzma.LZMADecompressor`, ++:class:`bz2.BZ2Decompressor`, and internal :class:`!zlib._ZlibDecompressor` ++when memory allocation fails with :exc:`MemoryError`, which could let a ++subsequent :meth:`!decompress` call read or write through a stale pointer to ++the already-released caller buffer. +diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c +index 9e85e0de42..055ce82e7d 100644 +--- a/Modules/_bz2module.c ++++ b/Modules/_bz2module.c +@@ -593,6 +593,7 @@ decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length) + return result; + + error: ++ bzs->next_in = NULL; + Py_XDECREF(result); + return NULL; + } +diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c +index 462c2181fa..6785dc5673 100644 +--- a/Modules/_lzmamodule.c ++++ b/Modules/_lzmamodule.c +@@ -1120,6 +1120,7 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) + return result; + + error: ++ lzs->next_in = NULL; + Py_XDECREF(result); + return NULL; + } +diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c +index 5b6b0c5cac..a86aa5fdbb 100644 +--- a/Modules/zlibmodule.c ++++ b/Modules/zlibmodule.c +@@ -1675,6 +1675,7 @@ decompress(ZlibDecompressor *self, uint8_t *data, + return result; + + error: ++ self->zst.next_in = NULL; + Py_XDECREF(result); + return NULL; + } diff --git a/python3.14.spec b/python3.14.spec index 2fa74e6..98548a3 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -447,6 +447,30 @@ Patch475: 00475-cve-2025-15367.patch # direct call to the check function. Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch +# 00479 # 97404b2cf62e545c2d41be7ccfed4e74da9ee665 +# CVE-2026-1502 +# +# Reject CR/LF in HTTP tunnel request headers +Patch479: 00479-cve-2026-1502.patch + +# 00480 # 858691f36890b33e713f330d24c6670329695c2e +# CVE-2026-4786 +# +# Fix webbrowser `%%action` substitution bypass of dash-prefix check +Patch480: 00480-cve-2026-4786.patch + +# 00481 # 4c1fd39918651c4559a4835d42b86639a192c2c5 +# CVE-2026-5713 +# +# Validate remote debug offset tables on load +Patch481: 00481-cve-2026-5713.patch + +# 00482 # 69f14bc306fc62400d45565faa980b77858b9151 +# CVE-2026-6100 +# +# Fix a possible UAF in {LZMA,BZ2,_Zlib}Decompressor +Patch482: 00482-cve-2026-6100.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -2000,6 +2024,10 @@ CheckPython freethreading # ====================================================== %changelog +* 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 From f45779a0aa4f74356165fe69e9a71b4990f9ab58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 14 Apr 2026 14:08:05 +0200 Subject: [PATCH 73/88] When comparing the pre-built JIT stencils for identity, exclude the checksum When autoconf was updated from 2.72 to 2.73, we observed a change in the checksum: + diff -u /builddir/build/SOURCES/Python-3.15.0a7-x86_64-debug-jit_stencils.h build/debug/jit_stencils-x86_64-unknown-linux-gnu.h --- /builddir/build/SOURCES/Python-3.15.0a7-x86_64-debug-jit_stencils.h 2026-03-10 00:00:00.000000000 +0000 +++ build/debug/jit_stencils-x86_64-unknown-linux-gnu.h 2026-03-31 21:12:53.391262973 +0000 @@ -1,4 +1,4 @@ -// 5e1dc452d67c20147c4ea13e692c2d3e7b0b47b24f8847354c58988c7ffa02bc +// c783e3946f774d4d83e8fdcca35678ec77006e1b96b12661fcbd3ee680d10e94 // $ python3.14 /builddir/build/BUILD/python3.14-3.15.0_a7-build/Python-3.15.0a7/Tools/jit/build.py x86_64-redhat-linux-gnu --output-dir . --pyconfig-dir . --cflags= --llvm-version= --debug void error: Bad exit status from /var/tmp/rpm-tmp.G15BYi (%check) The autoconf-generated pyconfig.h file is part of the checksum input: https://github.com/python/cpython/blob/v3.15.0a8/Tools/jit/_targets.py#L75 Generally, the reason for this checksum is to prevent outdated JIT stencils when Python is re-configured with different options (or when the stencils generation code is updated). As suspected, the change in checksum was caused by a change in pyconfig.h: --- pyconfig.h +++ pyconfig.h @@ -1882,6 +1882,10 @@ #ifndef _ALL_SOURCE # define _ALL_SOURCE 1 #endif +/* Enable extensions on Cosmopolitan Libc. */ +#ifndef _COSMO_SOURCE +# define _COSMO_SOURCE 1 +#endif /* Enable general extensions on macOS. */ #ifndef _DARWIN_C_SOURCE # define _DARWIN_C_SOURCE 1 This is expected, see https://cgit.git.savannah.gnu.org/cgit/autoconf.git/tree/NEWS?h=v2.73#n99 tl;dr when a new autoconf version changes the output of pyconfig.h, the checksum changes as well. We cannot update the pre-built stencils with the new checksum because that would make the build fail with older autoconf. Instead, we ignore the checksum in this check. We care for the contents, not checksums. Cherry-picked from python3.15 commit aab847c347b141083dbfbcf33fb38fb286dc2f62 --- python3.14.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index 98548a3..62c8a57 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -1498,7 +1498,8 @@ done %if %{with jit_build_stencils} for ConfName in %{?with_debug_build:debug} optimized; do if [ -s %{jit_stencils_source} ]; then - diff -u %{jit_stencils_source} build/${ConfName}/%{jit_stencils_filename} + # 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 From 9025dc97608c7a6896a947ddc94384e133090360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 17 Apr 2026 09:29:26 +0200 Subject: [PATCH 74/88] Fixup using prebuilt JIT on ELN See f45779a0aa4f74356165fe69e9a71b4990f9ab58 for context. After autoconf 2.73 landed in Fedora ELN, the pre-built JIT stencils were rejected because of checksum mismatch. This new patch adds an ability to circumvent that check. It has been offered upstream in https://github.com/python/cpython/issues/148646 https://github.com/python/cpython/pull/148647 While this has yet to be finalized upstream and might take a while, we need to fix the ELN build right away. (When we build the stencils on rawhide for the next release, the problem will shift from ELN with new autoconf to old Fedoras with old autoconf.) Cherry-picked from python3.15 commit 4a1f3dae4f24af60227469c76acf9452f02c90dd --- ...prebuilt-jit-stencils-configure-flag.patch | 146 ++++++++++++++++++ python3.14.spec | 6 +- 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch 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 new file mode 100644 index 0000000..7fdfd52 --- /dev/null +++ b/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch @@ -0,0 +1,146 @@ +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 8cfdda5a29..e3f51f1f86 100755 +--- a/configure ++++ b/configure +@@ -1104,6 +1104,7 @@ with_strict_overflow + enable_safety + enable_slower_safety + enable_experimental_jit ++enable_prebuilt_jit_stencils + with_dsymutil + with_address_sanitizer + with_memory_sanitizer +@@ -1841,6 +1842,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) +@@ -10932,6 +10936,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 1acb91fd27..462152c656 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2800,6 +2800,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/python3.14.spec b/python3.14.spec index 62c8a57..84fa23c 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -87,7 +87,7 @@ License: Python-2.0.1 %bcond jit_build_stencils %[%{with jit} && 0%{?fedora} >= 41] %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 +%global jit_flag --enable-experimental-jit=yes-off %{!?with_jit_build_stencils:--enable-prebuilt-jit-stencils} %endif # Main interpreter loop optimization @@ -471,6 +471,10 @@ Patch481: 00481-cve-2026-5713.patch # Fix a possible UAF in {LZMA,BZ2,_Zlib}Decompressor Patch482: 00482-cve-2026-6100.patch +# 00486 # 5ae0b81b3135319f8d75a886fb7a11fa40ac11f4 +# gh-148646: Add --enable-prebuilt-jit-stencils configure flag +Patch486: 00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., From b04f319cc685fc8d26243b3293ad8915fb1a5451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 5 May 2026 20:15:49 +0200 Subject: [PATCH 75/88] Update to 3.14.5rc1 Patches 479, 480, 482 merged upstream. --- ...not-working-with-older-expat-version.patch | 2 +- ...piled-for-a-different-python-version.patch | 4 +- 00479-cve-2026-1502.patch | 107 ------------------ 00480-cve-2026-4786.patch | 64 ----------- 00482-cve-2026-6100.patch | 64 ----------- ...prebuilt-jit-stencils-configure-flag.patch | 12 +- python3.14.spec | 40 ++----- sources | 10 +- 8 files changed, 26 insertions(+), 277 deletions(-) delete mode 100644 00479-cve-2026-1502.patch delete mode 100644 00480-cve-2026-4786.patch delete mode 100644 00482-cve-2026-6100.patch 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 index ce1c39d..3897b71 100644 --- 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 @@ -41,7 +41,7 @@ index 5c10bcedc6..1fd7a273b5 100644 result = BytesIO() xmlgen = XMLGenerator(result) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 0b343cc4bb..145ecacd21 100644 +index 1bd0fde844..f87134c11e 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1573,9 +1573,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): 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 index 5fd303c..e8f69ae 100644 --- 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 @@ -81,10 +81,10 @@ index 2a17c891dd..64017c666c 100644 } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in -index 80a1b590c2..f28f562930 100644 +index da6d7c3315..92a6825b5e 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -3415,3 +3415,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h +@@ -3420,3 +3420,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h # Local Variables: # mode: makefile # End: diff --git a/00479-cve-2026-1502.patch b/00479-cve-2026-1502.patch deleted file mode 100644 index c820171..0000000 --- a/00479-cve-2026-1502.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Seth Larson -Date: Fri, 10 Apr 2026 10:21:42 -0500 -Subject: 00479: CVE-2026-1502 - -Reject CR/LF in HTTP tunnel request headers - -Co-authored-by: Illia Volochii ---- - Lib/http/client.py | 11 ++++- - Lib/test/test_httplib.py | 45 +++++++++++++++++++ - ...-03-20-09-29-42.gh-issue-146211.PQVbs7.rst | 2 + - 3 files changed, 57 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst - -diff --git a/Lib/http/client.py b/Lib/http/client.py -index 77f8d26291..6fb7d254ea 100644 ---- a/Lib/http/client.py -+++ b/Lib/http/client.py -@@ -972,13 +972,22 @@ def _wrap_ipv6(self, ip): - return ip - - def _tunnel(self): -+ if _contains_disallowed_url_pchar_re.search(self._tunnel_host): -+ raise ValueError('Tunnel host can\'t contain control characters %r' -+ % (self._tunnel_host,)) - connect = b"CONNECT %s:%d %s\r\n" % ( - self._wrap_ipv6(self._tunnel_host.encode("idna")), - self._tunnel_port, - self._http_vsn_str.encode("ascii")) - headers = [connect] - for header, value in self._tunnel_headers.items(): -- headers.append(f"{header}: {value}\r\n".encode("latin-1")) -+ header_bytes = header.encode("latin-1") -+ value_bytes = value.encode("latin-1") -+ if not _is_legal_header_name(header_bytes): -+ raise ValueError('Invalid header name %r' % (header_bytes,)) -+ if _is_illegal_header_value(value_bytes): -+ raise ValueError('Invalid header value %r' % (value_bytes,)) -+ headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes)) - headers.append(b"\r\n") - # Making a single send() call instead of one per line encourages - # the host OS to use a more optimal packet size instead of -diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py -index bcb828edec..6f3eac6b98 100644 ---- a/Lib/test/test_httplib.py -+++ b/Lib/test/test_httplib.py -@@ -369,6 +369,51 @@ def test_invalid_headers(self): - with self.assertRaisesRegex(ValueError, 'Invalid header'): - conn.putheader(name, value) - -+ def test_invalid_tunnel_headers(self): -+ cases = ( -+ ('Invalid\r\nName', 'ValidValue'), -+ ('Invalid\rName', 'ValidValue'), -+ ('Invalid\nName', 'ValidValue'), -+ ('\r\nInvalidName', 'ValidValue'), -+ ('\rInvalidName', 'ValidValue'), -+ ('\nInvalidName', 'ValidValue'), -+ (' InvalidName', 'ValidValue'), -+ ('\tInvalidName', 'ValidValue'), -+ ('Invalid:Name', 'ValidValue'), -+ (':InvalidName', 'ValidValue'), -+ ('ValidName', 'Invalid\r\nValue'), -+ ('ValidName', 'Invalid\rValue'), -+ ('ValidName', 'Invalid\nValue'), -+ ('ValidName', 'InvalidValue\r\n'), -+ ('ValidName', 'InvalidValue\r'), -+ ('ValidName', 'InvalidValue\n'), -+ ) -+ for name, value in cases: -+ with self.subTest((name, value)): -+ conn = client.HTTPConnection('example.com') -+ conn.set_tunnel('tunnel', headers={ -+ name: value -+ }) -+ conn.sock = FakeSocket('') -+ with self.assertRaisesRegex(ValueError, 'Invalid header'): -+ conn._tunnel() # Called in .connect() -+ -+ def test_invalid_tunnel_host(self): -+ cases = ( -+ 'invalid\r.host', -+ '\ninvalid.host', -+ 'invalid.host\r\n', -+ 'invalid.host\x00', -+ 'invalid host', -+ ) -+ for tunnel_host in cases: -+ with self.subTest(tunnel_host): -+ conn = client.HTTPConnection('example.com') -+ conn.set_tunnel(tunnel_host) -+ conn.sock = FakeSocket('') -+ with self.assertRaisesRegex(ValueError, 'Tunnel host can\'t contain control characters'): -+ conn._tunnel() # Called in .connect() -+ - def test_headers_debuglevel(self): - body = ( - b'HTTP/1.1 200 OK\r\n' -diff --git a/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst b/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst -new file mode 100644 -index 0000000000..4993633b8e ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst -@@ -0,0 +1,2 @@ -+Reject CR/LF characters in tunnel request headers for the -+HTTPConnection.set_tunnel() method. diff --git a/00480-cve-2026-4786.patch b/00480-cve-2026-4786.patch deleted file mode 100644 index 1b51d5a..0000000 --- a/00480-cve-2026-4786.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stan Ulbrych -Date: Mon, 13 Apr 2026 20:02:52 +0100 -Subject: 00480: CVE-2026-4786 - -Fix webbrowser `%action` substitution bypass of dash-prefix check ---- - Lib/test/test_webbrowser.py | 9 +++++++++ - Lib/webbrowser.py | 5 +++-- - .../2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst | 2 ++ - 3 files changed, 14 insertions(+), 2 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst - -diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py -index 404b3a31a5..bfbcf112b0 100644 ---- a/Lib/test/test_webbrowser.py -+++ b/Lib/test/test_webbrowser.py -@@ -119,6 +119,15 @@ def test_open_bad_new_parameter(self): - arguments=[URL], - kw=dict(new=999)) - -+ def test_reject_action_dash_prefixes(self): -+ browser = self.browser_class(name=CMD_NAME) -+ with self.assertRaises(ValueError): -+ browser.open('%action--incognito') -+ # new=1: action is "--new-window", so "%action" itself expands to -+ # a dash-prefixed flag even with no dash in the original URL. -+ with self.assertRaises(ValueError): -+ browser.open('%action', new=1) -+ - - class EdgeCommandTest(CommandTestMixin, unittest.TestCase): - -diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py -index 0e0b5034e5..97aad6eea5 100644 ---- a/Lib/webbrowser.py -+++ b/Lib/webbrowser.py -@@ -274,7 +274,6 @@ def _invoke(self, args, remote, autoraise, url=None): - - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -- self._check_url(url) - if new == 0: - action = self.remote_action - elif new == 1: -@@ -288,7 +287,9 @@ def open(self, url, new=0, autoraise=True): - raise Error("Bad 'new' parameter to open(); " - f"expected 0, 1, or 2, got {new}") - -- args = [arg.replace("%s", url).replace("%action", action) -+ self._check_url(url.replace("%action", action)) -+ -+ args = [arg.replace("%action", action).replace("%s", url) - for arg in self.remote_args] - args = [arg for arg in args if arg] - success = self._invoke(args, True, autoraise, url) -diff --git a/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst -new file mode 100644 -index 0000000000..45cdeebe1b ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst -@@ -0,0 +1,2 @@ -+A bypass in :mod:`webbrowser` allowed URLs prefixed with ``%action`` to pass -+the dash-prefix safety check. diff --git a/00482-cve-2026-6100.patch b/00482-cve-2026-6100.patch deleted file mode 100644 index 0c42470..0000000 --- a/00482-cve-2026-6100.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Mon, 13 Apr 2026 03:40:54 +0200 -Subject: 00482: CVE-2026-6100 - -Fix a possible UAF in {LZMA,BZ2,_Zlib}Decompressor - -Co-authored-by: Stan Ulbrych ---- - .../Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst | 5 +++++ - Modules/_bz2module.c | 1 + - Modules/_lzmamodule.c | 1 + - Modules/zlibmodule.c | 1 + - 4 files changed, 8 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst - -diff --git a/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst b/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst -new file mode 100644 -index 0000000000..9502189ab1 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst -@@ -0,0 +1,5 @@ -+Fix a dangling input pointer in :class:`lzma.LZMADecompressor`, -+:class:`bz2.BZ2Decompressor`, and internal :class:`!zlib._ZlibDecompressor` -+when memory allocation fails with :exc:`MemoryError`, which could let a -+subsequent :meth:`!decompress` call read or write through a stale pointer to -+the already-released caller buffer. -diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c -index 9e85e0de42..055ce82e7d 100644 ---- a/Modules/_bz2module.c -+++ b/Modules/_bz2module.c -@@ -593,6 +593,7 @@ decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length) - return result; - - error: -+ bzs->next_in = NULL; - Py_XDECREF(result); - return NULL; - } -diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c -index 462c2181fa..6785dc5673 100644 ---- a/Modules/_lzmamodule.c -+++ b/Modules/_lzmamodule.c -@@ -1120,6 +1120,7 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) - return result; - - error: -+ lzs->next_in = NULL; - Py_XDECREF(result); - return NULL; - } -diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c -index 5b6b0c5cac..a86aa5fdbb 100644 ---- a/Modules/zlibmodule.c -+++ b/Modules/zlibmodule.c -@@ -1675,6 +1675,7 @@ decompress(ZlibDecompressor *self, uint8_t *data, - return result; - - error: -+ self->zst.next_in = NULL; - Py_XDECREF(result); - return NULL; - } 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 index 7fdfd52..f81dc51 100644 --- a/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch +++ b/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch @@ -70,10 +70,10 @@ index a073300592..5580985974 100644 ) jit_stencils_h = args.output_dir / "jit_stencils.h" diff --git a/configure b/configure -index 8cfdda5a29..e3f51f1f86 100755 +index 30590a397f..babde8c189 100755 --- a/configure +++ b/configure -@@ -1104,6 +1104,7 @@ with_strict_overflow +@@ -1105,6 +1105,7 @@ with_strict_overflow enable_safety enable_slower_safety enable_experimental_jit @@ -81,7 +81,7 @@ index 8cfdda5a29..e3f51f1f86 100755 with_dsymutil with_address_sanitizer with_memory_sanitizer -@@ -1841,6 +1842,9 @@ Optional Features: +@@ -1842,6 +1843,9 @@ Optional Features: --enable-experimental-jit[=no|yes|yes-off|interpreter] build the experimental just-in-time compiler (default is no) @@ -91,7 +91,7 @@ index 8cfdda5a29..e3f51f1f86 100755 --enable-loadable-sqlite-extensions support loadable extensions in the sqlite3 module, see Doc/library/sqlite3.rst (default is no) -@@ -10932,6 +10936,28 @@ fi +@@ -10986,6 +10990,28 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tier2_flags $jit_flags" >&5 printf "%s\n" "$tier2_flags $jit_flags" >&6; } @@ -121,10 +121,10 @@ index 8cfdda5a29..e3f51f1f86 100755 # 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 1acb91fd27..462152c656 100644 +index 87c0ead45a..70f2c5cbb9 100644 --- a/configure.ac +++ b/configure.ac -@@ -2800,6 +2800,19 @@ AC_SUBST([REGEN_JIT_COMMAND]) +@@ -2822,6 +2822,19 @@ AC_SUBST([REGEN_JIT_COMMAND]) AC_SUBST([JIT_STENCILS_H]) AC_MSG_RESULT([$tier2_flags $jit_flags]) diff --git a/python3.14.spec b/python3.14.spec index 84fa23c..1780acd 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,11 +45,11 @@ 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}.4 -#global prerel ... +%global general_version %{pybasever}.5 +%global prerel rc1 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -112,31 +112,30 @@ 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.0.1 +%global pip_version 26.1 %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.1.4 -Provides: bundled(python3dist(dependency-groups)) = 1.3.1 +Provides: bundled(python3dist(certifi)) = 2026.2.25 Provides: bundled(python3dist(distlib)) = 0.4 Provides: bundled(python3dist(distro)) = 1.9 Provides: bundled(python3dist(idna)) = 3.11 Provides: bundled(python3dist(msgpack)) = 1.1.2 -Provides: bundled(python3dist(packaging)) = 26 +Provides: bundled(python3dist(packaging)) = 26.2 Provides: bundled(python3dist(platformdirs)) = 4.5.1 Provides: bundled(python3dist(pygments)) = 2.19.2 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 -Provides: bundled(python3dist(requests)) = 2.32.5 +Provides: bundled(python3dist(requests)) = 2.33.1 Provides: bundled(python3dist(resolvelib)) = 1.2.1 Provides: bundled(python3dist(rich)) = 14.2 Provides: bundled(python3dist(setuptools)) = 70.3 -Provides: bundled(python3dist(tomli)) = 2.3 +Provides: bundled(python3dist(tomli)) = 2.3.1 Provides: bundled(python3dist(tomli-w)) = 1.2 Provides: bundled(python3dist(truststore)) = 0.10.4 -Provides: bundled(python3dist(urllib3)) = 1.26.20 +Provides: bundled(python3dist(urllib3)) = 2.6.3 } # setuptools # vendor.txt not in .whl @@ -447,30 +446,12 @@ Patch475: 00475-cve-2025-15367.patch # direct call to the check function. Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch -# 00479 # 97404b2cf62e545c2d41be7ccfed4e74da9ee665 -# CVE-2026-1502 -# -# Reject CR/LF in HTTP tunnel request headers -Patch479: 00479-cve-2026-1502.patch - -# 00480 # 858691f36890b33e713f330d24c6670329695c2e -# CVE-2026-4786 -# -# Fix webbrowser `%%action` substitution bypass of dash-prefix check -Patch480: 00480-cve-2026-4786.patch - # 00481 # 4c1fd39918651c4559a4835d42b86639a192c2c5 # CVE-2026-5713 # # Validate remote debug offset tables on load Patch481: 00481-cve-2026-5713.patch -# 00482 # 69f14bc306fc62400d45565faa980b77858b9151 -# CVE-2026-6100 -# -# Fix a possible UAF in {LZMA,BZ2,_Zlib}Decompressor -Patch482: 00482-cve-2026-6100.patch - # 00486 # 5ae0b81b3135319f8d75a886fb7a11fa40ac11f4 # gh-148646: Add --enable-prebuilt-jit-stencils configure flag Patch486: 00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch @@ -2029,6 +2010,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 diff --git a/sources b/sources index d2b1483..444a1fe 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.4.tar.xz) = 89a7f8b8a31f48d150badb4751df137d47d9014c9c422649a1a55aef5618aa7f0259dd18c151e6804fa8312c6a21544332a9f630ee81150dc00505637e62bb8c -SHA512 (Python-3.14.4-aarch64-debug-jit_stencils.h) = a3dd821a955043a45b03fa03db2492eea9333bf618df17154fe8c6626c5021d992b5bcd3143791526fdbc5ae16381de5a3966477669fa560278527279ba8687e -SHA512 (Python-3.14.4-aarch64-optimized-jit_stencils.h) = ee0d225a555fe340395ebf63e3816fae90be87e9eed12310b130d19149182aafb17d38c3853ada20480b18b1854666523b99de0ab4df196bcef18cde92817a05 -SHA512 (Python-3.14.4-x86_64-debug-jit_stencils.h) = 1e1770b1053e5c1504c3cfc246e970123f05366ff460383a902857f10afdc010d0bccaa1b5d48547c50840c3939ee2e4a6d153a67278a7bd4d5bfe5d16d947b5 -SHA512 (Python-3.14.4-x86_64-optimized-jit_stencils.h) = 6f41b130d47b6489db909bcd922a26f92ad62153bffcbf169c6137362877797c1efe8eca6811628429b599db962e14933fdbb24c4faa25b57e0d873d9124c7fb +SHA512 (Python-3.14.5rc1.tar.xz) = 67ede84d59046e3b413643449a7eced8cefcd908238b8a34d2ac38507d967201695c62c22464f1bfd51669daf306995262279c7bbfc5a25998ed867a3d743b38 +SHA512 (Python-3.14.5rc1-aarch64-debug-jit_stencils.h) = 46471b03f382e6fa9d9d320b78a01d1f69678b1ad9df9d7e4a448d58b900bb85c514eccf99e9b949ed6358e189ab10add1f636fae265a9bd5f36863c0284e054 +SHA512 (Python-3.14.5rc1-aarch64-optimized-jit_stencils.h) = ec18084587709875eccd31d2b940f2a501b62f874af82335a3db727fc62de2528d092ef34efaaef23502edfaef65cd8361b7e5d00068052d9ad2d96e60f6f9df +SHA512 (Python-3.14.5rc1-x86_64-debug-jit_stencils.h) = cd7be3ac92c518ae474bbe23b3d608ae166776bcf8c4326a130eba3f43f4aeda3b05bdd6758e5920ba1b8f65bfc00cf96158c76ebde538b9cd7226a95a5e8c0e +SHA512 (Python-3.14.5rc1-x86_64-optimized-jit_stencils.h) = e131d34417962003920b6fe03462cf0567a10d662750321307e50319e09932b55e3bd85004fa11310c16c015d6c6ce194425742f59105dbe60fcf1caab885e65 From fc230a4cf121ce0218e4f307790abe727664c21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 11 May 2026 11:27:24 +0200 Subject: [PATCH 76/88] Update to 3.14.5 --- 00481-cve-2026-5713.patch | 587 -------------------------------------- python3.14.spec | 13 +- sources | 10 +- 3 files changed, 10 insertions(+), 600 deletions(-) delete mode 100644 00481-cve-2026-5713.patch diff --git a/00481-cve-2026-5713.patch b/00481-cve-2026-5713.patch deleted file mode 100644 index d5b0551..0000000 --- a/00481-cve-2026-5713.patch +++ /dev/null @@ -1,587 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Pablo Galindo Salgado -Date: Mon, 13 Apr 2026 23:22:23 +0100 -Subject: 00481: CVE-2026-5713 - -Validate remote debug offset tables on load ---- - ...-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst | 2 + - Modules/_remote_debugging_module.c | 509 +++++++++++++++++- - 2 files changed, 505 insertions(+), 6 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst - -diff --git a/Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst b/Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst -new file mode 100644 -index 0000000000..ed138a54a8 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-04-06-13-55-00.gh-issue-148178.Rs7kLm.rst -@@ -0,0 +1,2 @@ -+Hardened :mod:`!_remote_debugging` by validating remote debug offset tables -+before using them to size memory reads or interpret remote layouts. -diff --git a/Modules/_remote_debugging_module.c b/Modules/_remote_debugging_module.c -index a327772258..d756ac326f 100644 ---- a/Modules/_remote_debugging_module.c -+++ b/Modules/_remote_debugging_module.c -@@ -20,6 +20,7 @@ - #include // FRAME_OWNED_BY_CSTACK - #include // struct llist_node - #include // Py_TAG_BITS -+#include // _PyThreadStateImpl - #include "../Python/remote_debug.h" - - // gh-141784: Python.h header must be included first, before system headers. -@@ -41,9 +42,11 @@ - * TYPE DEFINITIONS AND STRUCTURES - * ============================================================================ */ - --#define GET_MEMBER(type, obj, offset) (*(type*)((char*)(obj) + (offset))) -+#define GET_MEMBER(type, obj, offset) \ -+ (*(type *)memcpy(&(type){0}, (const char *)(obj) + (offset), sizeof(type))) - #define CLEAR_PTR_TAG(ptr) (((uintptr_t)(ptr) & ~Py_TAG_BITS)) --#define GET_MEMBER_NO_TAG(type, obj, offset) (type)(CLEAR_PTR_TAG(*(type*)((char*)(obj) + (offset)))) -+#define GET_MEMBER_NO_TAG(type, obj, offset) \ -+ (type)(CLEAR_PTR_TAG(GET_MEMBER(type, obj, offset))) - - /* Size macros for opaque buffers */ - #define SIZEOF_BYTES_OBJ sizeof(PyBytesObject) -@@ -107,6 +110,486 @@ struct _Py_AsyncioModuleDebugOffsets { - } asyncio_thread_state; - }; - -+/* Treat the remote debug tables as untrusted input and validate every -+ * size/offset we later dereference against a fixed local buffer or object -+ * layout before the unwinder starts using them. */ -+#define FIELD_SIZE(type, member) sizeof(((type *)0)->member) -+#define PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS (-2) -+ -+static inline int -+validate_section_size(const char *section_name, uint64_t size) -+{ -+ if (size == 0) { -+ PyErr_Format( -+ PyExc_RuntimeError, -+ "Invalid debug offsets: %s.size must be greater than zero", -+ section_name); -+ return -1; -+ } -+ return 0; -+} -+ -+static inline int -+validate_read_size(const char *section_name, uint64_t size, size_t buffer_size) -+{ -+ if (validate_section_size(section_name, size) < 0) { -+ return -1; -+ } -+ if (size > buffer_size) { -+ PyErr_Format( -+ PyExc_RuntimeError, -+ "Invalid debug offsets: %s.size=%llu exceeds local buffer size %zu", -+ section_name, -+ (unsigned long long)size, -+ buffer_size); -+ return -1; -+ } -+ return 0; -+} -+ -+static inline int -+validate_span( -+ const char *field_name, -+ uint64_t offset, -+ size_t width, -+ uint64_t limit, -+ const char *limit_name) -+{ -+ uint64_t span = (uint64_t)width; -+ if (span > limit || offset > limit - span) { -+ PyErr_Format( -+ PyExc_RuntimeError, -+ "Invalid debug offsets: %s=%llu with width %zu exceeds %s %llu", -+ field_name, -+ (unsigned long long)offset, -+ width, -+ limit_name, -+ (unsigned long long)limit); -+ return -1; -+ } -+ return 0; -+} -+ -+static inline int -+validate_alignment( -+ const char *field_name, -+ uint64_t offset, -+ size_t alignment) -+{ -+ if (alignment > 1 && offset % alignment != 0) { -+ PyErr_Format( -+ PyExc_RuntimeError, -+ "Invalid debug offsets: %s=%llu is not aligned to %zu bytes", -+ field_name, -+ (unsigned long long)offset, -+ alignment); -+ return -1; -+ } -+ return 0; -+} -+ -+static inline int -+validate_field( -+ const char *field_name, -+ uint64_t offset, -+ uint64_t reported_size, -+ size_t width, -+ size_t alignment, -+ size_t buffer_size) -+{ -+ if (validate_alignment(field_name, offset, alignment) < 0) { -+ return -1; -+ } -+ if (validate_span(field_name, offset, width, reported_size, "reported size") < 0) { -+ return -1; -+ } -+ return validate_span(field_name, offset, width, buffer_size, "local buffer size"); -+} -+ -+static inline int -+validate_fixed_field( -+ const char *field_name, -+ uint64_t offset, -+ size_t width, -+ size_t alignment, -+ size_t buffer_size) -+{ -+ if (validate_alignment(field_name, offset, alignment) < 0) { -+ return -1; -+ } -+ return validate_span(field_name, offset, width, buffer_size, "local buffer size"); -+} -+ -+#define PY_REMOTE_DEBUG_VALIDATE_SECTION(section) \ -+ do { \ -+ if (validate_section_size(#section, debug_offsets->section.size) < 0) { \ -+ return -1; \ -+ } \ -+ } while (0) -+ -+#define PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(section, buffer_size) \ -+ do { \ -+ if (validate_read_size(#section, debug_offsets->section.size, buffer_size) < 0) { \ -+ return -1; \ -+ } \ -+ } while (0) -+ -+#define PY_REMOTE_DEBUG_VALIDATE_FIELD(section, field, field_size, field_alignment, buffer_size) \ -+ do { \ -+ if (validate_field( \ -+ #section "." #field, \ -+ debug_offsets->section.field, \ -+ debug_offsets->section.size, \ -+ field_size, \ -+ field_alignment, \ -+ buffer_size) < 0) { \ -+ return -1; \ -+ } \ -+ } while (0) -+ -+#define PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD(section, field, field_size, field_alignment, buffer_size) \ -+ do { \ -+ if (validate_fixed_field( \ -+ #section "." #field, \ -+ debug_offsets->section.field, \ -+ field_size, \ -+ field_alignment, \ -+ buffer_size) < 0) { \ -+ return -1; \ -+ } \ -+ } while (0) -+ -+static inline int -+validate_debug_offsets_layout(struct _Py_DebugOffsets *debug_offsets) -+{ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(runtime_state); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ runtime_state, -+ interpreters_head, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ sizeof(_PyRuntimeState)); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(interpreter_state); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_state, -+ threads_head, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ INTERP_STATE_BUFFER_SIZE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_state, -+ threads_main, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ INTERP_STATE_BUFFER_SIZE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_state, -+ gil_runtime_state_locked, -+ sizeof(int), -+ _Alignof(int), -+ INTERP_STATE_BUFFER_SIZE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_state, -+ gil_runtime_state_holder, -+ sizeof(PyThreadState *), -+ _Alignof(PyThreadState *), -+ INTERP_STATE_BUFFER_SIZE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_state, -+ code_object_generation, -+ sizeof(uint64_t), -+ _Alignof(uint64_t), -+ INTERP_STATE_BUFFER_SIZE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_state, -+ tlbc_generation, -+ sizeof(uint32_t), -+ _Alignof(uint32_t), -+ INTERP_STATE_BUFFER_SIZE); -+ -+ PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(thread_state, SIZEOF_THREAD_STATE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ thread_state, -+ next, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_THREAD_STATE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ thread_state, -+ current_frame, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_THREAD_STATE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ thread_state, -+ native_thread_id, -+ sizeof(unsigned long), -+ _Alignof(unsigned long), -+ SIZEOF_THREAD_STATE); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ thread_state, -+ datastack_chunk, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_THREAD_STATE); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(interpreter_frame); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_frame, -+ previous, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_INTERP_FRAME); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_frame, -+ executable, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_INTERP_FRAME); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_frame, -+ instr_ptr, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_INTERP_FRAME); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_frame, -+ owner, -+ sizeof(char), -+ _Alignof(char), -+ SIZEOF_INTERP_FRAME); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_frame, -+ stackpointer, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_INTERP_FRAME); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ interpreter_frame, -+ tlbc_index, -+ sizeof(int32_t), -+ _Alignof(int32_t), -+ SIZEOF_INTERP_FRAME); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(code_object); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ code_object, -+ qualname, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_CODE_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ code_object, -+ filename, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_CODE_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ code_object, -+ linetable, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_CODE_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ code_object, -+ firstlineno, -+ sizeof(int), -+ _Alignof(int), -+ SIZEOF_CODE_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ code_object, -+ co_code_adaptive, -+ sizeof(char), -+ _Alignof(char), -+ SIZEOF_CODE_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ code_object, -+ co_tlbc, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_CODE_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(pyobject); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ pyobject, -+ ob_type, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_PYOBJECT); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(type_object); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ type_object, -+ tp_flags, -+ sizeof(unsigned long), -+ _Alignof(unsigned long), -+ SIZEOF_TYPE_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(set_object); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ set_object, -+ used, -+ sizeof(Py_ssize_t), -+ _Alignof(Py_ssize_t), -+ SIZEOF_SET_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ set_object, -+ mask, -+ sizeof(Py_ssize_t), -+ _Alignof(Py_ssize_t), -+ SIZEOF_SET_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ set_object, -+ table, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_SET_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(long_object, SIZEOF_LONG_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ long_object, -+ lv_tag, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_LONG_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ long_object, -+ ob_digit, -+ sizeof(digit), -+ _Alignof(digit), -+ SIZEOF_LONG_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(bytes_object); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ bytes_object, -+ ob_size, -+ sizeof(Py_ssize_t), -+ _Alignof(Py_ssize_t), -+ SIZEOF_BYTES_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ bytes_object, -+ ob_sval, -+ sizeof(char), -+ _Alignof(char), -+ SIZEOF_BYTES_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(unicode_object); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ unicode_object, -+ length, -+ sizeof(Py_ssize_t), -+ _Alignof(Py_ssize_t), -+ SIZEOF_UNICODE_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ unicode_object, -+ asciiobject_size, -+ sizeof(char), -+ _Alignof(char), -+ SIZEOF_UNICODE_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(gen_object); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ gen_object, -+ gi_frame_state, -+ sizeof(int8_t), -+ _Alignof(int8_t), -+ SIZEOF_GEN_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ gen_object, -+ gi_iframe, -+ FIELD_SIZE(PyGenObject, gi_iframe), -+ _Alignof(_PyInterpreterFrame), -+ SIZEOF_GEN_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD( -+ llist_node, -+ next, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_LLIST_NODE); -+ -+ return 0; -+} -+ -+static inline int -+validate_async_debug_offsets_layout(struct _Py_AsyncioModuleDebugOffsets *debug_offsets) -+{ -+ PY_REMOTE_DEBUG_VALIDATE_READ_SECTION(asyncio_task_object, SIZEOF_TASK_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_task_object, -+ task_name, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_TASK_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_task_object, -+ task_awaited_by, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_TASK_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_task_object, -+ task_is_task, -+ sizeof(char), -+ _Alignof(char), -+ SIZEOF_TASK_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_task_object, -+ task_awaited_by_is_set, -+ sizeof(char), -+ _Alignof(char), -+ SIZEOF_TASK_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_task_object, -+ task_coro, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ SIZEOF_TASK_OBJ); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_task_object, -+ task_node, -+ SIZEOF_LLIST_NODE, -+ _Alignof(struct llist_node), -+ SIZEOF_TASK_OBJ); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(asyncio_interpreter_state); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_interpreter_state, -+ asyncio_tasks_head, -+ SIZEOF_LLIST_NODE, -+ _Alignof(struct llist_node), -+ sizeof(PyInterpreterState)); -+ -+ PY_REMOTE_DEBUG_VALIDATE_SECTION(asyncio_thread_state); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_thread_state, -+ asyncio_running_loop, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ sizeof(_PyThreadStateImpl)); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_thread_state, -+ asyncio_running_task, -+ sizeof(uintptr_t), -+ _Alignof(uintptr_t), -+ sizeof(_PyThreadStateImpl)); -+ PY_REMOTE_DEBUG_VALIDATE_FIELD( -+ asyncio_thread_state, -+ asyncio_tasks_head, -+ SIZEOF_LLIST_NODE, -+ _Alignof(struct llist_node), -+ sizeof(_PyThreadStateImpl)); -+ -+ return 0; -+} -+ -+#undef PY_REMOTE_DEBUG_VALIDATE_SECTION -+#undef PY_REMOTE_DEBUG_VALIDATE_READ_SECTION -+#undef PY_REMOTE_DEBUG_VALIDATE_FIELD -+#undef PY_REMOTE_DEBUG_VALIDATE_FIXED_FIELD -+#undef FIELD_SIZE -+ - /* ============================================================================ - * STRUCTSEQ TYPE DEFINITIONS - * ============================================================================ */ -@@ -434,7 +917,7 @@ validate_debug_offsets(struct _Py_DebugOffsets *debug_offsets) - return -1; - } - -- return 0; -+ return validate_debug_offsets_layout(debug_offsets); - } - - // Generic function to iterate through all threads -@@ -877,8 +1360,13 @@ read_async_debug( - int result = _Py_RemoteDebug_PagedReadRemoteMemory(&unwinder->handle, async_debug_addr, size, &unwinder->async_debug_offsets); - if (result < 0) { - set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read AsyncioDebug offsets"); -+ return result; - } -- return result; -+ if (validate_async_debug_offsets_layout(&unwinder->async_debug_offsets) < 0) { -+ set_exception_cause(unwinder, PyExc_RuntimeError, "Invalid AsyncioDebug offsets"); -+ return PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS; -+ } -+ return 0; - } - - /* ============================================================================ -@@ -2054,10 +2542,15 @@ static void * - find_frame_in_chunks(StackChunkList *chunks, uintptr_t remote_ptr) - { - for (size_t i = 0; i < chunks->count; ++i) { -+ if (chunks->chunks[i].size <= offsetof(_PyStackChunk, data)) { -+ continue; -+ } - uintptr_t base = chunks->chunks[i].remote_addr + offsetof(_PyStackChunk, data); - size_t payload = chunks->chunks[i].size - offsetof(_PyStackChunk, data); - -- if (remote_ptr >= base && remote_ptr < base + payload) { -+ if (payload >= SIZEOF_INTERP_FRAME && -+ remote_ptr >= base && -+ remote_ptr <= base + payload - SIZEOF_INTERP_FRAME) { - return (char *)chunks->chunks[i].local_copy + (remote_ptr - chunks->chunks[i].remote_addr); - } - } -@@ -2624,7 +3117,11 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self, - - // Try to read async debug offsets, but don't fail if they're not available - self->async_debug_offsets_available = 1; -- if (read_async_debug(self) < 0) { -+ int async_debug_result = read_async_debug(self); -+ if (async_debug_result == PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS) { -+ return -1; -+ } -+ if (async_debug_result < 0) { - PyErr_Clear(); - memset(&self->async_debug_offsets, 0, sizeof(self->async_debug_offsets)); - self->async_debug_offsets_available = 0; diff --git a/python3.14.spec b/python3.14.spec index 1780acd..d394acf 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -46,7 +46,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}.5 -%global prerel rc1 +#global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} Release: 1%{?dist} @@ -112,7 +112,7 @@ 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.1 +%global pip_version 26.1.1 %global setuptools_version 79.0.1 # All of those also include a list of indirect bundled libs: # pip @@ -446,12 +446,6 @@ Patch475: 00475-cve-2025-15367.patch # direct call to the check function. Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch -# 00481 # 4c1fd39918651c4559a4835d42b86639a192c2c5 -# CVE-2026-5713 -# -# Validate remote debug offset tables on load -Patch481: 00481-cve-2026-5713.patch - # 00486 # 5ae0b81b3135319f8d75a886fb7a11fa40ac11f4 # gh-148646: Add --enable-prebuilt-jit-stencils configure flag Patch486: 00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch @@ -2010,6 +2004,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 diff --git a/sources b/sources index 444a1fe..6f9629a 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.5rc1.tar.xz) = 67ede84d59046e3b413643449a7eced8cefcd908238b8a34d2ac38507d967201695c62c22464f1bfd51669daf306995262279c7bbfc5a25998ed867a3d743b38 -SHA512 (Python-3.14.5rc1-aarch64-debug-jit_stencils.h) = 46471b03f382e6fa9d9d320b78a01d1f69678b1ad9df9d7e4a448d58b900bb85c514eccf99e9b949ed6358e189ab10add1f636fae265a9bd5f36863c0284e054 -SHA512 (Python-3.14.5rc1-aarch64-optimized-jit_stencils.h) = ec18084587709875eccd31d2b940f2a501b62f874af82335a3db727fc62de2528d092ef34efaaef23502edfaef65cd8361b7e5d00068052d9ad2d96e60f6f9df -SHA512 (Python-3.14.5rc1-x86_64-debug-jit_stencils.h) = cd7be3ac92c518ae474bbe23b3d608ae166776bcf8c4326a130eba3f43f4aeda3b05bdd6758e5920ba1b8f65bfc00cf96158c76ebde538b9cd7226a95a5e8c0e -SHA512 (Python-3.14.5rc1-x86_64-optimized-jit_stencils.h) = e131d34417962003920b6fe03462cf0567a10d662750321307e50319e09932b55e3bd85004fa11310c16c015d6c6ce194425742f59105dbe60fcf1caab885e65 +SHA512 (Python-3.14.5.tar.xz) = efbaf629703cd004f6b7bc75fb16df794185589adaf8807cd45928f212271045a399df3cd9573e47c8708fb5c5002f9d4efe4e41dde4313b81a3e9d73158769f +SHA512 (Python-3.14.5-aarch64-debug-jit_stencils.h) = 302563ab4fa858bcd49889b391e2970b9a5b1c5f69f74abc59524cd848f3eb89888117a3ea5f98e1d67bae86e8f491a895d2c23cf561b88ddf23bd4d8abb2597 +SHA512 (Python-3.14.5-aarch64-optimized-jit_stencils.h) = 0db85e77dcbd9318916845e927a3aecd43294c779e1d23f246e3adc49b339a819ab071d15fbd14d7352b95f8a314adeafdced14891762351478ce37588d25df4 +SHA512 (Python-3.14.5-x86_64-debug-jit_stencils.h) = 89ef636b138c2d176af23cadfa6f141d6190735e5ebe67335276a7c1f7afdea674ff39dd1eb6cc14ac0e6a12e9a9b1bc879457b4af60c8f1795166eda69f312a +SHA512 (Python-3.14.5-x86_64-optimized-jit_stencils.h) = 0bed1d68f3567b52b6b47802edbfd65ade48f993d857cca516fb4224811dca992f4740fe10acf13c63ad95dbd80ee093893fe56f6f89cd60c90452743f2a502d From 576eed68c6736dc2967992a051bca837cfdb3295 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Wed, 3 Jun 2026 12:28:22 +0200 Subject: [PATCH 77/88] Rebuilt as non-main Python on Fedora 45+ --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index d394acf..357bcbc 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -2004,6 +2004,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 From f26b7fcd3ab8d0a62e0eb198fc5172537b8e085f Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Thu, 11 Jun 2026 15:04:54 +0200 Subject: [PATCH 78/88] Update to Python 3.14.6 --- ...-pac-and-bti-protections-for-aarch64.patch | 102 ------------------ ...not-working-with-older-expat-version.patch | 10 +- 00474-cve-2025-15366.patch | 6 +- ...piled-for-a-different-python-version.patch | 10 +- ...prebuilt-jit-stencils-configure-flag.patch | 4 +- python3.14.spec | 26 ++--- sources | 10 +- 7 files changed, 26 insertions(+), 142 deletions(-) delete mode 100644 00464-enable-pac-and-bti-protections-for-aarch64.patch diff --git a/00464-enable-pac-and-bti-protections-for-aarch64.patch b/00464-enable-pac-and-bti-protections-for-aarch64.patch deleted file mode 100644 index 1a7acf3..0000000 --- a/00464-enable-pac-and-bti-protections-for-aarch64.patch +++ /dev/null @@ -1,102 +0,0 @@ -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-skip-tests-not-working-with-older-expat-version.patch b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch index 3897b71..1ec4926 100644 --- 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 @@ -15,10 +15,10 @@ which is tested as working. 3 files changed, 10 insertions(+) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index 465f65a03b..3379ab8aa9 100644 +index dea472335b..dfe41760af 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py -@@ -905,6 +905,8 @@ def start_element(name, _): +@@ -1031,6 +1031,8 @@ def start_element(name, _): self.assertEqual(started, ['doc']) @@ -41,10 +41,10 @@ index 5c10bcedc6..1fd7a273b5 100644 result = BytesIO() xmlgen = XMLGenerator(result) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 1bd0fde844..f87134c11e 100644 +index 8c693bfbdb..a71f230b77 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py -@@ -1573,9 +1573,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): +@@ -1598,9 +1598,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): self.assert_event_tags(parser, [('end', 'root')]) self.assertIsNone(parser.close()) @@ -58,7 +58,7 @@ index 1bd0fde844..f87134c11e 100644 def test_simple_xml_chunk_5(self): self.test_simple_xml(chunk_size=5, flush=True) -@@ -1802,6 +1806,8 @@ def test_flush_reparse_deferral_enabled(self): +@@ -1827,6 +1831,8 @@ def test_flush_reparse_deferral_enabled(self): self.assert_event_tags(parser, [('end', 'doc')]) diff --git a/00474-cve-2025-15366.patch b/00474-cve-2025-15366.patch index 985adbb..6c29cd9 100644 --- a/00474-cve-2025-15366.patch +++ b/00474-cve-2025-15366.patch @@ -12,7 +12,7 @@ Downstream only: Reject control characters in IMAP commands create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst diff --git a/Lib/imaplib.py b/Lib/imaplib.py -index cbe129b3e7..b9c691aacd 100644 +index e84ffb2eec..3465881270 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -131,7 +131,7 @@ @@ -34,10 +34,10 @@ index cbe129b3e7..b9c691aacd 100644 literal = self.literal diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py -index a03d7b8bb2..e26400b588 100644 +index f0b463949c..165390ee66 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py -@@ -663,6 +663,12 @@ def test_unselect(self): +@@ -673,6 +673,12 @@ def test_unselect(self): self.assertEqual(data[0], b'Returned to authenticated state. (Success)') self.assertEqual(client.state, 'AUTH') 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 index e8f69ae..b344a70 100644 --- 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 @@ -81,7 +81,7 @@ index 2a17c891dd..64017c666c 100644 } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in -index da6d7c3315..92a6825b5e 100644 +index f86d7363e0..6aa97b0b6f 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -3420,3 +3420,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h @@ -92,10 +92,10 @@ index da6d7c3315..92a6825b5e 100644 +# 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 2216de509e..a640496f7f 100644 +index 6c1af66408..2eb3665fa7 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c -@@ -3489,6 +3489,12 @@ static struct PyModuleDef _tkintermodule = { +@@ -3490,6 +3490,12 @@ static struct PyModuleDef _tkintermodule = { PyMODINIT_FUNC PyInit__tkinter(void) { @@ -126,10 +126,10 @@ index be71fc9fc9..67922098b2 100644 if (mod == NULL) { return NULL; diff --git a/Modules/readline.c b/Modules/readline.c -index 8475846eef..b3f5eb3a1f 100644 +index 7708f47d4d..7c0b70caa4 100644 --- a/Modules/readline.c +++ b/Modules/readline.c -@@ -1604,6 +1604,12 @@ static struct PyModuleDef readlinemodule = { +@@ -1612,6 +1612,12 @@ static struct PyModuleDef readlinemodule = { PyMODINIT_FUNC PyInit_readline(void) { 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 index f81dc51..06201ff 100644 --- a/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch +++ b/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch @@ -70,7 +70,7 @@ index a073300592..5580985974 100644 ) jit_stencils_h = args.output_dir / "jit_stencils.h" diff --git a/configure b/configure -index 30590a397f..babde8c189 100755 +index 2088290f0e..fd960d9551 100755 --- a/configure +++ b/configure @@ -1105,6 +1105,7 @@ with_strict_overflow @@ -121,7 +121,7 @@ index 30590a397f..babde8c189 100755 # 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 87c0ead45a..70f2c5cbb9 100644 +index aed1494673..10d78ae942 100644 --- a/configure.ac +++ b/configure.ac @@ -2822,6 +2822,19 @@ AC_SUBST([REGEN_JIT_COMMAND]) diff --git a/python3.14.spec b/python3.14.spec index 357bcbc..2752191 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,11 +45,11 @@ 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}.5 +%global general_version %{pybasever}.6 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -112,7 +112,7 @@ 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.1.1 +%global pip_version 26.1.2 %global setuptools_version 79.0.1 # All of those also include a list of indirect bundled libs: # pip @@ -392,23 +392,6 @@ 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 -# 00464 # 292acffec7a379cb6d1f3c47b9e5a2f170bbadb6 -# 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. -Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch - # 00466 # e10760fb955ee33d2917f8a57bb4e24d71e5341c # Downstream only: Skip tests not working with older expat version # @@ -2004,6 +1987,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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+ diff --git a/sources b/sources index 6f9629a..9504ccc 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.5.tar.xz) = efbaf629703cd004f6b7bc75fb16df794185589adaf8807cd45928f212271045a399df3cd9573e47c8708fb5c5002f9d4efe4e41dde4313b81a3e9d73158769f -SHA512 (Python-3.14.5-aarch64-debug-jit_stencils.h) = 302563ab4fa858bcd49889b391e2970b9a5b1c5f69f74abc59524cd848f3eb89888117a3ea5f98e1d67bae86e8f491a895d2c23cf561b88ddf23bd4d8abb2597 -SHA512 (Python-3.14.5-aarch64-optimized-jit_stencils.h) = 0db85e77dcbd9318916845e927a3aecd43294c779e1d23f246e3adc49b339a819ab071d15fbd14d7352b95f8a314adeafdced14891762351478ce37588d25df4 -SHA512 (Python-3.14.5-x86_64-debug-jit_stencils.h) = 89ef636b138c2d176af23cadfa6f141d6190735e5ebe67335276a7c1f7afdea674ff39dd1eb6cc14ac0e6a12e9a9b1bc879457b4af60c8f1795166eda69f312a -SHA512 (Python-3.14.5-x86_64-optimized-jit_stencils.h) = 0bed1d68f3567b52b6b47802edbfd65ade48f993d857cca516fb4224811dca992f4740fe10acf13c63ad95dbd80ee093893fe56f6f89cd60c90452743f2a502d +SHA512 (Python-3.14.6.tar.xz) = 90a82f46c28f0fca613b67358fdc57c145ab05d20fb56bf3bc0c9e4e54947c7d30fbaa6856c41a41909237a9e601d1a7d19579d4b25c7a784ebcfe9012defc41 +SHA512 (Python-3.14.6-aarch64-debug-jit_stencils.h) = f56cbdadc5448636257aa17998886b83d4e7dbf848827e08cf393fc61d0522e6976f7d2799c35e250013629b85f242e3647114ce8d0281b9ed67b45475c2cab2 +SHA512 (Python-3.14.6-aarch64-optimized-jit_stencils.h) = 6fa83d156d4bc73a49d1c03af88c00624dc6dd36fb7b28bf8642e310560a8c4a9bf7059102f2e9827ec30152efdcff839bc9dcf9a2a83e24c86207286c2dda7b +SHA512 (Python-3.14.6-x86_64-debug-jit_stencils.h) = b1edbd82f6e33f58211e00d862d407f1463d12263aa3386ad7e2f1a9c235226edb6ec11fdff1be8260914859e6089bd4b4a792e5cc5e3d5362cd80b383355b05 +SHA512 (Python-3.14.6-x86_64-optimized-jit_stencils.h) = b28575a1c8a3c5cdd6c7860136501359c5cfea92c645d3970b64c75359976a360e3213a68e6a9d589c9f72609b5152093bf10977d31e38ac9110db91e2054634 From 2b1a90b181b4631accbd3a50a2317e6d9b080349 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Wed, 24 Jun 2026 22:07:41 +0200 Subject: [PATCH 79/88] Run a new test to monitor changes in required symbols --- plan.fmf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plan.fmf b/plan.fmf index f904b17..bb45dcc 100644 --- a/plan.fmf +++ b/plan.fmf @@ -57,6 +57,9 @@ 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 @@ -78,8 +81,9 @@ 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 + - dnf # for upgrade and downgrade - name: Update packages how: shell script: dnf upgrade -y From 4669c6fce01b2883f16b44c9c2003027460878e8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jul 2026 22:48:27 +0000 Subject: [PATCH 80/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild --- python3.14.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index 2752191..8060621 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -1987,6 +1987,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 From 36fa2b08951c45024be07bc3c4b5fd8749ded0b4 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 10 Aug 2026 10:37:20 +0200 Subject: [PATCH 81/88] Update to Python 3.14.7 --- ...not-working-with-older-expat-version.patch | 6 +- 00474-cve-2025-15366.patch | 59 ------------------- ...piled-for-a-different-python-version.patch | 8 +-- ...prebuilt-jit-stencils-configure-flag.patch | 8 +-- plan.fmf | 5 +- python3.14.spec | 40 +++++++------ sources | 10 ++-- 7 files changed, 40 insertions(+), 96 deletions(-) delete mode 100644 00474-cve-2025-15366.patch 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 index 1ec4926..aded227 100644 --- 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 @@ -15,10 +15,10 @@ which is tested as working. 3 files changed, 10 insertions(+) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index dea472335b..dfe41760af 100644 +index fd3077063b..6e6468cb7d 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py -@@ -1031,6 +1031,8 @@ def start_element(name, _): +@@ -1037,6 +1037,8 @@ def start_element(name, _): self.assertEqual(started, ['doc']) @@ -41,7 +41,7 @@ index 5c10bcedc6..1fd7a273b5 100644 result = BytesIO() xmlgen = XMLGenerator(result) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 8c693bfbdb..a71f230b77 100644 +index 6da7c34dc4..e9912cb569 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1598,9 +1598,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): diff --git a/00474-cve-2025-15366.patch b/00474-cve-2025-15366.patch deleted file mode 100644 index 6c29cd9..0000000 --- a/00474-cve-2025-15366.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:45:42 -0600 -Subject: 00474: CVE-2025-15366 - -Downstream only: Reject control characters in IMAP commands ---- - Lib/imaplib.py | 4 +++- - Lib/test/test_imaplib.py | 6 ++++++ - .../Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 + - 3 files changed, 10 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst - -diff --git a/Lib/imaplib.py b/Lib/imaplib.py -index e84ffb2eec..3465881270 100644 ---- a/Lib/imaplib.py -+++ b/Lib/imaplib.py -@@ -131,7 +131,7 @@ - # We compile these in _mode_xxx. - _Literal = br'.*{(?P\d+)}$' - _Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' -- -+_control_chars = re.compile(b'[\x00-\x1F\x7F]') - - - class IMAP4: -@@ -1108,6 +1108,8 @@ def _command(self, name, *args): - if arg is None: continue - if isinstance(arg, str): - arg = bytes(arg, self._encoding) -+ if _control_chars.search(arg): -+ raise ValueError("Control characters not allowed in commands") - data = data + b' ' + arg - - literal = self.literal -diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py -index f0b463949c..165390ee66 100644 ---- a/Lib/test/test_imaplib.py -+++ b/Lib/test/test_imaplib.py -@@ -673,6 +673,12 @@ def test_unselect(self): - self.assertEqual(data[0], b'Returned to authenticated state. (Success)') - self.assertEqual(client.state, 'AUTH') - -+ def test_control_characters(self): -+ client, _ = self._setup(SimpleIMAPHandler) -+ for c0 in support.control_characters_c0(): -+ with self.assertRaises(ValueError): -+ client.login(f'user{c0}', 'pass') -+ - # property tests - - def test_file_property_should_not_be_accessed(self): -diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst -new file mode 100644 -index 0000000000..4e13fe92bc ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst -@@ -0,0 +1 @@ -+Reject control characters in IMAP 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 index b344a70..1ba9248 100644 --- 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 @@ -81,10 +81,10 @@ index 2a17c891dd..64017c666c 100644 } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in -index f86d7363e0..6aa97b0b6f 100644 +index 526d500fe0..506ec30408 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -3420,3 +3420,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h +@@ -3426,3 +3426,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h # Local Variables: # mode: makefile # End: @@ -92,10 +92,10 @@ index f86d7363e0..6aa97b0b6f 100644 +# 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 6c1af66408..2eb3665fa7 100644 +index 22126b67d8..7ef5b5d5cd 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c -@@ -3490,6 +3490,12 @@ static struct PyModuleDef _tkintermodule = { +@@ -3611,6 +3611,12 @@ static struct PyModuleDef _tkintermodule = { PyMODINIT_FUNC PyInit__tkinter(void) { 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 index 06201ff..79101b5 100644 --- a/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch +++ b/00486-gh-148646-add---enable-prebuilt-jit-stencils-configure-flag.patch @@ -70,7 +70,7 @@ index a073300592..5580985974 100644 ) jit_stencils_h = args.output_dir / "jit_stencils.h" diff --git a/configure b/configure -index 2088290f0e..fd960d9551 100755 +index 2cb22a7806..1b396c92b2 100755 --- a/configure +++ b/configure @@ -1105,6 +1105,7 @@ with_strict_overflow @@ -91,7 +91,7 @@ index 2088290f0e..fd960d9551 100755 --enable-loadable-sqlite-extensions support loadable extensions in the sqlite3 module, see Doc/library/sqlite3.rst (default is no) -@@ -10986,6 +10990,28 @@ fi +@@ -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; } @@ -121,10 +121,10 @@ index 2088290f0e..fd960d9551 100755 # 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 aed1494673..10d78ae942 100644 +index 967d34d47a..51160cafc2 100644 --- a/configure.ac +++ b/configure.ac -@@ -2822,6 +2822,19 @@ AC_SUBST([REGEN_JIT_COMMAND]) +@@ -2873,6 +2873,19 @@ AC_SUBST([REGEN_JIT_COMMAND]) AC_SUBST([JIT_STENCILS_H]) AC_MSG_RESULT([$tier2_flags $jit_flags]) diff --git a/plan.fmf b/plan.fmf index bb45dcc..09bf963 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,11 +24,12 @@ 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_subparser_inherits_reparse_deferral fails on RHEL 9: https://github.com/python/cpython/issues/155485 + test: "VERSION=${pybasever} X='-i test_check_probes -i test_subparser_inherits_reparse_deferral' ./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: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_base_interpreter -i test_subparser_inherits_reparse_deferral' ./parallel.sh" - name: freethreadingtest path: /selftest test: "VERSION=${pybasever}t X='-i test_check_probes -i test_base_interpreter' ./parallel.sh" diff --git a/python3.14.spec b/python3.14.spec index 8060621..ca7a4fe 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -45,11 +45,11 @@ 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}.6 +%global general_version %{pybasever}.7 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -112,30 +112,30 @@ 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.1.2 +%global pip_version 26.2.1 %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.2.25 -Provides: bundled(python3dist(distlib)) = 0.4 +Provides: bundled(python3dist(certifi)) = 2026.6.17 +Provides: bundled(python3dist(distlib)) = 0.4.2 Provides: bundled(python3dist(distro)) = 1.9 -Provides: bundled(python3dist(idna)) = 3.11 +Provides: bundled(python3dist(idna)) = 3.18 Provides: bundled(python3dist(msgpack)) = 1.1.2 Provides: bundled(python3dist(packaging)) = 26.2 -Provides: bundled(python3dist(platformdirs)) = 4.5.1 -Provides: bundled(python3dist(pygments)) = 2.19.2 +Provides: bundled(python3dist(platformdirs)) = 4.10 +Provides: bundled(python3dist(pygments)) = 2.20 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 -Provides: bundled(python3dist(requests)) = 2.33.1 +Provides: bundled(python3dist(requests)) = 2.34.2 Provides: bundled(python3dist(resolvelib)) = 1.2.1 Provides: bundled(python3dist(rich)) = 14.2 Provides: bundled(python3dist(setuptools)) = 70.3 -Provides: bundled(python3dist(tomli)) = 2.3.1 +Provides: bundled(python3dist(tomli)) = 2.4.1 Provides: bundled(python3dist(tomli-w)) = 1.2 Provides: bundled(python3dist(truststore)) = 0.10.4 -Provides: bundled(python3dist(urllib3)) = 2.6.3 +Provides: bundled(python3dist(urllib3)) = 2.7 } # setuptools # vendor.txt not in .whl @@ -401,12 +401,6 @@ Patch251: 00251-change-user-install-location.patch # which is tested as working. Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch -# 00474 # 0d9da266d5ecb31d8a417a0a5daa251a2d99389f -# CVE-2025-15366 -# -# Downstream only: Reject control characters in IMAP commands -Patch474: 00474-cve-2025-15366.patch - # 00475 # 91e12ebfb2a88b265f3764a0d852b6fa53b2386a # CVE-2025-15367 # @@ -557,7 +551,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 c695d550b135e53e38807e76496d1db17d22c40e461d1f3f354c86188d3305dd +%global license_file_hash cd6f471c0bfdb099efefc25ddff9b3df8bf62e10428987f1f05e6f2f9e35d563 # 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 @@ -581,7 +575,8 @@ 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 -%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 +# 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 %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 License: %{libs_license} @@ -1490,6 +1485,7 @@ CheckPython() { # 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_subparser_inherits_reparse_deferral: https://github.com/python/cpython/issues/155485 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1498,6 +1494,9 @@ CheckPython() { --timeout=2700 \ %endif -i test_check_probes \ + %if 0%{?rhel} == 9 + -i test_subparser_inherits_reparse_deferral \ + %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1987,6 +1986,9 @@ CheckPython freethreading # ====================================================== %changelog +* 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 diff --git a/sources b/sources index 9504ccc..48e32a1 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ -SHA512 (Python-3.14.6.tar.xz) = 90a82f46c28f0fca613b67358fdc57c145ab05d20fb56bf3bc0c9e4e54947c7d30fbaa6856c41a41909237a9e601d1a7d19579d4b25c7a784ebcfe9012defc41 -SHA512 (Python-3.14.6-aarch64-debug-jit_stencils.h) = f56cbdadc5448636257aa17998886b83d4e7dbf848827e08cf393fc61d0522e6976f7d2799c35e250013629b85f242e3647114ce8d0281b9ed67b45475c2cab2 -SHA512 (Python-3.14.6-aarch64-optimized-jit_stencils.h) = 6fa83d156d4bc73a49d1c03af88c00624dc6dd36fb7b28bf8642e310560a8c4a9bf7059102f2e9827ec30152efdcff839bc9dcf9a2a83e24c86207286c2dda7b -SHA512 (Python-3.14.6-x86_64-debug-jit_stencils.h) = b1edbd82f6e33f58211e00d862d407f1463d12263aa3386ad7e2f1a9c235226edb6ec11fdff1be8260914859e6089bd4b4a792e5cc5e3d5362cd80b383355b05 -SHA512 (Python-3.14.6-x86_64-optimized-jit_stencils.h) = b28575a1c8a3c5cdd6c7860136501359c5cfea92c645d3970b64c75359976a360e3213a68e6a9d589c9f72609b5152093bf10977d31e38ac9110db91e2054634 +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 From 9d987df72677feed38ab811d0d67df7fcd926449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 12 Aug 2026 17:31:43 +0200 Subject: [PATCH 82/88] On EL 9, also supports reparse deferral in expat This replaces one downstream-only patch with another. Yet arguably, this is the safer thing to do. Read the patch description for details; won't copy paste them here. Also, require expat >= version-release when expat < 2.7.4. Assisted-By: Claude Opus 4.6 (cherry picked from python3.13 commit 0ca3f59c07cb0d9bf01a0746d00773ed0c625755) --- ...rsion-threshold-for-reparse-deferral.patch | 133 ++++++++++++++++++ ...not-working-with-older-expat-version.patch | 69 --------- plan.fmf | 5 +- python3.14.spec | 39 +++-- 4 files changed, 160 insertions(+), 86 deletions(-) create mode 100644 00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch delete mode 100644 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch 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 new file mode 100644 index 0000000..43e2056 --- /dev/null +++ b/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch @@ -0,0 +1,133 @@ +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 deleted file mode 100644 index aded227..0000000 --- a/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch +++ /dev/null @@ -1,69 +0,0 @@ -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 fd3077063b..6e6468cb7d 100644 ---- a/Lib/test/test_pyexpat.py -+++ b/Lib/test/test_pyexpat.py -@@ -1037,6 +1037,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 6da7c34dc4..e9912cb569 100644 ---- a/Lib/test/test_xml_etree.py -+++ b/Lib/test/test_xml_etree.py -@@ -1598,9 +1598,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) - -@@ -1827,6 +1831,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/plan.fmf b/plan.fmf index 09bf963..bb45dcc 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,12 +24,11 @@ discover: test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} CYTHON=true ./venv.sh" - name: selftest path: /selftest - # test_subparser_inherits_reparse_deferral fails on RHEL 9: https://github.com/python/cpython/issues/155485 - test: "VERSION=${pybasever} X='-i test_check_probes -i test_subparser_inherits_reparse_deferral' ./parallel.sh" + test: "VERSION=${pybasever} X='-i test_check_probes' ./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 -i test_subparser_inherits_reparse_deferral' ./parallel.sh" + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_base_interpreter' ./parallel.sh" - name: freethreadingtest path: /selftest test: "VERSION=${pybasever}t X='-i test_check_probes -i test_base_interpreter' ./parallel.sh" diff --git a/python3.14.spec b/python3.14.spec index ca7a4fe..3e9905f 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -261,7 +261,7 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\ BuildRequires: autoconf BuildRequires: bluez-libs-devel BuildRequires: bzip2-devel -BuildRequires: expat-devel +BuildRequires: expat-devel >= 2.5.0-2 BuildRequires: findutils BuildRequires: gcc BuildRequires: gdbm-devel @@ -392,14 +392,24 @@ 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 # e10760fb955ee33d2917f8a57bb4e24d71e5341c -# Downstream only: Skip tests not working with older expat version +# 00466 # 713a1368544eddd55088d67f88a23ce31722a4cb +# Downstream only: Lower XML_COMBINED_VERSION threshold for reparse deferral # -# 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 +# 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 # 00475 # 91e12ebfb2a88b265f3764a0d852b6fa53b2386a # CVE-2025-15367 @@ -619,10 +629,12 @@ Requires: tzdata # 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}' expat.%{_target_cpu} | sed 's/.*not installed/0/') +%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 @@ -1485,7 +1497,6 @@ CheckPython() { # 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_subparser_inherits_reparse_deferral: https://github.com/python/cpython/issues/155485 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1494,9 +1505,6 @@ CheckPython() { --timeout=2700 \ %endif -i test_check_probes \ - %if 0%{?rhel} == 9 - -i test_subparser_inherits_reparse_deferral \ - %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1986,6 +1994,9 @@ 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 From c1b886b3b63ce10a55375d1e6eee4722ad2917e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 18 Aug 2026 16:14:55 +0200 Subject: [PATCH 83/88] Fix a typo in freethreading-devel package summary Caught by rpmlint spelling-error check. --- python3.14.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python3.14.spec b/python3.14.spec index 3e9905f..2d68d27 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -860,7 +860,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 evelopment +Summary: Libraries and header files needed for Free Threading Python development # Bundled mimalloc header files are MIT License: Python-2.0.1 AND MIT Requires: python%{pybasever}-freethreading = %{version}-%{release} From f4716cbb08982f85d1a38fa16987de9ad1f8f2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 18 Aug 2026 16:18:10 +0200 Subject: [PATCH 84/88] rpmlint: CPython is not a spelling error Also, the output looks different now: python3.15-freethreading.x86_64: E: spelling-error ("CPython's", "%description -l en_US CPython's -> C Python's, Python's, Pynchon's") python3.15-freethreading-devel.x86_64: E: spelling-error ('evelopment', 'Summary(en_US) evelopment -> envelopment, development, elopement') --- rpmlint.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpmlint.toml b/rpmlint.toml index 9ddef32..1cc1623 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -104,6 +104,6 @@ Filters = [ '\bpython3(\.\d+)?\.(src|spec): (E|W): specfile-error\s+$', # SPELLING ERRORS - 'spelling-error .* en_US (bytecode|pyc|filename|tkinter|namespaces|pytest|unittest|gil) ', + 'spelling-error .*\b(bytecode|pyc|filename|tkinter|namespaces|pytest|unittest|gil|CPython)\b', ] From bef861129d165208a595b6261eb9a825e3a60779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 19 Aug 2026 11:41:30 +0200 Subject: [PATCH 85/88] rpmlint: Extend the rule about no-documentation for freethreading subpackages This avoids: python3.15-freethreading-devel.aarch64: W: no-documentation python3.15-freethreading-devel.i686: W: no-documentation python3.15-freethreading-devel.ppc64le: W: no-documentation python3.15-freethreading-devel.s390x: W: no-documentation python3.15-freethreading-devel.x86_64: W: no-documentation python3.15-freethreading-idle.aarch64: W: no-documentation python3.15-freethreading-idle.i686: W: no-documentation python3.15-freethreading-idle.ppc64le: W: no-documentation python3.15-freethreading-idle.s390x: W: no-documentation python3.15-freethreading-idle.x86_64: W: no-documentation python3.15-freethreading-test.aarch64: W: no-documentation python3.15-freethreading-test.i686: W: no-documentation python3.15-freethreading-test.ppc64le: W: no-documentation python3.15-freethreading-test.s390x: W: no-documentation python3.15-freethreading-test.x86_64: W: no-documentation python3.15-freethreading-tkinter.aarch64: W: no-documentation python3.15-freethreading-tkinter.i686: W: no-documentation python3.15-freethreading-tkinter.ppc64le: W: no-documentation python3.15-freethreading-tkinter.s390x: W: no-documentation python3.15-freethreading-tkinter.x86_64: W: no-documentation --- rpmlint.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpmlint.toml b/rpmlint.toml index 1cc1623..169e95a 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -58,7 +58,7 @@ Filters = [ 'no-manual-page-for-binary python3\.\d+t?dm?$', # missing documentation from subpackages - '^python3(\.\d+)?-(freethreading(-debug)?|debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation', + '^python3(\.\d+)?-(freethreading(-\w+)?|debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation', # platform python is obsoleted, but not provided 'obsolete-not-provided platform-python', From bd2563ea4734eb20df5b54c5f92c1c4abe915baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 19 Aug 2026 11:44:07 +0200 Subject: [PATCH 86/88] rpmlint: Do not report idle as no-binary python3-idle.i686: E: no-binary python3.15-freethreading-idle.i686: E: no-binary We know this and we don't care. We won't make this noarch. It installs to lib64. Assisted-By: Claude Opus 4.6 --- rpmlint.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rpmlint.toml b/rpmlint.toml index 169e95a..e052f3f 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -60,6 +60,9 @@ Filters = [ # 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', + # platform python is obsoleted, but not provided 'obsolete-not-provided platform-python', From 79d64abadf52b8e4274519414c548e741c07df27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 19 Aug 2026 11:47:14 +0200 Subject: [PATCH 87/88] rpmlint: Also ignore file-not-in-%lang in tests This avoids: python3-test.aarch64: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/fuzzy.mo python3-test.aarch64: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/general.mo python3-test.i686: W: file-not-in-%lang /usr/lib/python3.15/test/test_tools/msgfmt_data/fuzzy.mo python3-test.i686: W: file-not-in-%lang /usr/lib/python3.15/test/test_tools/msgfmt_data/general.mo python3-test.ppc64le: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/fuzzy.mo python3-test.ppc64le: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/general.mo python3-test.s390x: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/fuzzy.mo python3-test.s390x: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/general.mo python3-test.x86_64: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/fuzzy.mo python3-test.x86_64: W: file-not-in-%lang /usr/lib64/python3.15/test/test_tools/msgfmt_data/general.mo python3.15-freethreading-test.aarch64: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/fuzzy.mo python3.15-freethreading-test.aarch64: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/general.mo python3.15-freethreading-test.i686: W: file-not-in-%lang /usr/lib/python3.15t/test/test_tools/msgfmt_data/fuzzy.mo python3.15-freethreading-test.i686: W: file-not-in-%lang /usr/lib/python3.15t/test/test_tools/msgfmt_data/general.mo python3.15-freethreading-test.ppc64le: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/fuzzy.mo python3.15-freethreading-test.ppc64le: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/general.mo python3.15-freethreading-test.s390x: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/fuzzy.mo python3.15-freethreading-test.s390x: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/general.mo python3.15-freethreading-test.x86_64: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/fuzzy.mo python3.15-freethreading-test.x86_64: W: file-not-in-%lang /usr/lib64/python3.15t/test/test_tools/msgfmt_data/general.mo --- rpmlint.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpmlint.toml b/rpmlint.toml index e052f3f..30ad48f 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -6,7 +6,7 @@ Filters = [ # TESTS: - '(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3\.\d+t?/test', + '(zero-length|pem-certificate|uncompressed-zip|file-not-in-%lang) /usr/lib(64)?/python3\.\d+t?/test', # OTHER DELIBERATES: From 2260bebdb9fdb31f58f77cdec0e8ce5f65e24b32 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 24 Aug 2026 13:39:06 +0200 Subject: [PATCH 88/88] rpmlint: Filter out obsolete-not-provided for freethreading subpackages The package has been split from a single -freethreading one. This avoids: python3.14-freethreading-devel.aarch64: W: obsolete-not-provided python3.14-freethreading python3.14-freethreading-devel.i686: W: obsolete-not-provided python3.14-freethreading python3.14-freethreading-devel.ppc64le: W: obsolete-not-provided python3.14-freethreading python3.14-freethreading-devel.s390x: W: obsolete-not-provided python3.14-freethreading python3.14-freethreading-devel.x86_64: W: obsolete-not-provided python3.14-freethreading python3.14-freethreading-idle.aarch64: W: obsolete-not-provided python3.14-freethreading ... --- rpmlint.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rpmlint.toml b/rpmlint.toml index 30ad48f..7ed20ba 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -21,6 +21,9 @@ 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})',