From 34677179536a7876efadc8510bb8befca4e41da55e563f77632068567b5cf3a7 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Fri, 14 Mar 2025 22:57:44 +0000
Subject: [PATCH 01/32] Accepting request 1253127 from devel:LoongArch:Factory
- don't require rpm-build-python for base to fix bootstrap issue
after primary_python change
- replace rpm-build-python alias with python-rpm-packaging package name
OBS-URL: https://build.opensuse.org/request/show/1253127
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=85
---
python313.changes | 7 +++++++
python313.spec | 6 ++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/python313.changes b/python313.changes
index 5678ee5..5c1088b 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Fri Mar 14 08:39:01 UTC 2025 - Adrian Schröter
+
+- don't require rpm-build-python for base to fix bootstrap issue
+ after primary_python change
+- replace rpm-build-python alias with python-rpm-packaging package name
+
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index ad9488a..05d6d30 100644
--- a/python313.spec
+++ b/python313.spec
@@ -238,8 +238,10 @@ BuildRequires: pkgconfig(uuid)
BuildRequires: pkgconfig(zlib)
#!BuildIgnore: gdk-pixbuf-loader-rsvg
%if 0%{?suse_version} >= 1550
-# The provider for python(abi) is in rpm-build-python
-BuildRequires: rpm-build-python
+# The provider for python(abi) is in python-rpm-packaging
+%if "%{flavor}" != "base"
+BuildRequires: python-rpm-packaging
+%endif
%endif
%if 0%{?suse_version} >= 1500 && 0%{?suse_version} < 1599
BuildRequires: pkgconfig(libnsl)
From 415df5f3cd200411cb7440b553ffeb635443c3b70b4f1e158134f5473836f521 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Fri, 11 Apr 2025 06:10:15 +0000
Subject: [PATCH 02/32] Accepting request 1268534 from
devel:languages:python:Factory
revert
OBS-URL: https://build.opensuse.org/request/show/1268534
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=86
---
python313.changes | 7 -------
python313.spec | 6 ++----
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/python313.changes b/python313.changes
index 5c1088b..5678ee5 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,10 +1,3 @@
--------------------------------------------------------------------
-Fri Mar 14 08:39:01 UTC 2025 - Adrian Schröter
-
-- don't require rpm-build-python for base to fix bootstrap issue
- after primary_python change
-- replace rpm-build-python alias with python-rpm-packaging package name
-
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index 05d6d30..ad9488a 100644
--- a/python313.spec
+++ b/python313.spec
@@ -238,10 +238,8 @@ BuildRequires: pkgconfig(uuid)
BuildRequires: pkgconfig(zlib)
#!BuildIgnore: gdk-pixbuf-loader-rsvg
%if 0%{?suse_version} >= 1550
-# The provider for python(abi) is in python-rpm-packaging
-%if "%{flavor}" != "base"
-BuildRequires: python-rpm-packaging
-%endif
+# The provider for python(abi) is in rpm-build-python
+BuildRequires: rpm-build-python
%endif
%if 0%{?suse_version} >= 1500 && 0%{?suse_version} < 1599
BuildRequires: pkgconfig(libnsl)
From 9624a1ae7e99787c5b933b540497572e7b1bdd27c121136ae3fe2e22b39dd154 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Fri, 11 Apr 2025 19:56:43 +0000
Subject: [PATCH 03/32] - Update to 3.13.3: - Tools/Demos - gh-131852:
msgfmt no longer adds the POT-Creation-Date to generated .mo files for
consistency with GNU msgfmt. - gh-85012: Correctly reset msgctxt when
compiling messages in msgfmt. - gh-130025: The iOS testbed now
correctly handles symlinks used as Python framework references. -
Tests - gh-131050: test_ssl.test_dh_params is skipped if the
underlying TLS library does not support finite-field ephemeral
Diffie-Hellman. - gh-129200: Multiple iOS testbed runners can now be
started at the same time without introducing an ambiguity over
simulator ownership. - gh-130292: The iOS testbed will now run
successfully on a machine that has not previously run Xcode tests (such
as CI configurations). - gh-130293: The tests of terminal
colorization are no longer sensitive to the value of the TERM variable
in the testing environment. - gh-126332: Add unit tests for pyrepl.
- Security - gh-131809: Update bundled libexpat to 2.7.1 -
gh-131261: Upgrade to libexpat 2.7.0 - gh-127371: Avoid unbounded
buffering for tempfile.SpooledTemporaryFile.writelines(). Previously,
disk spillover was only checked after the lines iterator had been
exhausted. This is now done after each line is written.
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=87
---
F00251-change-user-install-location.patch | 26 +-
Python-3.13.2.tar.xz | 3 -
Python-3.13.2.tar.xz.sigstore | 1 -
Python-3.13.3.tar.xz | 3 +
Python-3.13.3.tar.xz.sigstore | 1 +
bpo-31046_ensurepip_honours_prefix.patch | 66 +++---
doc-py38-to-py36.patch | 106 +++++----
python313.changes | 274 ++++++++++++++++++++++
python313.spec | 2 +-
subprocess-raise-timeout.patch | 31 ++-
10 files changed, 411 insertions(+), 102 deletions(-)
delete mode 100644 Python-3.13.2.tar.xz
delete mode 100644 Python-3.13.2.tar.xz.sigstore
create mode 100644 Python-3.13.3.tar.xz
create mode 100644 Python-3.13.3.tar.xz.sigstore
diff --git a/F00251-change-user-install-location.patch b/F00251-change-user-install-location.patch
index a08004d..0e67e07 100644
--- a/F00251-change-user-install-location.patch
+++ b/F00251-change-user-install-location.patch
@@ -28,9 +28,11 @@ Co-authored-by: Lumír Balhar
Lib/test/test_sysconfig.py | 17 +++++++++++--
2 files changed, 67 insertions(+), 7 deletions(-)
---- a/Lib/sysconfig/__init__.py
-+++ b/Lib/sysconfig/__init__.py
-@@ -106,6 +106,11 @@ if os.name == 'nt':
+Index: Python-3.13.3/Lib/sysconfig/__init__.py
+===================================================================
+--- Python-3.13.3.orig/Lib/sysconfig/__init__.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Lib/sysconfig/__init__.py 2025-04-11 21:52:31.769387873 +0200
+@@ -106,6 +106,11 @@
else:
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
@@ -42,7 +44,7 @@ Co-authored-by: Lumír Balhar
def _get_implementation():
return 'Python'
-@@ -167,13 +172,28 @@ if _HAS_USER_BASE:
+@@ -167,13 +172,28 @@
},
}
@@ -71,7 +73,7 @@ Co-authored-by: Lumír Balhar
_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
# Mutex guarding initialization of _CONFIG_VARS.
_CONFIG_VARS_LOCK = threading.RLock()
-@@ -259,11 +279,40 @@ def _extend_dict(target_dict, other_dict
+@@ -266,11 +286,40 @@
target_dict[key] = value
@@ -113,7 +115,7 @@ Co-authored-by: Lumír Balhar
if os.name == 'nt':
# On Windows we want to substitute 'lib' for schemes rather
# than the native value (without modifying vars, in case it
-@@ -464,10 +513,8 @@ def _init_config_vars():
+@@ -471,10 +520,8 @@
# Normalized versions of prefix and exec_prefix are handy to have;
# in fact, these are the standard versions used most places in the
# Distutils.
@@ -126,9 +128,11 @@ Co-authored-by: Lumír Balhar
_CONFIG_VARS['py_version'] = _PY_VERSION
_CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
_CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT
---- a/Lib/test/test_sysconfig.py
-+++ b/Lib/test/test_sysconfig.py
-@@ -130,8 +130,19 @@ class TestSysConfig(unittest.TestCase):
+Index: Python-3.13.3/Lib/test/test_sysconfig.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_sysconfig.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Lib/test/test_sysconfig.py 2025-04-11 21:52:31.769841915 +0200
+@@ -130,8 +130,19 @@
for scheme in _INSTALL_SCHEMES:
for name in _INSTALL_SCHEMES[scheme]:
expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars)
@@ -149,7 +153,7 @@ Co-authored-by: Lumír Balhar
os.path.normpath(expected),
)
-@@ -386,7 +397,7 @@ class TestSysConfig(unittest.TestCase):
+@@ -386,7 +397,7 @@
self.assertTrue(os.path.isfile(config_h), config_h)
def test_get_scheme_names(self):
@@ -158,7 +162,7 @@ Co-authored-by: Lumír Balhar
if HAS_USER_BASE:
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
-@@ -398,6 +409,8 @@ class TestSysConfig(unittest.TestCase):
+@@ -398,6 +409,8 @@
cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
diff --git a/Python-3.13.2.tar.xz b/Python-3.13.2.tar.xz
deleted file mode 100644
index a64a7f0..0000000
--- a/Python-3.13.2.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d984bcc57cd67caab26f7def42e523b1c015bbc5dc07836cf4f0b63fa159eb56
-size 22621108
diff --git a/Python-3.13.2.tar.xz.sigstore b/Python-3.13.2.tar.xz.sigstore
deleted file mode 100644
index 8b40472..0000000
--- a/Python-3.13.2.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAk+gAwIBAgIUD4NQdNCt1/K/JvAVyjbYigv67kIwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwMjA0MTg0NTIwWhcNMjUwMjA0MTg1NTIwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbqber3xDbIeHx40nXMQZcd3gsTxtq8e1TFD0eK7Im8V+dqVIRPey2E6BcnbwGMvL1q1qmTwGdUn5RPbFaehz7qOCAW4wggFqMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUSuhJIwDMV36A3eaykAuKcN4RnOEwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGJBgorBgEEAdZ5AgQCBHsEeQB3AHUA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGU0kf7wwAABAMARjBEAiAfqmC3I+sDSrXCjgOsO6Ur44c7jeAGRRwc7KdbXRBMzgIgAgcS4SWPdkxXIHicW4DulEn3ulaL3FVHBRLoNQW0JTcwCgYIKoZIzj0EAwMDaQAwZgIxAJ2T2M+pFCUERzOgZct1jxZpk9pgSQyuBU57U4/Hj3xKC12+PDgGcikx1FrC1wwr5wIxAJ156hL8usRvVGskEtmpiuTbaT9+zPgDjWfkvhx6b3Pdrn08XaQJ9EN9jiLrbeBM9g=="}, "tlogEntries": [{"logIndex": "168670065", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1738694720", "inclusionPromise": {"signedEntryTimestamp": "MEUCIAekV+blODko91xI2vm15TtdYBXhj8UF28Yt+cMx33rrAiEA0A6bc18P1q3drg9y9nR53/m8DXoKwsTEZm5yZ5+JFa4="}, "inclusionProof": {"logIndex": "46765803", "rootHash": "33ULyWL9ydLeQexNIooy3SJNY9i3ryqihkcOKvsQFF4=", "treeSize": "46765804", "hashes": ["3v2kqP/86p78AkWzBhXN+cNw9IypWJVk1oLovoNewtw=", "hymqDI9hjW2a2SKx04PIeTgJIL2IITHnQP5iCfIzoKM=", "om9oCy1VrcALPEQhPkoPogYSHHCAjFbWSLZJuHEfapo=", "opVQSZr0TT+f4kq/+ypm8ifo78VX/rg2sMxpk3Q6ZYQ=", "u+Mk6XwpHu128vzvk1pAczTT6FfryNB+dIhXYEj/H8c=", "625NsawEzZEukjE6mmJJ6hFySLGojGI4BGm8cRxwv68=", "5S8IyLnwlAhLZBEUNH1SaLO2dckc8NKwnGVgAO+3QQI=", "3onlfMyeVMDSIvH0BhkTTMYIWUuOZa+vitTl74eA7yo=", "TgYmpZ2JTTWko4kWZxTIAYkJpJpeOjVCg6ICKYnUS+8=", "PAMmlBIG22MGowjyiChYp5iB6NiTRa0xKI2vnvpExek=", "NS61TOUCaTiUJotPDnr7bTP/1ogKsWSnbgDlk1uvGzM=", "MvEBWaRrd43Pq04mjOFzGW9RiqBSzMBfuFXKBIVtQnc=", "Zse3BPkR/cJv62LvVuiDH+EpgIE5v3V3qXdG8HQFf1A=", "jU9+tgjTIKUYGeU7T7RjqyL+F+gFV9tCdwX2GZ1UtQs=", "vemyaMj0Na1LMjbB/9Dmkq8T+jAb3o+yCESgAayUABU="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n46765804\n33ULyWL9ydLeQexNIooy3SJNY9i3ryqihkcOKvsQFF4=\n\n\u2014 rekor.sigstore.dev wNI9ajBGAiEA+12Y0eYDOViIlr8UQrapNyarHE/PGGfC7iXrAHr0R2cCIQC0FJWVaUHoTxuMaM3KvZaY1toGa6U5sj9BcrhnwcEQ8A==\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJkOTg0YmNjNTdjZDY3Y2FhYjI2ZjdkZWY0MmU1MjNiMWMwMTViYmM1ZGMwNzgzNmNmNGYwYjYzZmExNTllYjU2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUNMQXBvUGEvQ0FZbVAxS0FSQ3Vmb1J6L1V2RVJhbDRKcnNkNXl4NmtleHpnSWdicEFIaUFTSjBDY2FKZm5LczFzL0VtZW0ybDNyT2svODdITVZaR0gwUUlJPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVdzclowRjNTVUpCWjBsVlJEUk9VV1JPUTNReEwwc3ZTblpCVm5scVlsbHBaM1kyTjJ0SmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDFxUVRCTlZHY3dUbFJKZDFkb1kwNU5hbFYzVFdwQk1FMVVaekZPVkVsM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZpY1dKbGNqTjRSR0pKWlVoNE5EQnVXRTFSV21Oa00yZHpWSGgwY1RobE1WUkdSREFLWlVzM1NXMDRWaXRrY1ZaSlVsQmxlVEpGTmtKamJtSjNSMDEyVERGeE1YRnRWSGRIWkZWdU5WSlFZa1poWldoNk4zRlBRMEZYTkhkblowWnhUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZUZFdoS0NrbDNSRTFXTXpaQk0yVmhlV3RCZFV0alRqUlNiazlGZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwcENaMjl5UW1kRlJVRmtXalZCWjFGRFFraHpSV1ZSUWpNS1FVaFZRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIVlRCclpqZDNkMEZCUWtGTlFRcFNha0pGUVdsQlpuRnRRek5KSzNORVUzSllRMnBuVDNOUE5sVnlORFJqTjJwbFFVZFNVbmRqTjB0a1lsaFNRazE2WjBsblFXZGpVelJUVjFCa2EzaFlDa2xJYVdOWE5FUjFiRVZ1TTNWc1lVd3pSbFpJUWxKTWIwNVJWekJLVkdOM1EyZFpTVXR2V2tsNmFqQkZRWGROUkdGUlFYZGFaMGw0UVVveVZESk5LM0FLUmtOVlJWSjZUMmRhWTNReGFuaGFjR3M1Y0dkVFVYbDFRbFUxTjFVMEwwaHFNM2hMUXpFeUsxQkVaMGRqYVd0NE1VWnlRekYzZDNJMWQwbDRRVW94TlFvMmFFdzRkWE5TZGxaSGMydEZkRzF3YVhWVVltRlVPU3Q2VUdkRWFsZG1hM1pvZURaaU0xQmtjbTR3T0ZoaFVVbzVSVTQ1YW1sTWNtSmxRazA1WnowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "2YS8xXzWfKqyb33vQuUjscAVu8XcB4Ns9PC2P6FZ61Y="}, "signature": "MEUCIQCLApoPa/CAYmP1KARCufoRz/UvERal4Jrsd5yx6kexzgIgbpAHiASJ0CcaJfnKs1s/Emem2l3rOk/87HMVZGH0QII="}}
diff --git a/Python-3.13.3.tar.xz b/Python-3.13.3.tar.xz
new file mode 100644
index 0000000..124c035
--- /dev/null
+++ b/Python-3.13.3.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:40f868bcbdeb8149a3149580bb9bfd407b3321cd48f0be631af955ac92c0e041
+size 22654240
diff --git a/Python-3.13.3.tar.xz.sigstore b/Python-3.13.3.tar.xz.sigstore
new file mode 100644
index 0000000..220fba8
--- /dev/null
+++ b/Python-3.13.3.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUW58MW2P+CwyzYzHaIuAK12gGJqIwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNDA4MTcwOTUwWhcNMjUwNDA4MTcxOTUwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf+cTSQIElx0bw4BYf2qpKSxfUtm3PhehuBcTW3uoM+EnAUOv1pvCmnTteblYdA5s80cFMzvztRCKUCnvBTi+cKOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU/72Qdhdl1+U/9MdaCnja9KhnRBgwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGWFmEv3gAABAMARzBFAiBJV9Vq6+FQfjXs74fcGUOsuBsMdCS1SzabcwCeFgO4UgIhAI1uOTXNb3iARGgglGWmTHeplKpGCHj+9yCPticrd2TrMAoGCCqGSM49BAMDA2gAMGUCMBRlMgfY9hXwAO7OtJpDIecgS9xyghjq/ECzfX12I1rDnF1i9DDr/1AY2SsOpAEW/AIxANwA+iMGDPdrvrp6iQtONa/37WhvKJQ+pglUHcrMcsZobpRHyD7shomq0SkxYA+icg=="}, "tlogEntries": [{"logIndex": "194024100", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1744132190", "inclusionPromise": {"signedEntryTimestamp": "MEQCIGlOwO+ANhog+/QCGrUQpJZ6axA6UaE86sNaN8vNj+QiAiA/7d5r4Em9+T6ZnAoc+BLv2ExsJcG8OCgqJvvF5ZJuxw=="}, "inclusionProof": {"logIndex": "72119838", "rootHash": "WvXJaELSoRtosW8xi2EfnsHoXkmpACSbqywq8TfHR1s=", "treeSize": "72119843", "hashes": ["jgENOnZn6TEf8ylEIYa0JR6FDNY+6ehLszSGwnEMpQU=", "n4F70M6fgFOoXeQXsHA3dWN3ASf9JTc8Z1qQuECW75M=", "RgczeejL0XzzT46BcDe3Z4s9D2QcpqnLv4M8+1//nUY=", "sfHyJ5ybNWBxYHNTEvBl90AOfY+44p++5XzDCBTB5RQ=", "JqDONCapxnE2xLLKg9gRz2xF/70qW/AT/GEk0BrOTw4=", "Kzx15aA9iYz3QmqQyoe03wPppaDYPNVmJeN2J8wCAR4=", "V5ZRP+iiphMoS6raAUPBERnIOeTUs8417+6gSEKM/n4=", "759Ej7PWC5mfI+qe2WSvB/3yyxTCPVUcjobBVnw5UkY=", "thdh10t3YSAkcLudlXJR1SELWGQbnzOa8SAkNLF/CYo=", "BmjRaZPKQ5bVHiwShpJ9cZKgX1rQ4iJrYo2rcEntw0o=", "Wr475nJfgYQLV7M6HuAo4zRJeK0nVZeV5zBNbie9m9U=", "cBeUncMhaAbVvOdQXg7Ev8AuOxlXrF0R/+5x1+5nmIo=", "K26LG80DXyb+bC58c4Nw00WigG52v0PCsZGY3ExGsts=", "WEm5OgPzJpYROv+4CcrieexCYyQKrLUH3hbxmcQQ+DM=", "7v8qPHNDLerpduaMx06eb/MwgoQwczTn/cYGKX/9wZ4="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n72119843\nWvXJaELSoRtosW8xi2EfnsHoXkmpACSbqywq8TfHR1s=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiAr3CtxLPjTl8zeJINGRTEhV2fchhMWTABj0kKfwmDvMwIgQYxaVBOI8NhmcU1YpPa7KD6770ZIC5invnZfRa/OpiU=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI0MGY4NjhiY2JkZWI4MTQ5YTMxNDk1ODBiYjliZmQ0MDdiMzMyMWNkNDhmMGJlNjMxYWY5NTVhYzkyYzBlMDQxIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUURHbFBQYytoNS9QVm9qaHRnUkdOc3A4NW9iT3d1YkVVVXN6REZWSmE2ZVVRSWhBSnlYVTlWeGNSNHR6WmJyVmtOeDBPMnJvc01xV1lVYXNtMGMxZmlndDFkZSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVlZ6VTRUVmN5VUN0RGQzbDZXWHBJWVVsMVFVc3hNbWRIU25GSmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDVFUVRSTlZHTjNUMVJWZDFkb1kwNU5hbFYzVGtSQk5FMVVZM2hQVkZWM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZtSzJOVVUxRkpSV3g0TUdKM05FSlpaakp4Y0V0VGVHWlZkRzB6VUdobGFIVkNZMVFLVnpOMWIwMHJSVzVCVlU5Mk1YQjJRMjF1VkhSbFlteFpaRUUxY3pnd1kwWk5lblo2ZEZKRFMxVkRiblpDVkdrclkwdFBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlV2TnpKUkNtUm9aR3d4SzFVdk9VMWtZVU51YW1FNVMyaHVVa0puZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIVjBadFJYWXpaMEZCUWtGTlFRcFNla0pHUVdsQ1NsWTVWbkUySzBaUlptcFljemMwWm1OSFZVOXpkVUp6VFdSRFV6RlRlbUZpWTNkRFpVWm5UelJWWjBsb1FVa3hkVTlVV0U1aU0ybEJDbEpIWjJkc1IxZHRWRWhsY0d4TGNFZERTR29yT1hsRFVIUnBZM0prTWxSeVRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFVKU2JFMW5abGtLT1doWWQwRlBOMDkwU25CRVNXVmpaMU01ZUhsbmFHcHhMMFZEZW1aWU1USkpNWEpFYmtZeGFUbEVSSEl2TVVGWk1sTnpUM0JCUlZjdlFVbDRRVTUzUVFvcmFVMUhSRkJrY25aeWNEWnBVWFJQVG1Fdk16ZFhhSFpMU2xFcmNHZHNWVWhqY2sxamMxcHZZbkJTU0hsRU4zTm9iMjF4TUZOcmVGbEJLMmxqWnowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "QPhovL3rgUmjFJWAu5v9QHszIc1I8L5jGvlVrJLA4EE="}, "signature": "MEYCIQDGlPPc+h5/PVojhtgRGNsp85obOwubEUUszDFVJa6eUQIhAJyXU9VxcR4tzZbrVkNx0O2rosMqWYUasm0c1figt1de"}}
diff --git a/bpo-31046_ensurepip_honours_prefix.patch b/bpo-31046_ensurepip_honours_prefix.patch
index 98c61a0..b62eacf 100644
--- a/bpo-31046_ensurepip_honours_prefix.patch
+++ b/bpo-31046_ensurepip_honours_prefix.patch
@@ -5,28 +5,32 @@ Subject: [PATCH] bpo-31046: ensurepip does not honour the value of $(prefix)
Co-Authored-By: Xavier de Gaye
---
- Doc/library/ensurepip.rst | 9 +++--
+ Doc/library/ensurepip.rst | 12 +++++-
Lib/ensurepip/__init__.py | 18 +++++++---
Lib/test/test_ensurepip.py | 11 ++++++
Makefile.pre.in | 4 +-
Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst | 1
- 5 files changed, 34 insertions(+), 9 deletions(-)
+ 5 files changed, 37 insertions(+), 9 deletions(-)
create mode 100644 Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
---- a/Doc/library/ensurepip.rst
-+++ b/Doc/library/ensurepip.rst
-@@ -59,8 +59,9 @@ is at least as recent as the one availab
+Index: Python-3.13.3/Doc/library/ensurepip.rst
+===================================================================
+--- Python-3.13.3.orig/Doc/library/ensurepip.rst 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/library/ensurepip.rst 2025-04-11 21:54:47.449458319 +0200
+@@ -61,7 +61,11 @@
By default, ``pip`` is installed into the current virtual environment
(if one is active) or into the system site packages (if there is no
active virtual environment). The installation location can be controlled
-through two additional command line options:
+through some additional command line options:
++
++.. option:: --prefix
++
++ Installs ``pip`` using the given directory prefix.
-+* ``--prefix ``: Installs ``pip`` using the given directory prefix.
- * :samp:`--root {dir}`: Installs ``pip`` relative to the given root directory
- rather than the root of the currently active virtual environment (if any)
- or the default root for the current Python installation.
-@@ -92,7 +93,7 @@ Module API
+ .. option:: --root
+
+@@ -102,7 +106,7 @@
Returns a string specifying the available version of pip that will be
installed when bootstrapping an environment.
@@ -35,7 +39,7 @@ Co-Authored-By: Xavier de Gaye
altinstall=False, default_pip=False, \
verbosity=0)
-@@ -102,6 +103,8 @@ Module API
+@@ -112,6 +116,8 @@
If *root* is ``None``, then installation uses the default install location
for the current environment.
@@ -44,7 +48,7 @@ Co-Authored-By: Xavier de Gaye
*upgrade* indicates whether or not to upgrade an existing installation
of an earlier version of ``pip`` to the available version.
-@@ -122,6 +125,8 @@ Module API
+@@ -132,6 +138,8 @@
*verbosity* controls the level of output to :data:`sys.stdout` from the
bootstrapping operation.
@@ -53,9 +57,11 @@ Co-Authored-By: Xavier de Gaye
.. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap
.. note::
---- a/Lib/ensurepip/__init__.py
-+++ b/Lib/ensurepip/__init__.py
-@@ -106,27 +106,27 @@ def _disable_pip_configuration_settings(
+Index: Python-3.13.3/Lib/ensurepip/__init__.py
+===================================================================
+--- Python-3.13.3.orig/Lib/ensurepip/__init__.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Lib/ensurepip/__init__.py 2025-04-11 21:53:49.548370352 +0200
+@@ -106,27 +106,27 @@
os.environ['PIP_CONFIG_FILE'] = os.devnull
@@ -88,7 +94,7 @@ Co-Authored-By: Xavier de Gaye
Note that calling this function will alter both sys.path and os.environ.
"""
-@@ -162,6 +162,8 @@ def _bootstrap(*, root=None, upgrade=Fal
+@@ -162,6 +162,8 @@
args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir]
if root:
args += ["--root", root]
@@ -97,7 +103,7 @@ Co-Authored-By: Xavier de Gaye
if upgrade:
args += ["--upgrade"]
if user:
-@@ -238,6 +240,11 @@ def _main(argv=None):
+@@ -238,6 +240,11 @@
help="Install everything relative to this alternate root directory.",
)
parser.add_argument(
@@ -109,7 +115,7 @@ Co-Authored-By: Xavier de Gaye
"--altinstall",
action="store_true",
default=False,
-@@ -256,6 +263,7 @@ def _main(argv=None):
+@@ -256,6 +263,7 @@
return _bootstrap(
root=args.root,
@@ -117,9 +123,11 @@ Co-Authored-By: Xavier de Gaye
upgrade=args.upgrade,
user=args.user,
verbosity=args.verbosity,
---- a/Lib/test/test_ensurepip.py
-+++ b/Lib/test/test_ensurepip.py
-@@ -101,6 +101,17 @@ class TestBootstrap(EnsurepipMixin, unit
+Index: Python-3.13.3/Lib/test/test_ensurepip.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_ensurepip.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Lib/test/test_ensurepip.py 2025-04-11 21:53:49.548691764 +0200
+@@ -101,6 +101,17 @@
unittest.mock.ANY,
)
@@ -137,9 +145,11 @@ Co-Authored-By: Xavier de Gaye
def test_bootstrapping_with_user(self):
ensurepip.bootstrap(user=True)
---- a/Makefile.pre.in
-+++ b/Makefile.pre.in
-@@ -2139,7 +2139,7 @@ install: @FRAMEWORKINSTALLFIRST@ @INSTAL
+Index: Python-3.13.3/Makefile.pre.in
+===================================================================
+--- Python-3.13.3.orig/Makefile.pre.in 2025-04-11 21:52:35.635495820 +0200
++++ Python-3.13.3/Makefile.pre.in 2025-04-11 21:53:49.549094822 +0200
+@@ -2139,7 +2139,7 @@
install|*) ensurepip="" ;; \
esac; \
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
@@ -148,7 +158,7 @@ Co-Authored-By: Xavier de Gaye
fi
.PHONY: altinstall
-@@ -2150,7 +2150,7 @@ altinstall: commoninstall
+@@ -2150,7 +2150,7 @@
install|*) ensurepip="--altinstall" ;; \
esac; \
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
@@ -157,7 +167,9 @@ Co-Authored-By: Xavier de Gaye
fi
.PHONY: commoninstall
---- /dev/null
-+++ b/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
+Index: Python-3.13.3/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ Python-3.13.3/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst 2025-04-11 21:53:49.549612071 +0200
@@ -0,0 +1 @@
+A directory prefix can now be specified when using :mod:`ensurepip`.
diff --git a/doc-py38-to-py36.patch b/doc-py38-to-py36.patch
index baf1d0a..28a725d 100644
--- a/doc-py38-to-py36.patch
+++ b/doc-py38-to-py36.patch
@@ -8,9 +8,11 @@
Doc/tools/extensions/patchlevel.py | 9 ++---
7 files changed, 87 insertions(+), 66 deletions(-)
---- a/Doc/conf.py
-+++ b/Doc/conf.py
-@@ -17,6 +17,9 @@ sys.path.append(os.path.abspath('include
+Index: Python-3.13.3/Doc/conf.py
+===================================================================
+--- Python-3.13.3.orig/Doc/conf.py 2025-04-11 21:52:28.845065297 +0200
++++ Python-3.13.3/Doc/conf.py 2025-04-11 21:55:28.065280454 +0200
+@@ -18,6 +18,9 @@
# Python specific content from Doc/Tools/extensions/pyspecific.py
from pyspecific import SOURCE_URI
@@ -20,16 +22,16 @@
# General configuration
# ---------------------
-@@ -90,7 +93,7 @@ highlight_language = 'python3'
+@@ -92,7 +95,7 @@
# Minimum version of sphinx required
# Keep this version in sync with ``Doc/requirements.txt``.
--needs_sphinx = '8.1.3'
+-needs_sphinx = '8.2.0'
+needs_sphinx = '4.2.0'
# Create table of contents entries for domain objects (e.g. functions, classes,
# attributes, etc.). Default is True.
-@@ -359,7 +362,7 @@ html_short_title = f'{release} Documenta
+@@ -361,7 +364,7 @@
# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html)
is_deployment_preview = os.getenv("READTHEDOCS_VERSION_TYPE") == "external"
repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL", "")
@@ -38,7 +40,7 @@
html_context = {
"is_deployment_preview": is_deployment_preview,
"repository_url": repository_url or None,
-@@ -604,6 +607,16 @@ extlinks = {
+@@ -606,6 +609,16 @@
}
extlinks_detect_hardcoded_links = True
@@ -55,9 +57,11 @@
# Options for c_annotations extension
# -----------------------------------
---- a/Doc/tools/check-warnings.py
-+++ b/Doc/tools/check-warnings.py
-@@ -228,7 +228,8 @@ def fail_if_regression(
+Index: Python-3.13.3/Doc/tools/check-warnings.py
+===================================================================
+--- Python-3.13.3.orig/Doc/tools/check-warnings.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/tools/check-warnings.py 2025-04-11 21:55:11.212002463 +0200
+@@ -228,7 +228,8 @@
print(filename)
for warning in warnings:
if filename in warning:
@@ -67,8 +71,10 @@
print(" {line}: {msg}".format_map(match))
return -1
return 0
---- a/Doc/tools/extensions/audit_events.py
-+++ b/Doc/tools/extensions/audit_events.py
+Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
+===================================================================
+--- Python-3.13.3.orig/Doc/tools/extensions/audit_events.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/tools/extensions/audit_events.py 2025-04-11 21:55:11.212275615 +0200
@@ -1,9 +1,6 @@
"""Support for documenting audit events."""
@@ -79,7 +85,7 @@
from docutils import nodes
from sphinx.errors import NoUri
-@@ -12,12 +9,11 @@ from sphinx.transforms.post_transforms i
+@@ -12,12 +9,11 @@
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
@@ -96,7 +102,7 @@
logger = logging.getLogger(__name__)
-@@ -32,16 +28,16 @@ _SYNONYMS = [
+@@ -32,16 +28,16 @@
class AuditEvents:
def __init__(self) -> None:
@@ -117,7 +123,7 @@
) -> None:
if name in self.events:
self._check_args_match(name, args)
-@@ -49,7 +45,7 @@ class AuditEvents:
+@@ -49,7 +45,7 @@
self.events[name] = args
self.sources.setdefault(name, []).append(source)
@@ -126,7 +132,7 @@
current_args = self.events[name]
msg = (
f"Mismatched arguments for audit-event {name}: "
-@@ -60,7 +56,7 @@ class AuditEvents:
+@@ -60,7 +56,7 @@
if len(current_args) != len(args):
logger.warning(msg)
return
@@ -135,7 +141,7 @@
if a1 == a2:
continue
if any(a1 in s and a2 in s for s in _SYNONYMS):
-@@ -73,7 +69,7 @@ class AuditEvents:
+@@ -73,7 +69,7 @@
name_clean = re.sub(r"\W", "_", name)
return f"audit_event_{name_clean}_{source_count}"
@@ -144,7 +150,7 @@
for name in sorted(self.events.keys()):
yield name, self.events[name], self.sources[name]
-@@ -97,7 +93,7 @@ def audit_events_purge(
+@@ -97,7 +93,7 @@
def audit_events_merge(
app: Sphinx,
env: BuildEnvironment,
@@ -153,7 +159,7 @@
other: BuildEnvironment,
) -> None:
"""In Sphinx parallel builds, this merges audit_events from subprocesses."""
-@@ -126,14 +122,16 @@ class AuditEvent(SphinxDirective):
+@@ -126,14 +122,16 @@
),
]
@@ -176,7 +182,7 @@
else:
args = []
ids = []
-@@ -169,7 +167,7 @@ class audit_event_list(nodes.General, no
+@@ -169,7 +167,7 @@
class AuditEventListDirective(SphinxDirective):
@@ -185,7 +191,7 @@
return [audit_event_list()]
-@@ -181,7 +179,11 @@ class AuditEventListTransform(SphinxPost
+@@ -181,7 +179,11 @@
return
table = self._make_table(self.app.builder, self.env.docname)
@@ -198,7 +204,7 @@
node.replace_self(table)
def _make_table(self, builder: Builder, docname: str) -> nodes.table:
-@@ -217,8 +219,8 @@ class AuditEventListTransform(SphinxPost
+@@ -217,8 +219,8 @@
builder: Builder,
docname: str,
name: str,
@@ -209,8 +215,10 @@
) -> nodes.row:
row = nodes.row()
name_node = nodes.paragraph("", nodes.Text(name))
---- a/Doc/tools/extensions/availability.py
-+++ b/Doc/tools/extensions/availability.py
+Index: Python-3.13.3/Doc/tools/extensions/availability.py
+===================================================================
+--- Python-3.13.3.orig/Doc/tools/extensions/availability.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/tools/extensions/availability.py 2025-04-11 21:55:11.212578519 +0200
@@ -1,8 +1,6 @@
"""Support for documenting platform availability"""
@@ -221,7 +229,7 @@
from docutils import nodes
from sphinx import addnodes
-@@ -55,7 +53,7 @@ class Availability(SphinxDirective):
+@@ -55,7 +53,7 @@
optional_arguments = 0
final_argument_whitespace = True
@@ -230,7 +238,7 @@
title = sphinx_gettext("Availability")
refnode = addnodes.pending_xref(
title,
-@@ -79,7 +77,7 @@ class Availability(SphinxDirective):
+@@ -79,7 +77,7 @@
return [cnode]
@@ -239,7 +247,7 @@
"""Parse platform information from arguments
Arguments is a comma-separated string of platforms. A platform may
-@@ -98,12 +96,13 @@ class Availability(SphinxDirective):
+@@ -98,12 +96,13 @@
platform, _, version = arg.partition(" >= ")
if platform.startswith("not "):
version = False
@@ -255,7 +263,7 @@
logger.warning(
"Unknown platform%s or syntax '%s' in '.. availability:: %s', "
"see %s:KNOWN_PLATFORMS for a set of known platforms.",
-@@ -116,7 +115,7 @@ class Availability(SphinxDirective):
+@@ -116,7 +115,7 @@
return platforms
@@ -264,9 +272,11 @@
app.add_directive("availability", Availability)
return {
---- a/Doc/tools/extensions/c_annotations.py
-+++ b/Doc/tools/extensions/c_annotations.py
-@@ -9,22 +9,18 @@ Configuration:
+Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
+===================================================================
+--- Python-3.13.3.orig/Doc/tools/extensions/c_annotations.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/tools/extensions/c_annotations.py 2025-04-11 21:55:11.212780990 +0200
+@@ -9,22 +9,18 @@
* Set ``stable_abi_file`` to the path to stable ABI list.
"""
@@ -292,7 +302,7 @@
ROLE_TO_OBJECT_TYPE = {
"func": "function",
-@@ -35,20 +31,20 @@ ROLE_TO_OBJECT_TYPE = {
+@@ -35,20 +31,20 @@
}
@@ -317,7 +327,7 @@
class StableABIEntry:
# Role of the object.
# Source: Each [item_kind] in stable_abi.toml is mapped to a C Domain role.
-@@ -67,7 +63,7 @@ class StableABIEntry:
+@@ -67,7 +63,7 @@
struct_abi_kind: str
@@ -326,7 +336,7 @@
refcount_data = {}
refcounts = refcount_filename.read_text(encoding="utf8")
for line in refcounts.splitlines():
-@@ -103,7 +99,7 @@ def read_refcount_data(refcount_filename
+@@ -103,7 +99,7 @@
return refcount_data
@@ -335,7 +345,7 @@
stable_abi_data = {}
with open(stable_abi_file, encoding="utf8") as fp:
for record in csv.DictReader(fp):
-@@ -123,11 +119,14 @@ def add_annotations(app: Sphinx, doctree
+@@ -123,11 +119,14 @@
continue
if not par[0].get("ids", None):
continue
@@ -352,7 +362,7 @@
if ROLE_TO_OBJECT_TYPE[record.role] != objtype:
msg = (
f"Object type mismatch in limited API annotation for {name}: "
-@@ -234,7 +233,7 @@ def _unstable_api_annotation() -> nodes.
+@@ -234,7 +233,7 @@
)
@@ -361,7 +371,7 @@
classes = ["refcount"]
if result_refs is None:
rc = sphinx_gettext("Return value: Always NULL.")
-@@ -254,7 +253,7 @@ class LimitedAPIList(SphinxDirective):
+@@ -254,7 +253,7 @@
optional_arguments = 0
final_argument_whitespace = True
@@ -370,7 +380,7 @@
state = self.env.domaindata["c_annotations"]
content = [
f"* :c:{record.role}:`{record.name}`"
-@@ -277,13 +276,23 @@ def init_annotations(app: Sphinx) -> Non
+@@ -277,13 +276,23 @@
)
@@ -395,8 +405,10 @@
return {
"version": "1.0",
"parallel_read_safe": True,
---- a/Doc/tools/extensions/glossary_search.py
-+++ b/Doc/tools/extensions/glossary_search.py
+Index: Python-3.13.3/Doc/tools/extensions/glossary_search.py
+===================================================================
+--- Python-3.13.3.orig/Doc/tools/extensions/glossary_search.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/tools/extensions/glossary_search.py 2025-04-11 21:55:11.212983043 +0200
@@ -1,18 +1,14 @@
"""Feature search results for glossary items prominently."""
@@ -418,7 +430,7 @@
logger = logging.getLogger(__name__)
-@@ -52,7 +48,7 @@ def write_glossary_json(app: Sphinx, _ex
+@@ -52,7 +48,7 @@
dest.write_text(json.dumps(app.env.glossary_terms), encoding='utf-8')
@@ -427,8 +439,10 @@
app.connect('doctree-resolved', process_glossary_nodes)
app.connect('build-finished', write_glossary_json)
---- a/Doc/tools/extensions/patchlevel.py
-+++ b/Doc/tools/extensions/patchlevel.py
+Index: Python-3.13.3/Doc/tools/extensions/patchlevel.py
+===================================================================
+--- Python-3.13.3.orig/Doc/tools/extensions/patchlevel.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Doc/tools/extensions/patchlevel.py 2025-04-11 21:55:11.213150035 +0200
@@ -3,7 +3,7 @@
import re
import sys
@@ -438,7 +452,7 @@
CPYTHON_ROOT = Path(
__file__, # cpython/Doc/tools/extensions/patchlevel.py
-@@ -26,7 +26,7 @@ class version_info(NamedTuple): # noqa:
+@@ -26,7 +26,7 @@
major: int #: Major release number
minor: int #: Minor release number
micro: int #: Patch release number
@@ -447,7 +461,7 @@
serial: int #: Serial release number
-@@ -37,7 +37,8 @@ def get_header_version_info() -> version
+@@ -37,7 +37,8 @@
defines = {}
patchlevel_h = PATCHLEVEL_H.read_text(encoding="utf-8")
for line in patchlevel_h.splitlines():
@@ -457,7 +471,7 @@
name, value = m.groups()
defines[name] = value
-@@ -50,7 +51,7 @@ def get_header_version_info() -> version
+@@ -50,7 +51,7 @@
)
diff --git a/python313.changes b/python313.changes
index 5678ee5..34cf35d 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,277 @@
+-------------------------------------------------------------------
+Fri Apr 11 19:47:34 UTC 2025 - Matej Cepl
+
+- Update to 3.13.3:
+ - Tools/Demos
+ - gh-131852: msgfmt no longer adds the POT-Creation-Date to
+ generated .mo files for consistency with GNU msgfmt.
+ - gh-85012: Correctly reset msgctxt when compiling messages
+ in msgfmt.
+ - gh-130025: The iOS testbed now correctly handles symlinks
+ used as Python framework references.
+ - Tests
+ - gh-131050: test_ssl.test_dh_params is skipped if the
+ underlying TLS library does not support finite-field
+ ephemeral Diffie-Hellman.
+ - gh-129200: Multiple iOS testbed runners can now be started
+ at the same time without introducing an ambiguity over
+ simulator ownership.
+ - gh-130292: The iOS testbed will now run successfully on a
+ machine that has not previously run Xcode tests (such as CI
+ configurations).
+ - gh-130293: The tests of terminal colorization are no longer
+ sensitive to the value of the TERM variable in the testing
+ environment.
+ - gh-126332: Add unit tests for pyrepl.
+ - Security
+ - gh-131809: Update bundled libexpat to 2.7.1
+ - gh-131261: Upgrade to libexpat 2.7.0
+ - gh-127371: Avoid unbounded buffering for
+ tempfile.SpooledTemporaryFile.writelines(). Previously,
+ disk spillover was only checked after the lines iterator
+ had been exhausted. This is now done after each line is
+ written.
+ - gh-121284: Fix bug in the folding of rfc2047 encoded-words
+ when flattening an email message using a modern email
+ policy. Previously when an encoded-word was too long for
+ a line, it would be decoded, split across lines, and
+ re-encoded. But commas and other special characters in the
+ original text could be left unencoded and unquoted. This
+ could theoretically be used to spoof header lines using
+ a carefully constructed encoded-word if the resulting
+ rendered email was transmitted or re-parsed.
+ - Library
+ - gh-132174: Fix function name in error message of
+ _interpreters.run_string.
+ - gh-132171: Fix crash of _interpreters.run_string on string
+ subclasses.
+ - gh-129204: Introduce new _PYTHON_SUBPROCESS_USE_POSIX_SPAWN
+ environment variable knob in subprocess to control the use
+ of os.posix_spawn().
+ - gh-132159: Do not shadow user arguments in generated
+ __new__() by decorator warnings.deprecated. Patch by Xuehai
+ Pan.
+ - gh-132075: Fix possible use of socket address structures
+ with uninitialized members. Now all structure members are
+ initialized with zeroes by default.
+ - gh-132002: Fix crash when deallocating
+ contextvars.ContextVar with weird unahashable string names.
+ - gh-131668: socket: Fix code parsing AF_BLUETOOTH socket
+ addresses.
+ - gh-131492: Fix a resource leak when constructing a
+ gzip.GzipFile with a filename fails, for example when
+ passing an invalid compresslevel.
+ - gh-131325: Fix sendfile fallback implementation to drain
+ data after writing to transport in asyncio.
+ - gh-129843: Fix incorrect argument passing in
+ warnings.warn_explicit().
+ - gh-131204: Use monospace font from System Font Stack for
+ cross-platform support in difflib.HtmlDiff.
+ - gh-130940: The PyConfig.use_system_logger attribute,
+ introduced in Python 3.13.2, has been removed. The
+ introduction of this attribute inadvertently introduced an
+ ABI breakage on macOS and iOS. The use of the system logger
+ is now enabled by default on iOS, and disabled by default
+ on macOS.
+ - gh-131045: Fix issue with __contains__, values, and
+ pseudo-members for enum.Flag.
+ - gh-130959: Fix pure-Python implementation of
+ datetime.time.fromisoformat() to reject times with spaces
+ in fractional part (for example, 12:34:56.400 +02:00),
+ matching the C implementation. Patch by Michał Gorny.
+ - gh-130637: Add validation for numeric response data in
+ poplib.POP3.stat() method
+ - gh-130461: Remove .. index:: directives from the uuid
+ module documentation. These directives previously created
+ entries in the general index for getnode() as well as
+ the uuid1(), uuid3(), uuid4(), and uuid5() constructor
+ functions.
+ - gh-130379: The zipapp module now calculates the list of
+ files to be added to the archive before creating the
+ archive. This avoids accidentally including the target when
+ it is being created in the source directory.
+ - gh-130285: Fix corner case for random.sample() allowing the
+ counts parameter to specify an empty population. So now,
+ sample([], 0, counts=[]) and sample('abc', k=0, counts=[0,
+ 0, 0]) both give the same result as sample([], 0).
+ - gh-130250: Fix regression in traceback.print_last().
+ - gh-130230: Fix crash in pow() with only Decimal third
+ argument.
+ - gh-118761: Reverts a change in the previous release
+ attempting to make some stdlib imports used within the
+ subprocess module lazy as this was causing errors during
+ __del__ finalizers calling methods such as terminate, or
+ kill, or send_signal.
+ - gh-130164: Fixed failure to raise TypeError in
+ inspect.Signature.bind() for positional-only arguments
+ provided by keyword when a variadic keyword argument (e.g.
+ --kwargs) is present.
+ - gh-130151: Fix reference leaks in _hashlib.hmac_new() and
+ _hashlib.hmac_digest(). Patch by Bénédikt Tran.
+ - gh-130145: Fix asyncio.AbstractEventloop.run_forever() when
+ another loop is already running.
+ - gh-129726: Fix gzip.GzipFile raising an unraisable
+ exception during garbage collection when referring to
+ a temporary object by breaking the reference loop with
+ weakref.
+ - gh-127750: Remove broken functools.singledispatchmethod()
+ caching introduced in gh-85160.
+ - gh-129583: Update bundled pip to 25.0.1
+ - gh-97850: Update the deprecation warning of
+ importlib.abc.Loader.load_module().
+ - gh-129646: Update the locale alias mapping in the locale
+ module to match the latest X Org locale alias mapping and
+ support new locales in Glibc 2.41.
+ - gh-129603: Fix bugs where sqlite3.Row objects could
+ segfault if their inherited description was set to
+ None. Patch by Erlend Aasland.
+ - gh-128231: Execution of multiple statements in the new
+ REPL now stops immediately upon the first exception
+ encountered. Patch by Bartosz Sławecki.
+ - gh-117779: Fix reading duplicated entries in zipfile by
+ name. Reading duplicated entries (except the last one)
+ by ZipInfo now emits a warning instead of raising an
+ exception.
+ - gh-128772: Fix pydoc for methods with the __module__
+ attribute equal to None.
+ - gh-92897: Scheduled the deprecation of the check_home
+ argument of sysconfig.is_python_build() to Python 3.15.
+ - gh-128657: Fix possible extra reference when using objects
+ returned by hashlib.sha256() under free threading.
+ - gh-128703: Fix mimetypes.guess_type() to use default
+ mapping for empty Content-Type in registry.
+ - gh-128308: Support the name keyword argument
+ for eager tasks in asyncio.loop.create_task(),
+ asyncio.create_task() and asyncio.TaskGroup.create_task(),
+ by passing on all kwargs to the task factory set by
+ asyncio.loop.set_task_factory().
+ - gh-128388: Fix PyREPL on Windows to support more
+ keybindings, like the Control-← and Control-→ word-skipping
+ keybindings and those with meta (i.e. Alt), e.g. Alt-d to
+ kill-word or Alt-Backspace backward-kill-word.
+ - gh-126037: xml.etree.ElementTree: Fix a crash in
+ Element.find, Element.findtext and Element.findall when
+ the tag to find implements an __eq__() method mutating the
+ element being queried. Patch by Bénédikt Tran.
+ - gh-127712: Fix handling of the secure argument of
+ logging.handlers.SMTPHandler.
+ - gh-126033: xml.etree.ElementTree: Fix a crash in
+ Element.remove when the element is concurrently
+ mutated. Patch by Bénédikt Tran.
+ - gh-118201: Fixed intermittent failures of os.confstr,
+ os.pathconf and os.sysconf on iOS and Android.
+ - gh-124927: Non-printing characters are now properly handled
+ in the new REPL.
+ - IDLE
+ - gh-129873: Simplify displaying the IDLE doc by only copying
+ the text section of idle.html to idlelib/help.html. Patch
+ by Stan Ulbrych.
+ - Documentation
+ - gh-131417: Mention asyncio.Future and asyncio.Task in
+ generic classes list.
+ - gh-125722: Require Sphinx 8.2.0 or later to build the
+ Python documentation. Patch by Adam Turner.
+ - gh-129712: The wheel tags supported by each macOS universal
+ SDK option are now documented.
+ - gh-46236: C API: Document PyUnicode_RSplit(),
+ PyUnicode_Partition() and PyUnicode_RPartition().
+ - Core and Builtins
+ - gh-132011: Fix crash when calling list.append() as an
+ unbound method.
+ - gh-131998: Fix a crash when using an unbound method
+ descriptor object in a function where a bound method
+ descriptor was used.
+ - gh-131988: Fix a performance regression that caused scaling
+ bottlenecks in the free threaded build in 3.13.1 and
+ 3.13.2.
+ - gh-131719: Fix missing NULL check in _PyMem_FreeDelayed in
+ free-threaded build.
+ - gh-131670: Fix anext() failing on sync __anext__() raising
+ an exception.
+ - gh-131141: Fix data race in sys.monitoring instrumentation
+ while registering callback.
+ - gh-130932: Fix incorrect exception handling in
+ _PyModule_IsPossiblyShadowing
+ - gh-130851: Fix a crash in the free threading build when
+ constructing a code object with co_consts that contains
+ instances of types that are not otherwise generated by the
+ bytecode compiler.
+ - gh-130794: Fix memory leak in the free threaded build
+ when resizing a shared list or dictionary from multiple
+ short-lived threads.
+ - gh-130775: Do not crash on negative column and end_column
+ in ast locations.
+ - gh-130382: Fix PyRefTracer_DESTROY not being sent from
+ Python/ceval.c Py_DECREF().
+ - gh-130618: Fix a bug that was causing UnicodeDecodeError or
+ SystemError to be raised when using f-strings with lambda
+ expressions with non-ASCII characters. Patch by Pablo
+ Galindo
+ - gh-130163: Fix possible crashes related to concurrent
+ change and use of the sys module attributes.
+ - gh-88887: Fixing multiprocessing Resource Tracker process
+ leaking, usually observed when running Python as PID 1.
+ - gh-130115: Fix an issue with thread identifiers being
+ sign-extended on some platforms.
+ - gh-128396: Fix a crash that occurs when calling locals()
+ inside an inline comprehension that uses the same local
+ variable as the outer frame scope where the variable is a
+ free or cell var.
+ - gh-116042: Fix location for SyntaxErrors of invalid escapes
+ in the tokenizer. Patch by Pablo Galindo
+ - gh-129983: Fix data race in compile_template in sre.c.
+ - gh-129967: Fix a race condition in the free threading build
+ when repr(set) is called concurrently with set.clear().
+ - gh-129900: Fix return codes inside SystemExit not getting
+ returned by the REPL.
+ - gh-129732: Fixed a race in _Py_qsbr_reserve in the free
+ threading build.
+ - gh-129643: Fix thread safety of PyList_Insert() in
+ free-threading builds.
+ - gh-129668: Fix race condition when raising MemoryError in
+ the free threaded build.
+ - gh-129643: Fix thread safety of PyList_SetItem() in
+ free-threading builds. Patch by Kumar Aditya.
+ - gh-128714: Fix the potential races in get/set dunder
+ methods __annotations__, __annotate__ and __type_params__
+ for function object, and add related tests.
+ - gh-128632: Disallow __classdict__ as the name of a type
+ parameter. Using this name would previously crash the
+ interpreter in some circumstances.
+ - gh-127953: The time to handle a LINE event in
+ sys.monitoring (and sys.settrace) is now independent of the
+ number of lines in the code object.
+ - gh-125331: from __future__ import barry_as_FLUFL now works
+ in more contexts, including when it is used in files,
+ with the -c flag, and in the REPL when there are multiple
+ statements on the same line. Previously, it worked only
+ on subsequent lines in the REPL, and when the appropriate
+ flags were passed directly to compile(). Patch by Pablo
+ Galindo.
+ - C API
+ - gh-131740: Update PyUnstable_GC_VisitObjects to traverse
+ perm gen.
+ - gh-129533: Update PyGC_Enable(), PyGC_Disable(),
+ PyGC_IsEnabled() to use atomic operation for thread-safety
+ at free-threading build. Patch by Donghee Na.
+ - Build
+ - gh-131865: The DTrace build now properly passes the CC
+ and CFLAGS variables to the dtrace command when utilizing
+ SystemTap on Linux.
+ - gh-131675: Fix mimalloc library builds for 32-bit ARM
+ targets.
+ - gh-130673: Fix potential KeyError when handling object
+ sections during JIT building process.
+ - gh-130740: Ensure that Python.h is included before
+ stdbool.h unless pyconfig.h is included before or in some
+ platform-specific contexts.
+ - gh-129838: Don’t redefine _Py_NO_SANITIZE_UNDEFINED when
+ compiling with a recent GCC version and undefined sanitizer
+ enabled.
+ - gh-129660: Drop test_embed from PGO training, whose
+ contribution in recent versions is considered to be
+ ignorable.
+
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index ad9488a..71fb5d6 100644
--- a/python313.spec
+++ b/python313.spec
@@ -162,7 +162,7 @@
# _md5.cpython-38m-x86_64-linux-gnu.so
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
Name: %{python_pkg_name}%{psuffix}
-Version: 3.13.2
+Version: 3.13.3
%define tarversion %{version}
%define tarname Python-%{tarversion}
Release: 0
diff --git a/subprocess-raise-timeout.patch b/subprocess-raise-timeout.patch
index b984fc4..aba113c 100644
--- a/subprocess-raise-timeout.patch
+++ b/subprocess-raise-timeout.patch
@@ -1,16 +1,21 @@
---
- Lib/test/test_subprocess.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
+ Lib/test/test_subprocess.py | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
---- a/Lib/test/test_subprocess.py
-+++ b/Lib/test/test_subprocess.py
-@@ -280,7 +280,8 @@ class ProcessTestCase(BaseTestCase):
- "time.sleep(3600)"],
- # Some heavily loaded buildbots (sparc Debian 3.x) require
- # this much time to start and print.
-- timeout=3)
-+ # OBS might require even more
-+ timeout=10)
- self.fail("Expected TimeoutExpired.")
- self.assertEqual(c.exception.output, b'BDFL')
+Index: Python-3.13.3/Lib/test/test_subprocess.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_subprocess.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Lib/test/test_subprocess.py 2025-04-11 21:53:36.198770341 +0200
+@@ -274,7 +274,11 @@
+ output = subprocess.check_output(
+ [sys.executable, "-c",
+ "import time; time.sleep(3600)"],
+- timeout=0.1)
++ # Some heavily loaded buildbots (sparc Debian 3.x) require
++ # this much time to start and print.
++ # timeout=3)
++ # OBS might require even more
++ timeout=10)
+ def test_call_kwargs(self):
+ # call() function with keyword args
From 9e2287fa694c1d639d1bb342ea4d7ba4072b01c411f265dc502e20c7011e0655 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Tue, 15 Apr 2025 14:09:42 +0000
Subject: [PATCH 04/32] - Add gh126985-mv-pyvenv.cfg2getpath.patch to remove
failing tests in test_sysconfig.
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=88
---
gh126985-mv-pyvenv.cfg2getpath.patch | 95 ++++++++++++++++++++++++++++
python313.changes | 2 +
python313.spec | 12 ++--
3 files changed, 103 insertions(+), 6 deletions(-)
create mode 100644 gh126985-mv-pyvenv.cfg2getpath.patch
diff --git a/gh126985-mv-pyvenv.cfg2getpath.patch b/gh126985-mv-pyvenv.cfg2getpath.patch
new file mode 100644
index 0000000..4105098
--- /dev/null
+++ b/gh126985-mv-pyvenv.cfg2getpath.patch
@@ -0,0 +1,95 @@
+commit 2b0e2b2893a821ca36cd65a204bed932741ac189
+Author: Filipe Laíns 🇵🇸
+Date: Tue Nov 26 13:46:33 2024 +0000
+
+ GH-126985: move pyvenv.cfg detection from site to getpath (#126987)
+
+---
+ Lib/test/test_sysconfig.py | 67 ---------------------------------------------
+ 1 file changed, 1 insertion(+), 66 deletions(-)
+
+Index: Python-3.13.3/Lib/test/test_sysconfig.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_sysconfig.py 2025-04-15 14:13:08.581364697 +0200
++++ Python-3.13.3/Lib/test/test_sysconfig.py 2025-04-15 14:13:54.955529034 +0200
+@@ -110,6 +110,7 @@
+ **venv_create_args,
+ )
+
++
+ def test_get_path_names(self):
+ self.assertEqual(get_path_names(), sysconfig._SCHEME_KEYS)
+
+@@ -604,72 +605,6 @@
+ suffix = sysconfig.get_config_var('EXT_SUFFIX')
+ self.assertTrue(suffix.endswith('-darwin.so'), suffix)
+
+- @requires_subprocess()
+- def test_config_vars_depend_on_site_initialization(self):
+- script = textwrap.dedent("""
+- import sysconfig
+-
+- config_vars = sysconfig.get_config_vars()
+-
+- import json
+- print(json.dumps(config_vars, indent=2))
+- """)
+-
+- with self.venv() as venv:
+- site_config_vars = json.loads(venv.run('-c', script).stdout)
+- no_site_config_vars = json.loads(venv.run('-S', '-c', script).stdout)
+-
+- self.assertNotEqual(site_config_vars, no_site_config_vars)
+- # With the site initialization, the virtual environment should be enabled.
+- self.assertEqual(site_config_vars['base'], venv.prefix)
+- self.assertEqual(site_config_vars['platbase'], venv.prefix)
+- #self.assertEqual(site_config_vars['prefix'], venv.prefix) # # FIXME: prefix gets overwriten by _init_posix
+- # Without the site initialization, the virtual environment should be disabled.
+- self.assertEqual(no_site_config_vars['base'], site_config_vars['installed_base'])
+- self.assertEqual(no_site_config_vars['platbase'], site_config_vars['installed_platbase'])
+-
+- @requires_subprocess()
+- def test_config_vars_recalculation_after_site_initialization(self):
+- script = textwrap.dedent("""
+- import sysconfig
+-
+- before = sysconfig.get_config_vars()
+-
+- import site
+- site.main()
+-
+- after = sysconfig.get_config_vars()
+-
+- import json
+- print(json.dumps({'before': before, 'after': after}, indent=2))
+- """)
+-
+- with self.venv() as venv:
+- config_vars = json.loads(venv.run('-S', '-c', script).stdout)
+-
+- self.assertNotEqual(config_vars['before'], config_vars['after'])
+- self.assertEqual(config_vars['after']['base'], venv.prefix)
+- #self.assertEqual(config_vars['after']['prefix'], venv.prefix) # FIXME: prefix gets overwriten by _init_posix
+- #self.assertEqual(config_vars['after']['exec_prefix'], venv.prefix) # FIXME: exec_prefix gets overwriten by _init_posix
+-
+- @requires_subprocess()
+- def test_paths_depend_on_site_initialization(self):
+- script = textwrap.dedent("""
+- import sysconfig
+-
+- paths = sysconfig.get_paths()
+-
+- import json
+- print(json.dumps(paths, indent=2))
+- """)
+-
+- with self.venv() as venv:
+- site_paths = json.loads(venv.run('-c', script).stdout)
+- no_site_paths = json.loads(venv.run('-S', '-c', script).stdout)
+-
+- self.assertNotEqual(site_paths, no_site_paths)
+-
+-
+ class MakefileTests(unittest.TestCase):
+
+ @unittest.skipIf(sys.platform.startswith('win'),
diff --git a/python313.changes b/python313.changes
index 34cf35d..59874cb 100644
--- a/python313.changes
+++ b/python313.changes
@@ -271,6 +271,8 @@ Fri Apr 11 19:47:34 UTC 2025 - Matej Cepl
- gh-129660: Drop test_embed from PGO training, whose
contribution in recent versions is considered to be
ignorable.
+- Add gh126985-mv-pyvenv.cfg2getpath.patch to remove failing
+ tests in test_sysconfig.
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index 71fb5d6..8fed4f3 100644
--- a/python313.spec
+++ b/python313.spec
@@ -222,6 +222,9 @@ Patch40: fix-test-recursion-limit-15.6.patch
# PATCH-FIX-SLE doc-py38-to-py36.patch mcepl@suse.com
# Make documentation extensions working with Python 3.6
Patch41: doc-py38-to-py36.patch
+# PATCH-FIX-UPSTREAM gh126985-mv-pyvenv.cfg2getpath.patch mcepl@suse.com
+# Remove tests failing in test_sysconfig
+Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
@@ -651,17 +654,14 @@ EXCLUDE="$EXCLUDE test_faulthandler"
EXCLUDE="$EXCLUDE test_external_inspection test_faulthandler test_os test_posix test_signal test_socket test_subprocess"
%endif
+# gh#python/cpython#132535
+EXCLUDE="$EXCLUDE test_timeout"
+
# This test (part of test_uuid) requires real network interfaces
# so that ifconfig output has "HWaddr ". Some kvm instances
# done have any such interface breaking the uuid module.
EXCLUDE="$EXCLUDE test_uuid"
-# bsc#1195140 and bpo#37169 - test_capi is failing on openSUSE, and not sure why
-EXCLUDE="$EXCLUDE test_capi"
-
-# Failing tests on python 3.13
-EXCLUDE="$EXCLUDE test_regrtest test_sysconfig"
-
# Limit virtual memory to avoid spurious failures
if test $(ulimit -v) = unlimited || test $(ulimit -v) -gt 10000000; then
ulimit -v 11000000 || :
From 384d0f4194f535e23cdc86b3df517d55d98445c56fe2427cd7faba5803e39e12 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Tue, 15 Apr 2025 22:19:57 +0000
Subject: [PATCH 05/32] - Add gh-132535-rsrc-warn-test_timeout.patch to fix
failing tests in the build system without network access
(gh#python/cpython#132535).
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=89
---
gh-132535-rsrc-warn-test_timeout.patch | 94 ++++++++++++++++++++++++++
python313.changes | 3 +
python313.spec | 6 +-
3 files changed, 100 insertions(+), 3 deletions(-)
create mode 100644 gh-132535-rsrc-warn-test_timeout.patch
diff --git a/gh-132535-rsrc-warn-test_timeout.patch b/gh-132535-rsrc-warn-test_timeout.patch
new file mode 100644
index 0000000..1dc73a4
--- /dev/null
+++ b/gh-132535-rsrc-warn-test_timeout.patch
@@ -0,0 +1,94 @@
+From 0e461dd411e9ec3dbdf376435154ca2834bcab51 Mon Sep 17 00:00:00 2001
+From: Serhiy Storchaka
+Date: Wed, 16 Apr 2025 00:24:56 +0300
+Subject: [PATCH] gh-132535: Fix resource warnings in test_timeout
+
+They were emitted if internet connection was not available.
+---
+ Lib/test/test_timeout.py | 43 ++++++++++++++++---------------------------
+ 1 file changed, 16 insertions(+), 27 deletions(-)
+
+Index: Python-3.13.3/Lib/test/test_timeout.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_timeout.py 2025-04-08 15:54:08.000000000 +0200
++++ Python-3.13.3/Lib/test/test_timeout.py 2025-04-15 23:45:55.028517897 +0200
+@@ -26,10 +26,8 @@
+ """Test case for socket.gettimeout() and socket.settimeout()"""
+
+ def setUp(self):
+- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+-
+- def tearDown(self):
+- self.sock.close()
++ self.sock = self.enterContext(
++ socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+
+ def testObjectCreation(self):
+ # Test Socket creation
+@@ -113,8 +111,6 @@
+ def setUp(self):
+ raise NotImplementedError()
+
+- tearDown = setUp
+-
+ def _sock_operation(self, count, timeout, method, *args):
+ """
+ Test the specified socket method.
+@@ -142,12 +138,10 @@
+ """TCP test case for socket.socket() timeout functions"""
+
+ def setUp(self):
+- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
++ self.sock = self.enterContext(
++ socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+ self.addr_remote = resolve_address('www.python.org.', 80)
+
+- def tearDown(self):
+- self.sock.close()
+-
+ def testConnectTimeout(self):
+ # Testing connect timeout is tricky: we need to have IP connectivity
+ # to a host that silently drops our packets. We can't simulate this
+@@ -190,19 +184,16 @@
+ # for the current configuration.
+
+ skip = True
+- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+- timeout = support.LOOPBACK_TIMEOUT
+- sock.settimeout(timeout)
+- try:
+- sock.connect((whitehole))
+- except TimeoutError:
+- pass
+- except OSError as err:
+- if err.errno == errno.ECONNREFUSED:
+- skip = False
+- finally:
+- sock.close()
+- del sock
++ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
++ try:
++ timeout = support.LOOPBACK_TIMEOUT
++ sock.settimeout(timeout)
++ sock.connect((whitehole))
++ except TimeoutError:
++ pass
++ except OSError as err:
++ if err.errno == errno.ECONNREFUSED:
++ skip = False
+
+ if skip:
+ self.skipTest(
+@@ -269,10 +260,8 @@
+ """UDP test case for socket.socket() timeout functions"""
+
+ def setUp(self):
+- self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+-
+- def tearDown(self):
+- self.sock.close()
++ self.sock = self.enterContext(
++ socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
+
+ def testRecvfromTimeout(self):
+ # Test recvfrom() timeout
diff --git a/python313.changes b/python313.changes
index 59874cb..095a92f 100644
--- a/python313.changes
+++ b/python313.changes
@@ -273,6 +273,9 @@ Fri Apr 11 19:47:34 UTC 2025 - Matej Cepl
ignorable.
- Add gh126985-mv-pyvenv.cfg2getpath.patch to remove failing
tests in test_sysconfig.
+- Add gh-132535-rsrc-warn-test_timeout.patch to fix
+ failing tests in the build system without network access
+ (gh#python/cpython#132535).
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index 8fed4f3..408383d 100644
--- a/python313.spec
+++ b/python313.spec
@@ -225,6 +225,9 @@ Patch41: doc-py38-to-py36.patch
# PATCH-FIX-UPSTREAM gh126985-mv-pyvenv.cfg2getpath.patch mcepl@suse.com
# Remove tests failing in test_sysconfig
Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
+# PATCH-FIX-UPSTREAM gh-132535-rsrc-warn-test_timeout.patch gh#python/cpython#132535 mcepl@suse.com
+# allows test_timeout tests to pass
+Patch43: gh-132535-rsrc-warn-test_timeout.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
@@ -654,9 +657,6 @@ EXCLUDE="$EXCLUDE test_faulthandler"
EXCLUDE="$EXCLUDE test_external_inspection test_faulthandler test_os test_posix test_signal test_socket test_subprocess"
%endif
-# gh#python/cpython#132535
-EXCLUDE="$EXCLUDE test_timeout"
-
# This test (part of test_uuid) requires real network interfaces
# so that ifconfig output has "HWaddr ". Some kvm instances
# done have any such interface breaking the uuid module.
From b91bbdde1bac60ebc52c2b79504e0ae181684c5046a44b84aec4e6bc41283524 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Wed, 16 Apr 2025 07:15:35 +0000
Subject: [PATCH 06/32] - Add
gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch and
gh-127257-ssl-OSError-ERR_LIB_SYS.patch to make the interpreter compatible
with OpenSSL 3.5 (bsc#1241067).
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=90
---
...l-no-stop-ThreadedEchoServer-OSError.patch | 82 +++++++++++++++++++
gh-127257-ssl-OSError-ERR_LIB_SYS.patch | 67 +++++++++++++++
python313.changes | 3 +
python313.spec | 4 +
4 files changed, 156 insertions(+)
create mode 100644 gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
create mode 100644 gh-127257-ssl-OSError-ERR_LIB_SYS.patch
diff --git a/gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch b/gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
new file mode 100644
index 0000000..bea4eed
--- /dev/null
+++ b/gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
@@ -0,0 +1,82 @@
+From 3d390148c05a7ea2d401c4633e7d4db75ebf97d9 Mon Sep 17 00:00:00 2001
+From: Petr Viktorin
+Date: Thu, 7 Nov 2024 11:07:02 +0100
+Subject: [PATCH] gh-126500: test_ssl: Don't stop ThreadedEchoServer on OSError
+ in ConnectionHandler; rely on __exit__ (GH-126503)
+
+If `read()` in the ConnectionHandler thread raises `OSError` (except `ConnectionError`),
+the ConnectionHandler shuts down the entire ThreadedEchoServer,
+preventing further connections.
+It also does that for `EPROTOTYPE` in `wrap_conn`.
+
+As far as I can see, this is done to avoid the server thread getting stuck,
+forgotten, in its accept loop. However, since 2011 (5b95eb90a7167285b6544b50865227c584943c9a)
+the server is used as a context manager, and its `__exit__` does `stop()` and `join()`.
+(I'm not sure if we *always* used `with` since that commit, but currently we do.)
+
+Make sure that the context manager *is* used, and remove the `server.stop()`
+calls from ConnectionHandler.
+(cherry picked from commit c9cda1608edf7664c10f4f467e24591062c2fe62)
+
+Co-authored-by: Petr Viktorin
+---
+ Lib/test/test_ssl.py | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
+index 9b59ddd887aa0b..b6421c7a3c827b 100644
+--- a/Lib/test/test_ssl.py
++++ b/Lib/test/test_ssl.py
+@@ -2300,7 +2300,6 @@ def wrap_conn(self):
+ # See also http://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
+ if e.errno != errno.EPROTOTYPE and sys.platform != "darwin":
+ self.running = False
+- self.server.stop()
+ self.close()
+ return False
+ else:
+@@ -2435,10 +2434,6 @@ def run(self):
+ self.close()
+ self.running = False
+
+- # normally, we'd just stop here, but for the test
+- # harness, we want to stop the server
+- self.server.stop()
+-
+ def __init__(self, certificate=None, ssl_version=None,
+ certreqs=None, cacerts=None,
+ chatty=True, connectionchatty=False, starttls_server=False,
+@@ -2472,21 +2467,33 @@ def __init__(self, certificate=None, ssl_version=None,
+ self.conn_errors = []
+ threading.Thread.__init__(self)
+ self.daemon = True
++ self._in_context = False
+
+ def __enter__(self):
++ if self._in_context:
++ raise ValueError('Re-entering ThreadedEchoServer context')
++ self._in_context = True
+ self.start(threading.Event())
+ self.flag.wait()
+ return self
+
+ def __exit__(self, *args):
++ assert self._in_context
++ self._in_context = False
+ self.stop()
+ self.join()
+
+ def start(self, flag=None):
++ if not self._in_context:
++ raise ValueError(
++ 'ThreadedEchoServer must be used as a context manager')
+ self.flag = flag
+ threading.Thread.start(self)
+
+ def run(self):
++ if not self._in_context:
++ raise ValueError(
++ 'ThreadedEchoServer must be used as a context manager')
+ self.sock.settimeout(1.0)
+ self.sock.listen(5)
+ self.active = True
diff --git a/gh-127257-ssl-OSError-ERR_LIB_SYS.patch b/gh-127257-ssl-OSError-ERR_LIB_SYS.patch
new file mode 100644
index 0000000..092d012
--- /dev/null
+++ b/gh-127257-ssl-OSError-ERR_LIB_SYS.patch
@@ -0,0 +1,67 @@
+From c7908750cbfcfb54688ffff654909ef021095026 Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-islington@users.noreply.github.com>
+Date: Mon, 16 Dec 2024 15:43:57 +0100
+Subject: [PATCH] [3.12] gh-127257: ssl: Raise OSError for ERR_LIB_SYS
+ (GH-127361) (GH-127905)
+
+gh-127257: ssl: Raise OSError for ERR_LIB_SYS (GH-127361)
+
+From the ERR_raise manpage:
+
+ ERR_LIB_SYS
+
+ This "library code" indicates that a system error is
+ being reported. In this case, the reason code given
+ to `ERR_raise()` and `ERR_raise_data()` *must* be
+ `errno(3)`.
+
+This PR only handles ERR_LIB_SYS for the high-lever error types
+SSL_ERROR_SYSCALL and SSL_ERROR_SSL, i.e., not the ones where
+OpenSSL indicates it has some more information about the issue.
+(cherry picked from commit f4b31edf2d9d72878dab1f66a36913b5bcc848ec)
+
+Co-authored-by: Petr Viktorin
+(cherry picked from commit 7f707fa6c67d0bfa9bbc1a9f344b932789659397)
+---
+ .../2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst | 2 ++
+ Modules/_ssl.c | 10 ++++++++++
+ 2 files changed, 12 insertions(+)
+ create mode 100644 Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst
+
+diff --git a/Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst b/Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst
+new file mode 100644
+index 00000000000000..fb0380cba0b607
+--- /dev/null
++++ b/Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst
+@@ -0,0 +1,2 @@
++In :mod:`ssl`, system call failures that OpenSSL reports using
++``ERR_LIB_SYS`` are now raised as :exc:`OSError`.
+diff --git a/Modules/_ssl.c b/Modules/_ssl.c
+index 120c739e196732..09207abde14545 100644
+--- a/Modules/_ssl.c
++++ b/Modules/_ssl.c
+@@ -654,6 +654,11 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
+ ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
+ type = state->PySSLCertVerificationErrorObject;
+ }
++ if (ERR_GET_LIB(e) == ERR_LIB_SYS) {
++ // A system error is being reported; reason is set to errno
++ errno = ERR_GET_REASON(e);
++ return PyErr_SetFromErrno(PyExc_OSError);
++ }
+ p = PY_SSL_ERROR_SYSCALL;
+ }
+ break;
+@@ -679,6 +684,11 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
+ errstr = "EOF occurred in violation of protocol";
+ }
+ #endif
++ if (ERR_GET_LIB(e) == ERR_LIB_SYS) {
++ // A system error is being reported; reason is set to errno
++ errno = ERR_GET_REASON(e);
++ return PyErr_SetFromErrno(PyExc_OSError);
++ }
+ break;
+ }
+ default:
diff --git a/python313.changes b/python313.changes
index 095a92f..18c4aec 100644
--- a/python313.changes
+++ b/python313.changes
@@ -276,6 +276,9 @@ Fri Apr 11 19:47:34 UTC 2025 - Matej Cepl
- Add gh-132535-rsrc-warn-test_timeout.patch to fix
failing tests in the build system without network access
(gh#python/cpython#132535).
+- Add gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
+ and gh-127257-ssl-OSError-ERR_LIB_SYS.patch to make the
+ interpreter compatible with OpenSSL 3.5 (bsc#1241067).
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index 408383d..2aa63d0 100644
--- a/python313.spec
+++ b/python313.spec
@@ -228,6 +228,10 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM gh-132535-rsrc-warn-test_timeout.patch gh#python/cpython#132535 mcepl@suse.com
# allows test_timeout tests to pass
Patch43: gh-132535-rsrc-warn-test_timeout.patch
+# PATCH-FIX-UPSTREAM bsc#1241067 mcepl@suse.com
+# Make the interpreter compatible with OpenSSL 3.5
+Patch44: gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
+Patch44: gh-127257-ssl-OSError-ERR_LIB_SYS.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From 55167f91bde76fc1220d86ea7e4cae24bca4e74e6ddd52fdf771c4d53be10d8d Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Wed, 16 Apr 2025 07:17:38 +0000
Subject: [PATCH 07/32] Fix patches
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=91
---
python313.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python313.spec b/python313.spec
index 2aa63d0..e5b5a93 100644
--- a/python313.spec
+++ b/python313.spec
@@ -231,7 +231,7 @@ Patch43: gh-132535-rsrc-warn-test_timeout.patch
# PATCH-FIX-UPSTREAM bsc#1241067 mcepl@suse.com
# Make the interpreter compatible with OpenSSL 3.5
Patch44: gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
-Patch44: gh-127257-ssl-OSError-ERR_LIB_SYS.patch
+Patch45: gh-127257-ssl-OSError-ERR_LIB_SYS.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From bb17c93a2ab001cb9fe4c081fa7b94921c3fb356231ab09d0d86ec862c4eced4 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Wed, 16 Apr 2025 07:52:47 +0000
Subject: [PATCH 08/32] This
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=92
---
...l-no-stop-ThreadedEchoServer-OSError.patch | 82 -------------------
gh-127257-ssl-OSError-ERR_LIB_SYS.patch | 67 ---------------
python313.changes | 3 -
python313.spec | 4 -
4 files changed, 156 deletions(-)
delete mode 100644 gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
delete mode 100644 gh-127257-ssl-OSError-ERR_LIB_SYS.patch
diff --git a/gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch b/gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
deleted file mode 100644
index bea4eed..0000000
--- a/gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 3d390148c05a7ea2d401c4633e7d4db75ebf97d9 Mon Sep 17 00:00:00 2001
-From: Petr Viktorin
-Date: Thu, 7 Nov 2024 11:07:02 +0100
-Subject: [PATCH] gh-126500: test_ssl: Don't stop ThreadedEchoServer on OSError
- in ConnectionHandler; rely on __exit__ (GH-126503)
-
-If `read()` in the ConnectionHandler thread raises `OSError` (except `ConnectionError`),
-the ConnectionHandler shuts down the entire ThreadedEchoServer,
-preventing further connections.
-It also does that for `EPROTOTYPE` in `wrap_conn`.
-
-As far as I can see, this is done to avoid the server thread getting stuck,
-forgotten, in its accept loop. However, since 2011 (5b95eb90a7167285b6544b50865227c584943c9a)
-the server is used as a context manager, and its `__exit__` does `stop()` and `join()`.
-(I'm not sure if we *always* used `with` since that commit, but currently we do.)
-
-Make sure that the context manager *is* used, and remove the `server.stop()`
-calls from ConnectionHandler.
-(cherry picked from commit c9cda1608edf7664c10f4f467e24591062c2fe62)
-
-Co-authored-by: Petr Viktorin
----
- Lib/test/test_ssl.py | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
-index 9b59ddd887aa0b..b6421c7a3c827b 100644
---- a/Lib/test/test_ssl.py
-+++ b/Lib/test/test_ssl.py
-@@ -2300,7 +2300,6 @@ def wrap_conn(self):
- # See also http://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
- if e.errno != errno.EPROTOTYPE and sys.platform != "darwin":
- self.running = False
-- self.server.stop()
- self.close()
- return False
- else:
-@@ -2435,10 +2434,6 @@ def run(self):
- self.close()
- self.running = False
-
-- # normally, we'd just stop here, but for the test
-- # harness, we want to stop the server
-- self.server.stop()
--
- def __init__(self, certificate=None, ssl_version=None,
- certreqs=None, cacerts=None,
- chatty=True, connectionchatty=False, starttls_server=False,
-@@ -2472,21 +2467,33 @@ def __init__(self, certificate=None, ssl_version=None,
- self.conn_errors = []
- threading.Thread.__init__(self)
- self.daemon = True
-+ self._in_context = False
-
- def __enter__(self):
-+ if self._in_context:
-+ raise ValueError('Re-entering ThreadedEchoServer context')
-+ self._in_context = True
- self.start(threading.Event())
- self.flag.wait()
- return self
-
- def __exit__(self, *args):
-+ assert self._in_context
-+ self._in_context = False
- self.stop()
- self.join()
-
- def start(self, flag=None):
-+ if not self._in_context:
-+ raise ValueError(
-+ 'ThreadedEchoServer must be used as a context manager')
- self.flag = flag
- threading.Thread.start(self)
-
- def run(self):
-+ if not self._in_context:
-+ raise ValueError(
-+ 'ThreadedEchoServer must be used as a context manager')
- self.sock.settimeout(1.0)
- self.sock.listen(5)
- self.active = True
diff --git a/gh-127257-ssl-OSError-ERR_LIB_SYS.patch b/gh-127257-ssl-OSError-ERR_LIB_SYS.patch
deleted file mode 100644
index 092d012..0000000
--- a/gh-127257-ssl-OSError-ERR_LIB_SYS.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From c7908750cbfcfb54688ffff654909ef021095026 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Mon, 16 Dec 2024 15:43:57 +0100
-Subject: [PATCH] [3.12] gh-127257: ssl: Raise OSError for ERR_LIB_SYS
- (GH-127361) (GH-127905)
-
-gh-127257: ssl: Raise OSError for ERR_LIB_SYS (GH-127361)
-
-From the ERR_raise manpage:
-
- ERR_LIB_SYS
-
- This "library code" indicates that a system error is
- being reported. In this case, the reason code given
- to `ERR_raise()` and `ERR_raise_data()` *must* be
- `errno(3)`.
-
-This PR only handles ERR_LIB_SYS for the high-lever error types
-SSL_ERROR_SYSCALL and SSL_ERROR_SSL, i.e., not the ones where
-OpenSSL indicates it has some more information about the issue.
-(cherry picked from commit f4b31edf2d9d72878dab1f66a36913b5bcc848ec)
-
-Co-authored-by: Petr Viktorin
-(cherry picked from commit 7f707fa6c67d0bfa9bbc1a9f344b932789659397)
----
- .../2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst | 2 ++
- Modules/_ssl.c | 10 ++++++++++
- 2 files changed, 12 insertions(+)
- create mode 100644 Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst
-
-diff --git a/Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst b/Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst
-new file mode 100644
-index 00000000000000..fb0380cba0b607
---- /dev/null
-+++ b/Misc/NEWS.d/next/Library/2024-11-28-14-14-46.gh-issue-127257.n6-jU9.rst
-@@ -0,0 +1,2 @@
-+In :mod:`ssl`, system call failures that OpenSSL reports using
-+``ERR_LIB_SYS`` are now raised as :exc:`OSError`.
-diff --git a/Modules/_ssl.c b/Modules/_ssl.c
-index 120c739e196732..09207abde14545 100644
---- a/Modules/_ssl.c
-+++ b/Modules/_ssl.c
-@@ -654,6 +654,11 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
- ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
- type = state->PySSLCertVerificationErrorObject;
- }
-+ if (ERR_GET_LIB(e) == ERR_LIB_SYS) {
-+ // A system error is being reported; reason is set to errno
-+ errno = ERR_GET_REASON(e);
-+ return PyErr_SetFromErrno(PyExc_OSError);
-+ }
- p = PY_SSL_ERROR_SYSCALL;
- }
- break;
-@@ -679,6 +684,11 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
- errstr = "EOF occurred in violation of protocol";
- }
- #endif
-+ if (ERR_GET_LIB(e) == ERR_LIB_SYS) {
-+ // A system error is being reported; reason is set to errno
-+ errno = ERR_GET_REASON(e);
-+ return PyErr_SetFromErrno(PyExc_OSError);
-+ }
- break;
- }
- default:
diff --git a/python313.changes b/python313.changes
index 18c4aec..095a92f 100644
--- a/python313.changes
+++ b/python313.changes
@@ -276,9 +276,6 @@ Fri Apr 11 19:47:34 UTC 2025 - Matej Cepl
- Add gh-132535-rsrc-warn-test_timeout.patch to fix
failing tests in the build system without network access
(gh#python/cpython#132535).
-- Add gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
- and gh-127257-ssl-OSError-ERR_LIB_SYS.patch to make the
- interpreter compatible with OpenSSL 3.5 (bsc#1241067).
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann
diff --git a/python313.spec b/python313.spec
index e5b5a93..408383d 100644
--- a/python313.spec
+++ b/python313.spec
@@ -228,10 +228,6 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM gh-132535-rsrc-warn-test_timeout.patch gh#python/cpython#132535 mcepl@suse.com
# allows test_timeout tests to pass
Patch43: gh-132535-rsrc-warn-test_timeout.patch
-# PATCH-FIX-UPSTREAM bsc#1241067 mcepl@suse.com
-# Make the interpreter compatible with OpenSSL 3.5
-Patch44: gh-126500-test_ssl-no-stop-ThreadedEchoServer-OSError.patch
-Patch45: gh-127257-ssl-OSError-ERR_LIB_SYS.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From d8af743464267fd9f85f44647e593fabfd9bef4e8a9b1519da8fec2e549c9799 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Sat, 10 May 2025 11:43:36 +0000
Subject: [PATCH 09/32] - Remove python-3.3.0b1-test-posix_fadvise.patch (not
needed since kernel 3.6-rc1)
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=94
---
python-3.3.0b1-test-posix_fadvise.patch | 15 ---------------
python313.changes | 6 ++++++
python313.spec | 2 --
3 files changed, 6 insertions(+), 17 deletions(-)
delete mode 100644 python-3.3.0b1-test-posix_fadvise.patch
diff --git a/python-3.3.0b1-test-posix_fadvise.patch b/python-3.3.0b1-test-posix_fadvise.patch
deleted file mode 100644
index 0a6b091..0000000
--- a/python-3.3.0b1-test-posix_fadvise.patch
+++ /dev/null
@@ -1,15 +0,0 @@
----
- Lib/test/test_posix.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/Lib/test/test_posix.py
-+++ b/Lib/test/test_posix.py
-@@ -437,7 +437,7 @@ class PosixTester(unittest.TestCase):
- def test_posix_fadvise(self):
- fd = os.open(os_helper.TESTFN, os.O_RDONLY)
- try:
-- posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
-+ posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_RANDOM)
- finally:
- os.close(fd)
-
diff --git a/python313.changes b/python313.changes
index 095a92f..030266a 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Sat May 10 11:38:27 UTC 2025 - Matej Cepl
+
+- Remove python-3.3.0b1-test-posix_fadvise.patch (not needed
+ since kernel 3.6-rc1)
+
-------------------------------------------------------------------
Fri Apr 11 19:47:34 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index 408383d..d1801aa 100644
--- a/python313.spec
+++ b/python313.spec
@@ -206,8 +206,6 @@ Patch02: F00251-change-user-install-location.patch
Patch03: python-3.3.0b1-localpath.patch
# replace DATE, TIME and COMPILER by fixed definitions to aid reproducible builds
Patch04: python-3.3.0b1-fix_date_time_compiler.patch
-# POSIX_FADV_WILLNEED throws EINVAL. Use a different constant in test
-Patch05: python-3.3.0b1-test-posix_fadvise.patch
# Raise timeout value for test_subprocess
Patch06: subprocess-raise-timeout.patch
# PATCH-FEATURE-UPSTREAM bpo-31046_ensurepip_honours_prefix.patch bpo#31046 mcepl@suse.com
From 487ae82f04380c228100832424ba237dccb36abe03fe6901dd939faf1a655ceb Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Sat, 17 May 2025 07:34:05 +0000
Subject: [PATCH 10/32] - Add CVE-2025-4516-DecodeError-handler.patch fixing
CVE-2025-4516 (bsc#1243273) blocking DecodeError handling vulnerability,
which could lead to DoS.
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=96
---
CVE-2025-4516-DecodeError-handler.patch | 483 ++++++++++++++++++++++++
python313.changes | 7 +
python313.spec | 3 +
3 files changed, 493 insertions(+)
create mode 100644 CVE-2025-4516-DecodeError-handler.patch
diff --git a/CVE-2025-4516-DecodeError-handler.patch b/CVE-2025-4516-DecodeError-handler.patch
new file mode 100644
index 0000000..4dcba72
--- /dev/null
+++ b/CVE-2025-4516-DecodeError-handler.patch
@@ -0,0 +1,483 @@
+From 0afcdf15f64273dc5e4ed12ea63a01f7f1136d71 Mon Sep 17 00:00:00 2001
+From: Serhiy Storchaka
+Date: Mon, 12 May 2025 20:42:23 +0300
+Subject: [PATCH] [3.13] gh-133767: Fix use-after-free in the unicode-escape
+ decoder with an error handler (GH-129648)
+
+If the error handler is used, a new bytes object is created to set as
+the object attribute of UnicodeDecodeError, and that bytes object then
+replaces the original data. A pointer to the decoded data will became invalid
+after destroying that temporary bytes object. So we need other way to return
+the first invalid escape from _PyUnicode_DecodeUnicodeEscapeInternal().
+
+_PyBytes_DecodeEscape() does not have such issue, because it does not
+use the error handlers registry, but it should be changed for compatibility
+with _PyUnicode_DecodeUnicodeEscapeInternal().
+(cherry picked from commit 9f69a58623bd01349a18ba0c7a9cb1dad6a51e8e)
+
+Co-authored-by: Serhiy Storchaka
+---
+ Include/internal/pycore_bytesobject.h | 5
+ Include/internal/pycore_unicodeobject.h | 12 +-
+ Lib/test/test_codeccallbacks.py | 39 +++++++
+ Lib/test/test_codecs.py | 52 ++++++++--
+ Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst | 2
+ Objects/bytesobject.c | 41 ++++---
+ Objects/unicodeobject.c | 46 +++++---
+ Parser/string_parser.c | 26 +++--
+ 8 files changed, 160 insertions(+), 63 deletions(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst
+
+Index: Python-3.13.3/Include/internal/pycore_bytesobject.h
+===================================================================
+--- Python-3.13.3.orig/Include/internal/pycore_bytesobject.h 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Include/internal/pycore_bytesobject.h 2025-05-17 07:33:22.001814947 +0000
+@@ -20,8 +20,9 @@
+
+ // Helper for PyBytes_DecodeEscape that detects invalid escape chars.
+ // Export for test_peg_generator.
+-PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
+- const char *, const char **);
++PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape2(const char *, Py_ssize_t,
++ const char *,
++ int *, const char **);
+
+
+ // Substring Search.
+Index: Python-3.13.3/Include/internal/pycore_unicodeobject.h
+===================================================================
+--- Python-3.13.3.orig/Include/internal/pycore_unicodeobject.h 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Include/internal/pycore_unicodeobject.h 2025-05-17 07:33:22.001974979 +0000
+@@ -142,14 +142,18 @@
+ // Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape
+ // chars.
+ // Export for test_peg_generator.
+-PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal(
++PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal2(
+ const char *string, /* Unicode-Escape encoded string */
+ Py_ssize_t length, /* size of string */
+ const char *errors, /* error handling */
+ Py_ssize_t *consumed, /* bytes consumed */
+- const char **first_invalid_escape); /* on return, points to first
+- invalid escaped char in
+- string. */
++ int *first_invalid_escape_char, /* on return, if not -1, contain the first
++ invalid escaped char (<= 0xff) or invalid
++ octal escape (> 0xff) in string. */
++ const char **first_invalid_escape_ptr); /* on return, if not NULL, may
++ point to the first invalid escaped
++ char in string.
++ May be NULL if errors is not NULL. */
+
+ /* --- Raw-Unicode-Escape Codecs ---------------------------------------------- */
+
+Index: Python-3.13.3/Lib/test/test_codeccallbacks.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_codeccallbacks.py 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Lib/test/test_codeccallbacks.py 2025-05-17 07:33:22.002185827 +0000
+@@ -1,6 +1,7 @@
+ import codecs
+ import html.entities
+ import itertools
++import re
+ import sys
+ import unicodedata
+ import unittest
+@@ -1124,7 +1125,7 @@
+ text = 'abcghi'*n
+ text.translate(charmap)
+
+- def test_mutatingdecodehandler(self):
++ def test_mutating_decode_handler(self):
+ baddata = [
+ ("ascii", b"\xff"),
+ ("utf-7", b"++"),
+@@ -1159,6 +1160,42 @@
+ for (encoding, data) in baddata:
+ self.assertEqual(data.decode(encoding, "test.mutating"), "\u4242")
+
++ def test_mutating_decode_handler_unicode_escape(self):
++ decode = codecs.unicode_escape_decode
++ def mutating(exc):
++ if isinstance(exc, UnicodeDecodeError):
++ r = data.get(exc.object[:exc.end])
++ if r is not None:
++ exc.object = r[0] + exc.object[exc.end:]
++ return ('\u0404', r[1])
++ raise AssertionError("don't know how to handle %r" % exc)
++
++ codecs.register_error('test.mutating2', mutating)
++ data = {
++ br'\x0': (b'\\', 0),
++ br'\x3': (b'xxx\\', 3),
++ br'\x5': (b'x\\', 1),
++ }
++ def check(input, expected, msg):
++ with self.assertWarns(DeprecationWarning) as cm:
++ self.assertEqual(decode(input, 'test.mutating2'), (expected, len(input)))
++ self.assertIn(msg, str(cm.warning))
++
++ check(br'\x0n\z', '\u0404\n\\z', r"invalid escape sequence '\z'")
++ check(br'\x0n\501', '\u0404\n\u0141', r"invalid octal escape sequence '\501'")
++ check(br'\x0z', '\u0404\\z', r"invalid escape sequence '\z'")
++
++ check(br'\x3n\zr', '\u0404\n\\zr', r"invalid escape sequence '\z'")
++ check(br'\x3zr', '\u0404\\zr', r"invalid escape sequence '\z'")
++ check(br'\x3z5', '\u0404\\z5', r"invalid escape sequence '\z'")
++ check(memoryview(br'\x3z5x')[:-1], '\u0404\\z5', r"invalid escape sequence '\z'")
++ check(memoryview(br'\x3z5xy')[:-2], '\u0404\\z5', r"invalid escape sequence '\z'")
++
++ check(br'\x5n\z', '\u0404\n\\z', r"invalid escape sequence '\z'")
++ check(br'\x5n\501', '\u0404\n\u0141', r"invalid octal escape sequence '\501'")
++ check(br'\x5z', '\u0404\\z', r"invalid escape sequence '\z'")
++ check(memoryview(br'\x5zy')[:-1], '\u0404\\z', r"invalid escape sequence '\z'")
++
+ # issue32583
+ def test_crashing_decode_handler(self):
+ # better generating one more character to fill the extra space slot
+Index: Python-3.13.3/Lib/test/test_codecs.py
+===================================================================
+--- Python-3.13.3.orig/Lib/test/test_codecs.py 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Lib/test/test_codecs.py 2025-05-17 07:33:22.002507164 +0000
+@@ -1196,23 +1196,39 @@
+ check(br"[\1010]", b"[A0]")
+ check(br"[\x41]", b"[A]")
+ check(br"[\x410]", b"[A0]")
++
++ def test_warnings(self):
++ decode = codecs.escape_decode
++ check = coding_checker(self, decode)
+ for i in range(97, 123):
+ b = bytes([i])
+ if b not in b'abfnrtvx':
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\%c'" % i):
+ check(b"\\" + b, b"\\" + b)
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\%c'" % (i-32)):
+ check(b"\\" + b.upper(), b"\\" + b.upper())
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\8'"):
+ check(br"\8", b"\\8")
+ with self.assertWarns(DeprecationWarning):
+ check(br"\9", b"\\9")
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\\xfa'") as cm:
+ check(b"\\\xfa", b"\\\xfa")
+ for i in range(0o400, 0o1000):
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid octal escape sequence '\\%o'" % i):
+ check(rb'\%o' % i, bytes([i & 0o377]))
+
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\z'"):
++ self.assertEqual(decode(br'\x\z', 'ignore'), (b'\\z', 4))
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid octal escape sequence '\\501'"):
++ self.assertEqual(decode(br'\x\501', 'ignore'), (b'A', 6))
++
+ def test_errors(self):
+ decode = codecs.escape_decode
+ self.assertRaises(ValueError, decode, br"\x")
+@@ -2661,24 +2677,40 @@
+ check(br"[\x410]", "[A0]")
+ check(br"\u20ac", "\u20ac")
+ check(br"\U0001d120", "\U0001d120")
++
++ def test_decode_warnings(self):
++ decode = codecs.unicode_escape_decode
++ check = coding_checker(self, decode)
+ for i in range(97, 123):
+ b = bytes([i])
+ if b not in b'abfnrtuvx':
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\%c'" % i):
+ check(b"\\" + b, "\\" + chr(i))
+ if b.upper() not in b'UN':
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\%c'" % (i-32)):
+ check(b"\\" + b.upper(), "\\" + chr(i-32))
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\8'"):
+ check(br"\8", "\\8")
+ with self.assertWarns(DeprecationWarning):
+ check(br"\9", "\\9")
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\\xfa'") as cm:
+ check(b"\\\xfa", "\\\xfa")
+ for i in range(0o400, 0o1000):
+- with self.assertWarns(DeprecationWarning):
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid octal escape sequence '\\%o'" % i):
+ check(rb'\%o' % i, chr(i))
+
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid escape sequence '\\z'"):
++ self.assertEqual(decode(br'\x\z', 'ignore'), ('\\z', 4))
++ with self.assertWarnsRegex(DeprecationWarning,
++ r"invalid octal escape sequence '\\501'"):
++ self.assertEqual(decode(br'\x\501', 'ignore'), ('\u0141', 6))
++
+ def test_decode_errors(self):
+ decode = codecs.unicode_escape_decode
+ for c, d in (b'x', 2), (b'u', 4), (b'U', 4):
+Index: Python-3.13.3/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ Python-3.13.3/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst 2025-05-17 07:33:22.002786511 +0000
+@@ -0,0 +1,2 @@
++Fix use-after-free in the "unicode-escape" decoder with a non-"strict" error
++handler.
+Index: Python-3.13.3/Objects/bytesobject.c
+===================================================================
+--- Python-3.13.3.orig/Objects/bytesobject.c 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Objects/bytesobject.c 2025-05-17 07:33:22.003325939 +0000
+@@ -1065,10 +1065,11 @@
+ }
+
+ /* Unescape a backslash-escaped string. */
+-PyObject *_PyBytes_DecodeEscape(const char *s,
++PyObject *_PyBytes_DecodeEscape2(const char *s,
+ Py_ssize_t len,
+ const char *errors,
+- const char **first_invalid_escape)
++ int *first_invalid_escape_char,
++ const char **first_invalid_escape_ptr)
+ {
+ int c;
+ char *p;
+@@ -1082,7 +1083,8 @@
+ return NULL;
+ writer.overallocate = 1;
+
+- *first_invalid_escape = NULL;
++ *first_invalid_escape_char = -1;
++ *first_invalid_escape_ptr = NULL;
+
+ end = s + len;
+ while (s < end) {
+@@ -1120,9 +1122,10 @@
+ c = (c<<3) + *s++ - '0';
+ }
+ if (c > 0377) {
+- if (*first_invalid_escape == NULL) {
+- *first_invalid_escape = s-3; /* Back up 3 chars, since we've
+- already incremented s. */
++ if (*first_invalid_escape_char == -1) {
++ *first_invalid_escape_char = c;
++ /* Back up 3 chars, since we've already incremented s. */
++ *first_invalid_escape_ptr = s - 3;
+ }
+ }
+ *p++ = c;
+@@ -1163,9 +1166,10 @@
+ break;
+
+ default:
+- if (*first_invalid_escape == NULL) {
+- *first_invalid_escape = s-1; /* Back up one char, since we've
+- already incremented s. */
++ if (*first_invalid_escape_char == -1) {
++ *first_invalid_escape_char = (unsigned char)s[-1];
++ /* Back up one char, since we've already incremented s. */
++ *first_invalid_escape_ptr = s - 1;
+ }
+ *p++ = '\\';
+ s--;
+@@ -1185,17 +1189,18 @@
+ Py_ssize_t Py_UNUSED(unicode),
+ const char *Py_UNUSED(recode_encoding))
+ {
+- const char* first_invalid_escape;
+- PyObject *result = _PyBytes_DecodeEscape(s, len, errors,
+- &first_invalid_escape);
++ int first_invalid_escape_char;
++ const char *first_invalid_escape_ptr;
++ PyObject *result = _PyBytes_DecodeEscape2(s, len, errors,
++ &first_invalid_escape_char,
++ &first_invalid_escape_ptr);
+ if (result == NULL)
+ return NULL;
+- if (first_invalid_escape != NULL) {
+- unsigned char c = *first_invalid_escape;
+- if ('4' <= c && c <= '7') {
++ if (first_invalid_escape_char != -1) {
++ if (first_invalid_escape_char > 0xff) {
+ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+- "invalid octal escape sequence '\\%.3s'",
+- first_invalid_escape) < 0)
++ "invalid octal escape sequence '\\%o'",
++ first_invalid_escape_char) < 0)
+ {
+ Py_DECREF(result);
+ return NULL;
+@@ -1204,7 +1209,7 @@
+ else {
+ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+ "invalid escape sequence '\\%c'",
+- c) < 0)
++ first_invalid_escape_char) < 0)
+ {
+ Py_DECREF(result);
+ return NULL;
+Index: Python-3.13.3/Objects/unicodeobject.c
+===================================================================
+--- Python-3.13.3.orig/Objects/unicodeobject.c 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Objects/unicodeobject.c 2025-05-17 07:33:22.004748214 +0000
+@@ -6177,13 +6177,15 @@
+ /* --- Unicode Escape Codec ----------------------------------------------- */
+
+ PyObject *
+-_PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
++_PyUnicode_DecodeUnicodeEscapeInternal2(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ Py_ssize_t *consumed,
+- const char **first_invalid_escape)
++ int *first_invalid_escape_char,
++ const char **first_invalid_escape_ptr)
+ {
+ const char *starts = s;
++ const char *initial_starts = starts;
+ _PyUnicodeWriter writer;
+ const char *end;
+ PyObject *errorHandler = NULL;
+@@ -6191,7 +6193,8 @@
+ _PyUnicode_Name_CAPI *ucnhash_capi;
+
+ // so we can remember if we've seen an invalid escape char or not
+- *first_invalid_escape = NULL;
++ *first_invalid_escape_char = -1;
++ *first_invalid_escape_ptr = NULL;
+
+ if (size == 0) {
+ if (consumed) {
+@@ -6279,9 +6282,12 @@
+ }
+ }
+ if (ch > 0377) {
+- if (*first_invalid_escape == NULL) {
+- *first_invalid_escape = s-3; /* Back up 3 chars, since we've
+- already incremented s. */
++ if (*first_invalid_escape_char == -1) {
++ *first_invalid_escape_char = ch;
++ if (starts == initial_starts) {
++ /* Back up 3 chars, since we've already incremented s. */
++ *first_invalid_escape_ptr = s - 3;
++ }
+ }
+ }
+ WRITE_CHAR(ch);
+@@ -6376,9 +6382,12 @@
+ goto error;
+
+ default:
+- if (*first_invalid_escape == NULL) {
+- *first_invalid_escape = s-1; /* Back up one char, since we've
+- already incremented s. */
++ if (*first_invalid_escape_char == -1) {
++ *first_invalid_escape_char = c;
++ if (starts == initial_starts) {
++ /* Back up one char, since we've already incremented s. */
++ *first_invalid_escape_ptr = s - 1;
++ }
+ }
+ WRITE_ASCII_CHAR('\\');
+ WRITE_CHAR(c);
+@@ -6423,18 +6432,19 @@
+ const char *errors,
+ Py_ssize_t *consumed)
+ {
+- const char *first_invalid_escape;
+- PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal(s, size, errors,
++ int first_invalid_escape_char;
++ const char *first_invalid_escape_ptr;
++ PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal2(s, size, errors,
+ consumed,
+- &first_invalid_escape);
++ &first_invalid_escape_char,
++ &first_invalid_escape_ptr);
+ if (result == NULL)
+ return NULL;
+- if (first_invalid_escape != NULL) {
+- unsigned char c = *first_invalid_escape;
+- if ('4' <= c && c <= '7') {
++ if (first_invalid_escape_char != -1) {
++ if (first_invalid_escape_char > 0xff) {
+ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+- "invalid octal escape sequence '\\%.3s'",
+- first_invalid_escape) < 0)
++ "invalid octal escape sequence '\\%o'",
++ first_invalid_escape_char) < 0)
+ {
+ Py_DECREF(result);
+ return NULL;
+@@ -6443,7 +6453,7 @@
+ else {
+ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+ "invalid escape sequence '\\%c'",
+- c) < 0)
++ first_invalid_escape_char) < 0)
+ {
+ Py_DECREF(result);
+ return NULL;
+Index: Python-3.13.3/Parser/string_parser.c
+===================================================================
+--- Python-3.13.3.orig/Parser/string_parser.c 2025-04-08 13:54:08.000000000 +0000
++++ Python-3.13.3/Parser/string_parser.c 2025-05-17 07:33:22.005519309 +0000
+@@ -184,15 +184,18 @@
+ len = (size_t)(p - buf);
+ s = buf;
+
+- const char *first_invalid_escape;
+- v = _PyUnicode_DecodeUnicodeEscapeInternal(s, (Py_ssize_t)len, NULL, NULL, &first_invalid_escape);
++ int first_invalid_escape_char;
++ const char *first_invalid_escape_ptr;
++ v = _PyUnicode_DecodeUnicodeEscapeInternal2(s, (Py_ssize_t)len, NULL, NULL,
++ &first_invalid_escape_char,
++ &first_invalid_escape_ptr);
+
+ // HACK: later we can simply pass the line no, since we don't preserve the tokens
+ // when we are decoding the string but we preserve the line numbers.
+- if (v != NULL && first_invalid_escape != NULL && t != NULL) {
+- if (warn_invalid_escape_sequence(parser, s, first_invalid_escape, t) < 0) {
+- /* We have not decref u before because first_invalid_escape points
+- inside u. */
++ if (v != NULL && first_invalid_escape_ptr != NULL && t != NULL) {
++ if (warn_invalid_escape_sequence(parser, s, first_invalid_escape_ptr, t) < 0) {
++ /* We have not decref u before because first_invalid_escape_ptr
++ points inside u. */
+ Py_XDECREF(u);
+ Py_DECREF(v);
+ return NULL;
+@@ -205,14 +208,17 @@
+ static PyObject *
+ decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t)
+ {
+- const char *first_invalid_escape;
+- PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, &first_invalid_escape);
++ int first_invalid_escape_char;
++ const char *first_invalid_escape_ptr;
++ PyObject *result = _PyBytes_DecodeEscape2(s, len, NULL,
++ &first_invalid_escape_char,
++ &first_invalid_escape_ptr);
+ if (result == NULL) {
+ return NULL;
+ }
+
+- if (first_invalid_escape != NULL) {
+- if (warn_invalid_escape_sequence(p, s, first_invalid_escape, t) < 0) {
++ if (first_invalid_escape_ptr != NULL) {
++ if (warn_invalid_escape_sequence(p, s, first_invalid_escape_ptr, t) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
diff --git a/python313.changes b/python313.changes
index 030266a..7fa89c2 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Fri May 16 13:44:12 UTC 2025 - Matej Cepl
+
+- Add CVE-2025-4516-DecodeError-handler.patch fixing
+ CVE-2025-4516 (bsc#1243273) blocking DecodeError handling
+ vulnerability, which could lead to DoS.
+
-------------------------------------------------------------------
Sat May 10 11:38:27 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index d1801aa..2e91972 100644
--- a/python313.spec
+++ b/python313.spec
@@ -226,6 +226,9 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM gh-132535-rsrc-warn-test_timeout.patch gh#python/cpython#132535 mcepl@suse.com
# allows test_timeout tests to pass
Patch43: gh-132535-rsrc-warn-test_timeout.patch
+# PATCH-FIX-UPSTREAM CVE-2025-4516-DecodeError-handler.patch bsc#1243273 mcepl@suse.com
+# this patch makes things totally awesome
+Patch44: CVE-2025-4516-DecodeError-handler.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From 6d5d3f96b081962b0505752cd776af183eab8d9544a0959c06efb11f1ce56e67 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Wed, 28 May 2025 09:47:26 +0000
Subject: [PATCH 11/32] - Don't use %elif, it is supported only from rpm
4.15.0, which is not in SLE-15.
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=98
---
python313.changes | 6 ++++++
python313.spec | 25 +++++++++++++------------
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/python313.changes b/python313.changes
index 7fa89c2..ea04a7f 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Wed May 28 09:46:40 UTC 2025 - Matej Cepl
+
+- Don't use %elif, it is supported only from rpm 4.15.0, which is
+ not in SLE-15.
+
-------------------------------------------------------------------
Fri May 16 13:44:12 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index 2e91972..3c26f11 100644
--- a/python313.spec
+++ b/python313.spec
@@ -83,19 +83,20 @@
# No experimental_jit in SLES, there's no clang >=18
%if 0%{?suse_version} <= 1600
%bcond_with experimental_jit
-# Disable experimental_jit for primary python.
-# llvm is not part of ring0 and experimental_jit requires clang >= 18
-%elif !%{primary_interpreter}
-# Currently supported architectures
-# https://peps.python.org/pep-0744/#support
-%ifarch x86_64 %{x86_64} aarch64
-%bcond_without experimental_jit
%else
-%bcond_with experimental_jit
-%endif
-
-%else
-%bcond_with experimental_jit
+ # Disable experimental_jit for primary python.
+ # llvm is not part of ring0 and experimental_jit requires clang >= 18
+ %if !%{primary_interpreter}
+ # Currently supported architectures
+ # https://peps.python.org/pep-0744/#support
+ %ifarch x86_64 %{x86_64} aarch64
+ %bcond_without experimental_jit
+ %else
+ %bcond_with experimental_jit
+ %endif
+ %else
+ %bcond_with experimental_jit
+ %endif
%endif
# %%if 0%%{?sle_version} && 0%%{?suse_version} < 1550
From 6072bbdbcd7bfd8c5f3324786ce6dd96d225d95ce88a1f7b964a5ecc4e69059e Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Mon, 9 Jun 2025 21:38:15 +0000
Subject: [PATCH 12/32] =?UTF-8?q?-=20Update=20to=203.13.4:=20=20=20-=20Sec?=
=?UTF-8?q?urity=20=20=20=20=20-=20gh-135034:=20Fixes=20multiple=20issues?=
=?UTF-8?q?=20that=20allowed=20tarfile=20=20=20=20=20=20=20extraction=20fi?=
=?UTF-8?q?lters=20(filter=3D"data"=20and=20filter=3D"tar")=20to=20be=20?=
=?UTF-8?q?=20=20=20=20=20=20bypassed=20using=20crafted=20symlinks=20and?=
=?UTF-8?q?=20hard=20links.=20=20=20=20=20=20=20Addresses=20CVE-2024-12718?=
=?UTF-8?q?=20(bsc#1244056),=20CVE-2025-4138=20=20=20=20=20=20=20(bsc#1244?=
=?UTF-8?q?059),=20CVE-2025-4330=20(bsc#1244060),=20and=20=20=20=20=20=20?=
=?UTF-8?q?=20CVE-2025-4517=20(bsc#1244032).=20=20=20=20=20-=20gh-133767:?=
=?UTF-8?q?=20Fix=20use-after-free=20in=20the=20=E2=80=9Cunicode-escape?=
=?UTF-8?q?=E2=80=9D=20=20=20=20=20=20=20decoder=20with=20a=20non-?=
=?UTF-8?q?=E2=80=9Cstrict=E2=80=9D=20error=20handler=20(CVE-2025-4516,=20?=
=?UTF-8?q?=20=20=20=20=20=20bsc#1243273).=20=20=20=20=20-=20gh-128840:=20?=
=?UTF-8?q?Short-circuit=20the=20processing=20of=20long=20IPv6=20=20=20=20?=
=?UTF-8?q?=20=20=20addresses=20early=20in=20ipaddress=20to=20prevent=20ex?=
=?UTF-8?q?cessive=20memory=20=20=20=20=20=20=20consumption=20and=20a=20mi?=
=?UTF-8?q?nor=20denial-of-service.=20=20=20-=20Library=20=20=20=20=20-=20?=
=?UTF-8?q?gh-134718:=20ast.dump()=20now=20only=20omits=20None=20and=20[]?=
=?UTF-8?q?=20values=20if=20=20=20=20=20=20=20they=20are=20default=20value?=
=?UTF-8?q?s.=20=20=20=20=20-=20gh-128840:=20Fix=20parsing=20long=20IPv6?=
=?UTF-8?q?=20addresses=20with=20embedded=20=20=20=20=20=20=20IPv4=20addre?=
=?UTF-8?q?ss.=20=20=20=20=20-=20gh-134696:=20Built-in=20HACL*=20and=20Ope?=
=?UTF-8?q?nSSL=20implementations=20of=20=20=20=20=20=20=20hash=20function?=
=?UTF-8?q?=20constructors=20now=20correctly=20accept=20the=20same=20=20?=
=?UTF-8?q?=20=20=20=20=20documented=20named=20arguments.=20For=20instance?=
=?UTF-8?q?,=20md5()=20could=20be=20=20=20=20=20=20=20previously=20invoked?=
=?UTF-8?q?=20as=20md5(data=3Ddata)=20or=20md5(string=3Dstring)=20=20=20?=
=?UTF-8?q?=20=20=20=20depending=20on=20the=20underlying=20implementation?=
=?UTF-8?q?=20but=20these=20calls=20=20=20=20=20=20=20were=20not=20compati?=
=?UTF-8?q?ble.=20Patch=20by=20B=C3=A9n=C3=A9dikt=20Tran.=20=20=20=20=20-?=
=?UTF-8?q?=20gh-134210:=20curses.window.getch()=20now=20correctly=20handl?=
=?UTF-8?q?es=20=20=20=20=20=20=20signals.=20Patch=20by=20B=C3=A9n=C3=A9di?=
=?UTF-8?q?kt=20Tran.=20=20=20=20=20-=20gh-80334:=20multiprocessing.freeze?=
=?UTF-8?q?=5Fsupport()=20now=20checks=20for=20=20=20=20=20=20=20work=20on?=
=?UTF-8?q?=20any=20=E2=80=9Cspawn=E2=80=9D=20start=20method=20platform=20?=
=?UTF-8?q?rather=20than=20only=20=20=20=20=20=20=20on=20Windows.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=100
---
CVE-2025-4516-DecodeError-handler.patch | 483 --------------------
Python-3.13.3.tar.xz | 3 -
Python-3.13.3.tar.xz.sigstore | 1 -
Python-3.13.4.tar.xz | 3 +
Python-3.13.4.tar.xz.sigstore | 1 +
bpo-31046_ensurepip_honours_prefix.patch | 52 +--
doc-py38-to-py36.patch | 131 +++---
gh-132535-rsrc-warn-test_timeout.patch | 94 ----
python-3.3.0b1-fix_date_time_compiler.patch | 2 +-
python-3.3.0b1-localpath.patch | 14 +-
python313.changes | 259 +++++++++++
python313.spec | 8 +-
subprocess-raise-timeout.patch | 8 +-
13 files changed, 356 insertions(+), 703 deletions(-)
delete mode 100644 CVE-2025-4516-DecodeError-handler.patch
delete mode 100644 Python-3.13.3.tar.xz
delete mode 100644 Python-3.13.3.tar.xz.sigstore
create mode 100644 Python-3.13.4.tar.xz
create mode 100644 Python-3.13.4.tar.xz.sigstore
delete mode 100644 gh-132535-rsrc-warn-test_timeout.patch
diff --git a/CVE-2025-4516-DecodeError-handler.patch b/CVE-2025-4516-DecodeError-handler.patch
deleted file mode 100644
index 4dcba72..0000000
--- a/CVE-2025-4516-DecodeError-handler.patch
+++ /dev/null
@@ -1,483 +0,0 @@
-From 0afcdf15f64273dc5e4ed12ea63a01f7f1136d71 Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Mon, 12 May 2025 20:42:23 +0300
-Subject: [PATCH] [3.13] gh-133767: Fix use-after-free in the unicode-escape
- decoder with an error handler (GH-129648)
-
-If the error handler is used, a new bytes object is created to set as
-the object attribute of UnicodeDecodeError, and that bytes object then
-replaces the original data. A pointer to the decoded data will became invalid
-after destroying that temporary bytes object. So we need other way to return
-the first invalid escape from _PyUnicode_DecodeUnicodeEscapeInternal().
-
-_PyBytes_DecodeEscape() does not have such issue, because it does not
-use the error handlers registry, but it should be changed for compatibility
-with _PyUnicode_DecodeUnicodeEscapeInternal().
-(cherry picked from commit 9f69a58623bd01349a18ba0c7a9cb1dad6a51e8e)
-
-Co-authored-by: Serhiy Storchaka
----
- Include/internal/pycore_bytesobject.h | 5
- Include/internal/pycore_unicodeobject.h | 12 +-
- Lib/test/test_codeccallbacks.py | 39 +++++++
- Lib/test/test_codecs.py | 52 ++++++++--
- Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst | 2
- Objects/bytesobject.c | 41 ++++---
- Objects/unicodeobject.c | 46 +++++---
- Parser/string_parser.c | 26 +++--
- 8 files changed, 160 insertions(+), 63 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst
-
-Index: Python-3.13.3/Include/internal/pycore_bytesobject.h
-===================================================================
---- Python-3.13.3.orig/Include/internal/pycore_bytesobject.h 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Include/internal/pycore_bytesobject.h 2025-05-17 07:33:22.001814947 +0000
-@@ -20,8 +20,9 @@
-
- // Helper for PyBytes_DecodeEscape that detects invalid escape chars.
- // Export for test_peg_generator.
--PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
-- const char *, const char **);
-+PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape2(const char *, Py_ssize_t,
-+ const char *,
-+ int *, const char **);
-
-
- // Substring Search.
-Index: Python-3.13.3/Include/internal/pycore_unicodeobject.h
-===================================================================
---- Python-3.13.3.orig/Include/internal/pycore_unicodeobject.h 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Include/internal/pycore_unicodeobject.h 2025-05-17 07:33:22.001974979 +0000
-@@ -142,14 +142,18 @@
- // Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape
- // chars.
- // Export for test_peg_generator.
--PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal(
-+PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal2(
- const char *string, /* Unicode-Escape encoded string */
- Py_ssize_t length, /* size of string */
- const char *errors, /* error handling */
- Py_ssize_t *consumed, /* bytes consumed */
-- const char **first_invalid_escape); /* on return, points to first
-- invalid escaped char in
-- string. */
-+ int *first_invalid_escape_char, /* on return, if not -1, contain the first
-+ invalid escaped char (<= 0xff) or invalid
-+ octal escape (> 0xff) in string. */
-+ const char **first_invalid_escape_ptr); /* on return, if not NULL, may
-+ point to the first invalid escaped
-+ char in string.
-+ May be NULL if errors is not NULL. */
-
- /* --- Raw-Unicode-Escape Codecs ---------------------------------------------- */
-
-Index: Python-3.13.3/Lib/test/test_codeccallbacks.py
-===================================================================
---- Python-3.13.3.orig/Lib/test/test_codeccallbacks.py 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Lib/test/test_codeccallbacks.py 2025-05-17 07:33:22.002185827 +0000
-@@ -1,6 +1,7 @@
- import codecs
- import html.entities
- import itertools
-+import re
- import sys
- import unicodedata
- import unittest
-@@ -1124,7 +1125,7 @@
- text = 'abcghi'*n
- text.translate(charmap)
-
-- def test_mutatingdecodehandler(self):
-+ def test_mutating_decode_handler(self):
- baddata = [
- ("ascii", b"\xff"),
- ("utf-7", b"++"),
-@@ -1159,6 +1160,42 @@
- for (encoding, data) in baddata:
- self.assertEqual(data.decode(encoding, "test.mutating"), "\u4242")
-
-+ def test_mutating_decode_handler_unicode_escape(self):
-+ decode = codecs.unicode_escape_decode
-+ def mutating(exc):
-+ if isinstance(exc, UnicodeDecodeError):
-+ r = data.get(exc.object[:exc.end])
-+ if r is not None:
-+ exc.object = r[0] + exc.object[exc.end:]
-+ return ('\u0404', r[1])
-+ raise AssertionError("don't know how to handle %r" % exc)
-+
-+ codecs.register_error('test.mutating2', mutating)
-+ data = {
-+ br'\x0': (b'\\', 0),
-+ br'\x3': (b'xxx\\', 3),
-+ br'\x5': (b'x\\', 1),
-+ }
-+ def check(input, expected, msg):
-+ with self.assertWarns(DeprecationWarning) as cm:
-+ self.assertEqual(decode(input, 'test.mutating2'), (expected, len(input)))
-+ self.assertIn(msg, str(cm.warning))
-+
-+ check(br'\x0n\z', '\u0404\n\\z', r"invalid escape sequence '\z'")
-+ check(br'\x0n\501', '\u0404\n\u0141', r"invalid octal escape sequence '\501'")
-+ check(br'\x0z', '\u0404\\z', r"invalid escape sequence '\z'")
-+
-+ check(br'\x3n\zr', '\u0404\n\\zr', r"invalid escape sequence '\z'")
-+ check(br'\x3zr', '\u0404\\zr', r"invalid escape sequence '\z'")
-+ check(br'\x3z5', '\u0404\\z5', r"invalid escape sequence '\z'")
-+ check(memoryview(br'\x3z5x')[:-1], '\u0404\\z5', r"invalid escape sequence '\z'")
-+ check(memoryview(br'\x3z5xy')[:-2], '\u0404\\z5', r"invalid escape sequence '\z'")
-+
-+ check(br'\x5n\z', '\u0404\n\\z', r"invalid escape sequence '\z'")
-+ check(br'\x5n\501', '\u0404\n\u0141', r"invalid octal escape sequence '\501'")
-+ check(br'\x5z', '\u0404\\z', r"invalid escape sequence '\z'")
-+ check(memoryview(br'\x5zy')[:-1], '\u0404\\z', r"invalid escape sequence '\z'")
-+
- # issue32583
- def test_crashing_decode_handler(self):
- # better generating one more character to fill the extra space slot
-Index: Python-3.13.3/Lib/test/test_codecs.py
-===================================================================
---- Python-3.13.3.orig/Lib/test/test_codecs.py 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Lib/test/test_codecs.py 2025-05-17 07:33:22.002507164 +0000
-@@ -1196,23 +1196,39 @@
- check(br"[\1010]", b"[A0]")
- check(br"[\x41]", b"[A]")
- check(br"[\x410]", b"[A0]")
-+
-+ def test_warnings(self):
-+ decode = codecs.escape_decode
-+ check = coding_checker(self, decode)
- for i in range(97, 123):
- b = bytes([i])
- if b not in b'abfnrtvx':
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\%c'" % i):
- check(b"\\" + b, b"\\" + b)
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\%c'" % (i-32)):
- check(b"\\" + b.upper(), b"\\" + b.upper())
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\8'"):
- check(br"\8", b"\\8")
- with self.assertWarns(DeprecationWarning):
- check(br"\9", b"\\9")
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\\xfa'") as cm:
- check(b"\\\xfa", b"\\\xfa")
- for i in range(0o400, 0o1000):
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid octal escape sequence '\\%o'" % i):
- check(rb'\%o' % i, bytes([i & 0o377]))
-
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\z'"):
-+ self.assertEqual(decode(br'\x\z', 'ignore'), (b'\\z', 4))
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid octal escape sequence '\\501'"):
-+ self.assertEqual(decode(br'\x\501', 'ignore'), (b'A', 6))
-+
- def test_errors(self):
- decode = codecs.escape_decode
- self.assertRaises(ValueError, decode, br"\x")
-@@ -2661,24 +2677,40 @@
- check(br"[\x410]", "[A0]")
- check(br"\u20ac", "\u20ac")
- check(br"\U0001d120", "\U0001d120")
-+
-+ def test_decode_warnings(self):
-+ decode = codecs.unicode_escape_decode
-+ check = coding_checker(self, decode)
- for i in range(97, 123):
- b = bytes([i])
- if b not in b'abfnrtuvx':
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\%c'" % i):
- check(b"\\" + b, "\\" + chr(i))
- if b.upper() not in b'UN':
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\%c'" % (i-32)):
- check(b"\\" + b.upper(), "\\" + chr(i-32))
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\8'"):
- check(br"\8", "\\8")
- with self.assertWarns(DeprecationWarning):
- check(br"\9", "\\9")
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\\xfa'") as cm:
- check(b"\\\xfa", "\\\xfa")
- for i in range(0o400, 0o1000):
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid octal escape sequence '\\%o'" % i):
- check(rb'\%o' % i, chr(i))
-
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid escape sequence '\\z'"):
-+ self.assertEqual(decode(br'\x\z', 'ignore'), ('\\z', 4))
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r"invalid octal escape sequence '\\501'"):
-+ self.assertEqual(decode(br'\x\501', 'ignore'), ('\u0141', 6))
-+
- def test_decode_errors(self):
- decode = codecs.unicode_escape_decode
- for c, d in (b'x', 2), (b'u', 4), (b'U', 4):
-Index: Python-3.13.3/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.13.3/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst 2025-05-17 07:33:22.002786511 +0000
-@@ -0,0 +1,2 @@
-+Fix use-after-free in the "unicode-escape" decoder with a non-"strict" error
-+handler.
-Index: Python-3.13.3/Objects/bytesobject.c
-===================================================================
---- Python-3.13.3.orig/Objects/bytesobject.c 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Objects/bytesobject.c 2025-05-17 07:33:22.003325939 +0000
-@@ -1065,10 +1065,11 @@
- }
-
- /* Unescape a backslash-escaped string. */
--PyObject *_PyBytes_DecodeEscape(const char *s,
-+PyObject *_PyBytes_DecodeEscape2(const char *s,
- Py_ssize_t len,
- const char *errors,
-- const char **first_invalid_escape)
-+ int *first_invalid_escape_char,
-+ const char **first_invalid_escape_ptr)
- {
- int c;
- char *p;
-@@ -1082,7 +1083,8 @@
- return NULL;
- writer.overallocate = 1;
-
-- *first_invalid_escape = NULL;
-+ *first_invalid_escape_char = -1;
-+ *first_invalid_escape_ptr = NULL;
-
- end = s + len;
- while (s < end) {
-@@ -1120,9 +1122,10 @@
- c = (c<<3) + *s++ - '0';
- }
- if (c > 0377) {
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-3; /* Back up 3 chars, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = c;
-+ /* Back up 3 chars, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 3;
- }
- }
- *p++ = c;
-@@ -1163,9 +1166,10 @@
- break;
-
- default:
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-1; /* Back up one char, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = (unsigned char)s[-1];
-+ /* Back up one char, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 1;
- }
- *p++ = '\\';
- s--;
-@@ -1185,17 +1189,18 @@
- Py_ssize_t Py_UNUSED(unicode),
- const char *Py_UNUSED(recode_encoding))
- {
-- const char* first_invalid_escape;
-- PyObject *result = _PyBytes_DecodeEscape(s, len, errors,
-- &first_invalid_escape);
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ PyObject *result = _PyBytes_DecodeEscape2(s, len, errors,
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
- if (result == NULL)
- return NULL;
-- if (first_invalid_escape != NULL) {
-- unsigned char c = *first_invalid_escape;
-- if ('4' <= c && c <= '7') {
-+ if (first_invalid_escape_char != -1) {
-+ if (first_invalid_escape_char > 0xff) {
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
-- "invalid octal escape sequence '\\%.3s'",
-- first_invalid_escape) < 0)
-+ "invalid octal escape sequence '\\%o'",
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-@@ -1204,7 +1209,7 @@
- else {
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
- "invalid escape sequence '\\%c'",
-- c) < 0)
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-Index: Python-3.13.3/Objects/unicodeobject.c
-===================================================================
---- Python-3.13.3.orig/Objects/unicodeobject.c 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Objects/unicodeobject.c 2025-05-17 07:33:22.004748214 +0000
-@@ -6177,13 +6177,15 @@
- /* --- Unicode Escape Codec ----------------------------------------------- */
-
- PyObject *
--_PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
-+_PyUnicode_DecodeUnicodeEscapeInternal2(const char *s,
- Py_ssize_t size,
- const char *errors,
- Py_ssize_t *consumed,
-- const char **first_invalid_escape)
-+ int *first_invalid_escape_char,
-+ const char **first_invalid_escape_ptr)
- {
- const char *starts = s;
-+ const char *initial_starts = starts;
- _PyUnicodeWriter writer;
- const char *end;
- PyObject *errorHandler = NULL;
-@@ -6191,7 +6193,8 @@
- _PyUnicode_Name_CAPI *ucnhash_capi;
-
- // so we can remember if we've seen an invalid escape char or not
-- *first_invalid_escape = NULL;
-+ *first_invalid_escape_char = -1;
-+ *first_invalid_escape_ptr = NULL;
-
- if (size == 0) {
- if (consumed) {
-@@ -6279,9 +6282,12 @@
- }
- }
- if (ch > 0377) {
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-3; /* Back up 3 chars, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = ch;
-+ if (starts == initial_starts) {
-+ /* Back up 3 chars, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 3;
-+ }
- }
- }
- WRITE_CHAR(ch);
-@@ -6376,9 +6382,12 @@
- goto error;
-
- default:
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-1; /* Back up one char, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = c;
-+ if (starts == initial_starts) {
-+ /* Back up one char, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 1;
-+ }
- }
- WRITE_ASCII_CHAR('\\');
- WRITE_CHAR(c);
-@@ -6423,18 +6432,19 @@
- const char *errors,
- Py_ssize_t *consumed)
- {
-- const char *first_invalid_escape;
-- PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal(s, size, errors,
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal2(s, size, errors,
- consumed,
-- &first_invalid_escape);
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
- if (result == NULL)
- return NULL;
-- if (first_invalid_escape != NULL) {
-- unsigned char c = *first_invalid_escape;
-- if ('4' <= c && c <= '7') {
-+ if (first_invalid_escape_char != -1) {
-+ if (first_invalid_escape_char > 0xff) {
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
-- "invalid octal escape sequence '\\%.3s'",
-- first_invalid_escape) < 0)
-+ "invalid octal escape sequence '\\%o'",
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-@@ -6443,7 +6453,7 @@
- else {
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
- "invalid escape sequence '\\%c'",
-- c) < 0)
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-Index: Python-3.13.3/Parser/string_parser.c
-===================================================================
---- Python-3.13.3.orig/Parser/string_parser.c 2025-04-08 13:54:08.000000000 +0000
-+++ Python-3.13.3/Parser/string_parser.c 2025-05-17 07:33:22.005519309 +0000
-@@ -184,15 +184,18 @@
- len = (size_t)(p - buf);
- s = buf;
-
-- const char *first_invalid_escape;
-- v = _PyUnicode_DecodeUnicodeEscapeInternal(s, (Py_ssize_t)len, NULL, NULL, &first_invalid_escape);
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ v = _PyUnicode_DecodeUnicodeEscapeInternal2(s, (Py_ssize_t)len, NULL, NULL,
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
-
- // HACK: later we can simply pass the line no, since we don't preserve the tokens
- // when we are decoding the string but we preserve the line numbers.
-- if (v != NULL && first_invalid_escape != NULL && t != NULL) {
-- if (warn_invalid_escape_sequence(parser, s, first_invalid_escape, t) < 0) {
-- /* We have not decref u before because first_invalid_escape points
-- inside u. */
-+ if (v != NULL && first_invalid_escape_ptr != NULL && t != NULL) {
-+ if (warn_invalid_escape_sequence(parser, s, first_invalid_escape_ptr, t) < 0) {
-+ /* We have not decref u before because first_invalid_escape_ptr
-+ points inside u. */
- Py_XDECREF(u);
- Py_DECREF(v);
- return NULL;
-@@ -205,14 +208,17 @@
- static PyObject *
- decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t)
- {
-- const char *first_invalid_escape;
-- PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, &first_invalid_escape);
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ PyObject *result = _PyBytes_DecodeEscape2(s, len, NULL,
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
- if (result == NULL) {
- return NULL;
- }
-
-- if (first_invalid_escape != NULL) {
-- if (warn_invalid_escape_sequence(p, s, first_invalid_escape, t) < 0) {
-+ if (first_invalid_escape_ptr != NULL) {
-+ if (warn_invalid_escape_sequence(p, s, first_invalid_escape_ptr, t) < 0) {
- Py_DECREF(result);
- return NULL;
- }
diff --git a/Python-3.13.3.tar.xz b/Python-3.13.3.tar.xz
deleted file mode 100644
index 124c035..0000000
--- a/Python-3.13.3.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:40f868bcbdeb8149a3149580bb9bfd407b3321cd48f0be631af955ac92c0e041
-size 22654240
diff --git a/Python-3.13.3.tar.xz.sigstore b/Python-3.13.3.tar.xz.sigstore
deleted file mode 100644
index 220fba8..0000000
--- a/Python-3.13.3.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUW58MW2P+CwyzYzHaIuAK12gGJqIwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNDA4MTcwOTUwWhcNMjUwNDA4MTcxOTUwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf+cTSQIElx0bw4BYf2qpKSxfUtm3PhehuBcTW3uoM+EnAUOv1pvCmnTteblYdA5s80cFMzvztRCKUCnvBTi+cKOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU/72Qdhdl1+U/9MdaCnja9KhnRBgwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGWFmEv3gAABAMARzBFAiBJV9Vq6+FQfjXs74fcGUOsuBsMdCS1SzabcwCeFgO4UgIhAI1uOTXNb3iARGgglGWmTHeplKpGCHj+9yCPticrd2TrMAoGCCqGSM49BAMDA2gAMGUCMBRlMgfY9hXwAO7OtJpDIecgS9xyghjq/ECzfX12I1rDnF1i9DDr/1AY2SsOpAEW/AIxANwA+iMGDPdrvrp6iQtONa/37WhvKJQ+pglUHcrMcsZobpRHyD7shomq0SkxYA+icg=="}, "tlogEntries": [{"logIndex": "194024100", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1744132190", "inclusionPromise": {"signedEntryTimestamp": "MEQCIGlOwO+ANhog+/QCGrUQpJZ6axA6UaE86sNaN8vNj+QiAiA/7d5r4Em9+T6ZnAoc+BLv2ExsJcG8OCgqJvvF5ZJuxw=="}, "inclusionProof": {"logIndex": "72119838", "rootHash": "WvXJaELSoRtosW8xi2EfnsHoXkmpACSbqywq8TfHR1s=", "treeSize": "72119843", "hashes": ["jgENOnZn6TEf8ylEIYa0JR6FDNY+6ehLszSGwnEMpQU=", "n4F70M6fgFOoXeQXsHA3dWN3ASf9JTc8Z1qQuECW75M=", "RgczeejL0XzzT46BcDe3Z4s9D2QcpqnLv4M8+1//nUY=", "sfHyJ5ybNWBxYHNTEvBl90AOfY+44p++5XzDCBTB5RQ=", "JqDONCapxnE2xLLKg9gRz2xF/70qW/AT/GEk0BrOTw4=", "Kzx15aA9iYz3QmqQyoe03wPppaDYPNVmJeN2J8wCAR4=", "V5ZRP+iiphMoS6raAUPBERnIOeTUs8417+6gSEKM/n4=", "759Ej7PWC5mfI+qe2WSvB/3yyxTCPVUcjobBVnw5UkY=", "thdh10t3YSAkcLudlXJR1SELWGQbnzOa8SAkNLF/CYo=", "BmjRaZPKQ5bVHiwShpJ9cZKgX1rQ4iJrYo2rcEntw0o=", "Wr475nJfgYQLV7M6HuAo4zRJeK0nVZeV5zBNbie9m9U=", "cBeUncMhaAbVvOdQXg7Ev8AuOxlXrF0R/+5x1+5nmIo=", "K26LG80DXyb+bC58c4Nw00WigG52v0PCsZGY3ExGsts=", "WEm5OgPzJpYROv+4CcrieexCYyQKrLUH3hbxmcQQ+DM=", "7v8qPHNDLerpduaMx06eb/MwgoQwczTn/cYGKX/9wZ4="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n72119843\nWvXJaELSoRtosW8xi2EfnsHoXkmpACSbqywq8TfHR1s=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiAr3CtxLPjTl8zeJINGRTEhV2fchhMWTABj0kKfwmDvMwIgQYxaVBOI8NhmcU1YpPa7KD6770ZIC5invnZfRa/OpiU=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI0MGY4NjhiY2JkZWI4MTQ5YTMxNDk1ODBiYjliZmQ0MDdiMzMyMWNkNDhmMGJlNjMxYWY5NTVhYzkyYzBlMDQxIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUURHbFBQYytoNS9QVm9qaHRnUkdOc3A4NW9iT3d1YkVVVXN6REZWSmE2ZVVRSWhBSnlYVTlWeGNSNHR6WmJyVmtOeDBPMnJvc01xV1lVYXNtMGMxZmlndDFkZSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVlZ6VTRUVmN5VUN0RGQzbDZXWHBJWVVsMVFVc3hNbWRIU25GSmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDVFUVRSTlZHTjNUMVJWZDFkb1kwNU5hbFYzVGtSQk5FMVVZM2hQVkZWM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZtSzJOVVUxRkpSV3g0TUdKM05FSlpaakp4Y0V0VGVHWlZkRzB6VUdobGFIVkNZMVFLVnpOMWIwMHJSVzVCVlU5Mk1YQjJRMjF1VkhSbFlteFpaRUUxY3pnd1kwWk5lblo2ZEZKRFMxVkRiblpDVkdrclkwdFBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlV2TnpKUkNtUm9aR3d4SzFVdk9VMWtZVU51YW1FNVMyaHVVa0puZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIVjBadFJYWXpaMEZCUWtGTlFRcFNla0pHUVdsQ1NsWTVWbkUySzBaUlptcFljemMwWm1OSFZVOXpkVUp6VFdSRFV6RlRlbUZpWTNkRFpVWm5UelJWWjBsb1FVa3hkVTlVV0U1aU0ybEJDbEpIWjJkc1IxZHRWRWhsY0d4TGNFZERTR29yT1hsRFVIUnBZM0prTWxSeVRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFVKU2JFMW5abGtLT1doWWQwRlBOMDkwU25CRVNXVmpaMU01ZUhsbmFHcHhMMFZEZW1aWU1USkpNWEpFYmtZeGFUbEVSSEl2TVVGWk1sTnpUM0JCUlZjdlFVbDRRVTUzUVFvcmFVMUhSRkJrY25aeWNEWnBVWFJQVG1Fdk16ZFhhSFpMU2xFcmNHZHNWVWhqY2sxamMxcHZZbkJTU0hsRU4zTm9iMjF4TUZOcmVGbEJLMmxqWnowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "QPhovL3rgUmjFJWAu5v9QHszIc1I8L5jGvlVrJLA4EE="}, "signature": "MEYCIQDGlPPc+h5/PVojhtgRGNsp85obOwubEUUszDFVJa6eUQIhAJyXU9VxcR4tzZbrVkNx0O2rosMqWYUasm0c1figt1de"}}
diff --git a/Python-3.13.4.tar.xz b/Python-3.13.4.tar.xz
new file mode 100644
index 0000000..423e749
--- /dev/null
+++ b/Python-3.13.4.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:27b15a797562a2971dce3ffe31bb216042ce0b995b39d768cf15f784cc757365
+size 22672472
diff --git a/Python-3.13.4.tar.xz.sigstore b/Python-3.13.4.tar.xz.sigstore
new file mode 100644
index 0000000..ef8d16e
--- /dev/null
+++ b/Python-3.13.4.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICzDCCAlGgAwIBAgIUO5JdWUQQH0AKKhZQ86mzrah+aHgwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNjAzMTczNDEwWhcNMjUwNjAzMTc0NDEwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgJAyXDyFDJsY+or0M9p1w5KvL3+oZuieOqdDU6Gh9qvOZrWVSvZPOZBGyz/EeUNOJObcOk1IhevZUFhXh5u9NaOCAXAwggFsMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUjB59Lh3csAPMT3DhyuwWeIWhVh0wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGLBgorBgEEAdZ5AgQCBH0EewB5AHcA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGXNtuZFwAABAMASDBGAiEAtNGTM9VDDbVXwR3TgugfGns9nzo6R/JOIkUfJuZ5FaACIQDrA24Mj6a4LegeVBvZ9HFL5FwtoJgaea+ENOuA9dD56zAKBggqhkjOPQQDAwNpADBmAjEAlLDQV+HOGajtbJxtOTRltXbNwUwchium//yOldpEu0FM/H/DbeDD9Un81BRL/rn/AjEAhKsjsB/fwcxcSkF1dXI3gbKJEZIrBVoVv6HKV11BY7qOP84vHOquEOz//N3MZIFC"}, "tlogEntries": [{"logIndex": "228874080", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1748972051", "inclusionPromise": {"signedEntryTimestamp": "MEUCIQDL78XHlNQD+0lTPncrwH+XfGjXGDl3XgDzU2QjFRoqcQIgRkVgEwkUa1tVdGjQWMMUZfY2Dbkzk1JrrcENoIsng/s="}, "inclusionProof": {"logIndex": "106969818", "rootHash": "+h7KA5AELljEYPaFPgSmnZyY0Da3w9hxsf5RPjjvol0=", "treeSize": "106969820", "hashes": ["+wFAYkn4BCFt0K3mtMHu6s8tG6bbKjXsXaHhz1z1xEM=", "8pBLgkVh8zd9pK662U3mjwsxnwg4ZApT/iml+5U4n0E=", "yP7p3olgvk5E8bbyCn5V/xJhQY0z23Y8T3JoBBQzBBc=", "zP7tQ4DpmQptR54rK1PpfdlvfPZBalQEYcdFCrn2W8c=", "Q1gnGCWZvzY0Px0RpNv8hIRPQLEcyGLYhugDpYkxoE4=", "5S2DqBJZbuLio6e9iBmJWALzYi0hcpXFV3Z8ydE2lrA=", "n5MzQvR+waONXmENXriYi92eiz9pa5whuAyHmzyZa9Q=", "S+DrHAWb67kO9sHsAjIJ89A0RLlbeXy6mUvzoKO3dMI=", "JQ9xTJKo/o9IWVV8l4RTm06tpXUcGCeAh8ciAprOIoE=", "pqCD1LoiP58WZ9AfwL1uMRLqmiQQKDHHSdnl+4lB+/0=", "uEJFtwcGQJMd9kjQhkXb7gl2WD3WMElCc15uDFvFGxs=", "VdOKzpQhJlpXgijzXANf/hNlje1G/N1kUuVnKNskkso=", "mta5fH/gFwxJ/0fT8yGpn3sFCY0G1RY555Iflm0LInM=", "7v8qPHNDLerpduaMx06eb/MwgoQwczTn/cYGKX/9wZ4="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n106969820\n+h7KA5AELljEYPaFPgSmnZyY0Da3w9hxsf5RPjjvol0=\n\n\u2014 rekor.sigstore.dev wNI9ajBGAiEAs6seTO9AxVZIS/HmvX1ZRibir/qonYfB+9RAgl/DZB4CIQCq+rKh4xxwYTzpbdg4zDl77noWEK27NCTE0TinoQM+5Q==\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIyN2IxNWE3OTc1NjJhMjk3MWRjZTNmZmUzMWJiMjE2MDQyY2UwYjk5NWIzOWQ3NjhjZjE1Zjc4NGNjNzU3MzY1In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJRU5GcjFleURKbk0xeEdnOWNjaFZPL3poUUhIT0d1VCttTjhVbzZOQWJWVEFpQXBrdFhIRFR4eXZNbUJTWjN6dUFuR0NLNkV0Q0dFdyt1bENUZDk3anVvU3c9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZSRU5EUVd4SFowRjNTVUpCWjBsVlR6VktaRmRWVVZGSU1FRkxTMmhhVVRnMmJYcHlZV2dyWVVobmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDVxUVhwTlZHTjZUa1JGZDFkb1kwNU5hbFYzVG1wQmVrMVVZekJPUkVWM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZuU2tGNVdFUjVSa1JLYzFrcmIzSXdUVGx3TVhjMVMzWk1NeXR2V25WcFpVOXhaRVFLVlRaSGFEbHhkazlhY2xkV1UzWmFVRTlhUWtkNWVpOUZaVlZPVDBwUFltTlBhekZKYUdWMldsVkdhRmhvTlhVNVRtRlBRMEZZUVhkblowWnpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZxUWpVNUNreG9NMk56UVZCTlZETkVhSGwxZDFkbFNWZG9WbWd3ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIweENaMjl5UW1kRlJVRmtXalZCWjFGRFFrZ3dSV1YzUWpVS1FVaGpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV0U1MGRWcEdkMEZCUWtGTlFRcFRSRUpIUVdsRlFYUk9SMVJOT1ZaRVJHSldXSGRTTTFSbmRXZG1SMjV6T1c1NmJ6WlNMMHBQU1d0VlprcDFXalZHWVVGRFNWRkVja0V5TkUxcU5tRTBDa3hsWjJWV1FuWmFPVWhHVERWR2QzUnZTbWRoWldFclJVNVBkVUU1WkVRMU5ucEJTMEpuWjNGb2EycFBVRkZSUkVGM1RuQkJSRUp0UVdwRlFXeE1SRkVLVml0SVQwZGhhblJpU25oMFQxUlNiSFJZWWs1M1ZYZGphR2wxYlM4dmVVOXNaSEJGZFRCR1RTOUlMMFJpWlVSRU9WVnVPREZDVWt3dmNtNHZRV3BGUVFwb1MzTnFjMEl2Wm5kamVHTlRhMFl4WkZoSk0yZGlTMHBGV2tseVFsWnZWblkyU0V0V01URkNXVGR4VDFBNE5IWklUM0YxUlU5Nkx5OU9NMDFhU1VaRENpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "J7FaeXViopcdzj/+MbshYELOC5lbOddozxX3hMx1c2U="}, "signature": "MEQCIENFr1eyDJnM1xGg9cchVO/zhQHHOGuT+mN8Uo6NAbVTAiApktXHDTxyvMmBSZ3zuAnGCK6EtCGEw+ulCTd97juoSw=="}}
diff --git a/bpo-31046_ensurepip_honours_prefix.patch b/bpo-31046_ensurepip_honours_prefix.patch
index b62eacf..44ed8cc 100644
--- a/bpo-31046_ensurepip_honours_prefix.patch
+++ b/bpo-31046_ensurepip_honours_prefix.patch
@@ -13,11 +13,9 @@ Co-Authored-By: Xavier de Gaye
5 files changed, 37 insertions(+), 9 deletions(-)
create mode 100644 Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
-Index: Python-3.13.3/Doc/library/ensurepip.rst
-===================================================================
---- Python-3.13.3.orig/Doc/library/ensurepip.rst 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/library/ensurepip.rst 2025-04-11 21:54:47.449458319 +0200
-@@ -61,7 +61,11 @@
+--- a/Doc/library/ensurepip.rst
++++ b/Doc/library/ensurepip.rst
+@@ -61,7 +61,11 @@ is at least as recent as the one availab
By default, ``pip`` is installed into the current virtual environment
(if one is active) or into the system site packages (if there is no
active virtual environment). The installation location can be controlled
@@ -30,7 +28,7 @@ Index: Python-3.13.3/Doc/library/ensurepip.rst
.. option:: --root
-@@ -102,7 +106,7 @@
+@@ -102,7 +106,7 @@ Module API
Returns a string specifying the available version of pip that will be
installed when bootstrapping an environment.
@@ -39,7 +37,7 @@ Index: Python-3.13.3/Doc/library/ensurepip.rst
altinstall=False, default_pip=False, \
verbosity=0)
-@@ -112,6 +116,8 @@
+@@ -112,6 +116,8 @@ Module API
If *root* is ``None``, then installation uses the default install location
for the current environment.
@@ -48,7 +46,7 @@ Index: Python-3.13.3/Doc/library/ensurepip.rst
*upgrade* indicates whether or not to upgrade an existing installation
of an earlier version of ``pip`` to the available version.
-@@ -132,6 +138,8 @@
+@@ -132,6 +138,8 @@ Module API
*verbosity* controls the level of output to :data:`sys.stdout` from the
bootstrapping operation.
@@ -57,11 +55,9 @@ Index: Python-3.13.3/Doc/library/ensurepip.rst
.. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap
.. note::
-Index: Python-3.13.3/Lib/ensurepip/__init__.py
-===================================================================
---- Python-3.13.3.orig/Lib/ensurepip/__init__.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Lib/ensurepip/__init__.py 2025-04-11 21:53:49.548370352 +0200
-@@ -106,27 +106,27 @@
+--- a/Lib/ensurepip/__init__.py
++++ b/Lib/ensurepip/__init__.py
+@@ -106,27 +106,27 @@ def _disable_pip_configuration_settings(
os.environ['PIP_CONFIG_FILE'] = os.devnull
@@ -94,7 +90,7 @@ Index: Python-3.13.3/Lib/ensurepip/__init__.py
Note that calling this function will alter both sys.path and os.environ.
"""
-@@ -162,6 +162,8 @@
+@@ -162,6 +162,8 @@ def _bootstrap(*, root=None, upgrade=Fal
args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir]
if root:
args += ["--root", root]
@@ -103,7 +99,7 @@ Index: Python-3.13.3/Lib/ensurepip/__init__.py
if upgrade:
args += ["--upgrade"]
if user:
-@@ -238,6 +240,11 @@
+@@ -238,6 +240,11 @@ def _main(argv=None):
help="Install everything relative to this alternate root directory.",
)
parser.add_argument(
@@ -115,7 +111,7 @@ Index: Python-3.13.3/Lib/ensurepip/__init__.py
"--altinstall",
action="store_true",
default=False,
-@@ -256,6 +263,7 @@
+@@ -256,6 +263,7 @@ def _main(argv=None):
return _bootstrap(
root=args.root,
@@ -123,11 +119,9 @@ Index: Python-3.13.3/Lib/ensurepip/__init__.py
upgrade=args.upgrade,
user=args.user,
verbosity=args.verbosity,
-Index: Python-3.13.3/Lib/test/test_ensurepip.py
-===================================================================
---- Python-3.13.3.orig/Lib/test/test_ensurepip.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Lib/test/test_ensurepip.py 2025-04-11 21:53:49.548691764 +0200
-@@ -101,6 +101,17 @@
+--- a/Lib/test/test_ensurepip.py
++++ b/Lib/test/test_ensurepip.py
+@@ -101,6 +101,17 @@ class TestBootstrap(EnsurepipMixin, unit
unittest.mock.ANY,
)
@@ -145,11 +139,9 @@ Index: Python-3.13.3/Lib/test/test_ensurepip.py
def test_bootstrapping_with_user(self):
ensurepip.bootstrap(user=True)
-Index: Python-3.13.3/Makefile.pre.in
-===================================================================
---- Python-3.13.3.orig/Makefile.pre.in 2025-04-11 21:52:35.635495820 +0200
-+++ Python-3.13.3/Makefile.pre.in 2025-04-11 21:53:49.549094822 +0200
-@@ -2139,7 +2139,7 @@
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -2145,7 +2145,7 @@ install: @FRAMEWORKINSTALLFIRST@ @INSTAL
install|*) ensurepip="" ;; \
esac; \
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
@@ -158,7 +150,7 @@ Index: Python-3.13.3/Makefile.pre.in
fi
.PHONY: altinstall
-@@ -2150,7 +2150,7 @@
+@@ -2156,7 +2156,7 @@ altinstall: commoninstall
install|*) ensurepip="--altinstall" ;; \
esac; \
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
@@ -167,9 +159,7 @@ Index: Python-3.13.3/Makefile.pre.in
fi
.PHONY: commoninstall
-Index: Python-3.13.3/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.13.3/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst 2025-04-11 21:53:49.549612071 +0200
+--- /dev/null
++++ b/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
@@ -0,0 +1 @@
+A directory prefix can now be specified when using :mod:`ensurepip`.
diff --git a/doc-py38-to-py36.patch b/doc-py38-to-py36.patch
index 28a725d..84eec6b 100644
--- a/doc-py38-to-py36.patch
+++ b/doc-py38-to-py36.patch
@@ -1,18 +1,16 @@
---
- Doc/conf.py | 17 ++++++++--
+ Doc/conf.py | 17 ++++++++-
Doc/tools/check-warnings.py | 3 +
- Doc/tools/extensions/audit_events.py | 54 ++++++++++++++++----------------
+ Doc/tools/extensions/audit_events.py | 55 ++++++++++++++++----------------
Doc/tools/extensions/availability.py | 15 ++++----
- Doc/tools/extensions/c_annotations.py | 45 ++++++++++++++++----------
+ Doc/tools/extensions/c_annotations.py | 45 +++++++++++++++-----------
Doc/tools/extensions/glossary_search.py | 10 +----
Doc/tools/extensions/patchlevel.py | 9 ++---
- 7 files changed, 87 insertions(+), 66 deletions(-)
+ 7 files changed, 87 insertions(+), 67 deletions(-)
-Index: Python-3.13.3/Doc/conf.py
-===================================================================
---- Python-3.13.3.orig/Doc/conf.py 2025-04-11 21:52:28.845065297 +0200
-+++ Python-3.13.3/Doc/conf.py 2025-04-11 21:55:28.065280454 +0200
-@@ -18,6 +18,9 @@
+--- a/Doc/conf.py
++++ b/Doc/conf.py
+@@ -18,6 +18,9 @@ sys.path.append(os.path.abspath('include
# Python specific content from Doc/Tools/extensions/pyspecific.py
from pyspecific import SOURCE_URI
@@ -22,7 +20,7 @@ Index: Python-3.13.3/Doc/conf.py
# General configuration
# ---------------------
-@@ -92,7 +95,7 @@
+@@ -92,7 +95,7 @@ highlight_language = 'python3'
# Minimum version of sphinx required
# Keep this version in sync with ``Doc/requirements.txt``.
@@ -31,7 +29,7 @@ Index: Python-3.13.3/Doc/conf.py
# Create table of contents entries for domain objects (e.g. functions, classes,
# attributes, etc.). Default is True.
-@@ -361,7 +364,7 @@
+@@ -360,7 +363,7 @@ html_short_title = f'{release} Documenta
# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html)
is_deployment_preview = os.getenv("READTHEDOCS_VERSION_TYPE") == "external"
repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL", "")
@@ -40,7 +38,7 @@ Index: Python-3.13.3/Doc/conf.py
html_context = {
"is_deployment_preview": is_deployment_preview,
"repository_url": repository_url or None,
-@@ -606,6 +609,16 @@
+@@ -605,6 +608,16 @@ extlinks = {
}
extlinks_detect_hardcoded_links = True
@@ -57,11 +55,9 @@ Index: Python-3.13.3/Doc/conf.py
# Options for c_annotations extension
# -----------------------------------
-Index: Python-3.13.3/Doc/tools/check-warnings.py
-===================================================================
---- Python-3.13.3.orig/Doc/tools/check-warnings.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/tools/check-warnings.py 2025-04-11 21:55:11.212002463 +0200
-@@ -228,7 +228,8 @@
+--- a/Doc/tools/check-warnings.py
++++ b/Doc/tools/check-warnings.py
+@@ -228,7 +228,8 @@ def fail_if_regression(
print(filename)
for warning in warnings:
if filename in warning:
@@ -71,11 +67,9 @@ Index: Python-3.13.3/Doc/tools/check-warnings.py
print(" {line}: {msg}".format_map(match))
return -1
return 0
-Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
-===================================================================
---- Python-3.13.3.orig/Doc/tools/extensions/audit_events.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/tools/extensions/audit_events.py 2025-04-11 21:55:11.212275615 +0200
-@@ -1,9 +1,6 @@
+--- a/Doc/tools/extensions/audit_events.py
++++ b/Doc/tools/extensions/audit_events.py
+@@ -1,23 +1,18 @@
"""Support for documenting audit events."""
-from __future__ import annotations
@@ -84,15 +78,16 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
-from typing import TYPE_CHECKING
from docutils import nodes
++from typing import Any, List, Tuple
from sphinx.errors import NoUri
-@@ -12,12 +9,11 @@
+ from sphinx.locale import _ as sphinx_gettext
+ from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
-if TYPE_CHECKING:
-- from collections.abc import Iterator
-+from typing import Any, List, Tuple
-
+- from collections.abc import Iterator, Set
+-
- from sphinx.application import Sphinx
- from sphinx.builders import Builder
- from sphinx.environment import BuildEnvironment
@@ -102,12 +97,12 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
logger = logging.getLogger(__name__)
-@@ -32,16 +28,16 @@
+@@ -32,16 +27,16 @@ _SYNONYMS = [
class AuditEvents:
def __init__(self) -> None:
- self.events: dict[str, list[str]] = {}
-- self.sources: dict[str, list[tuple[str, str]]] = {}
+- self.sources: dict[str, set[tuple[str, str]]] = {}
+ self.events: dict[str, List[str]] = {}
+ self.sources: dict[str, List[Tuple[str, str]]] = {}
@@ -123,16 +118,16 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
) -> None:
if name in self.events:
self._check_args_match(name, args)
-@@ -49,7 +45,7 @@
+@@ -49,7 +44,7 @@ class AuditEvents:
self.events[name] = args
- self.sources.setdefault(name, []).append(source)
+ self.sources.setdefault(name, set()).add(source)
- def _check_args_match(self, name: str, args: list[str]) -> None:
+ def _check_args_match(self, name: str, args: List[str]) -> None:
current_args = self.events[name]
msg = (
f"Mismatched arguments for audit-event {name}: "
-@@ -60,7 +56,7 @@
+@@ -60,7 +55,7 @@ class AuditEvents:
if len(current_args) != len(args):
logger.warning(msg)
return
@@ -141,16 +136,16 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
if a1 == a2:
continue
if any(a1 in s and a2 in s for s in _SYNONYMS):
-@@ -73,7 +69,7 @@
+@@ -73,7 +68,7 @@ class AuditEvents:
name_clean = re.sub(r"\W", "_", name)
return f"audit_event_{name_clean}_{source_count}"
-- def rows(self) -> Iterator[tuple[str, list[str], list[tuple[str, str]]]]:
+- def rows(self) -> Iterator[tuple[str, list[str], Set[tuple[str, str]]]]:
+ def rows(self) -> Any:
for name in sorted(self.events.keys()):
yield name, self.events[name], self.sources[name]
-@@ -97,7 +93,7 @@
+@@ -97,7 +92,7 @@ def audit_events_purge(
def audit_events_merge(
app: Sphinx,
env: BuildEnvironment,
@@ -159,7 +154,7 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
other: BuildEnvironment,
) -> None:
"""In Sphinx parallel builds, this merges audit_events from subprocesses."""
-@@ -126,14 +122,16 @@
+@@ -126,14 +121,16 @@ class AuditEvent(SphinxDirective):
),
]
@@ -182,7 +177,7 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
else:
args = []
ids = []
-@@ -169,7 +167,7 @@
+@@ -169,7 +166,7 @@ class audit_event_list(nodes.General, no
class AuditEventListDirective(SphinxDirective):
@@ -191,7 +186,7 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
return [audit_event_list()]
-@@ -181,7 +179,11 @@
+@@ -181,7 +178,11 @@ class AuditEventListTransform(SphinxPost
return
table = self._make_table(self.app.builder, self.env.docname)
@@ -204,21 +199,19 @@ Index: Python-3.13.3/Doc/tools/extensions/audit_events.py
node.replace_self(table)
def _make_table(self, builder: Builder, docname: str) -> nodes.table:
-@@ -217,8 +219,8 @@
+@@ -217,8 +218,8 @@ class AuditEventListTransform(SphinxPost
builder: Builder,
docname: str,
name: str,
- args: list[str],
-- sources: list[tuple[str, str]],
+- sources: Set[tuple[str, str]],
+ args: List[str],
-+ sources: List[Tuple[str, str]],
++ sources: Set[Tuple[str, str]],
) -> nodes.row:
row = nodes.row()
name_node = nodes.paragraph("", nodes.Text(name))
-Index: Python-3.13.3/Doc/tools/extensions/availability.py
-===================================================================
---- Python-3.13.3.orig/Doc/tools/extensions/availability.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/tools/extensions/availability.py 2025-04-11 21:55:11.212578519 +0200
+--- a/Doc/tools/extensions/availability.py
++++ b/Doc/tools/extensions/availability.py
@@ -1,8 +1,6 @@
"""Support for documenting platform availability"""
@@ -229,7 +222,7 @@ Index: Python-3.13.3/Doc/tools/extensions/availability.py
from docutils import nodes
from sphinx import addnodes
-@@ -55,7 +53,7 @@
+@@ -55,7 +53,7 @@ class Availability(SphinxDirective):
optional_arguments = 0
final_argument_whitespace = True
@@ -238,7 +231,7 @@ Index: Python-3.13.3/Doc/tools/extensions/availability.py
title = sphinx_gettext("Availability")
refnode = addnodes.pending_xref(
title,
-@@ -79,7 +77,7 @@
+@@ -79,7 +77,7 @@ class Availability(SphinxDirective):
return [cnode]
@@ -247,7 +240,7 @@ Index: Python-3.13.3/Doc/tools/extensions/availability.py
"""Parse platform information from arguments
Arguments is a comma-separated string of platforms. A platform may
-@@ -98,12 +96,13 @@
+@@ -98,12 +96,13 @@ class Availability(SphinxDirective):
platform, _, version = arg.partition(" >= ")
if platform.startswith("not "):
version = False
@@ -263,7 +256,7 @@ Index: Python-3.13.3/Doc/tools/extensions/availability.py
logger.warning(
"Unknown platform%s or syntax '%s' in '.. availability:: %s', "
"see %s:KNOWN_PLATFORMS for a set of known platforms.",
-@@ -116,7 +115,7 @@
+@@ -116,7 +115,7 @@ class Availability(SphinxDirective):
return platforms
@@ -272,11 +265,9 @@ Index: Python-3.13.3/Doc/tools/extensions/availability.py
app.add_directive("availability", Availability)
return {
-Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
-===================================================================
---- Python-3.13.3.orig/Doc/tools/extensions/c_annotations.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/tools/extensions/c_annotations.py 2025-04-11 21:55:11.212780990 +0200
-@@ -9,22 +9,18 @@
+--- a/Doc/tools/extensions/c_annotations.py
++++ b/Doc/tools/extensions/c_annotations.py
+@@ -9,22 +9,18 @@ Configuration:
* Set ``stable_abi_file`` to the path to stable ABI list.
"""
@@ -302,7 +293,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
ROLE_TO_OBJECT_TYPE = {
"func": "function",
-@@ -35,20 +31,20 @@
+@@ -35,20 +31,20 @@ ROLE_TO_OBJECT_TYPE = {
}
@@ -327,7 +318,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
class StableABIEntry:
# Role of the object.
# Source: Each [item_kind] in stable_abi.toml is mapped to a C Domain role.
-@@ -67,7 +63,7 @@
+@@ -67,7 +63,7 @@ class StableABIEntry:
struct_abi_kind: str
@@ -336,7 +327,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
refcount_data = {}
refcounts = refcount_filename.read_text(encoding="utf8")
for line in refcounts.splitlines():
-@@ -103,7 +99,7 @@
+@@ -103,7 +99,7 @@ def read_refcount_data(refcount_filename
return refcount_data
@@ -345,7 +336,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
stable_abi_data = {}
with open(stable_abi_file, encoding="utf8") as fp:
for record in csv.DictReader(fp):
-@@ -123,11 +119,14 @@
+@@ -123,11 +119,14 @@ def add_annotations(app: Sphinx, doctree
continue
if not par[0].get("ids", None):
continue
@@ -362,7 +353,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
if ROLE_TO_OBJECT_TYPE[record.role] != objtype:
msg = (
f"Object type mismatch in limited API annotation for {name}: "
-@@ -234,7 +233,7 @@
+@@ -234,7 +233,7 @@ def _unstable_api_annotation() -> nodes.
)
@@ -371,7 +362,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
classes = ["refcount"]
if result_refs is None:
rc = sphinx_gettext("Return value: Always NULL.")
-@@ -254,7 +253,7 @@
+@@ -254,7 +253,7 @@ class LimitedAPIList(SphinxDirective):
optional_arguments = 0
final_argument_whitespace = True
@@ -380,7 +371,7 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
state = self.env.domaindata["c_annotations"]
content = [
f"* :c:{record.role}:`{record.name}`"
-@@ -277,13 +276,23 @@
+@@ -277,13 +276,23 @@ def init_annotations(app: Sphinx) -> Non
)
@@ -405,10 +396,8 @@ Index: Python-3.13.3/Doc/tools/extensions/c_annotations.py
return {
"version": "1.0",
"parallel_read_safe": True,
-Index: Python-3.13.3/Doc/tools/extensions/glossary_search.py
-===================================================================
---- Python-3.13.3.orig/Doc/tools/extensions/glossary_search.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/tools/extensions/glossary_search.py 2025-04-11 21:55:11.212983043 +0200
+--- a/Doc/tools/extensions/glossary_search.py
++++ b/Doc/tools/extensions/glossary_search.py
@@ -1,18 +1,14 @@
"""Feature search results for glossary items prominently."""
@@ -430,7 +419,7 @@ Index: Python-3.13.3/Doc/tools/extensions/glossary_search.py
logger = logging.getLogger(__name__)
-@@ -52,7 +48,7 @@
+@@ -52,7 +48,7 @@ def write_glossary_json(app: Sphinx, _ex
dest.write_text(json.dumps(app.env.glossary_terms), encoding='utf-8')
@@ -439,10 +428,8 @@ Index: Python-3.13.3/Doc/tools/extensions/glossary_search.py
app.connect('doctree-resolved', process_glossary_nodes)
app.connect('build-finished', write_glossary_json)
-Index: Python-3.13.3/Doc/tools/extensions/patchlevel.py
-===================================================================
---- Python-3.13.3.orig/Doc/tools/extensions/patchlevel.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Doc/tools/extensions/patchlevel.py 2025-04-11 21:55:11.213150035 +0200
+--- a/Doc/tools/extensions/patchlevel.py
++++ b/Doc/tools/extensions/patchlevel.py
@@ -3,7 +3,7 @@
import re
import sys
@@ -452,7 +439,7 @@ Index: Python-3.13.3/Doc/tools/extensions/patchlevel.py
CPYTHON_ROOT = Path(
__file__, # cpython/Doc/tools/extensions/patchlevel.py
-@@ -26,7 +26,7 @@
+@@ -26,7 +26,7 @@ class version_info(NamedTuple): # noqa:
major: int #: Major release number
minor: int #: Minor release number
micro: int #: Patch release number
@@ -461,7 +448,7 @@ Index: Python-3.13.3/Doc/tools/extensions/patchlevel.py
serial: int #: Serial release number
-@@ -37,7 +37,8 @@
+@@ -37,7 +37,8 @@ def get_header_version_info() -> version
defines = {}
patchlevel_h = PATCHLEVEL_H.read_text(encoding="utf-8")
for line in patchlevel_h.splitlines():
@@ -471,7 +458,7 @@ Index: Python-3.13.3/Doc/tools/extensions/patchlevel.py
name, value = m.groups()
defines[name] = value
-@@ -50,7 +51,7 @@
+@@ -50,7 +51,7 @@ def get_header_version_info() -> version
)
diff --git a/gh-132535-rsrc-warn-test_timeout.patch b/gh-132535-rsrc-warn-test_timeout.patch
deleted file mode 100644
index 1dc73a4..0000000
--- a/gh-132535-rsrc-warn-test_timeout.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 0e461dd411e9ec3dbdf376435154ca2834bcab51 Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Wed, 16 Apr 2025 00:24:56 +0300
-Subject: [PATCH] gh-132535: Fix resource warnings in test_timeout
-
-They were emitted if internet connection was not available.
----
- Lib/test/test_timeout.py | 43 ++++++++++++++++---------------------------
- 1 file changed, 16 insertions(+), 27 deletions(-)
-
-Index: Python-3.13.3/Lib/test/test_timeout.py
-===================================================================
---- Python-3.13.3.orig/Lib/test/test_timeout.py 2025-04-08 15:54:08.000000000 +0200
-+++ Python-3.13.3/Lib/test/test_timeout.py 2025-04-15 23:45:55.028517897 +0200
-@@ -26,10 +26,8 @@
- """Test case for socket.gettimeout() and socket.settimeout()"""
-
- def setUp(self):
-- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
--
-- def tearDown(self):
-- self.sock.close()
-+ self.sock = self.enterContext(
-+ socket.socket(socket.AF_INET, socket.SOCK_STREAM))
-
- def testObjectCreation(self):
- # Test Socket creation
-@@ -113,8 +111,6 @@
- def setUp(self):
- raise NotImplementedError()
-
-- tearDown = setUp
--
- def _sock_operation(self, count, timeout, method, *args):
- """
- Test the specified socket method.
-@@ -142,12 +138,10 @@
- """TCP test case for socket.socket() timeout functions"""
-
- def setUp(self):
-- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-+ self.sock = self.enterContext(
-+ socket.socket(socket.AF_INET, socket.SOCK_STREAM))
- self.addr_remote = resolve_address('www.python.org.', 80)
-
-- def tearDown(self):
-- self.sock.close()
--
- def testConnectTimeout(self):
- # Testing connect timeout is tricky: we need to have IP connectivity
- # to a host that silently drops our packets. We can't simulate this
-@@ -190,19 +184,16 @@
- # for the current configuration.
-
- skip = True
-- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-- timeout = support.LOOPBACK_TIMEOUT
-- sock.settimeout(timeout)
-- try:
-- sock.connect((whitehole))
-- except TimeoutError:
-- pass
-- except OSError as err:
-- if err.errno == errno.ECONNREFUSED:
-- skip = False
-- finally:
-- sock.close()
-- del sock
-+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
-+ try:
-+ timeout = support.LOOPBACK_TIMEOUT
-+ sock.settimeout(timeout)
-+ sock.connect((whitehole))
-+ except TimeoutError:
-+ pass
-+ except OSError as err:
-+ if err.errno == errno.ECONNREFUSED:
-+ skip = False
-
- if skip:
- self.skipTest(
-@@ -269,10 +260,8 @@
- """UDP test case for socket.socket() timeout functions"""
-
- def setUp(self):
-- self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
--
-- def tearDown(self):
-- self.sock.close()
-+ self.sock = self.enterContext(
-+ socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
-
- def testRecvfromTimeout(self):
- # Test recvfrom() timeout
diff --git a/python-3.3.0b1-fix_date_time_compiler.patch b/python-3.3.0b1-fix_date_time_compiler.patch
index 6b739fa..6b7e491 100644
--- a/python-3.3.0b1-fix_date_time_compiler.patch
+++ b/python-3.3.0b1-fix_date_time_compiler.patch
@@ -4,7 +4,7 @@
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
-@@ -1679,11 +1679,18 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \
+@@ -1684,11 +1684,18 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \
$(DTRACE_OBJS) \
$(srcdir)/Modules/getbuildinfo.c
$(CC) -c $(PY_CORE_CFLAGS) \
diff --git a/python-3.3.0b1-localpath.patch b/python-3.3.0b1-localpath.patch
index 00d6dba..3dffb30 100644
--- a/python-3.3.0b1-localpath.patch
+++ b/python-3.3.0b1-localpath.patch
@@ -1,9 +1,11 @@
-Index: Python-3.13.0a3/Lib/site.py
-===================================================================
---- Python-3.13.0a3.orig/Lib/site.py
-+++ Python-3.13.0a3/Lib/site.py
-@@ -77,7 +77,7 @@ import io
- import stat
+---
+ Lib/site.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Lib/site.py
++++ b/Lib/site.py
+@@ -78,7 +78,7 @@ import stat
+ import errno
# Prefixes for site-packages; add additional prefixes like /usr/local here
-PREFIXES = [sys.prefix, sys.exec_prefix]
diff --git a/python313.changes b/python313.changes
index ea04a7f..28ca241 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,262 @@
+-------------------------------------------------------------------
+Mon Jun 9 21:24:09 UTC 2025 - Matej Cepl
+
+- Update to 3.13.4:
+ - Security
+ - gh-135034: Fixes multiple issues that allowed tarfile
+ extraction filters (filter="data" and filter="tar") to be
+ bypassed using crafted symlinks and hard links.
+ Addresses CVE-2024-12718 (bsc#1244056), CVE-2025-4138
+ (bsc#1244059), CVE-2025-4330 (bsc#1244060), and
+ CVE-2025-4517 (bsc#1244032).
+ - gh-133767: Fix use-after-free in the “unicode-escape”
+ decoder with a non-“strict” error handler (CVE-2025-4516,
+ bsc#1243273).
+ - gh-128840: Short-circuit the processing of long IPv6
+ addresses early in ipaddress to prevent excessive memory
+ consumption and a minor denial-of-service.
+ - Library
+ - gh-134718: ast.dump() now only omits None and [] values if
+ they are default values.
+ - gh-128840: Fix parsing long IPv6 addresses with embedded
+ IPv4 address.
+ - gh-134696: Built-in HACL* and OpenSSL implementations of
+ hash function constructors now correctly accept the same
+ documented named arguments. For instance, md5() could be
+ previously invoked as md5(data=data) or md5(string=string)
+ depending on the underlying implementation but these calls
+ were not compatible. Patch by Bénédikt Tran.
+ - gh-134210: curses.window.getch() now correctly handles
+ signals. Patch by Bénédikt Tran.
+ - gh-80334: multiprocessing.freeze_support() now checks for
+ work on any “spawn” start method platform rather than only
+ on Windows.
+ - gh-114177: Fix asyncio to not close subprocess pipes which
+ would otherwise error out when the event loop is already
+ closed.
+ - gh-134152: Fixed UnboundLocalError that could occur during
+ email header parsing if an expected trailing delimiter is
+ missing in some contexts.
+ - gh-62184: Remove import of C implementation of io.FileIO
+ from Python implementation which has its own implementation
+ - gh-133982: Emit RuntimeWarning in the Python implementation
+ of io when the file-like object is not closed explicitly in
+ the presence of multiple I/O layers.
+ - gh-133890: The tarfile module now handles
+ UnicodeEncodeError in the same way as OSError when cannot
+ extract a member.
+ - gh-134097: Fix interaction of the new REPL and -X
+ showrefcount command line option.
+ - gh-133889: The generated directory listing page in
+ http.server.SimpleHTTPRequestHandler now only shows the
+ decoded path component of the requested URL, and not the
+ query and fragment.
+ - gh-134098: Fix handling paths that end with
+ a percent-encoded slash (%2f or %2F) in
+ http.server.SimpleHTTPRequestHandler.
+ - gh-134062: ipaddress: fix collisions in __hash__() for
+ IPv4Network and IPv6Network objects.
+ - gh-133745: In 3.13.3 we accidentally changed the signature
+ of the asyncio create_task() family of methods and how it
+ calls a custom task factory in a backwards incompatible
+ way. Since some 3rd party libraries have already made
+ changes to work around the issue that might break if
+ we simply reverted the changes, we’re instead changing
+ things to be backwards compatible with 3.13.2 while still
+ supporting those workarounds for 3.13.3. In particular, the
+ special-casing of name and context is back (until 3.14) and
+ consequently eager tasks may still find that their name
+ hasn’t been set before they execute their first yielding
+ await.
+ - gh-71253: Raise ValueError in open() if opener returns a
+ negative file-descriptor in the Python implementation of io
+ to match the C implementation.
+ - gh-77057: Fix handling of invalid markup declarations in
+ html.parser.HTMLParser.
+ - gh-133489: random.getrandbits() can now generate more that
+ 231 bits. random.randbytes() can now generate more that 256
+ MiB.
+ - gh-133290: Fix attribute caching issue when setting
+ ctypes._Pointer._type_ in the undocumented and deprecated
+ ctypes.SetPointerType() function and the undocumented
+ set_type() method.
+ - gh-132876: ldexp() on Windows doesn’t round subnormal
+ results before Windows 11, but should. Python’s
+ math.ldexp() wrapper now does round them, so results may
+ change slightly, in rare cases of very small results, on
+ Windows versions before 11.
+ - gh-133089: Use original timeout value for
+ subprocess.TimeoutExpired when the func subprocess.run()
+ is called with a timeout instead of sometimes a confusing
+ partial remaining time out value used internally on the
+ final wait().
+ - gh-133009: xml.etree.ElementTree: Fix a crash in
+ Element.__deepcopy__ when the element is concurrently
+ mutated. Patch by Bénédikt Tran.
+ - gh-132995: Bump the version of pip bundled in ensurepip to
+ version 25.1.1
+ - gh-132017: Fix error when pyrepl is suspended, then resumed
+ and terminated.
+ - gh-132673: Fix a crash when using _align_ = 0 and _fields_
+ = [] in a ctypes.Structure.
+ - gh-132527: Include the valid typecode ‘w’ in the error
+ message when an invalid typecode is passed to array.array.
+ - gh-132439: Fix PyREPL on Windows: characters entered via
+ AltGr are swallowed. Patch by Chris Eibl.
+ - gh-132429: Fix support of Bluetooth sockets on NetBSD and
+ DragonFly BSD.
+ - gh-132106: QueueListener.start now raises a RuntimeError if
+ the listener is already started.
+ - gh-132417: Fix a NULL pointer dereference when a C function
+ called using ctypes with restype py_object returns NULL.
+ - gh-132385: Fix instance error suggestions trigger potential
+ exceptions in object.__getattr__() in traceback.
+ - gh-132308: A traceback.TracebackException now correctly
+ renders the __context__ and __cause__ attributes from
+ falsey Exception, and the exceptions attribute from falsey
+ ExceptionGroup.
+ - gh-132250: Fixed the SystemError in cProfile when locating
+ the actual C function of a method raises an exception.
+ - gh-132063: Prevent exceptions that evaluate as
+ falsey (namely, when their __bool__ method returns
+ False or their __len__ method returns 0) from being
+ ignored by concurrent.futures.ProcessPoolExecutor and
+ concurrent.futures.ThreadPoolExecutor.
+ - gh-119605: Respect follow_wrapped for __init__() and
+ __new__() methods when getting the class signature for a
+ class with inspect.signature(). Preserve class signature
+ after wrapping with warnings.deprecated(). Patch by Xuehai
+ Pan.
+ - gh-91555: Ignore log messages generated during handling of
+ log messages, to avoid deadlock or infinite recursion.
+ - gh-131434: Improve error reporting for incorrect format in
+ time.strptime().
+ - gh-131127: Systems using LibreSSL now successfully build.
+ - gh-130999: Avoid exiting the new REPL and offer suggestions
+ even if there are non-string candidates when errors occur.
+ - gh-130941: Fix configparser.ConfigParser parsing empty
+ interpolation with allow_no_value set to True.
+ - gh-129098: Fix REPL traceback reporting when using
+ compile() with an inexisting file. Patch by Bénédikt Tran.
+ - gh-130631: http.cookiejar.join_header_words() is now more
+ similar to the original Perl version. It now quotes the
+ same set of characters and always quote values that end
+ with "\n".
+ - gh-129719: Fix missing socket.CAN_RAW_ERR_FILTER constant
+ in the socket module on Linux systems. It was missing since
+ Python 3.11.
+ - gh-124096: Turn on virtual terminal mode and enable
+ bracketed paste in REPL on Windows console. (If the
+ terminal does not support bracketed paste, enabling it does
+ nothing.)
+ - gh-122559: Remove __reduce__() and __reduce_ex__() methods
+ that always raise TypeError in the C implementation
+ of io.FileIO, io.BufferedReader, io.BufferedWriter
+ and io.BufferedRandom and replace them with default
+ __getstate__() methods that raise TypeError. This restores
+ fine details of behavior of Python 3.11 and older versions.
+ - gh-122179: hashlib.file_digest() now raises BlockingIOError
+ when no data is available during non-blocking I/O. Before,
+ it added spurious null bytes to the digest.
+ - gh-86155: html.parser.HTMLParser.close() no longer loses
+ data when the "/>.=20=20=20=20=20?=
=?UTF-8?q?=20=20=20=20-=20Multiple=20slashes=20and=20whitespaces=20betwee?=
=?UTF-8?q?n=20the=20last=20=20=20=20=20=20=20=20=20=20=20attribute=20and?=
=?UTF-8?q?=20closing=20>=20are=20now=20ignored=20in=20both=20start=20=20?=
=?UTF-8?q?=20=20=20=20=20=20=20=20=20and=20end=20tags.=20E.g.=20.=20=20=20=20=20=20=20=20=20-=20Multiple=20=3D=20b?=
=?UTF-8?q?etween=20attribute=20name=20and=20value=20are=20no=20=20=20=20?=
=?UTF-8?q?=20=20=20=20=20=20=20longer=20collapsed.=20E.g.=20=20produces=20attribute?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=115
---
CVE-2025-8194-tarfile-no-neg-offsets.patch | 212 ---------------------
Python-3.13.5.tar.xz | 3 -
Python-3.13.5.tar.xz.sigstore | 1 -
Python-3.13.6.tar.xz | 3 +
Python-3.13.6.tar.xz.sigstore | 1 +
python313.changes | 206 ++++++++++++++++++++
python313.spec | 7 +-
7 files changed, 212 insertions(+), 221 deletions(-)
delete mode 100644 CVE-2025-8194-tarfile-no-neg-offsets.patch
delete mode 100644 Python-3.13.5.tar.xz
delete mode 100644 Python-3.13.5.tar.xz.sigstore
create mode 100644 Python-3.13.6.tar.xz
create mode 100644 Python-3.13.6.tar.xz.sigstore
diff --git a/CVE-2025-8194-tarfile-no-neg-offsets.patch b/CVE-2025-8194-tarfile-no-neg-offsets.patch
deleted file mode 100644
index 96d08b0..0000000
--- a/CVE-2025-8194-tarfile-no-neg-offsets.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From fd29bcd380150035ef825b762d8cd085bdab6e53 Mon Sep 17 00:00:00 2001
-From: Alexander Urieles
-Date: Mon, 28 Jul 2025 17:37:26 +0200
-Subject: [PATCH] gh-130577: tarfile now validates archives to ensure member
- offsets are non-negative (GH-137027) (cherry picked from commit
- 7040aa54f14676938970e10c5f74ea93cd56aa38)
-
-Co-authored-by: Alexander Urieles
-Co-authored-by: Gregory P. Smith
----
- Lib/tarfile.py | 3
- Lib/test/test_tarfile.py | 156 ++++++++++
- Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst | 3
- 3 files changed, 162 insertions(+)
- create mode 100644 Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
-
-Index: Python-3.13.5/Lib/tarfile.py
-===================================================================
---- Python-3.13.5.orig/Lib/tarfile.py 2025-08-01 22:13:44.185826095 +0200
-+++ Python-3.13.5/Lib/tarfile.py 2025-08-01 22:13:45.524140183 +0200
-@@ -1636,6 +1636,9 @@
- """Round up a byte count by BLOCKSIZE and return it,
- e.g. _block(834) => 1024.
- """
-+ # Only non-negative offsets are allowed
-+ if count < 0:
-+ raise InvalidHeaderError("invalid offset")
- blocks, remainder = divmod(count, BLOCKSIZE)
- if remainder:
- blocks += 1
-Index: Python-3.13.5/Lib/test/test_tarfile.py
-===================================================================
---- Python-3.13.5.orig/Lib/test/test_tarfile.py 2025-06-11 17:36:57.000000000 +0200
-+++ Python-3.13.5/Lib/test/test_tarfile.py 2025-08-01 22:13:45.524778259 +0200
-@@ -50,6 +50,7 @@
- xzname = os.path.join(TEMPDIR, "testtar.tar.xz")
- tmpname = os.path.join(TEMPDIR, "tmp.tar")
- dotlessname = os.path.join(TEMPDIR, "testtar")
-+SPACE = b" "
-
- sha256_regtype = (
- "e09e4bc8b3c9d9177e77256353b36c159f5f040531bbd4b024a8f9b9196c71ce"
-@@ -4578,6 +4579,161 @@
- ar.extractall(self.testdir, filter='fully_trusted')
-
-
-+class OffsetValidationTests(unittest.TestCase):
-+ tarname = tmpname
-+ invalid_posix_header = (
-+ # name: 100 bytes
-+ tarfile.NUL * tarfile.LENGTH_NAME
-+ # mode, space, null terminator: 8 bytes
-+ + b"000755" + SPACE + tarfile.NUL
-+ # uid, space, null terminator: 8 bytes
-+ + b"000001" + SPACE + tarfile.NUL
-+ # gid, space, null terminator: 8 bytes
-+ + b"000001" + SPACE + tarfile.NUL
-+ # size, space: 12 bytes
-+ + b"\xff" * 11 + SPACE
-+ # mtime, space: 12 bytes
-+ + tarfile.NUL * 11 + SPACE
-+ # chksum: 8 bytes
-+ + b"0011407" + tarfile.NUL
-+ # type: 1 byte
-+ + tarfile.REGTYPE
-+ # linkname: 100 bytes
-+ + tarfile.NUL * tarfile.LENGTH_LINK
-+ # magic: 6 bytes, version: 2 bytes
-+ + tarfile.POSIX_MAGIC
-+ # uname: 32 bytes
-+ + tarfile.NUL * 32
-+ # gname: 32 bytes
-+ + tarfile.NUL * 32
-+ # devmajor, space, null terminator: 8 bytes
-+ + tarfile.NUL * 6 + SPACE + tarfile.NUL
-+ # devminor, space, null terminator: 8 bytes
-+ + tarfile.NUL * 6 + SPACE + tarfile.NUL
-+ # prefix: 155 bytes
-+ + tarfile.NUL * tarfile.LENGTH_PREFIX
-+ # padding: 12 bytes
-+ + tarfile.NUL * 12
-+ )
-+ invalid_gnu_header = (
-+ # name: 100 bytes
-+ tarfile.NUL * tarfile.LENGTH_NAME
-+ # mode, null terminator: 8 bytes
-+ + b"0000755" + tarfile.NUL
-+ # uid, null terminator: 8 bytes
-+ + b"0000001" + tarfile.NUL
-+ # gid, space, null terminator: 8 bytes
-+ + b"0000001" + tarfile.NUL
-+ # size, space: 12 bytes
-+ + b"\xff" * 11 + SPACE
-+ # mtime, space: 12 bytes
-+ + tarfile.NUL * 11 + SPACE
-+ # chksum: 8 bytes
-+ + b"0011327" + tarfile.NUL
-+ # type: 1 byte
-+ + tarfile.REGTYPE
-+ # linkname: 100 bytes
-+ + tarfile.NUL * tarfile.LENGTH_LINK
-+ # magic: 8 bytes
-+ + tarfile.GNU_MAGIC
-+ # uname: 32 bytes
-+ + tarfile.NUL * 32
-+ # gname: 32 bytes
-+ + tarfile.NUL * 32
-+ # devmajor, null terminator: 8 bytes
-+ + tarfile.NUL * 8
-+ # devminor, null terminator: 8 bytes
-+ + tarfile.NUL * 8
-+ # padding: 167 bytes
-+ + tarfile.NUL * 167
-+ )
-+ invalid_v7_header = (
-+ # name: 100 bytes
-+ tarfile.NUL * tarfile.LENGTH_NAME
-+ # mode, space, null terminator: 8 bytes
-+ + b"000755" + SPACE + tarfile.NUL
-+ # uid, space, null terminator: 8 bytes
-+ + b"000001" + SPACE + tarfile.NUL
-+ # gid, space, null terminator: 8 bytes
-+ + b"000001" + SPACE + tarfile.NUL
-+ # size, space: 12 bytes
-+ + b"\xff" * 11 + SPACE
-+ # mtime, space: 12 bytes
-+ + tarfile.NUL * 11 + SPACE
-+ # chksum: 8 bytes
-+ + b"0010070" + tarfile.NUL
-+ # type: 1 byte
-+ + tarfile.REGTYPE
-+ # linkname: 100 bytes
-+ + tarfile.NUL * tarfile.LENGTH_LINK
-+ # padding: 255 bytes
-+ + tarfile.NUL * 255
-+ )
-+ valid_gnu_header = tarfile.TarInfo("filename").tobuf(tarfile.GNU_FORMAT)
-+ data_block = b"\xff" * tarfile.BLOCKSIZE
-+
-+ def _write_buffer(self, buffer):
-+ with open(self.tarname, "wb") as f:
-+ f.write(buffer)
-+
-+ def _get_members(self, ignore_zeros=None):
-+ with open(self.tarname, "rb") as f:
-+ with tarfile.open(
-+ mode="r", fileobj=f, ignore_zeros=ignore_zeros
-+ ) as tar:
-+ return tar.getmembers()
-+
-+ def _assert_raises_read_error_exception(self):
-+ with self.assertRaisesRegex(
-+ tarfile.ReadError, "file could not be opened successfully"
-+ ):
-+ self._get_members()
-+
-+ def test_invalid_offset_header_validations(self):
-+ for tar_format, invalid_header in (
-+ ("posix", self.invalid_posix_header),
-+ ("gnu", self.invalid_gnu_header),
-+ ("v7", self.invalid_v7_header),
-+ ):
-+ with self.subTest(format=tar_format):
-+ self._write_buffer(invalid_header)
-+ self._assert_raises_read_error_exception()
-+
-+ def test_early_stop_at_invalid_offset_header(self):
-+ buffer = self.valid_gnu_header + self.invalid_gnu_header + self.valid_gnu_header
-+ self._write_buffer(buffer)
-+ members = self._get_members()
-+ self.assertEqual(len(members), 1)
-+ self.assertEqual(members[0].name, "filename")
-+ self.assertEqual(members[0].offset, 0)
-+
-+ def test_ignore_invalid_archive(self):
-+ # 3 invalid headers with their respective data
-+ buffer = (self.invalid_gnu_header + self.data_block) * 3
-+ self._write_buffer(buffer)
-+ members = self._get_members(ignore_zeros=True)
-+ self.assertEqual(len(members), 0)
-+
-+ def test_ignore_invalid_offset_headers(self):
-+ for first_block, second_block, expected_offset in (
-+ (
-+ (self.valid_gnu_header),
-+ (self.invalid_gnu_header + self.data_block),
-+ 0,
-+ ),
-+ (
-+ (self.invalid_gnu_header + self.data_block),
-+ (self.valid_gnu_header),
-+ 1024,
-+ ),
-+ ):
-+ self._write_buffer(first_block + second_block)
-+ members = self._get_members(ignore_zeros=True)
-+ self.assertEqual(len(members), 1)
-+ self.assertEqual(members[0].name, "filename")
-+ self.assertEqual(members[0].offset, expected_offset)
-+
-+
- def setUpModule():
- os_helper.unlink(TEMPDIR)
- os.makedirs(TEMPDIR)
-Index: Python-3.13.5/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.13.5/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst 2025-08-01 22:13:45.525174751 +0200
-@@ -0,0 +1,3 @@
-+:mod:`tarfile` now validates archives to ensure member offsets are
-+non-negative. (Contributed by Alexander Enrique Urieles Nieto in
-+:gh:`130577`.)
diff --git a/Python-3.13.5.tar.xz b/Python-3.13.5.tar.xz
deleted file mode 100644
index 16b1f7d..0000000
--- a/Python-3.13.5.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:93e583f243454e6e9e4588ca2c2662206ad961659863277afcdb96801647d640
-size 22856016
diff --git a/Python-3.13.5.tar.xz.sigstore b/Python-3.13.5.tar.xz.sigstore
deleted file mode 100644
index 225651c..0000000
--- a/Python-3.13.5.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUdRfsw3XxSwqBsRu/Ryhu0kfD1TEwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNjExMTc0NjIzWhcNMjUwNjExMTc1NjIzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE616iCJ8T+boBEGZNSBgbHZ2TS6Bl7yRCs1F78fvUBWcO/fJl9vTWXF+oPaOhLWVl35iAkn1W04PDVWrqNpFntKOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUlLnv2c6W2ETiqJdQsF9NjtUCVqEwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGXYBmnGAAABAMARzBFAiBDOyOIs3CL2AVMb7j6sHu3PYA8pOzJQNmm7J+zPIYzlgIhAK5GqY5j781IK5E7NTaGuPzwcj08xstDLULewS3KRwLBMAoGCCqGSM49BAMDA2gAMGUCMQDn2SkdZvHZZ6RKG8bIgPJdW+qMM9DNUmRm0/F+ePCPjMNwNUY/VQHqgsD4+m7FoX0CMAoIIxK3JZiKBFcP0oUNpnoZcZzZg/SeCkY6fePDlrRMMh5guyKUvMjXOIFREzNaRA=="}, "tlogEntries": [{"logIndex": "235130253", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1749663983", "inclusionPromise": {"signedEntryTimestamp": "MEUCIEXmlLAwKmFPqJl0qZIn6l9LeN1eFpo/O29cweVvcLM6AiEAkPbiV9MFAugYnKigfY2M6d4/IlgLMlamVTNMjYG1Ujc="}, "inclusionProof": {"logIndex": "113225991", "rootHash": "+L93VCZOPa9BkLmARBWDo1xEWF+fT68+yQcazjpxAAU=", "treeSize": "113225992", "hashes": ["Rdu+myw6n6JxBUvJ8Q+8oqhqACFhkt/3w7I+DEesttk=", "RxFdYWKOAXBMCLz1xkC2n0/oY0PPGjB9g/1mK9X9Lpk=", "nRMGDo+FIXFJXJGmLI3xYofkA1BacK+jsaHI6Dah6SQ=", "P4PZCTzvD59p99NgLr2g5UaCSGBHniridbmhL+bTkOA=", "Ho1rvGrV8vApgV6ObQmLHUFtPdLht0dxaKIMr2L227A=", "bUrfsqt1y90MYAQSa4N7IMFLQ58Gr3kyGuZsXADQmyk=", "zQYNyoYKqtevNhM4z5didetaiTZZe4Ydpenxywyp2HM=", "yB2hiozejE1yTbQwbDQpScNo2G9QaqtVTvrtSzcAWLk=", "ni+UOcPDIr1WWONf2Z1uda+A31LRXKpMYBvhb3MyUvI=", "jak2gEavHKki8uP+13+VibRhrrjlEQ57Cu6sFEmzL98=", "x/DbUcJZd7Krichz/nbTRqNRynFXkcgDj6/SVp3Xpa8=", "KL733V6m2mKaszPoebRYld3g+XcUSNldm6GnXG4M7kM=", "f42cOIPnrB9x+HYKZ+7UAkXKjk7k9ttvx1Mm5/glCwo=", "G4CdPz/xjoqWI4G874tZWPeP98DJpseyihrtz0ivBtU=", "mta5fH/gFwxJ/0fT8yGpn3sFCY0G1RY555Iflm0LInM=", "7v8qPHNDLerpduaMx06eb/MwgoQwczTn/cYGKX/9wZ4="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n113225992\n+L93VCZOPa9BkLmARBWDo1xEWF+fT68+yQcazjpxAAU=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBKR6/aQGwMRmyBmdgiaLd8393XQqJh41H6LIYA8Y6SYgIgDMucmAXZHwIDjA6YXg9k2vhoOuscGewoHiSomHsf+kg=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI5M2U1ODNmMjQzNDU0ZTZlOWU0NTg4Y2EyYzI2NjIyMDZhZDk2MTY1OTg2MzI3N2FmY2RiOTY4MDE2NDdkNjQwIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRWVnU0xnMVBzNmNEMkpNbTJzK1o4dzBzbGlMazY0SCtHeHQ2VFpRb1NIaUFpRUE1b2FmTTJhNlJqQSszUFpVdmNjUWNhQ0QzRVFsQ1hSdmI3d2x3SU9JQ1IwPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVlpGSm1jM2N6V0hoVGQzRkNjMUoxTDFKNWFIVXdhMlpFTVZSRmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDVxUlhoTlZHTXdUbXBKZWxkb1kwNU5hbFYzVG1wRmVFMVVZekZPYWtsNlYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUyTVRacFEwbzRWQ3RpYjBKRlIxcE9VMEpuWWtoYU1sUlROa0pzTjNsU1EzTXhSamNLT0daMlZVSlhZMDh2Wmtwc09YWlVWMWhHSzI5UVlVOW9URmRXYkRNMWFVRnJiakZYTURSUVJGWlhjbkZPY0VadWRFdFBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZzVEc1MkNqSmpObGN5UlZScGNVcGtVWE5HT1U1cWRGVkRWbkZGZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV0ZsQ2JXNUhRVUZCUWtGTlFRcFNla0pHUVdsQ1JFOTVUMGx6TTBOTU1rRldUV0kzYWpaelNIVXpVRmxCT0hCUGVrcFJUbTF0TjBvcmVsQkpXWHBzWjBsb1FVczFSM0ZaTldvM09ERkpDa3MxUlRkT1ZHRkhkVkI2ZDJOcU1EaDRjM1JFVEZWTVpYZFRNMHRTZDB4Q1RVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFZGRWJqSlRhMlFLV25aSVdsbzJVa3RIT0dKSloxQktaRmNyY1UxTk9VUk9WVzFTYlRBdlJpdGxVRU5RYWsxT2QwNVZXUzlXVVVoeFozTkVOQ3R0TjBadldEQkRUVUZ2U1FwSmVFc3pTbHBwUzBKR1kxQXdiMVZPY0c1dldtTmFlbHBuTDFObFEydFpObVpsVUVSc2NsSk5UV2cxWjNWNVMxVjJUV3BZVDBsR1VrVjZUbUZTUVQwOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "k+WD8kNFTm6eRYjKLCZiIGrZYWWYYyd6/NuWgBZH1kA="}, "signature": "MEUCIEegSLg1Ps6cD2JMm2s+Z8w0sliLk64H+Gxt6TZQoSHiAiEA5oafM2a6RjA+3PZUvccQcaCD3EQlCXRvb7wlwIOICR0="}}
diff --git a/Python-3.13.6.tar.xz b/Python-3.13.6.tar.xz
new file mode 100644
index 0000000..45693a9
--- /dev/null
+++ b/Python-3.13.6.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:17ba5508819d8736a14fbfc47d36e184946a877851b2e9c4b6c43acb44a3b104
+size 22761268
diff --git a/Python-3.13.6.tar.xz.sigstore b/Python-3.13.6.tar.xz.sigstore
new file mode 100644
index 0000000..849237d
--- /dev/null
+++ b/Python-3.13.6.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUIT3VXYZsgJBBLFYgnUd3yPWDR14wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwODA2MTUxOTAzWhcNMjUwODA2MTUyOTAzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENQnI68efruhc/qXKi3t/8sqIuDaRnuIwRFUnkF4A2waeN+IzagQ0N+naFAZdKn36t/W21EFOB9NpdHOc4IsvBKOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUwuKqH8hgzo3y/mXe+uV5YElD+wowHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGYf/bkHAAABAMARzBFAiBHMrjIDQAwDBXoGbltVdYPHSUejHkEdNhg8tfNuKS9VgIhAJk8J4X1XqlMXJfd+WltTk33D4ktHK4bqmstq/9VVHyoMAoGCCqGSM49BAMDA2gAMGUCMQCvd2vT066cA2WufLrQmlcjJ5ibnPUWr/o8USFrCd/e3Rv3MycHOi6oTk78xXQdsw4CMGoE5ETpgkfvlDKM8HXMGUaX+mXDZYd4nwH5w+HpoDXmfKZHPdOS/jokolmPEK4EVw=="}, "tlogEntries": [{"logIndex": "357334837", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1754493543", "inclusionPromise": {"signedEntryTimestamp": "MEQCIFB4cDBZVdygUBVVVwa50eFqQfnXia5VLvYT5La7DiPcAiBfeHQv6VwoCV8eWWkubfw7XiFTyZbFUztjsaEajCqStg=="}, "inclusionProof": {"logIndex": "235430575", "rootHash": "Glr+4g4bat4RwhMw/RhFX50HnBM1W7QEKz9sIHUzoo8=", "treeSize": "235430587", "hashes": ["EZsghZu+T1pEYnc5dQ4ku383SGmdF4Vi5z8QLvrUBiE=", "QdL10lLuyibm9U7VPxXiKCS5j3etGVR/zsL9Wb4YEic=", "hOdtwXckZXPPVGDipnQurns8YlGf7FvsPA0Bg0HjfoM=", "oMbtJ33vNBXJ3GRmCIyxtZ0DXj+U2hFPTn7LlduEhfo=", "FpgVGNakFzY7wY7H6BmgDJWiAJdJmnVEV+LVKLNGMA8=", "eYnyLnUnBAXk9NYcyFkkVWeeyY+IzzRJuFX5oNu7hjs=", "5/w4GgbnOf1ey9f5PsAJ/L+fUruO/pL4AkhrYlf1z6g=", "KOdSczh0sMksRbJ5MtuAQTd+ol7RSEMHTbScms6+yiY=", "pGvHucRuMO5oMlmhAUPoYfC7aUD0lGZQYzdyBWRotpM=", "Rdwnt8l+kitCx3q9MjvY521Vs1UGB65Yr5SL3DBIBZw=", "VlTxRYMi0uf0Jsl/dln/6MRW+6h4IwIRRM1h1l8YMnY=", "4UEb5oiYfLnEfmBDb+rZMlzYP20NXNd6288+yuM/qus=", "Q8AUdGrLOK/+q7Zpb5T3hpo2AMEg3qW2VHw5OtFthRI=", "wLANT0NMxIRh/p5rRcam4MppSIbUXIfT1Ht9FQA2XnI="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n235430587\nGlr+4g4bat4RwhMw/RhFX50HnBM1W7QEKz9sIHUzoo8=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBXv2s18aClhm2gewXKAZaMl3AGewwjjak9sXp+A5beSAIgU3pnjQgePf6ndF2Oru+Ma7JS81eAJlWxP/uB2RjP61o=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIxN2JhNTUwODgxOWQ4NzM2YTE0ZmJmYzQ3ZDM2ZTE4NDk0NmE4Nzc4NTFiMmU5YzRiNmM0M2FjYjQ0YTNiMTA0In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUURqYW9uOGRjbDNGY2pWOHJobUlndEMrNUYvdVpDVk8vUjJUZnNucnVnVHhRSWhBUG9pTUdZczkrRm9OdFhNb1BBWko3Y203c2EvZnJodnJ0QU9JWUcySWRVLyIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVlNWUXpWbGhaV25OblNrSkNURVpaWjI1VlpETjVVRmRFVWpFMGQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUVRKTlZGVjRUMVJCZWxkb1kwNU5hbFYzVDBSQk1rMVVWWGxQVkVGNlYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZPVVc1Sk5qaGxabkoxYUdNdmNWaExhVE4wTHpoemNVbDFSR0ZTYm5WSmQxSkdWVzRLYTBZMFFUSjNZV1ZPSzBsNllXZFJNRTRyYm1GR1FWcGtTMjR6Tm5RdlZ6SXhSVVpQUWpsT2NHUklUMk0wU1hOMlFrdFBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlYzZFV0eENrZzRhR2Q2YnpONUwyMVlaU3QxVmpWWlJXeEVLM2R2ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV1dZdlltdElRVUZCUWtGTlFRcFNla0pHUVdsQ1NFMXlha2xFVVVGM1JFSlliMGRpYkhSV1pGbFFTRk5WWldwSWEwVmtUbWhuT0hSbVRuVkxVemxXWjBsb1FVcHJPRW8wV0RGWWNXeE5DbGhLWm1RclYyeDBWR3N6TTBRMGEzUklTelJpY1cxemRIRXZPVlpXU0hsdlRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFZGRGRtUXlkbFFLTURZMlkwRXlWM1ZtVEhKUmJXeGpha28xYVdKdVVGVlhjaTl2T0ZWVFJuSkRaQzlsTTFKMk0wMTVZMGhQYVRadlZHczNPSGhZVVdSemR6UkRUVWR2UlFvMVJWUndaMnRtZG14RVMwMDRTRmhOUjFWaFdDdHRXRVJhV1dRMGJuZElOWGNyU0hCdlJGaHRaa3RhU0ZCa1QxTXZhbTlyYjJ4dFVFVkxORVZXZHowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "F7pVCIGdhzahT7/EfTbhhJRqh3hRsunEtsQ6y0SjsQQ="}, "signature": "MEYCIQDjaon8dcl3FcjV8rhmIgtC+5F/uZCVO/R2TfsnrugTxQIhAPoiMGYs9+FoNtXMoPAZJ7cm7sa/frhvrtAOIYG2IdU/"}}
diff --git a/python313.changes b/python313.changes
index a7bcaf0..d106598 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,209 @@
+-------------------------------------------------------------------
+Thu Aug 7 10:08:11 UTC 2025 - Matej Cepl
+
+- Update to 3.13.6:
+ - Security
+ - gh-135661: Fix parsing start and end tags in
+ html.parser.HTMLParser according to the HTML5 standard.
+ - Whitespaces no longer accepted between and the tag
+ name. E.g. script> does not end the script section.
+ - Vertical tabulation (\v) and non-ASCII whitespaces no
+ longer recognized as whitespaces. The only whitespaces
+ are \t\n\r\f and space.
+ - Null character (U+0000) no longer ends the tag name.
+ - Attributes and slashes after the tag name in end tags
+ are now ignored, instead of terminating after the first
+ > in quoted attribute value. E.g. "/>.
+ - Multiple slashes and whitespaces between the last
+ attribute and closing > are now ignored in both start
+ and end tags. E.g. .
+ - Multiple = between attribute name and value are no
+ longer collapsed. E.g. produces attribute
+ “foo” with value “=bar”.
+ - gh-102555: Fix comment parsing in html.parser.HTMLParser
+ according to the HTML5 standard. --!> now ends the comment.
+ -- > no longer ends the comment. Support abnormally ended
+ empty comments <--> and <--->.
+ - gh-135462: Fix quadratic complexity in processing specially
+ crafted input in html.parser.HTMLParser. End-of-file errors
+ are now handled according to the HTML5 specs – comments and
+ declarations are automatically closed, tags are ignored.
+ - gh-118350: Fix support of escapable raw text mode (elements
+ “textarea” and “title”) in html.parser.HTMLParser.
+ - Core and Builtins
+ - gh-58124: Fix name of the Python encoding in Unicode errors
+ of the code page codec: use “cp65000” and “cp65001” instead
+ of “CP_UTF7” and “CP_UTF8” which are not valid Python code
+ names. Patch by Victor Stinner.
+ - gh-137314: Fixed a regression where raw f-strings
+ incorrectly interpreted escape sequences in format
+ specifications. Raw f-strings now properly preserve literal
+ backslashes in format specs, matching the behavior from
+ Python 3.11. For example, rf"{obj:\xFF}" now correctly
+ produces '\\xFF' instead of 'ÿ'. Patch by Pablo Galindo.
+ - gh-136541: Fix some issues with the perf trampolines
+ on x86-64 and aarch64. The trampolines were not being
+ generated correctly for some cases, which could lead to
+ the perf integration not working correctly. Patch by Pablo
+ Galindo.
+ - gh-109700: Fix memory error handling in
+ PyDict_SetDefault().
+ - gh-78465: Fix error message for cls.__new__(cls, ...) where
+ cls is not instantiable builtin or extension type (with
+ tp_new set to NULL).
+ - gh-135871: Non-blocking mutex lock attempts now return
+ immediately when the lock is busy instead of briefly
+ spinning in the free threading build.
+ - gh-135607: Fix potential weakref races in an object’s
+ destructor on the free threaded build.
+ - gh-135496: Fix typo in the f-string conversion type error
+ (“exclamanation” -> “exclamation”).
+ - gh-130077: Properly raise custom syntax errors when
+ incorrect syntax containing names that are prefixes of soft
+ keywords is encountered. Patch by Pablo Galindo.
+ - gh-135148: Fixed a bug where f-string debug expressions
+ (using =) would incorrectly strip out parts of strings
+ containing escaped quotes and # characters. Patch by Pablo
+ Galindo.
+ - gh-133136: Limit excess memory usage in the free threading
+ build when a large dictionary or list is resized and
+ accessed by multiple threads.
+ - gh-132617: Fix dict.update() modification check that could
+ incorrectly raise a “dict mutated during update” error when
+ a different dictionary was modified that happens to share
+ the same underlying keys object.
+ - gh-91153: Fix a crash when a bytearray is concurrently
+ mutated during item assignment.
+ - gh-127971: Fix off-by-one read beyond the end of a string
+ in string search.
+ - gh-125723: Fix crash with gi_frame.f_locals when generator
+ frames outlive their generator. Patch by Mikhail Efimov.
+ - Library
+ - gh-132710: If possible, ensure that uuid.getnode()
+ returns the same result even across different processes.
+ Previously, the result was constant only within the same
+ process. Patch by Bénédikt Tran.
+ - gh-137273: Fix debug assertion failure in
+ locale.setlocale() on Windows.
+ - gh-137257: Bump the version of pip bundled in ensurepip to
+ version 25.2
+ - gh-81325: tarfile.TarFile now accepts a path-like when
+ working on a tar archive. (Contributed by Alexander Enrique
+ Urieles Nieto in gh-81325.)
+ - gh-130522: Fix unraisable TypeError raised during
+ interpreter shutdown in the threading module.
+ - gh-130577: tarfile now validates archives to ensure member
+ offsets are non-negative. (Contributed by Alexander Enrique
+ Urieles Nieto in gh-130577; CVE-2025-8194, bsc#1247249).
+ - gh-136549: Fix signature of threading.excepthook().
+ - gh-136523: Fix wave.Wave_write emitting an unraisable when
+ open raises.
+ - gh-52876: Add missing keepends (default True)
+ parameter to codecs.StreamReaderWriter.readline() and
+ codecs.StreamReaderWriter.readlines().
+ - gh-85702: If zoneinfo._common.load_tzdata is given a
+ package without a resource a zoneinfo.ZoneInfoNotFoundError
+ is raised rather than a PermissionError. Patch by Victor
+ Stinner.
+ - gh-134759: Fix UnboundLocalError in
+ email.message.Message.get_payload() when the payload to
+ decode is a bytes object. Patch by Kliment Lamonov.
+ - gh-136028: Fix parsing month names containing “İ” (U+0130,
+ LATIN CAPITAL LETTER I WITH DOT ABOVE) in time.strptime().
+ This affects locales az_AZ, ber_DZ, ber_MA and crh_UA.
+ - gh-135995: In the palmos encoding, make byte 0x9b decode to
+ › (U+203A - SINGLE RIGHT-POINTING ANGLE QUOTATION MARK).
+ - gh-53203: Fix time.strptime() for %c and %x formats on
+ locales byn_ER, wal_ET and lzh_TW, and for %X format on
+ locales ar_SA, bg_BG and lzh_TW.
+ - gh-91555: An earlier change, which was introduced in
+ 3.13.4, has been reverted. It disabled logging for a logger
+ during handling of log messages for that logger. Since the
+ reversion, the behaviour should be as it was before 3.13.4.
+ - gh-135878: Fixes a crash of types.SimpleNamespace on free
+ threading builds, when several threads were calling its
+ __repr__() method at the same time.
+ - gh-135836: Fix IndexError in
+ asyncio.loop.create_connection() that could occur when
+ non-OSError exception is raised during connection and
+ socket’s close() raises OSError.
+ - gh-135836: Fix IndexError in
+ asyncio.loop.create_connection() that could occur when the
+ Happy Eyeballs algorithm resulted in an empty exceptions
+ list during connection attempts.
+ - gh-135855: Raise TypeError instead of SystemError when
+ _interpreters.set___main___attrs() is passed a non-dict
+ object. Patch by Brian Schubert.
+ - gh-135815: netrc: skip security checks if os.getuid() is
+ missing. Patch by Bénédikt Tran.
+ - gh-135640: Address bug where it was possible to call
+ xml.etree.ElementTree.ElementTree.write() on an ElementTree
+ object with an invalid root element. This behavior blanked
+ the file passed to write if it already existed.
+ - gh-135444: Fix asyncio.DatagramTransport.sendto() to
+ account for datagram header size when data cannot be sent.
+ - gh-135497: Fix os.getlogin() failing for longer usernames
+ on BSD-based platforms.
+ - gh-135487: Fix reprlib.Repr.repr_int() when given integers
+ with more than sys.get_int_max_str_digits() digits. Patch
+ by Bénédikt Tran.
+ - gh-135335: multiprocessing: Flush stdout and stderr after
+ preloading modules in the forkserver.
+ - gh-135244: uuid: when the MAC address cannot be
+ determined, the 48-bit node ID is now generated with a
+ cryptographically-secure pseudo-random number generator
+ (CSPRNG) as per RFC 9562, §6.10.3. This affects uuid1().
+ - gh-135069: Fix the “Invalid error handling” exception in
+ encodings.idna.IncrementalDecoder to correctly replace the
+ ‘errors’ parameter.
+ - gh-134698: Fix a crash when calling methods of
+ ssl.SSLContext or ssl.SSLSocket across multiple threads.
+ - gh-132124: On POSIX-compliant systems,
+ multiprocessing.util.get_temp_dir() now ignores TMPDIR
+ (and similar environment variables) if the path length of
+ AF_UNIX socket files exceeds the platform-specific maximum
+ length when using the forkserver start method. Patch by
+ Bénédikt Tran.
+ - gh-133439: Fix dot commands with trailing spaces are
+ mistaken for multi-line SQL statements in the sqlite3
+ command-line interface.
+ - gh-132969: Prevent the ProcessPoolExecutor executor thread,
+ which remains running when shutdown(wait=False), from
+ attempting to adjust the pool’s worker processes after
+ the object state has already been reset during shutdown.
+ A combination of conditions, including a worker process
+ having terminated abormally, resulted in an exception and
+ a potential hang when the still-running executor thread
+ attempted to replace dead workers within the pool.
+ - gh-130664: Support the '_' digit separator in formatting
+ of the integral part of Decimal’s. Patch by Sergey B
+ Kirpichev.
+ - gh-85702: If zoneinfo._common.load_tzdata is given a
+ package without a resource a ZoneInfoNotFoundError is
+ raised rather than a IsADirectoryError.
+ - gh-130664: Handle corner-case for Fraction’s formatting:
+ treat zero-padding (preceding the width field by a zero
+ ('0') character) as an equivalent to a fill character of
+ '0' with an alignment type of '=', just as in case of
+ float’s.
+ - Tools/Demos
+ - gh-135968: Stubs for strip are now provided as part of an
+ iOS install.
+ - Tests
+ - gh-135966: The iOS testbed now handles the app_packages
+ folder as a site directory.
+ - gh-135494: Fix regrtest to support excluding tests from
+ --pgo tests. Patch by Victor Stinner.
+ - gh-135489: Show verbose output for failing tests during PGO
+ profiling step with –enable-optimizations.
+ - Documentation
+ - gh-135171: Document that the iterator for the leftmost for
+ clause in the generator expression is created immediately.
+ - Build
+ - gh-135497: Fix the detection of MAXLOGNAME in the
+ configure.ac script.
+- Remove CVE-2025-8194-tarfile-no-neg-offsets.patch
+
-------------------------------------------------------------------
Fri Aug 1 20:09:24 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index dce9b8e..8d27fc7 100644
--- a/python313.spec
+++ b/python313.spec
@@ -1,7 +1,7 @@
#
# spec file for package python313
#
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -167,7 +167,7 @@
# _md5.cpython-38m-x86_64-linux-gnu.so
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
Name: %{python_pkg_name}%{psuffix}
-Version: 3.13.5
+Version: 3.13.6
%define tarversion %{version}
%define tarname Python-%{tarversion}
Release: 0
@@ -234,9 +234,6 @@ Patch43: bsc1243155-sphinx-non-determinism.patch
# PATCH-FIX-UPSTREAM CVE-2025-6069-quad-complex-HTMLParser.patch bsc#1244705 mcepl@suse.com
# avoid quadratic complexity when processing malformed inputs with HTMLParser
Patch44: CVE-2025-6069-quad-complex-HTMLParser.patch
-# PATCH-FIX-UPSTREAM CVE-2025-8194-tarfile-no-neg-offsets.patch bsc#1247249 mcepl@suse.com
-# tarfile now validates archives to ensure member offsets are non-negative
-Patch45: CVE-2025-8194-tarfile-no-neg-offsets.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From 588cd5ec7f3ea2a58a63da072a378edd95f59bcf9c44a2bd1dedc1754175b168 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Thu, 7 Aug 2025 10:56:04 +0000
Subject: [PATCH 24/32] declarations are automatically closed, tags are ignored
(CVE-2025-6069, bsc#1244705). - Remove upstreamed patches: -
CVE-2025-8194-tarfile-no-neg-offsets.patch -
CVE-2025-6069-quad-complex-HTMLParser.patch
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=116
---
CVE-2025-6069-quad-complex-HTMLParser.patch | 247 --------------------
bsc1243155-sphinx-non-determinism.patch | 6 +-
doc-py38-to-py36.patch | 126 +++++-----
python313.changes | 7 +-
python313.spec | 3 -
5 files changed, 71 insertions(+), 318 deletions(-)
delete mode 100644 CVE-2025-6069-quad-complex-HTMLParser.patch
diff --git a/CVE-2025-6069-quad-complex-HTMLParser.patch b/CVE-2025-6069-quad-complex-HTMLParser.patch
deleted file mode 100644
index 3336e74..0000000
--- a/CVE-2025-6069-quad-complex-HTMLParser.patch
+++ /dev/null
@@ -1,247 +0,0 @@
-From 9043edabc7e2f0dd655146e0a4571e2a0b2906af Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Fri, 13 Jun 2025 19:57:48 +0300
-Subject: [PATCH] gh-135462: Fix quadratic complexity in processing special
- input in HTMLParser (GH-135464)
-
-End-of-file errors are now handled according to the HTML5 specs --
-comments and declarations are automatically closed, tags are ignored.
-(cherry picked from commit 6eb6c5dbfb528bd07d77b60fd71fd05d81d45c41)
-
-Co-authored-by: Serhiy Storchaka
----
- Lib/html/parser.py | 41 +++-
- Lib/test/test_htmlparser.py | 97 +++++++---
- Misc/NEWS.d/next/Security/2025-06-13-15-55-22.gh-issue-135462.KBeJpc.rst | 4
- 3 files changed, 111 insertions(+), 31 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2025-06-13-15-55-22.gh-issue-135462.KBeJpc.rst
-
-Index: Python-3.13.5/Lib/html/parser.py
-===================================================================
---- Python-3.13.5.orig/Lib/html/parser.py 2025-06-11 17:36:57.000000000 +0200
-+++ Python-3.13.5/Lib/html/parser.py 2025-07-02 16:49:52.020175099 +0200
-@@ -27,6 +27,7 @@
- attr_charref = re.compile(r'&(#[0-9]+|#[xX][0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*)[;=]?')
-
- starttagopen = re.compile('<[a-zA-Z]')
-+endtagopen = re.compile('[a-zA-Z]')
- piclose = re.compile('>')
- commentclose = re.compile(r'--\s*>')
- # Note:
-@@ -195,7 +196,7 @@
- k = self.parse_pi(i)
- elif startswith("', i + 1)
-- if k < 0:
-- k = rawdata.find('<', i + 1)
-- if k < 0:
-- k = i + 1
-+ if starttagopen.match(rawdata, i): # < + letter
-+ pass
-+ elif startswith("", i):
-+ if i + 2 == n:
-+ self.handle_data("")
-+ elif endtagopen.match(rawdata, i): # + letter
-+ pass
-+ else:
-+ # bogus comment
-+ self.handle_comment(rawdata[i+2:])
-+ elif startswith("', [('comment', '-!>')]),
-+ (''
- ''
- ''
-@@ -604,6 +640,7 @@
- '' # required '[' after CDATA
- )
- expected = [
-+ ('comment', 'ELEMENT br EMPTY'),
- ('comment', ' not really a comment '),
- ('comment', ' not a comment either --'),
- ('comment', ' -- close enough --'),
-@@ -684,6 +721,26 @@
- ('endtag', 'a'), ('data', ' bar & baz')]
- )
-
-+ @support.requires_resource('cpu')
-+ def test_eof_no_quadratic_complexity(self):
-+ # Each of these examples used to take about an hour.
-+ # Now they take a fraction of a second.
-+ def check(source):
-+ parser = html.parser.HTMLParser()
-+ parser.feed(source)
-+ parser.close()
-+ n = 120_000
-+ check("= 4.0
root_doc = 'contents'
@@ -146,7 +146,7 @@ Index: Python-3.13.5/Doc/conf.py
# Allow translation of index directives
gettext_additional_targets = [
'index',
-@@ -362,7 +367,7 @@
+@@ -297,7 +302,7 @@
# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html)
is_deployment_preview = os.getenv("READTHEDOCS_VERSION_TYPE") == "external"
repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL", "")
@@ -155,7 +155,7 @@ Index: Python-3.13.5/Doc/conf.py
html_context = {
"is_deployment_preview": is_deployment_preview,
"repository_url": repository_url or None,
-@@ -607,6 +612,16 @@
+@@ -542,6 +547,16 @@
}
extlinks_detect_hardcoded_links = True
@@ -172,22 +172,22 @@ Index: Python-3.13.5/Doc/conf.py
# Options for c_annotations extension
# -----------------------------------
-Index: Python-3.13.5/Doc/library/doctest.rst
+Index: Python-3.13.6/Doc/library/doctest.rst
===================================================================
---- Python-3.13.5.orig/Doc/library/doctest.rst 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/library/doctest.rst 2025-06-12 21:38:04.909944989 +0200
-@@ -308,7 +308,6 @@
- searched. Objects imported into the module are not searched.
+--- Python-3.13.6.orig/Doc/library/doctest.rst 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/library/doctest.rst 2025-08-07 12:16:58.255583157 +0200
+@@ -310,7 +310,6 @@
+ .. currentmodule:: None
.. attribute:: module.__test__
- :no-typesetting:
- In addition, there are cases when you want tests to be part of a module but not part
- of the help text, which requires that the tests not be included in the docstring.
-Index: Python-3.13.5/Doc/library/email.compat32-message.rst
+ .. currentmodule:: doctest
+
+Index: Python-3.13.6/Doc/library/email.compat32-message.rst
===================================================================
---- Python-3.13.5.orig/Doc/library/email.compat32-message.rst 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/library/email.compat32-message.rst 2025-06-12 21:38:04.910320877 +0200
+--- Python-3.13.6.orig/Doc/library/email.compat32-message.rst 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/library/email.compat32-message.rst 2025-08-07 12:16:58.256095517 +0200
@@ -7,7 +7,6 @@
:synopsis: The base class representing email messages in a fashion
backward compatible with Python 3.2
@@ -196,11 +196,11 @@ Index: Python-3.13.5/Doc/library/email.compat32-message.rst
The :class:`Message` class is very similar to the
-Index: Python-3.13.5/Doc/library/xml.etree.elementtree.rst
+Index: Python-3.13.6/Doc/library/xml.etree.elementtree.rst
===================================================================
---- Python-3.13.5.orig/Doc/library/xml.etree.elementtree.rst 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/library/xml.etree.elementtree.rst 2025-06-12 21:38:04.910594893 +0200
-@@ -874,7 +874,6 @@
+--- Python-3.13.6.orig/Doc/library/xml.etree.elementtree.rst 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/library/xml.etree.elementtree.rst 2025-08-07 12:16:58.256380542 +0200
+@@ -873,7 +873,6 @@
.. module:: xml.etree.ElementTree
:noindex:
@@ -208,10 +208,10 @@ Index: Python-3.13.5/Doc/library/xml.etree.elementtree.rst
.. class:: Element(tag, attrib={}, **extra)
-Index: Python-3.13.5/Doc/tools/check-warnings.py
+Index: Python-3.13.6/Doc/tools/check-warnings.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/check-warnings.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/check-warnings.py 2025-06-12 21:38:04.910896050 +0200
+--- Python-3.13.6.orig/Doc/tools/check-warnings.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/check-warnings.py 2025-08-07 12:16:58.256796101 +0200
@@ -228,7 +228,8 @@
print(filename)
for warning in warnings:
@@ -231,10 +231,10 @@ Index: Python-3.13.5/Doc/tools/check-warnings.py
for warning in warnings
if "Doc/" in warning
}
-Index: Python-3.13.5/Doc/tools/extensions/audit_events.py
+Index: Python-3.13.6/Doc/tools/extensions/audit_events.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/audit_events.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/audit_events.py 2025-06-12 21:38:04.911151491 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/audit_events.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/audit_events.py 2025-08-07 12:16:58.257103336 +0200
@@ -1,9 +1,6 @@
"""Support for documenting audit events."""
@@ -370,10 +370,10 @@ Index: Python-3.13.5/Doc/tools/extensions/audit_events.py
) -> nodes.row:
row = nodes.row()
name_node = nodes.paragraph("", nodes.Text(name))
-Index: Python-3.13.5/Doc/tools/extensions/availability.py
+Index: Python-3.13.6/Doc/tools/extensions/availability.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/availability.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/availability.py 2025-06-12 21:38:04.911376735 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/availability.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/availability.py 2025-08-07 12:16:58.257352322 +0200
@@ -1,8 +1,6 @@
"""Support for documenting platform availability"""
@@ -427,10 +427,10 @@ Index: Python-3.13.5/Doc/tools/extensions/availability.py
app.add_directive("availability", Availability)
return {
-Index: Python-3.13.5/Doc/tools/extensions/c_annotations.py
+Index: Python-3.13.6/Doc/tools/extensions/c_annotations.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/c_annotations.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/c_annotations.py 2025-06-12 21:38:04.911575881 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/c_annotations.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/c_annotations.py 2025-08-07 12:16:58.257571556 +0200
@@ -9,22 +9,26 @@
* Set ``stable_abi_file`` to the path to stable ABI list.
"""
@@ -568,10 +568,10 @@ Index: Python-3.13.5/Doc/tools/extensions/c_annotations.py
return {
"version": "1.0",
"parallel_read_safe": True,
-Index: Python-3.13.5/Doc/tools/extensions/changes.py
+Index: Python-3.13.6/Doc/tools/extensions/changes.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/changes.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/changes.py 2025-06-12 21:38:04.911758715 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/changes.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/changes.py 2025-08-07 12:16:58.257773818 +0200
@@ -1,7 +1,5 @@
"""Support for documenting version of changes, additions, deprecations."""
@@ -607,10 +607,10 @@ Index: Python-3.13.5/Doc/tools/extensions/changes.py
# Override Sphinx's directives with support for 'next'
app.add_directive("versionadded", PyVersionChange, override=True)
app.add_directive("versionchanged", PyVersionChange, override=True)
-Index: Python-3.13.5/Doc/tools/extensions/glossary_search.py
+Index: Python-3.13.6/Doc/tools/extensions/glossary_search.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/glossary_search.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/glossary_search.py 2025-06-12 21:38:04.911907976 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/glossary_search.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/glossary_search.py 2025-08-07 12:16:58.257959947 +0200
@@ -1,21 +1,27 @@
"""Feature search results for glossary items prominently."""
@@ -654,10 +654,10 @@ Index: Python-3.13.5/Doc/tools/extensions/glossary_search.py
app.connect('doctree-resolved', process_glossary_nodes)
app.connect('build-finished', write_glossary_json)
-Index: Python-3.13.5/Doc/tools/extensions/implementation_detail.py
+Index: Python-3.13.6/Doc/tools/extensions/implementation_detail.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/implementation_detail.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/implementation_detail.py 2025-06-12 21:38:04.912061736 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/implementation_detail.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/implementation_detail.py 2025-08-07 12:16:58.258140488 +0200
@@ -1,17 +1,10 @@
"""Support for marking up implementation details."""
@@ -708,10 +708,10 @@ Index: Python-3.13.5/Doc/tools/extensions/implementation_detail.py
app.add_directive("impl-detail", ImplementationDetail)
return {
-Index: Python-3.13.5/Doc/tools/extensions/issue_role.py
+Index: Python-3.13.6/Doc/tools/extensions/issue_role.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/issue_role.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/issue_role.py 2025-06-12 21:38:04.912236134 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/issue_role.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/issue_role.py 2025-08-07 12:16:58.258306293 +0200
@@ -1,22 +1,18 @@
"""Support for referencing issues in the tracker."""
@@ -757,10 +757,10 @@ Index: Python-3.13.5/Doc/tools/extensions/issue_role.py
app.add_role("issue", BPOIssue())
app.add_role("gh", GitHubIssue())
-Index: Python-3.13.5/Doc/tools/extensions/misc_news.py
+Index: Python-3.13.6/Doc/tools/extensions/misc_news.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/misc_news.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/misc_news.py 2025-06-12 21:38:04.912390144 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/misc_news.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/misc_news.py 2025-08-07 12:16:58.258481107 +0200
@@ -1,7 +1,5 @@
"""Support for including Misc/NEWS."""
@@ -813,10 +813,10 @@ Index: Python-3.13.5/Doc/tools/extensions/misc_news.py
app.add_directive("miscnews", MiscNews)
return {
-Index: Python-3.13.5/Doc/tools/extensions/patchlevel.py
+Index: Python-3.13.6/Doc/tools/extensions/patchlevel.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/patchlevel.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/patchlevel.py 2025-06-12 21:38:04.912563631 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/patchlevel.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/patchlevel.py 2025-08-07 12:16:58.258716335 +0200
@@ -3,7 +3,7 @@
import re
import sys
@@ -854,10 +854,10 @@ Index: Python-3.13.5/Doc/tools/extensions/patchlevel.py
version = f"{info.major}.{info.minor}"
release = f"{info.major}.{info.minor}.{info.micro}"
if info.releaselevel != "final":
-Index: Python-3.13.5/Doc/tools/extensions/pydoc_topics.py
+Index: Python-3.13.6/Doc/tools/extensions/pydoc_topics.py
===================================================================
---- Python-3.13.5.orig/Doc/tools/extensions/pydoc_topics.py 2025-06-12 21:37:37.257659788 +0200
-+++ Python-3.13.5/Doc/tools/extensions/pydoc_topics.py 2025-06-12 21:38:04.912726688 +0200
+--- Python-3.13.6.orig/Doc/tools/extensions/pydoc_topics.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Doc/tools/extensions/pydoc_topics.py 2025-08-07 12:16:58.258911962 +0200
@@ -1,21 +1,23 @@
"""Support for building "topic help" for pydoc."""
diff --git a/python313.changes b/python313.changes
index d106598..6e417f6 100644
--- a/python313.changes
+++ b/python313.changes
@@ -27,7 +27,8 @@ Thu Aug 7 10:08:11 UTC 2025 - Matej Cepl
- gh-135462: Fix quadratic complexity in processing specially
crafted input in html.parser.HTMLParser. End-of-file errors
are now handled according to the HTML5 specs – comments and
- declarations are automatically closed, tags are ignored.
+ declarations are automatically closed, tags are ignored
+ (CVE-2025-6069, bsc#1244705).
- gh-118350: Fix support of escapable raw text mode (elements
“textarea” and “title”) in html.parser.HTMLParser.
- Core and Builtins
@@ -202,7 +203,9 @@ Thu Aug 7 10:08:11 UTC 2025 - Matej Cepl
- Build
- gh-135497: Fix the detection of MAXLOGNAME in the
configure.ac script.
-- Remove CVE-2025-8194-tarfile-no-neg-offsets.patch
+- Remove upstreamed patches:
+ - CVE-2025-8194-tarfile-no-neg-offsets.patch
+ - CVE-2025-6069-quad-complex-HTMLParser.patch
-------------------------------------------------------------------
Fri Aug 1 20:09:24 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index 8d27fc7..ef9e2af 100644
--- a/python313.spec
+++ b/python313.spec
@@ -231,9 +231,6 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM bsc1243155-sphinx-non-determinism.patch bsc#1243155 mcepl@suse.com
# Doc: Generate ids for audit_events using docname
Patch43: bsc1243155-sphinx-non-determinism.patch
-# PATCH-FIX-UPSTREAM CVE-2025-6069-quad-complex-HTMLParser.patch bsc#1244705 mcepl@suse.com
-# avoid quadratic complexity when processing malformed inputs with HTMLParser
-Patch44: CVE-2025-6069-quad-complex-HTMLParser.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From af83d0ea022b6e41bf03fb4e5ed4045278dc071f9f9f8aee39dbd59792429397 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Tue, 12 Aug 2025 09:37:56 +0000
Subject: [PATCH 25/32] - Add gh137583-only-lock-SSL-context.patch fixing the
regression in 3.13.6 by breaking non-blocking TLS connections
(gh#python/cpython#137583).
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=117
---
gh137583-only-lock-SSL-context.patch | 187 +++++++++++++++++++++++++++
python313.changes | 7 +
python313.spec | 3 +
3 files changed, 197 insertions(+)
create mode 100644 gh137583-only-lock-SSL-context.patch
diff --git a/gh137583-only-lock-SSL-context.patch b/gh137583-only-lock-SSL-context.patch
new file mode 100644
index 0000000..3a5ff62
--- /dev/null
+++ b/gh137583-only-lock-SSL-context.patch
@@ -0,0 +1,187 @@
+---
+ Lib/test/test_ssl.py | 36 ++++++++++
+ Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst | 4 +
+ Modules/_ssl.c | 33 ++++-----
+ Modules/_ssl/debughelpers.c | 1
+ 4 files changed, 57 insertions(+), 17 deletions(-)
+
+Index: Python-3.13.6/Lib/test/test_ssl.py
+===================================================================
+--- Python-3.13.6.orig/Lib/test/test_ssl.py 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Lib/test/test_ssl.py 2025-08-12 11:34:50.729724565 +0200
+@@ -4584,6 +4584,42 @@
+ with client_context.wrap_socket(socket.socket()) as s:
+ s.connect((HOST, server.port))
+
++ def test_thread_recv_while_main_thread_sends(self):
++ # GH-137583: Locking was added to calls to send() and recv() on SSL
++ # socket objects. This seemed fine at the surface level because those
++ # calls weren't re-entrant, but recv() calls would implicitly mimick
++ # holding a lock by blocking until it received data. This means that
++ # if a thread started to infinitely block until data was received, calls
++ # to send() would deadlock, because it would wait forever on the lock
++ # that the recv() call held.
++ data = b"1" * 1024
++ event = threading.Event()
++ def background(sock):
++ event.set()
++ received = sock.recv(len(data))
++ self.assertEqual(received, data)
++
++ client_context, server_context, hostname = testing_context()
++ server = ThreadedEchoServer(context=server_context)
++ with server:
++ with client_context.wrap_socket(socket.socket(),
++ server_hostname=hostname) as sock:
++ sock.connect((HOST, server.port))
++ sock.settimeout(1)
++ sock.setblocking(1)
++ # Ensure that the server is ready to accept requests
++ sock.sendall(b"123")
++ self.assertEqual(sock.recv(3), b"123")
++ with threading_helper.catch_threading_exception() as cm:
++ thread = threading.Thread(target=background,
++ args=(sock,), daemon=True)
++ thread.start()
++ event.wait()
++ sock.sendall(data)
++ thread.join()
++ if cm.exc_value is not None:
++ raise cm.exc_value
++
+
+ @unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3")
+ class TestPostHandshakeAuth(unittest.TestCase):
+Index: Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst 2025-08-12 11:34:50.730240349 +0200
+@@ -0,0 +1,4 @@
++Fix a deadlock introduced in 3.13.6 when a call to
++:meth:`ssl.SSLSocket.recv ` was blocked in one thread,
++and then another method on the object (such as :meth:`ssl.SSLSocket.send `)
++was subsequently called in another thread.
+Index: Python-3.13.6/Modules/_ssl.c
+===================================================================
+--- Python-3.13.6.orig/Modules/_ssl.c 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Modules/_ssl.c 2025-08-12 11:34:50.730789308 +0200
+@@ -332,9 +332,6 @@
+ * and shutdown methods check for chained exceptions.
+ */
+ PyObject *exc;
+- /* Lock to synchronize calls when the thread state is detached.
+- See also gh-134698. */
+- PyMutex tstate_mutex;
+ } PySSLSocket;
+
+ typedef struct {
+@@ -846,7 +843,6 @@
+ self->server_hostname = NULL;
+ self->err = err;
+ self->exc = NULL;
+- self->tstate_mutex = (PyMutex){0};
+
+ /* Make sure the SSL error state is initialized */
+ ERR_clear_error();
+@@ -919,12 +915,12 @@
+ BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
+ }
+
+- PySSL_BEGIN_ALLOW_THREADS(self)
++ Py_BEGIN_ALLOW_THREADS;
+ if (socket_type == PY_SSL_CLIENT)
+ SSL_set_connect_state(self->ssl);
+ else
+ SSL_set_accept_state(self->ssl);
+- PySSL_END_ALLOW_THREADS(self)
++ Py_END_ALLOW_THREADS;
+
+ self->socket_type = socket_type;
+ if (sock != NULL) {
+@@ -993,10 +989,11 @@
+ /* Actually negotiate SSL connection */
+ /* XXX If SSL_do_handshake() returns 0, it's also a failure. */
+ do {
+- PySSL_BEGIN_ALLOW_THREADS(self)
++ Py_BEGIN_ALLOW_THREADS
+ ret = SSL_do_handshake(self->ssl);
+ err = _PySSL_errno(ret < 1, self->ssl, ret);
+- PySSL_END_ALLOW_THREADS(self)
++ Py_END_ALLOW_THREADS;
++ _PySSL_FIX_ERRNO;
+ self->err = err;
+
+ if (PyErr_CheckSignals())
+@@ -2462,10 +2459,11 @@
+ }
+
+ do {
+- PySSL_BEGIN_ALLOW_THREADS(self)
++ Py_BEGIN_ALLOW_THREADS;
+ retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count);
+ err = _PySSL_errno(retval == 0, self->ssl, retval);
+- PySSL_END_ALLOW_THREADS(self)
++ Py_END_ALLOW_THREADS;
++ _PySSL_FIX_ERRNO;
+ self->err = err;
+
+ if (PyErr_CheckSignals())
+@@ -2523,10 +2521,11 @@
+ int count = 0;
+ _PySSLError err;
+
+- PySSL_BEGIN_ALLOW_THREADS(self)
++ Py_BEGIN_ALLOW_THREADS;
+ count = SSL_pending(self->ssl);
+ err = _PySSL_errno(count < 0, self->ssl, count);
+- PySSL_END_ALLOW_THREADS(self)
++ Py_END_ALLOW_THREADS;
++ _PySSL_FIX_ERRNO;
+ self->err = err;
+
+ if (count < 0)
+@@ -2617,10 +2616,11 @@
+ deadline = _PyDeadline_Init(timeout);
+
+ do {
+- PySSL_BEGIN_ALLOW_THREADS(self)
++ Py_BEGIN_ALLOW_THREADS;
+ retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count);
+ err = _PySSL_errno(retval == 0, self->ssl, retval);
+- PySSL_END_ALLOW_THREADS(self)
++ Py_END_ALLOW_THREADS;
++ _PySSL_FIX_ERRNO;
+ self->err = err;
+
+ if (PyErr_CheckSignals())
+@@ -2719,7 +2719,7 @@
+ }
+
+ while (1) {
+- PySSL_BEGIN_ALLOW_THREADS(self)
++ Py_BEGIN_ALLOW_THREADS;
+ /* Disable read-ahead so that unwrap can work correctly.
+ * Otherwise OpenSSL might read in too much data,
+ * eating clear text data that happens to be
+@@ -2732,7 +2732,8 @@
+ SSL_set_read_ahead(self->ssl, 0);
+ ret = SSL_shutdown(self->ssl);
+ err = _PySSL_errno(ret < 0, self->ssl, ret);
+- PySSL_END_ALLOW_THREADS(self)
++ Py_END_ALLOW_THREADS;
++ _PySSL_FIX_ERRNO;
+ self->err = err;
+
+ /* If err == 1, a secure shutdown with SSL_shutdown() is complete */
+Index: Python-3.13.6/Modules/_ssl/debughelpers.c
+===================================================================
+--- Python-3.13.6.orig/Modules/_ssl/debughelpers.c 2025-08-06 15:05:20.000000000 +0200
++++ Python-3.13.6/Modules/_ssl/debughelpers.c 2025-08-12 11:34:50.731270311 +0200
+@@ -135,7 +135,6 @@
+ * critical debug helper.
+ */
+
+- assert(PyMutex_IsLocked(&ssl_obj->tstate_mutex));
+ Py_BEGIN_ALLOW_THREADS
+ PyThread_acquire_lock(lock, 1);
+ res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line);
diff --git a/python313.changes b/python313.changes
index 6e417f6..9107409 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Tue Aug 12 09:16:40 UTC 2025 - Matej Cepl
+
+- Add gh137583-only-lock-SSL-context.patch fixing the
+ regression in 3.13.6 by breaking non-blocking TLS connections
+ (gh#python/cpython#137583).
+
-------------------------------------------------------------------
Thu Aug 7 10:08:11 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index ef9e2af..2207d5d 100644
--- a/python313.spec
+++ b/python313.spec
@@ -231,6 +231,9 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM bsc1243155-sphinx-non-determinism.patch bsc#1243155 mcepl@suse.com
# Doc: Generate ids for audit_events using docname
Patch43: bsc1243155-sphinx-non-determinism.patch
+# PATCH-FIX-UPSTREAM gh137583-only-lock-SSL-context.patch gh#python/cpython#137583 mcepl@suse.com
+# Only lock the SSL context, not the SSL socket
+Patch44: gh137583-only-lock-SSL-context.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From 6ca12749fe4ff39b73337ab69cdc9a9eb2e47c43de211b9fa964238601af8125 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Tue, 12 Aug 2025 22:07:14 +0000
Subject: [PATCH 26/32] Accepting request 1299154 from
home:mcepl:branches:devel:languages:python:Factory
REfresh the patch
OBS-URL: https://build.opensuse.org/request/show/1299154
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=118
---
gh137583-only-lock-SSL-context.patch | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/gh137583-only-lock-SSL-context.patch b/gh137583-only-lock-SSL-context.patch
index 3a5ff62..1d92227 100644
--- a/gh137583-only-lock-SSL-context.patch
+++ b/gh137583-only-lock-SSL-context.patch
@@ -8,7 +8,7 @@
Index: Python-3.13.6/Lib/test/test_ssl.py
===================================================================
--- Python-3.13.6.orig/Lib/test/test_ssl.py 2025-08-06 15:05:20.000000000 +0200
-+++ Python-3.13.6/Lib/test/test_ssl.py 2025-08-12 11:34:50.729724565 +0200
++++ Python-3.13.6/Lib/test/test_ssl.py 2025-08-12 21:19:23.884259654 +0200
@@ -4584,6 +4584,42 @@
with client_context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port))
@@ -55,7 +55,7 @@ Index: Python-3.13.6/Lib/test/test_ssl.py
Index: Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst 2025-08-12 11:34:50.730240349 +0200
++++ Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst 2025-08-12 21:19:23.885093243 +0200
@@ -0,0 +1,4 @@
+Fix a deadlock introduced in 3.13.6 when a call to
+:meth:`ssl.SSLSocket.recv ` was blocked in one thread,
@@ -64,7 +64,7 @@ Index: Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-13758
Index: Python-3.13.6/Modules/_ssl.c
===================================================================
--- Python-3.13.6.orig/Modules/_ssl.c 2025-08-06 15:05:20.000000000 +0200
-+++ Python-3.13.6/Modules/_ssl.c 2025-08-12 11:34:50.730789308 +0200
++++ Python-3.13.6/Modules/_ssl.c 2025-08-12 21:19:23.886222384 +0200
@@ -332,9 +332,6 @@
* and shutdown methods check for chained exceptions.
*/
@@ -176,7 +176,7 @@ Index: Python-3.13.6/Modules/_ssl.c
Index: Python-3.13.6/Modules/_ssl/debughelpers.c
===================================================================
--- Python-3.13.6.orig/Modules/_ssl/debughelpers.c 2025-08-06 15:05:20.000000000 +0200
-+++ Python-3.13.6/Modules/_ssl/debughelpers.c 2025-08-12 11:34:50.731270311 +0200
++++ Python-3.13.6/Modules/_ssl/debughelpers.c 2025-08-12 21:19:23.886886469 +0200
@@ -135,7 +135,6 @@
* critical debug helper.
*/
From f819c56b57e9fb05172dbace605b2308666e1dd4032414f5d176f66439b604dc Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Fri, 15 Aug 2025 12:33:36 +0000
Subject: [PATCH 27/32] - Update to 3.13.7: - gh-137583: Fix a deadlock
introduced in 3.13.6 when a call to ssl.SSLSocket.recv was blocked in one
thread, and then another method on the object (such as
ssl.SSLSocket.send) was subsequently called in another thread. -
gh-137044: Return large limit values as positive integers instead of
negative integers in resource.getrlimit(). Accept large values and reject
negative values (except RLIM_INFINITY) for limits in
resource.setrlimit(). - gh-136914: Fix retrieval of doctest.DocTest.lineno
for objects decorated with functools.cache() or
functools.cached_property. - gh-131788: Make ResourceTracker.send from
multiprocessing re-entrant safe - gh-136155: We are now checking for
fatal errors in EPUB builds in CI. - gh-137400: Fix a crash in the free
threading build when disabling profiling or tracing across all threads
with PyEval_SetProfileAllThreads() or PyEval_SetTraceAllThreads() or
their Python equivalents threading.settrace_all_threads() and
threading.setprofile_all_threads(). - Remove upstreamed patch: -
gh137583-only-lock-SSL-context.patch
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=119
---
Python-3.13.6.tar.xz | 3 -
Python-3.13.6.tar.xz.sigstore | 1 -
Python-3.13.7.tar.xz | 3 +
Python-3.13.7.tar.xz.sigstore | 1 +
gh137583-only-lock-SSL-context.patch | 187 ---------------------------
python313.changes | 27 ++++
python313.spec | 5 +-
7 files changed, 32 insertions(+), 195 deletions(-)
delete mode 100644 Python-3.13.6.tar.xz
delete mode 100644 Python-3.13.6.tar.xz.sigstore
create mode 100644 Python-3.13.7.tar.xz
create mode 100644 Python-3.13.7.tar.xz.sigstore
delete mode 100644 gh137583-only-lock-SSL-context.patch
diff --git a/Python-3.13.6.tar.xz b/Python-3.13.6.tar.xz
deleted file mode 100644
index 45693a9..0000000
--- a/Python-3.13.6.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:17ba5508819d8736a14fbfc47d36e184946a877851b2e9c4b6c43acb44a3b104
-size 22761268
diff --git a/Python-3.13.6.tar.xz.sigstore b/Python-3.13.6.tar.xz.sigstore
deleted file mode 100644
index 849237d..0000000
--- a/Python-3.13.6.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUIT3VXYZsgJBBLFYgnUd3yPWDR14wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwODA2MTUxOTAzWhcNMjUwODA2MTUyOTAzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENQnI68efruhc/qXKi3t/8sqIuDaRnuIwRFUnkF4A2waeN+IzagQ0N+naFAZdKn36t/W21EFOB9NpdHOc4IsvBKOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUwuKqH8hgzo3y/mXe+uV5YElD+wowHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGYf/bkHAAABAMARzBFAiBHMrjIDQAwDBXoGbltVdYPHSUejHkEdNhg8tfNuKS9VgIhAJk8J4X1XqlMXJfd+WltTk33D4ktHK4bqmstq/9VVHyoMAoGCCqGSM49BAMDA2gAMGUCMQCvd2vT066cA2WufLrQmlcjJ5ibnPUWr/o8USFrCd/e3Rv3MycHOi6oTk78xXQdsw4CMGoE5ETpgkfvlDKM8HXMGUaX+mXDZYd4nwH5w+HpoDXmfKZHPdOS/jokolmPEK4EVw=="}, "tlogEntries": [{"logIndex": "357334837", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1754493543", "inclusionPromise": {"signedEntryTimestamp": "MEQCIFB4cDBZVdygUBVVVwa50eFqQfnXia5VLvYT5La7DiPcAiBfeHQv6VwoCV8eWWkubfw7XiFTyZbFUztjsaEajCqStg=="}, "inclusionProof": {"logIndex": "235430575", "rootHash": "Glr+4g4bat4RwhMw/RhFX50HnBM1W7QEKz9sIHUzoo8=", "treeSize": "235430587", "hashes": ["EZsghZu+T1pEYnc5dQ4ku383SGmdF4Vi5z8QLvrUBiE=", "QdL10lLuyibm9U7VPxXiKCS5j3etGVR/zsL9Wb4YEic=", "hOdtwXckZXPPVGDipnQurns8YlGf7FvsPA0Bg0HjfoM=", "oMbtJ33vNBXJ3GRmCIyxtZ0DXj+U2hFPTn7LlduEhfo=", "FpgVGNakFzY7wY7H6BmgDJWiAJdJmnVEV+LVKLNGMA8=", "eYnyLnUnBAXk9NYcyFkkVWeeyY+IzzRJuFX5oNu7hjs=", "5/w4GgbnOf1ey9f5PsAJ/L+fUruO/pL4AkhrYlf1z6g=", "KOdSczh0sMksRbJ5MtuAQTd+ol7RSEMHTbScms6+yiY=", "pGvHucRuMO5oMlmhAUPoYfC7aUD0lGZQYzdyBWRotpM=", "Rdwnt8l+kitCx3q9MjvY521Vs1UGB65Yr5SL3DBIBZw=", "VlTxRYMi0uf0Jsl/dln/6MRW+6h4IwIRRM1h1l8YMnY=", "4UEb5oiYfLnEfmBDb+rZMlzYP20NXNd6288+yuM/qus=", "Q8AUdGrLOK/+q7Zpb5T3hpo2AMEg3qW2VHw5OtFthRI=", "wLANT0NMxIRh/p5rRcam4MppSIbUXIfT1Ht9FQA2XnI="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n235430587\nGlr+4g4bat4RwhMw/RhFX50HnBM1W7QEKz9sIHUzoo8=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBXv2s18aClhm2gewXKAZaMl3AGewwjjak9sXp+A5beSAIgU3pnjQgePf6ndF2Oru+Ma7JS81eAJlWxP/uB2RjP61o=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIxN2JhNTUwODgxOWQ4NzM2YTE0ZmJmYzQ3ZDM2ZTE4NDk0NmE4Nzc4NTFiMmU5YzRiNmM0M2FjYjQ0YTNiMTA0In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUURqYW9uOGRjbDNGY2pWOHJobUlndEMrNUYvdVpDVk8vUjJUZnNucnVnVHhRSWhBUG9pTUdZczkrRm9OdFhNb1BBWko3Y203c2EvZnJodnJ0QU9JWUcySWRVLyIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVlNWUXpWbGhaV25OblNrSkNURVpaWjI1VlpETjVVRmRFVWpFMGQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUVRKTlZGVjRUMVJCZWxkb1kwNU5hbFYzVDBSQk1rMVVWWGxQVkVGNlYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZPVVc1Sk5qaGxabkoxYUdNdmNWaExhVE4wTHpoemNVbDFSR0ZTYm5WSmQxSkdWVzRLYTBZMFFUSjNZV1ZPSzBsNllXZFJNRTRyYm1GR1FWcGtTMjR6Tm5RdlZ6SXhSVVpQUWpsT2NHUklUMk0wU1hOMlFrdFBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlYzZFV0eENrZzRhR2Q2YnpONUwyMVlaU3QxVmpWWlJXeEVLM2R2ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV1dZdlltdElRVUZCUWtGTlFRcFNla0pHUVdsQ1NFMXlha2xFVVVGM1JFSlliMGRpYkhSV1pGbFFTRk5WWldwSWEwVmtUbWhuT0hSbVRuVkxVemxXWjBsb1FVcHJPRW8wV0RGWWNXeE5DbGhLWm1RclYyeDBWR3N6TTBRMGEzUklTelJpY1cxemRIRXZPVlpXU0hsdlRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFZGRGRtUXlkbFFLTURZMlkwRXlWM1ZtVEhKUmJXeGpha28xYVdKdVVGVlhjaTl2T0ZWVFJuSkRaQzlsTTFKMk0wMTVZMGhQYVRadlZHczNPSGhZVVdSemR6UkRUVWR2UlFvMVJWUndaMnRtZG14RVMwMDRTRmhOUjFWaFdDdHRXRVJhV1dRMGJuZElOWGNyU0hCdlJGaHRaa3RhU0ZCa1QxTXZhbTlyYjJ4dFVFVkxORVZXZHowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "F7pVCIGdhzahT7/EfTbhhJRqh3hRsunEtsQ6y0SjsQQ="}, "signature": "MEYCIQDjaon8dcl3FcjV8rhmIgtC+5F/uZCVO/R2TfsnrugTxQIhAPoiMGYs9+FoNtXMoPAZJ7cm7sa/frhvrtAOIYG2IdU/"}}
diff --git a/Python-3.13.7.tar.xz b/Python-3.13.7.tar.xz
new file mode 100644
index 0000000..ecc0ff3
--- /dev/null
+++ b/Python-3.13.7.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5462f9099dfd30e238def83c71d91897d8caa5ff6ebc7a50f14d4802cdaaa79a
+size 22769492
diff --git a/Python-3.13.7.tar.xz.sigstore b/Python-3.13.7.tar.xz.sigstore
new file mode 100644
index 0000000..0796b6d
--- /dev/null
+++ b/Python-3.13.7.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyTCCAlCgAwIBAgIUZMI+1qoqVltZwoOEGQ4+re/SlS4wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwODE0MTM0OTQyWhcNMjUwODE0MTM1OTQyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkKFnh1U6aDYKiIU0p7mtDbbxTezpcJrivGvrwtuUviVav74GRKEp/vcRZnlnVn6olDcrk33qi78husSHeD1VN6OCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUaes5BWscCJHaWxt5BY13fiF+sb8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGYqNf2TAAABAMARzBFAiB3VC3ZdiYFvHtFHxRfU4vdiUZjC+VM/cY0nUHpRZ+aqQIhALglsfszSnn7LZNgw3no+XTnlO+mzMAdCLArnFKuyQo0MAoGCCqGSM49BAMDA2cAMGQCME73khzLHp2xLGwh1g0U5yt9CZu0YfQ52BJ0gL3J2adJsuCvmr76YbDnGWOM2IJLYwIwbWuLaywCs9V1hHqx4IewPWU6kGTDL2p3t7RMb7OK9etOkF4xHxV9IaGZZSFwDmSC"}, "tlogEntries": [{"logIndex": "394375946", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1755179382", "inclusionPromise": {"signedEntryTimestamp": "MEYCIQDofYinceCg3x7ldRHdwLc7aoB6pX2+kukjFdQXFflKdwIhAK7YnONsVnbwsSZpLex8Q7tSMHHglIEQaqavuKAD5taI"}, "inclusionProof": {"logIndex": "272471684", "rootHash": "D6O1d0rPsmFUhblg+N/WsWhcTQVKMGbTlauX5huq8Q0=", "treeSize": "272471685", "hashes": ["12rv4cU8JBEnhl8jcQleuU0gXnRpH2B6oGsUtKoIBHQ=", "PXscKvmfKyXbaxsj99FlqImW6Bg1k3WBNWtHTzgtSVk=", "BaDXQZRZZLXILekCZ5e2TyrtJiYKeNUb2BW6hgybhG0=", "IQvrVF5nsAhxYBjFEIIqcy67H9HEwRdM5XEvXGMlcSc=", "I/JNRoCea85lOiusHIKoAblvRmo6NwnDAtfOV/JiSvQ=", "CjR2KouFHnbUwdf0xk9/f1IcsYFdo4/LMKPy9TV0keM=", "uSQzyFvNic+ZM0goS8qbxn95hvb1YCdWvV0/TnqHDEg=", "LM7bDk+koNXHbb9JB2IH+truLnDDC6WfDzp12zjdFkQ=", "4k9InE/ch3n4a/TapEK+nqfXhlMZEcbvL849wNGtBuo=", "6QfFjG3kfyjFx5PdzVrWBdbNza9Mf4ldecvoXhR3Ip8=", "RllwumeGwAfTxo/zlW3B2deC36+2Lu0FY/hP+QL2aT8=", "vS7O4ozHIQZJWBiov+mkpI27GE8zAmVCEkRcP3NDyNE="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n272471685\nD6O1d0rPsmFUhblg+N/WsWhcTQVKMGbTlauX5huq8Q0=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBr7yQXNBvCAOgKzReWm4ERI79K22ifVZFn9VUxx5nSxQIgWIPYVrO1E+vP3VRWPptUMs1arlLguTIMkT1tX5WCRoM=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NDYyZjkwOTlkZmQzMGUyMzhkZWY4M2M3MWQ5MTg5N2Q4Y2FhNWZmNmViYzdhNTBmMTRkNDgwMmNkYWFhNzlhIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUR4RjM5Z0VUZDgvUWMwbHd5Sk5Mbk5NK3RrTmozaEYyWE1DelZDdjZXOEJBSWdkQUxIWTl3MU14bVNKYUNKMlNtL1p5QWRrL1gwSVF4THFENHA3TSt5UzZRPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVWRU5EUVd4RFowRjNTVUpCWjBsVldrMUpLekZ4YjNGV2JIUmFkMjlQUlVkUk5DdHlaUzlUYkZNMGQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUlRCTlZFMHdUMVJSZVZkb1kwNU5hbFYzVDBSRk1FMVVUVEZQVkZGNVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZyUzBadWFERlZObUZFV1V0cFNWVXdjRGR0ZEVSaVluaFVaWHB3WTBweWFYWkhkbklLZDNSMVZYWnBWbUYyTnpSSFVrdEZjQzkyWTFKYWJteHVWbTQyYjJ4RVkzSnJNek54YVRjNGFIVnpVMGhsUkRGV1RqWlBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZoWlhNMUNrSlhjMk5EU2toaFYzaDBOVUpaTVRObWFVWXJjMkk0ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV1hGT1pqSlVRVUZCUWtGTlFRcFNla0pHUVdsQ00xWkRNMXBrYVZsR2RraDBSa2g0VW1aVk5IWmthVlZhYWtNclZrMHZZMWt3YmxWSWNGSmFLMkZ4VVVsb1FVeG5iSE5tYzNwVGJtNDNDa3hhVG1kM00yNXZLMWhVYm14UEsyMTZUVUZrUTB4QmNtNUdTM1Y1VVc4d1RVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVkwRk5SMUZEVFVVM00ydG9la3dLU0hBeWVFeEhkMmd4WnpCVk5YbDBPVU5hZFRCWlpsRTFNa0pLTUdkTU0wb3lZV1JLYzNWRGRtMXlOelpaWWtSdVIxZFBUVEpKU2t4WmQwbDNZbGQxVEFwaGVYZERjemxXTVdoSWNYZzBTV1YzVUZkVk5tdEhWRVJNTW5BemREZFNUV0kzVDBzNVpYUlBhMFkwZUVoNFZqbEpZVWRhV2xOR2QwUnRVME1LTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "VGL5CZ39MOI43vg8cdkYl9jKpf9uvHpQ8U1IAs2qp5o="}, "signature": "MEUCIQDxF39gETd8/Qc0lwyJNLnNM+tkNj3hF2XMCzVCv6W8BAIgdALHY9w1MxmSJaCJ2Sm/ZyAdk/X0IQxLqD4p7M+yS6Q="}}
diff --git a/gh137583-only-lock-SSL-context.patch b/gh137583-only-lock-SSL-context.patch
deleted file mode 100644
index 1d92227..0000000
--- a/gh137583-only-lock-SSL-context.patch
+++ /dev/null
@@ -1,187 +0,0 @@
----
- Lib/test/test_ssl.py | 36 ++++++++++
- Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst | 4 +
- Modules/_ssl.c | 33 ++++-----
- Modules/_ssl/debughelpers.c | 1
- 4 files changed, 57 insertions(+), 17 deletions(-)
-
-Index: Python-3.13.6/Lib/test/test_ssl.py
-===================================================================
---- Python-3.13.6.orig/Lib/test/test_ssl.py 2025-08-06 15:05:20.000000000 +0200
-+++ Python-3.13.6/Lib/test/test_ssl.py 2025-08-12 21:19:23.884259654 +0200
-@@ -4584,6 +4584,42 @@
- with client_context.wrap_socket(socket.socket()) as s:
- s.connect((HOST, server.port))
-
-+ def test_thread_recv_while_main_thread_sends(self):
-+ # GH-137583: Locking was added to calls to send() and recv() on SSL
-+ # socket objects. This seemed fine at the surface level because those
-+ # calls weren't re-entrant, but recv() calls would implicitly mimick
-+ # holding a lock by blocking until it received data. This means that
-+ # if a thread started to infinitely block until data was received, calls
-+ # to send() would deadlock, because it would wait forever on the lock
-+ # that the recv() call held.
-+ data = b"1" * 1024
-+ event = threading.Event()
-+ def background(sock):
-+ event.set()
-+ received = sock.recv(len(data))
-+ self.assertEqual(received, data)
-+
-+ client_context, server_context, hostname = testing_context()
-+ server = ThreadedEchoServer(context=server_context)
-+ with server:
-+ with client_context.wrap_socket(socket.socket(),
-+ server_hostname=hostname) as sock:
-+ sock.connect((HOST, server.port))
-+ sock.settimeout(1)
-+ sock.setblocking(1)
-+ # Ensure that the server is ready to accept requests
-+ sock.sendall(b"123")
-+ self.assertEqual(sock.recv(3), b"123")
-+ with threading_helper.catch_threading_exception() as cm:
-+ thread = threading.Thread(target=background,
-+ args=(sock,), daemon=True)
-+ thread.start()
-+ event.wait()
-+ sock.sendall(data)
-+ thread.join()
-+ if cm.exc_value is not None:
-+ raise cm.exc_value
-+
-
- @unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3")
- class TestPostHandshakeAuth(unittest.TestCase):
-Index: Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst 2025-08-12 21:19:23.885093243 +0200
-@@ -0,0 +1,4 @@
-+Fix a deadlock introduced in 3.13.6 when a call to
-+:meth:`ssl.SSLSocket.recv ` was blocked in one thread,
-+and then another method on the object (such as :meth:`ssl.SSLSocket.send `)
-+was subsequently called in another thread.
-Index: Python-3.13.6/Modules/_ssl.c
-===================================================================
---- Python-3.13.6.orig/Modules/_ssl.c 2025-08-06 15:05:20.000000000 +0200
-+++ Python-3.13.6/Modules/_ssl.c 2025-08-12 21:19:23.886222384 +0200
-@@ -332,9 +332,6 @@
- * and shutdown methods check for chained exceptions.
- */
- PyObject *exc;
-- /* Lock to synchronize calls when the thread state is detached.
-- See also gh-134698. */
-- PyMutex tstate_mutex;
- } PySSLSocket;
-
- typedef struct {
-@@ -846,7 +843,6 @@
- self->server_hostname = NULL;
- self->err = err;
- self->exc = NULL;
-- self->tstate_mutex = (PyMutex){0};
-
- /* Make sure the SSL error state is initialized */
- ERR_clear_error();
-@@ -919,12 +915,12 @@
- BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
- }
-
-- PySSL_BEGIN_ALLOW_THREADS(self)
-+ Py_BEGIN_ALLOW_THREADS;
- if (socket_type == PY_SSL_CLIENT)
- SSL_set_connect_state(self->ssl);
- else
- SSL_set_accept_state(self->ssl);
-- PySSL_END_ALLOW_THREADS(self)
-+ Py_END_ALLOW_THREADS;
-
- self->socket_type = socket_type;
- if (sock != NULL) {
-@@ -993,10 +989,11 @@
- /* Actually negotiate SSL connection */
- /* XXX If SSL_do_handshake() returns 0, it's also a failure. */
- do {
-- PySSL_BEGIN_ALLOW_THREADS(self)
-+ Py_BEGIN_ALLOW_THREADS
- ret = SSL_do_handshake(self->ssl);
- err = _PySSL_errno(ret < 1, self->ssl, ret);
-- PySSL_END_ALLOW_THREADS(self)
-+ Py_END_ALLOW_THREADS;
-+ _PySSL_FIX_ERRNO;
- self->err = err;
-
- if (PyErr_CheckSignals())
-@@ -2462,10 +2459,11 @@
- }
-
- do {
-- PySSL_BEGIN_ALLOW_THREADS(self)
-+ Py_BEGIN_ALLOW_THREADS;
- retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count);
- err = _PySSL_errno(retval == 0, self->ssl, retval);
-- PySSL_END_ALLOW_THREADS(self)
-+ Py_END_ALLOW_THREADS;
-+ _PySSL_FIX_ERRNO;
- self->err = err;
-
- if (PyErr_CheckSignals())
-@@ -2523,10 +2521,11 @@
- int count = 0;
- _PySSLError err;
-
-- PySSL_BEGIN_ALLOW_THREADS(self)
-+ Py_BEGIN_ALLOW_THREADS;
- count = SSL_pending(self->ssl);
- err = _PySSL_errno(count < 0, self->ssl, count);
-- PySSL_END_ALLOW_THREADS(self)
-+ Py_END_ALLOW_THREADS;
-+ _PySSL_FIX_ERRNO;
- self->err = err;
-
- if (count < 0)
-@@ -2617,10 +2616,11 @@
- deadline = _PyDeadline_Init(timeout);
-
- do {
-- PySSL_BEGIN_ALLOW_THREADS(self)
-+ Py_BEGIN_ALLOW_THREADS;
- retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count);
- err = _PySSL_errno(retval == 0, self->ssl, retval);
-- PySSL_END_ALLOW_THREADS(self)
-+ Py_END_ALLOW_THREADS;
-+ _PySSL_FIX_ERRNO;
- self->err = err;
-
- if (PyErr_CheckSignals())
-@@ -2719,7 +2719,7 @@
- }
-
- while (1) {
-- PySSL_BEGIN_ALLOW_THREADS(self)
-+ Py_BEGIN_ALLOW_THREADS;
- /* Disable read-ahead so that unwrap can work correctly.
- * Otherwise OpenSSL might read in too much data,
- * eating clear text data that happens to be
-@@ -2732,7 +2732,8 @@
- SSL_set_read_ahead(self->ssl, 0);
- ret = SSL_shutdown(self->ssl);
- err = _PySSL_errno(ret < 0, self->ssl, ret);
-- PySSL_END_ALLOW_THREADS(self)
-+ Py_END_ALLOW_THREADS;
-+ _PySSL_FIX_ERRNO;
- self->err = err;
-
- /* If err == 1, a secure shutdown with SSL_shutdown() is complete */
-Index: Python-3.13.6/Modules/_ssl/debughelpers.c
-===================================================================
---- Python-3.13.6.orig/Modules/_ssl/debughelpers.c 2025-08-06 15:05:20.000000000 +0200
-+++ Python-3.13.6/Modules/_ssl/debughelpers.c 2025-08-12 21:19:23.886886469 +0200
-@@ -135,7 +135,6 @@
- * critical debug helper.
- */
-
-- assert(PyMutex_IsLocked(&ssl_obj->tstate_mutex));
- Py_BEGIN_ALLOW_THREADS
- PyThread_acquire_lock(lock, 1);
- res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line);
diff --git a/python313.changes b/python313.changes
index 9107409..38632be 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,30 @@
+-------------------------------------------------------------------
+Fri Aug 15 12:31:08 UTC 2025 - Matej Cepl
+
+- Update to 3.13.7:
+ - gh-137583: Fix a deadlock introduced in 3.13.6 when a call
+ to ssl.SSLSocket.recv was blocked in one thread, and then
+ another method on the object (such as ssl.SSLSocket.send) was
+ subsequently called in another thread.
+ - gh-137044: Return large limit values as positive integers
+ instead of negative integers in resource.getrlimit().
+ Accept large values and reject negative values (except
+ RLIM_INFINITY) for limits in resource.setrlimit().
+ - gh-136914: Fix retrieval of doctest.DocTest.lineno
+ for objects decorated with functools.cache() or
+ functools.cached_property.
+ - gh-131788: Make ResourceTracker.send from multiprocessing
+ re-entrant safe
+ - gh-136155: We are now checking for fatal errors in EPUB
+ builds in CI.
+ - gh-137400: Fix a crash in the free threading build when
+ disabling profiling or tracing across all threads with
+ PyEval_SetProfileAllThreads() or PyEval_SetTraceAllThreads()
+ or their Python equivalents threading.settrace_all_threads()
+ and threading.setprofile_all_threads().
+- Remove upstreamed patch:
+ - gh137583-only-lock-SSL-context.patch
+
-------------------------------------------------------------------
Tue Aug 12 09:16:40 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index 2207d5d..2ae2949 100644
--- a/python313.spec
+++ b/python313.spec
@@ -167,7 +167,7 @@
# _md5.cpython-38m-x86_64-linux-gnu.so
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
Name: %{python_pkg_name}%{psuffix}
-Version: 3.13.6
+Version: 3.13.7
%define tarversion %{version}
%define tarname Python-%{tarversion}
Release: 0
@@ -231,9 +231,6 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM bsc1243155-sphinx-non-determinism.patch bsc#1243155 mcepl@suse.com
# Doc: Generate ids for audit_events using docname
Patch43: bsc1243155-sphinx-non-determinism.patch
-# PATCH-FIX-UPSTREAM gh137583-only-lock-SSL-context.patch gh#python/cpython#137583 mcepl@suse.com
-# Only lock the SSL context, not the SSL socket
-Patch44: gh137583-only-lock-SSL-context.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From 45ae9e0091e6d5ec72ecc18568d191a8df220702929ddfe2bbb177b57a2d3ab3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mark=C3=A9ta=20Machov=C3=A1?=
Date: Fri, 12 Sep 2025 07:39:47 +0000
Subject: [PATCH 28/32] Accepting request 1303343 from
home:dgarcia:branches:devel:languages:python:Factory
- Add gh138131-exclude-pycache-from-digest.patch fixing reproducible
build for python-nogil.
(bsc#1244680, gh#python/cpython#138131)
OBS-URL: https://build.opensuse.org/request/show/1303343
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=121
---
gh138131-exclude-pycache-from-digest.patch | 30 ++++++++++++++++++++++
python313.changes | 7 +++++
python313.spec | 2 ++
3 files changed, 39 insertions(+)
create mode 100644 gh138131-exclude-pycache-from-digest.patch
diff --git a/gh138131-exclude-pycache-from-digest.patch b/gh138131-exclude-pycache-from-digest.patch
new file mode 100644
index 0000000..996d217
--- /dev/null
+++ b/gh138131-exclude-pycache-from-digest.patch
@@ -0,0 +1,30 @@
+From 4bb41b28d5bac09bccd636d8c5fefe1a462f63a7 Mon Sep 17 00:00:00 2001
+From: Alm
+Date: Mon, 25 Aug 2025 08:56:38 +0300
+Subject: [PATCH 1/4] Exclude .pyc files from the computed digest in the jit
+ stencils
+
+---
+ Tools/jit/_targets.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: Python-3.13.7/Tools/jit/_targets.py
+===================================================================
+--- Python-3.13.7.orig/Tools/jit/_targets.py
++++ Python-3.13.7/Tools/jit/_targets.py
+@@ -53,6 +53,9 @@ class _Target(typing.Generic[_S, _R]):
+ hasher.update(PYTHON_EXECUTOR_CASES_C_H.read_bytes())
+ hasher.update((out / "pyconfig.h").read_bytes())
+ for dirpath, _, filenames in sorted(os.walk(TOOLS_JIT)):
++ # Exclude cache files from digest computation to ensure reproducible builds.
++ if dirpath.endswith("__pycache__"):
++ continue
+ for filename in filenames:
+ hasher.update(pathlib.Path(dirpath, filename).read_bytes())
+ return hasher.hexdigest()
+Index: Python-3.13.7/Misc/NEWS.d/next/Build/2025-08-27-09-52-45.gh-issue-138061.fMVS9w.rst
+===================================================================
+--- /dev/null
++++ Python-3.13.7/Misc/NEWS.d/next/Build/2025-08-27-09-52-45.gh-issue-138061.fMVS9w.rst
+@@ -0,0 +1 @@
++Ensure reproducible builds by making JIT stencil header generation deterministic.
diff --git a/python313.changes b/python313.changes
index 38632be..5cb8169 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Tue Sep 9 10:11:58 UTC 2025 - Daniel Garcia
+
+- Add gh138131-exclude-pycache-from-digest.patch fixing reproducible
+ build for python-nogil.
+ (bsc#1244680, gh#python/cpython#138131)
+
-------------------------------------------------------------------
Fri Aug 15 12:31:08 UTC 2025 - Matej Cepl
diff --git a/python313.spec b/python313.spec
index 2ae2949..e1e38b1 100644
--- a/python313.spec
+++ b/python313.spec
@@ -231,6 +231,8 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM bsc1243155-sphinx-non-determinism.patch bsc#1243155 mcepl@suse.com
# Doc: Generate ids for audit_events using docname
Patch43: bsc1243155-sphinx-non-determinism.patch
+# PATCH-FIX-UPSTREAM gh138131-exclude-pycache-from-digest.patch bsc#1244680 daniel.garcia@suse.com
+Patch44: gh138131-exclude-pycache-from-digest.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From d782ad00cac81613ba6aa30bf5fca4789244f85f4d262250a9a7be73af67d3c2 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Thu, 18 Sep 2025 14:05:23 +0000
Subject: [PATCH 29/32] - Require AppStream to validate appdata file instead of
deprecated appstream-glib. - Update idle3.appdata.xml to pass the more
pedantic appstreamcli.
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=123
---
idle3.appdata.xml | 44 ++++++++++++++++++++++++++++++--------------
python313.changes | 7 +++++++
python313.spec | 4 ++--
3 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/idle3.appdata.xml b/idle3.appdata.xml
index 554b7c4..b494f1e 100644
--- a/idle3.appdata.xml
+++ b/idle3.appdata.xml
@@ -1,16 +1,16 @@
-
-
- idle3.desktop
+
+ org.python.IDLE3
+ idle3.desktop
+
IDLE3
- CC0
- Python-2.0
Python 3 Integrated Development and Learning Environment
+
IDLE is Python’s Integrated Development and Learning Environment.
- The GUI is uniform between Windows, Unix, and Mac OS X.
+ The GUI is uniform between Windows, Unix, and macOS.
IDLE provides an easy way to start writing, running, and debugging
Python code.
@@ -19,17 +19,33 @@
It provides:
- - a Python shell window (interactive interpreter) with colorizing of code input, output, and error messages,
- - a multi-window text editor with multiple undo, Python colorizing, smart indent, call tips, auto completion, and other features,
- - search within any window, replace within editor windows, and search through multiple files (grep),
- - a debugger with persistent breakpoints, stepping, and viewing of global and local namespaces.
+ - a Python shell window (interactive interpreter) with colorizing of code input, output, and error messages,
+ - a multi-window text editor with multiple undo, Python colorizing, smart indent, call tips, auto completion, and other features,
+ - search within any window, replace within editor windows, and search through multiple files (grep),
+ - a debugger with persistent breakpoints, stepping, and viewing of global and local namespaces.
+
+
+ Python Software Foundation
+
+
https://docs.python.org/3/library/idle.html
+
- http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-main-window.png
- http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-class-browser.png
- http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-code-viewer.png
+
+ https://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-main-window.png
+
+
+ https://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-class-browser.png
+
+
+ https://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-code-viewer.png
+
+
+ Python-2.0
+ CC0-1.0
zbyszek@in.waw.pl
-
+
+
diff --git a/python313.changes b/python313.changes
index 5cb8169..993f444 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Thu Sep 18 08:15:31 UTC 2025 - Dominique Leuenberger
+
+- Require AppStream to validate appdata file instead of deprecated
+ appstream-glib.
+- Update idle3.appdata.xml to pass the more pedantic appstreamcli.
+
-------------------------------------------------------------------
Tue Sep 9 10:11:58 UTC 2025 - Daniel Garcia
diff --git a/python313.spec b/python313.spec
index e1e38b1..821b4fa 100644
--- a/python313.spec
+++ b/python313.spec
@@ -288,7 +288,7 @@ ExcludeArch: aarch64
%if %{with general}
# required for idle3 (.desktop and .appdata.xml files)
-BuildRequires: appstream-glib
+BuildRequires: AppStream
BuildRequires: gcc-c++
BuildRequires: gdbm-devel
BuildRequires: gettext
@@ -780,7 +780,7 @@ install -m 644 -D -t %{buildroot}%{_datadir}/applications idle%{python_abi}.desk
cp %{SOURCE20} idle%{python_abi}.appdata.xml
sed -i -e 's:idle3.desktop:idle%{python_abi}.desktop:g' idle%{python_abi}.appdata.xml
install -m 644 -D -t %{buildroot}%{_datadir}/metainfo idle%{python_abi}.appdata.xml
-appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/idle%{python_abi}.appdata.xml
+appstreamcli validate --no-net %{buildroot}%{_datadir}/metainfo/idle%{python_version}.appdata.xml
%fdupes %{buildroot}/%{_libdir}/python%{python_abi}
%endif
From 97f2e509544fcfcb17030551a99165db0a68ada678ca3c3fe6bcde896dbf1289 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mark=C3=A9ta=20Machov=C3=A1?=
Date: Mon, 22 Sep 2025 12:45:38 +0000
Subject: [PATCH 30/32] Accepting request 1306454 from home:dimstar:Factory
- Drop AppStream: this results in a different cycle than
appstream-glib. As the appdata.xml is controlled by ourselves, we
can get away with just manually validating it when changing it.
OBS-URL: https://build.opensuse.org/request/show/1306454
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=124
---
python313.changes | 7 +++++++
python313.spec | 3 ---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/python313.changes b/python313.changes
index 993f444..a57b072 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Mon Sep 22 06:41:53 UTC 2025 - Dominique Leuenberger
+
+- Drop AppStream: this results in a different cycle than
+ appstream-glib. As the appdata.xml is controlled by ourselves, we
+ can get away with just manually validating it when changing it.
+
-------------------------------------------------------------------
Thu Sep 18 08:15:31 UTC 2025 - Dominique Leuenberger
diff --git a/python313.spec b/python313.spec
index 821b4fa..32125b9 100644
--- a/python313.spec
+++ b/python313.spec
@@ -287,8 +287,6 @@ ExcludeArch: aarch64
%endif
%if %{with general}
-# required for idle3 (.desktop and .appdata.xml files)
-BuildRequires: AppStream
BuildRequires: gcc-c++
BuildRequires: gdbm-devel
BuildRequires: gettext
@@ -780,7 +778,6 @@ install -m 644 -D -t %{buildroot}%{_datadir}/applications idle%{python_abi}.desk
cp %{SOURCE20} idle%{python_abi}.appdata.xml
sed -i -e 's:idle3.desktop:idle%{python_abi}.desktop:g' idle%{python_abi}.appdata.xml
install -m 644 -D -t %{buildroot}%{_datadir}/metainfo idle%{python_abi}.appdata.xml
-appstreamcli validate --no-net %{buildroot}%{_datadir}/metainfo/idle%{python_version}.appdata.xml
%fdupes %{buildroot}/%{_libdir}/python%{python_abi}
%endif
From 6ccfd57cb6e25a78122c9ffabf2223e9ca6d10496ebaa5d5156565a1dfd32fdc Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Mon, 29 Sep 2025 16:57:25 +0000
Subject: [PATCH 31/32] Accepting request 1307678 from
home:dgarcia:branches:devel:languages:python:Factory
- Add gh139257-Support-docutils-0.22.patch to fix build with latest
docutils (>=0.22) gh#python/cpython#139257
OBS-URL: https://build.opensuse.org/request/show/1307678
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=126
---
gh139257-Support-docutils-0.22.patch | 36 ++++++++++++++++++++++++++++
python313.changes | 6 +++++
python313.spec | 2 ++
3 files changed, 44 insertions(+)
create mode 100644 gh139257-Support-docutils-0.22.patch
diff --git a/gh139257-Support-docutils-0.22.patch b/gh139257-Support-docutils-0.22.patch
new file mode 100644
index 0000000..1f83363
--- /dev/null
+++ b/gh139257-Support-docutils-0.22.patch
@@ -0,0 +1,36 @@
+From 19b61747df3d62c822285c488753d6fbdf91e3ac Mon Sep 17 00:00:00 2001
+From: Daniel Garcia Moreno
+Date: Tue, 23 Sep 2025 10:20:16 +0200
+Subject: [PATCH 1/2] gh-139257: Support docutils >= 0.22
+
+---
+ Doc/tools/extensions/pyspecific.py | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+Index: Python-3.13.7/Doc/tools/extensions/pyspecific.py
+===================================================================
+--- Python-3.13.7.orig/Doc/tools/extensions/pyspecific.py
++++ Python-3.13.7/Doc/tools/extensions/pyspecific.py
+@@ -25,11 +25,21 @@ from sphinx.util.docutils import SphinxD
+ SOURCE_URI = 'https://github.com/python/cpython/tree/3.13/%s'
+
+ # monkey-patch reST parser to disable alphabetic and roman enumerated lists
++def _disable_alphabetic_and_roman(text):
++ try:
++ # docutils >= 0.22
++ from docutils.parsers.rst.states import InvalidRomanNumeralError
++ raise InvalidRomanNumeralError(text)
++ except ImportError:
++ # docutils < 0.22
++ return None
++
++
+ from docutils.parsers.rst.states import Body
+ Body.enum.converters['loweralpha'] = \
+ Body.enum.converters['upperalpha'] = \
+ Body.enum.converters['lowerroman'] = \
+- Body.enum.converters['upperroman'] = lambda x: None
++ Body.enum.converters['upperroman'] = _disable_alphabetic_and_roman
+
+
+ class PyAwaitableMixin(object):
diff --git a/python313.changes b/python313.changes
index a57b072..32943d0 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Mon Sep 29 06:52:07 UTC 2025 - Daniel Garcia
+
+- Add gh139257-Support-docutils-0.22.patch to fix build with latest
+ docutils (>=0.22) gh#python/cpython#139257
+
-------------------------------------------------------------------
Mon Sep 22 06:41:53 UTC 2025 - Dominique Leuenberger
diff --git a/python313.spec b/python313.spec
index 32125b9..1616677 100644
--- a/python313.spec
+++ b/python313.spec
@@ -233,6 +233,8 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
Patch43: bsc1243155-sphinx-non-determinism.patch
# PATCH-FIX-UPSTREAM gh138131-exclude-pycache-from-digest.patch bsc#1244680 daniel.garcia@suse.com
Patch44: gh138131-exclude-pycache-from-digest.patch
+# PATCH-FIX-OPENSUSE gh139257-Support-docutils-0.22.patch gh#python/cpython#139257 daniel.garcia@suse.com
+Patch45: gh139257-Support-docutils-0.22.patch
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes
From 216aee44d29248c14f2906cd0b5cbc05976b0d1ee0c9463db200947957cd7319 Mon Sep 17 00:00:00 2001
From: Matej Cepl
Date: Thu, 16 Oct 2025 16:27:11 +0000
Subject: [PATCH 32/32] Accepting request 1311480 from
home:dgarcia:branches:devel:languages:python:Factory
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Update to 3.13.9:
- Library
- gh-139783: Fix inspect.getsourcelines() for the case when a
decorator is followed by a comment or an empty line.
- Update to 3.13.8:
- macOS
- gh-124111: Update macOS installer to use Tcl/Tk 8.6.17.
- gh-139573: Updated bundled version of OpenSSL to 3.0.18.
- Windows
- gh-139573: Updated bundled version of OpenSSL to 3.0.18.
- gh-138896: Fix error installing C runtime on non-updated Windows
machines
- Tools/Demos
- gh-139330: SBOM generation tool didn’t cross-check the version
and checksum values against the Modules/expat/refresh.sh script,
leading to the values becoming out-of-date during routine
updates.
- gh-137873: The iOS test runner has been simplified, resolving
some issues that have been observed using the runner in GitHub
Actions and Azure Pipelines test environments.
- Tests
- gh-139208: Fix regrtest --fast-ci --verbose: don’t ignore the
--verbose option anymore. Patch by Victor Stinner.
- Security
- gh-139400: xml.parsers.expat: Make sure that parent Expat
parsers are only garbage-collected once they are no longer
referenced by subparsers created by
ExternalEntityParserCreate(). Patch by Sebastian Pipping.
- gh-139283: sqlite3: correctly handle maximum number of rows to
fetch in Cursor.fetchmany and reject negative values for
OBS-URL: https://build.opensuse.org/request/show/1311480
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=128
---
Python-3.13.7.tar.xz | 3 -
Python-3.13.7.tar.xz.sigstore | 1 -
Python-3.13.9.tar.xz | 3 +
Python-3.13.9.tar.xz.sigstore | 1 +
python313.changes | 171 ++++++++++++++++++++++++++++++++++
python313.spec | 4 +-
6 files changed, 177 insertions(+), 6 deletions(-)
delete mode 100644 Python-3.13.7.tar.xz
delete mode 100644 Python-3.13.7.tar.xz.sigstore
create mode 100644 Python-3.13.9.tar.xz
create mode 100644 Python-3.13.9.tar.xz.sigstore
diff --git a/Python-3.13.7.tar.xz b/Python-3.13.7.tar.xz
deleted file mode 100644
index ecc0ff3..0000000
--- a/Python-3.13.7.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5462f9099dfd30e238def83c71d91897d8caa5ff6ebc7a50f14d4802cdaaa79a
-size 22769492
diff --git a/Python-3.13.7.tar.xz.sigstore b/Python-3.13.7.tar.xz.sigstore
deleted file mode 100644
index 0796b6d..0000000
--- a/Python-3.13.7.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyTCCAlCgAwIBAgIUZMI+1qoqVltZwoOEGQ4+re/SlS4wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwODE0MTM0OTQyWhcNMjUwODE0MTM1OTQyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkKFnh1U6aDYKiIU0p7mtDbbxTezpcJrivGvrwtuUviVav74GRKEp/vcRZnlnVn6olDcrk33qi78husSHeD1VN6OCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUaes5BWscCJHaWxt5BY13fiF+sb8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGYqNf2TAAABAMARzBFAiB3VC3ZdiYFvHtFHxRfU4vdiUZjC+VM/cY0nUHpRZ+aqQIhALglsfszSnn7LZNgw3no+XTnlO+mzMAdCLArnFKuyQo0MAoGCCqGSM49BAMDA2cAMGQCME73khzLHp2xLGwh1g0U5yt9CZu0YfQ52BJ0gL3J2adJsuCvmr76YbDnGWOM2IJLYwIwbWuLaywCs9V1hHqx4IewPWU6kGTDL2p3t7RMb7OK9etOkF4xHxV9IaGZZSFwDmSC"}, "tlogEntries": [{"logIndex": "394375946", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1755179382", "inclusionPromise": {"signedEntryTimestamp": "MEYCIQDofYinceCg3x7ldRHdwLc7aoB6pX2+kukjFdQXFflKdwIhAK7YnONsVnbwsSZpLex8Q7tSMHHglIEQaqavuKAD5taI"}, "inclusionProof": {"logIndex": "272471684", "rootHash": "D6O1d0rPsmFUhblg+N/WsWhcTQVKMGbTlauX5huq8Q0=", "treeSize": "272471685", "hashes": ["12rv4cU8JBEnhl8jcQleuU0gXnRpH2B6oGsUtKoIBHQ=", "PXscKvmfKyXbaxsj99FlqImW6Bg1k3WBNWtHTzgtSVk=", "BaDXQZRZZLXILekCZ5e2TyrtJiYKeNUb2BW6hgybhG0=", "IQvrVF5nsAhxYBjFEIIqcy67H9HEwRdM5XEvXGMlcSc=", "I/JNRoCea85lOiusHIKoAblvRmo6NwnDAtfOV/JiSvQ=", "CjR2KouFHnbUwdf0xk9/f1IcsYFdo4/LMKPy9TV0keM=", "uSQzyFvNic+ZM0goS8qbxn95hvb1YCdWvV0/TnqHDEg=", "LM7bDk+koNXHbb9JB2IH+truLnDDC6WfDzp12zjdFkQ=", "4k9InE/ch3n4a/TapEK+nqfXhlMZEcbvL849wNGtBuo=", "6QfFjG3kfyjFx5PdzVrWBdbNza9Mf4ldecvoXhR3Ip8=", "RllwumeGwAfTxo/zlW3B2deC36+2Lu0FY/hP+QL2aT8=", "vS7O4ozHIQZJWBiov+mkpI27GE8zAmVCEkRcP3NDyNE="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n272471685\nD6O1d0rPsmFUhblg+N/WsWhcTQVKMGbTlauX5huq8Q0=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBr7yQXNBvCAOgKzReWm4ERI79K22ifVZFn9VUxx5nSxQIgWIPYVrO1E+vP3VRWPptUMs1arlLguTIMkT1tX5WCRoM=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NDYyZjkwOTlkZmQzMGUyMzhkZWY4M2M3MWQ5MTg5N2Q4Y2FhNWZmNmViYzdhNTBmMTRkNDgwMmNkYWFhNzlhIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUR4RjM5Z0VUZDgvUWMwbHd5Sk5Mbk5NK3RrTmozaEYyWE1DelZDdjZXOEJBSWdkQUxIWTl3MU14bVNKYUNKMlNtL1p5QWRrL1gwSVF4THFENHA3TSt5UzZRPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVWRU5EUVd4RFowRjNTVUpCWjBsVldrMUpLekZ4YjNGV2JIUmFkMjlQUlVkUk5DdHlaUzlUYkZNMGQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUlRCTlZFMHdUMVJSZVZkb1kwNU5hbFYzVDBSRk1FMVVUVEZQVkZGNVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZyUzBadWFERlZObUZFV1V0cFNWVXdjRGR0ZEVSaVluaFVaWHB3WTBweWFYWkhkbklLZDNSMVZYWnBWbUYyTnpSSFVrdEZjQzkyWTFKYWJteHVWbTQyYjJ4RVkzSnJNek54YVRjNGFIVnpVMGhsUkRGV1RqWlBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZoWlhNMUNrSlhjMk5EU2toaFYzaDBOVUpaTVRObWFVWXJjMkk0ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV1hGT1pqSlVRVUZCUWtGTlFRcFNla0pHUVdsQ00xWkRNMXBrYVZsR2RraDBSa2g0VW1aVk5IWmthVlZhYWtNclZrMHZZMWt3YmxWSWNGSmFLMkZ4VVVsb1FVeG5iSE5tYzNwVGJtNDNDa3hhVG1kM00yNXZLMWhVYm14UEsyMTZUVUZrUTB4QmNtNUdTM1Y1VVc4d1RVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVkwRk5SMUZEVFVVM00ydG9la3dLU0hBeWVFeEhkMmd4WnpCVk5YbDBPVU5hZFRCWlpsRTFNa0pLTUdkTU0wb3lZV1JLYzNWRGRtMXlOelpaWWtSdVIxZFBUVEpKU2t4WmQwbDNZbGQxVEFwaGVYZERjemxXTVdoSWNYZzBTV1YzVUZkVk5tdEhWRVJNTW5BemREZFNUV0kzVDBzNVpYUlBhMFkwZUVoNFZqbEpZVWRhV2xOR2QwUnRVME1LTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "VGL5CZ39MOI43vg8cdkYl9jKpf9uvHpQ8U1IAs2qp5o="}, "signature": "MEUCIQDxF39gETd8/Qc0lwyJNLnNM+tkNj3hF2XMCzVCv6W8BAIgdALHY9w1MxmSJaCJ2Sm/ZyAdk/X0IQxLqD4p7M+yS6Q="}}
diff --git a/Python-3.13.9.tar.xz b/Python-3.13.9.tar.xz
new file mode 100644
index 0000000..760c7af
--- /dev/null
+++ b/Python-3.13.9.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ed5ef34cda36cfa2f3a340f07cac7e7814f91c7f3c411f6d3562323a866c5c66
+size 22681368
diff --git a/Python-3.13.9.tar.xz.sigstore b/Python-3.13.9.tar.xz.sigstore
new file mode 100644
index 0000000..9f18da1
--- /dev/null
+++ b/Python-3.13.9.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUY2me70edxRKEcCCyZ5IxW04GUyowCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUxMDE0MTQzMTMyWhcNMjUxMDE0MTQ0MTMyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELoRO1nGvvt0Re9EEuEURAgbvYfBZGKVeXZJ4TMXRaguoQ234OaePlcAe1i7BwYYC66rIbrcvayVtIGVODpjoKaOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUGNf/veOSM+Ff67rmibv6xt8S+oMwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGZ4yIw9QAABAMARzBFAiBFhajuKoOCWgsAz1l9RlYS7U6cH/3fY1TxkoG7abKa3QIhAKSeSjaz987c/yCcQhU/Qr7Chi7XmXbfZMp2xAh8yBX+MAoGCCqGSM49BAMDA2gAMGUCMERKd5M3HrGRoWEwZuOc4e26LeQz9PSLU6OdlTwejx6QA1XP/0Xir/W/x8lMEOFuzAIxANg4WBGY7CPzXhkLWB4Fc6zEEV0fG/hzsMnlXiv8khUnMn+lCPbvRota+OFCYH2qMA=="}, "tlogEntries": [{"logIndex": "605359044", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1760452293", "inclusionPromise": {"signedEntryTimestamp": "MEQCIAaCd+PcR5ygZyPHR1OsuaW+lNBWINYyIlKeGPEcPwepAiBNdcg2JJu+x5se+ceR53vLqLBjva3kQ4IlP9nlhX9Qog=="}, "inclusionProof": {"logIndex": "483454782", "rootHash": "oZMALhkG2Ovf519HU5mhGbEaroNwGUX6BRT0JwDqOBE=", "treeSize": "483454785", "hashes": ["NrDN7yu6uq+l3SddRxs5n9GNxvPxfC5ztPCuaBEuxBE=", "67FUfgzcBEiMHBjMBhIP7z7NP1Y6OtbC48553/VTk7A=", "VIwMTLnjS3Z1W4xcLQrca60FRxxSnqyUAN8dQtvaRdI=", "i8G+g499zPGEcpT54dYVUUmczZRJucNYWmKOrEO004s=", "+wR1k80yWhpO7od/bitq3mkjQF5vuuWhLFeWqUHVfV8=", "uHZHioqKhUEko9UubGg2/N0lkvsPtoAaqr95f03cHYY=", "EiH2b8iGJWXAiLOBI7xekwQSojCUemRypbzmcQo4vaI=", "2aaLDAVeQGJoklTLWwIPILMvGhrc+9mnB2HsRWCldwY=", "wNzqPqvA41e6acbb4z7HxMdHzg9S6jufxg2MVgB4ykw=", "boLAJ9DO0lKL3HJUTpKJMBhDTVZZCfc/oBPm+gLAx4Q=", "Vxc/L8MXSU0zqWj6P5yi6L02Lc2HxpkHqYzJLcNbzEs=", "PPdBf0yipi+yQC3iEH5JI4MmFnEgb40zV1eCf+8/MOY=", "laQiGsY+h3TioXfWSoLJMMtb2TORNubw90KH+z/fdyw=", "pcc0HeMv4rm7/8RoNMUYk4tbxPt+lc2wMvbSrB3Negw=", "inrOYOb+roitD1EYWHmRPy8aJnjhSAhp5cHXbXVlxU4=", "8nCds1SUzxGg2Xoa+M1tOFTwx+1BGtp8TDMSS4P54xQ=", "V5lOdefY1WOOt4iQp7tZoyj1beBDVi24KsEMcgsqZds=", "2Wv4GiithwNukRKV06clevnQQYCzXmSS/+/OJtXgsXQ=", "1mfy94KpcItqshH9+gwqV6jccupcaMpVsF28New8zDY=", "vS7O4ozHIQZJWBiov+mkpI27GE8zAmVCEkRcP3NDyNE="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n483454785\noZMALhkG2Ovf519HU5mhGbEaroNwGUX6BRT0JwDqOBE=\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiEA2g7XsvpZpF/BYV+Jr6KRvdE2kuWjmN7xVyr7HLWRXlECIC0okqz3vQ2B/Bng/2BAQVIIiLMhnrXedUeoygtWn4Kh\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJlZDVlZjM0Y2RhMzZjZmEyZjNhMzQwZjA3Y2FjN2U3ODE0ZjkxYzdmM2M0MTFmNmQzNTYyMzIzYTg2NmM1YzY2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUNSMlVSSm44Unc3ZnpmbkhjOFpXSmdTVU1tdEl1RFF2dFF2S05VejlmUkpRSWdNRm1UU0dWUXJDeGlheXpwYVUxcmh0d0wyL256elhjNnh0enF0dW5JZUhjPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVldUSnRaVGN3WldSNFVrdEZZME5EZVZvMVNYaFhNRFJIVlhsdmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZlRTFFUlRCTlZGRjZUVlJOZVZkb1kwNU5hbFY0VFVSRk1FMVVVVEJOVkUxNVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZNYjFKUE1XNUhkblowTUZKbE9VVkZkVVZWVWtGblluWlpaa0phUjB0V1pWaGFTalFLVkUxWVVtRm5kVzlSTWpNMFQyRmxVR3hqUVdVeGFUZENkMWxaUXpZMmNrbGljbU4yWVhsV2RFbEhWazlFY0dwdlMyRlBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZIVG1ZdkNuWmxUMU5OSzBabU5qZHliV2xpZGpaNGREaFRLMjlOZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV2pSNVNYYzVVVUZCUWtGTlFRcFNla0pHUVdsQ1JtaGhhblZMYjA5RFYyZHpRWG94YkRsU2JGbFROMVUyWTBndk0yWlpNVlI0YTI5SE4yRmlTMkV6VVVsb1FVdFRaVk5xWVhvNU9EZGpDaTk1UTJOUmFGVXZVWEkzUTJocE4xaHRXR0ptV2sxd01uaEJhRGg1UWxnclRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFVWU1MyUTFUVE1LU0hKSFVtOVhSWGRhZFU5ak5HVXlOa3hsVVhvNVVGTk1WVFpQWkd4VWQyVnFlRFpSUVRGWVVDOHdXR2x5TDFjdmVEaHNUVVZQUm5WNlFVbDRRVTVuTkFwWFFrZFpOME5RZWxob2EweFhRalJHWXpaNlJVVldNR1pITDJoNmMwMXViRmhwZGpocmFGVnVUVzRyYkVOUVluWlNiM1JoSzA5R1ExbElNbkZOUVQwOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "7V7zTNo2z6Lzo0DwfKx+eBT5HH88QR9tNWIyOoZsXGY="}, "signature": "MEUCIQCR2URJn8Rw7fzfnHc8ZWJgSUMmtIuDQvtQvKNUz9fRJQIgMFmTSGVQrCxiayzpaU1rhtwL2/nzzXc6xtzqtunIeHc="}}
diff --git a/python313.changes b/python313.changes
index 32943d0..0793f2d 100644
--- a/python313.changes
+++ b/python313.changes
@@ -1,3 +1,174 @@
+-------------------------------------------------------------------
+Wed Oct 15 09:15:38 UTC 2025 - Daniel Garcia
+
+- Update to 3.13.9:
+ - Library
+ - gh-139783: Fix inspect.getsourcelines() for the case when a
+ decorator is followed by a comment or an empty line.
+- Update to 3.13.8:
+ - macOS
+ - gh-124111: Update macOS installer to use Tcl/Tk 8.6.17.
+ - gh-139573: Updated bundled version of OpenSSL to 3.0.18.
+ - Windows
+ - gh-139573: Updated bundled version of OpenSSL to 3.0.18.
+ - gh-138896: Fix error installing C runtime on non-updated Windows
+ machines
+ - Tools/Demos
+ - gh-139330: SBOM generation tool didn’t cross-check the version
+ and checksum values against the Modules/expat/refresh.sh script,
+ leading to the values becoming out-of-date during routine
+ updates.
+ - gh-137873: The iOS test runner has been simplified, resolving
+ some issues that have been observed using the runner in GitHub
+ Actions and Azure Pipelines test environments.
+ - Tests
+ - gh-139208: Fix regrtest --fast-ci --verbose: don’t ignore the
+ --verbose option anymore. Patch by Victor Stinner.
+ - Security
+ - gh-139400: xml.parsers.expat: Make sure that parent Expat
+ parsers are only garbage-collected once they are no longer
+ referenced by subparsers created by
+ ExternalEntityParserCreate(). Patch by Sebastian Pipping.
+ - gh-139283: sqlite3: correctly handle maximum number of rows to
+ fetch in Cursor.fetchmany and reject negative values for
+ Cursor.arraysize. Patch by Bénédikt Tran.
+ - gh-135661: Fix CDATA section parsing in html.parser.HTMLParser
+ according to the HTML5 standard: ] ]> and ]] > no longer end the
+ CDATA section. Add private method _set_support_cdata() which can
+ be used to specify how to parse <[CDATA[ — as a CDATA section in
+ foreign content (SVG or MathML) or as a bogus comment in the
+ HTML namespace.
+ - Library
+ - gh-139312: Upgrade bundled libexpat to 2.7.3
+ - gh-139289: Do a real lazy-import on rlcompleter in pdb and
+ restore the existing completer after importing rlcompleter.
+ - gh-139210: Fix use-after-free when reporting unknown event in
+ xml.etree.ElementTree.iterparse(). Patch by Ken Jin.
+ - gh-138860: Lazy import rlcompleter in pdb to avoid deadlock in
+ subprocess.
+ - gh-112729: Fix crash when calling _interpreters.create when the
+ process is out of memory.
+ - gh-139076: Fix a bug in the pydoc module that was hiding
+ functions in a Python module if they were implemented in an
+ extension module and the module did not have __all__.
+ - gh-138998: Update bundled libexpat to 2.7.2
+ - gh-130567: Fix possible crash in locale.strxfrm() due to a
+ platform bug on macOS.
+ - gh-138779: Support device numbers larger than 2**63-1 for the
+ st_rdev field of the os.stat_result structure.
+ - gh-128636: Fix crash in PyREPL when os.environ is overwritten
+ with an invalid value for mac
+ - gh-88375: Fix normalization of the robots.txt rules and URLs in
+ the urllib.robotparser module. No longer ignore trailing ?.
+ Distinguish raw special characters ?, = and & from the
+ percent-encoded ones.
+ - gh-138515: email is added to Emscripten build.
+ - gh-111788: Fix parsing errors in the urllib.robotparser module.
+ Don’t fail trying to parse weird paths. Don’t fail trying to
+ decode non-UTF-8 robots.txt files.
+ - gh-138432: zoneinfo.reset_tzpath() will now convert any
+ os.PathLike objects it receives into strings before adding them
+ to TZPATH. It will raise TypeError if anything other than a
+ string is found after this conversion. If given an os.PathLike
+ object that represents a relative path, it will now raise
+ ValueError instead of TypeError, and present a more informative
+ error message.
+ - gh-138008: Fix segmentation faults in the ctypes module due to
+ invalid argtypes. Patch by Dung Nguyen.
+ - gh-60462: Fix locale.strxfrm() on Solaris (and possibly other
+ platforms).
+ - gh-138204: Forbid expansion of shared anonymous memory maps on
+ Linux, which caused a bus error.
+ - gh-138010: Fix an issue where defining a class with a
+ @warnings.deprecated-decorated base class may not invoke the
+ correct __init_subclass__() method in cases involving multiple
+ inheritance. Patch by Brian Schubert.
+ - gh-138133: Prevent infinite traceback loop when sending CTRL^C
+ to Python through strace.
+ - gh-134869: Fix an issue where pressing Ctrl+C during tab
+ completion in the REPL would leave the autocompletion menu in a
+ corrupted state.
+ - gh-137317: inspect.signature() now correctly handles classes
+ that use a descriptor on a wrapped __init__() or __new__()
+ method. Contributed by Yongyu Yan.
+ - gh-137754: Fix import of the zoneinfo module if the C
+ implementation of the datetime module is not available.
+ - gh-137490: Handle ECANCELED in the same way as EINTR in
+ signal.sigwaitinfo() on NetBSD.
+ - gh-137477: Fix inspect.getblock(), inspect.getsourcelines() and
+ inspect.getsource() for generator expressions.
+ - gh-137017: Fix threading.Thread.is_alive to remain True until
+ the underlying OS thread is fully cleaned up. This avoids false
+ negatives in edge cases involving thread monitoring or premature
+ threading.Thread.is_alive calls.
+ - gh-136134: SMTP.auth_cram_md5() now raises an SMTPException
+ instead of a ValueError if Python has been built without MD5
+ support. In particular, SMTP clients will not attempt to use
+ this method even if the remote server is assumed to support it.
+ Patch by Bénédikt Tran.
+ - gh-136134: IMAP4.login_cram_md5 now raises an IMAP4.error if
+ CRAM-MD5 authentication is not supported. Patch by Bénédikt
+ Tran.
+ - gh-135386: Fix opening a dbm.sqlite3 database for reading from
+ read-only file or directory.
+ - gh-126631: Fix multiprocessing forkserver bug which prevented
+ __main__ from being preloaded.
+ - gh-123085: In a bare call to importlib.resources.files(), ensure
+ the caller’s frame is properly detected when importlib.resources
+ is itself available as a compiled module only (no source).
+ - gh-118981: Fix potential hang in
+ multiprocessing.popen_spawn_posix that can happen when the child
+ proc dies early by closing the child fds right away.
+ - gh-78319: UTF8 support for the IMAP APPEND command has been made
+ RFC compliant.
+ - bpo-38735: Fix failure when importing a module from the root
+ directory on unix-like platforms with sys.pycache_prefix set.
+ - bpo-41839: Allow negative priority values from
+ os.sched_get_priority_min() and os.sched_get_priority_max()
+ functions.
+ - Core and Builtins
+ - gh-134466: Don’t run PyREPL in a degraded environment where
+ setting termios attributes is not allowed.
+ - gh-71810: Raise OverflowError for (-1).to_bytes() for signed
+ conversions when bytes count is zero. Patch by Sergey B
+ Kirpichev.
+ - gh-105487: Remove non-existent __copy__(), __deepcopy__(), and
+ __bases__ from the __dir__() entries of types.GenericAlias.
+ - gh-134163: Fix a hang when the process is out of memory inside
+ an exception handler.
+ - gh-138479: Fix a crash when a generic object’s __typing_subst__
+ returns an object that isn’t a tuple.
+ - gh-137576: Fix for incorrect source code being shown in
+ tracebacks from the Basic REPL when PYTHONSTARTUP is given.
+ Patch by Adam Hartz.
+ - gh-132744: Certain calls now check for runaway recursion and
+ respect the system recursion limit.
+ - C API
+ - gh-87135: Attempting to acquire the GIL after runtime
+ finalization has begun in a different thread now causes the
+ thread to hang rather than terminate, which avoids potential
+ crashes or memory corruption caused by attempting to terminate a
+ thread that is running code not specifically designed to support
+ termination. In most cases this hanging is harmless since the
+ process will soon exit anyway.
+ While not officially marked deprecated until 3.14,
+ PyThread_exit_thread is no longer called internally and remains
+ solely for interface compatibility. Its behavior is inconsistent
+ across platforms, and it can only be used safely in the unlikely
+ case that every function in the entire call stack has been
+ designed to support the platform-dependent termination
+ mechanism. It is recommended that users of this function change
+ their design to not require thread termination. In the unlikely
+ case that thread termination is needed and can be done safely,
+ users may migrate to calling platform-specific APIs such as
+ pthread_exit (POSIX) or _endthreadex (Windows) directly.
+ - Build
+ - gh-135734: Python can correctly be configured and built with
+ ./configure --enable-optimizations --disable-test-modules.
+ Previously, the profile data generation step failed due to PGO
+ tests where immortalization couldn’t be properly suppressed.
+ Patch by Bénédikt Tran.
+
-------------------------------------------------------------------
Mon Sep 29 06:52:07 UTC 2025 - Daniel Garcia
diff --git a/python313.spec b/python313.spec
index 1616677..1335e0e 100644
--- a/python313.spec
+++ b/python313.spec
@@ -167,7 +167,7 @@
# _md5.cpython-38m-x86_64-linux-gnu.so
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
Name: %{python_pkg_name}%{psuffix}
-Version: 3.13.7
+Version: 3.13.9
%define tarversion %{version}
%define tarname Python-%{tarversion}
Release: 0
@@ -555,7 +555,7 @@ rm Lib/site-packages/README.txt
tar xvf %{SOURCE21}
# Don't fail on warnings when building documentation
-# sed -i -e '/^SPHINXERRORHANDLING/s/-W//' Doc/Makefile
+sed -i -e '/^SPHINXERRORHANDLING/s/--fail-on-warning//' Doc/Makefile
%build
export SUSE_VERSION="0%{?suse_version}"