From 05411b4c04c36e05ee5df8ea8fe388fd185e4dc1 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 7 May 2025 20:22:24 +0200 Subject: [PATCH 01/70] 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 02/70] 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 03/70] 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 04/70] 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 05/70] 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 06/70] 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 07/70] 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 08/70] 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 09/70] 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 10/70] 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 11/70] 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 12/70] 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 13/70] 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 14/70] 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 15/70] 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 16/70] 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 17/70] 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 18/70] 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 19/70] 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 20/70] 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 21/70] 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 22/70] 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 23/70] 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 24/70] 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 25/70] 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 26/70] 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 27/70] 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 28/70] 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 29/70] 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 30/70] 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 31/70] 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 32/70] 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 33/70] 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 34/70] 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 35/70] 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 36/70] 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 37/70] 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 38/70] 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 39/70] 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 40/70] 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 41/70] 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 42/70] 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 43/70] 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 44/70] 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 45/70] 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 46/70] 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 47/70] 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 48/70] 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 49/70] 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 50/70] 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 51/70] 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 52/70] 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 53/70] 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 54/70] 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 55/70] 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 56/70] 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 57/70] 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 58/70] 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 59/70] 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 60/70] 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 61/70] 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 62/70] 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 63/70] 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 64/70] 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 65/70] 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 66/70] 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 67/70] 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 68/70] 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 69/70] 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 70/70] 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})',