diff --git a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch b/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch deleted file mode 100644 index 15de467..0000000 --- a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Wed, 12 Aug 2026 15:18:39 +0200 -Subject: 00466: Downstream only: Lower XML_COMBINED_VERSION threshold for - reparse deferral - -RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported -via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. -CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter -as a no-op, so SetReparseDeferralEnabled silently does nothing and -GetReparseDeferralEnabled always returns False, even though the expat -library actually supports (and enables) reparse deferral. - -Lower the threshold from 20600 to 20500 so that CPython uses the -backported function. This makes the Python API actually work on RHEL 9 -and fixes test failures (test_reparse_deferral_disabled, -test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). - -The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the -backported function is available. ---- - Lib/test/test_pyexpat.py | 6 +++--- - Lib/test/test_sax.py | 4 ++-- - Lib/test/test_xml_etree.py | 4 ++-- - Modules/pyexpat.c | 6 +++--- - 4 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index ae7cec6540..7f73a8c5e7 100644 ---- a/Lib/test/test_pyexpat.py -+++ b/Lib/test/test_pyexpat.py -@@ -1001,7 +1001,7 @@ def test_error_path_no_crash(self): - class ReparseDeferralTest(unittest.TestCase): - def test_getter_setter_round_trip(self): - parser = expat.ParserCreate() -- enabled = (expat.version_info >= (2, 6, 0)) -+ enabled = (expat.version_info >= (2, 5, 0)) - - self.assertIs(parser.GetReparseDeferralEnabled(), enabled) - parser.SetReparseDeferralEnabled(False) -@@ -1010,7 +1010,7 @@ def test_getter_setter_round_trip(self): - self.assertIs(parser.GetReparseDeferralEnabled(), enabled) - - def test_reparse_deferral_enabled(self): -- if expat.version_info < (2, 6, 0): -+ if expat.version_info < (2, 5, 0): - self.skipTest(f'Expat {expat.version_info} does not ' - 'support reparse deferral') - -@@ -1041,7 +1041,7 @@ def start_element(name, _): - - parser = expat.ParserCreate() - parser.StartElementHandler = start_element -- if expat.version_info >= (2, 6, 0): -+ if expat.version_info >= (2, 5, 0): - parser.SetReparseDeferralEnabled(False) - self.assertFalse(parser.GetReparseDeferralEnabled()) - -diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py -index 9b3014a94a..0e38c9488e 100644 ---- a/Lib/test/test_sax.py -+++ b/Lib/test/test_sax.py -@@ -1215,7 +1215,7 @@ def test_expat_incremental_reset(self): - - self.assertEqual(result.getvalue(), start + b"text") - -- @unittest.skipIf(pyexpat.version_info < (2, 6, 0), -+ @unittest.skipIf(pyexpat.version_info < (2, 5, 0), - f'Expat {pyexpat.version_info} does not ' - 'support reparse deferral') - def test_flush_reparse_deferral_enabled(self): -@@ -1249,7 +1249,7 @@ def test_flush_reparse_deferral_disabled(self): - for chunk in (""): - parser.feed(chunk) - -- if pyexpat.version_info >= (2, 6, 0): -+ if pyexpat.version_info >= (2, 5, 0): - parser._parser.SetReparseDeferralEnabled(False) - self.assertEqual(result.getvalue(), start) # i.e. no elements started - -diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 4a76a5be1e..effb899d7b 100644 ---- a/Lib/test/test_xml_etree.py -+++ b/Lib/test/test_xml_etree.py -@@ -1804,7 +1804,7 @@ def test_unknown_event(self): - with self.assertRaisesRegex(ValueError, "unknown event 'bogus'"): - ET.XMLPullParser(events=(x.decode() for x in (b'start', b'end', b'bogus'))) - -- @unittest.skipIf(pyexpat.version_info < (2, 6, 0), -+ @unittest.skipIf(pyexpat.version_info < (2, 5, 0), - f'Expat {pyexpat.version_info} does not ' - 'support reparse deferral') - def test_flush_reparse_deferral_enabled(self): -@@ -1834,7 +1834,7 @@ def test_flush_reparse_deferral_disabled(self): - for chunk in (""): - parser.feed(chunk) - -- if pyexpat.version_info >= (2, 6, 0): -+ if pyexpat.version_info >= (2, 5, 0): - if not ET is pyET: - self.skipTest(f'XMLParser.(Get|Set)ReparseDeferralEnabled ' - 'methods not available in C') -diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c -index 9e5d84eb5e..b008fe66c1 100644 ---- a/Modules/pyexpat.c -+++ b/Modules/pyexpat.c -@@ -781,7 +781,7 @@ pyexpat_xmlparser_SetReparseDeferralEnabled_impl(xmlparseobject *self, - int enabled) - /*[clinic end generated code: output=5ec539e3b63c8c49 input=021eb9e0bafc32c5]*/ - { --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - XML_SetReparseDeferralEnabled(self->itself, enabled ? XML_TRUE : XML_FALSE); - self->reparse_deferral_enabled = (bool)enabled; - #endif -@@ -1446,7 +1446,7 @@ newxmlparseobject(pyexpat_state *state, const char *encoding, - self->ns_prefixes = 0; - self->handlers = NULL; - self->intern = Py_XNewRef(intern); --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - self->reparse_deferral_enabled = true; - #else - self->reparse_deferral_enabled = false; -@@ -2332,7 +2332,7 @@ pyexpat_exec(PyObject *mod) - #else - capi->SetHashSalt16Bytes = NULL; - #endif --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - capi->SetReparseDeferralEnabled = XML_SetReparseDeferralEnabled; - #else - capi->SetReparseDeferralEnabled = NULL; diff --git a/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch new file mode 100644 index 0000000..349deeb --- /dev/null +++ b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Tue, 24 Jun 2025 11:12:13 +0200 +Subject: 00466: Downstream only: Skip tests not working with older expat + version + +We want to run these tests in Fedora and EPEL 10, but not in EPEL 9, +which has too old version of expat. We set the upper bound version +in the conditionalized skip to a release available in CentOS Stream 10, +which is tested as working. +--- + Lib/test/test_pyexpat.py | 2 ++ + Lib/test/test_sax.py | 2 ++ + Lib/test/test_xml_etree.py | 6 ++++++ + 3 files changed, 10 insertions(+) + +diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py +index ae7cec6540..4770c5cc4f 100644 +--- a/Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -1033,6 +1033,8 @@ def start_element(name, _): + + self.assertEqual(started, ['doc']) + ++ @unittest.skipIf(expat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_reparse_deferral_disabled(self): + started = [] + +diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py +index 9b3014a94a..90401e0d8f 100644 +--- a/Lib/test/test_sax.py ++++ b/Lib/test/test_sax.py +@@ -1240,6 +1240,8 @@ def test_flush_reparse_deferral_enabled(self): + + self.assertEqual(result.getvalue(), start + b"") + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_flush_reparse_deferral_disabled(self): + result = BytesIO() + xmlgen = XMLGenerator(result) +diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py +index 4a76a5be1e..d740e30123 100644 +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -1599,9 +1599,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): + self.assert_event_tags(parser, [('end', 'root')]) + self.assertIsNone(parser.close()) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_simple_xml_chunk_1(self): + self.test_simple_xml(chunk_size=1, flush=True) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_simple_xml_chunk_5(self): + self.test_simple_xml(chunk_size=5, flush=True) + +@@ -1828,6 +1832,8 @@ def test_flush_reparse_deferral_enabled(self): + + self.assert_event_tags(parser, [('end', 'doc')]) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_flush_reparse_deferral_disabled(self): + parser = ET.XMLPullParser(events=('start', 'end')) + diff --git a/plan.fmf b/plan.fmf index 9c9afb8..71d0124 100644 --- a/plan.fmf +++ b/plan.fmf @@ -24,10 +24,11 @@ discover: test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} CYTHON=false ./venv.sh" - name: selftest path: /selftest - test: "VERSION=${pybasever} X='-i test_check_probes' ./parallel.sh" + # test_subparser_inherits_reparse_deferral fails on EPEL9: https://github.com/python/cpython/issues/155485 + test: "VERSION=${pybasever} X='-i test_check_probes -i test_subparser_inherits_reparse_deferral' ./parallel.sh" - name: debugtest path: /selftest - test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes' ./parallel.sh" + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes -i test_subparser_inherits_reparse_deferral' ./parallel.sh" - name: optimizedflags path: /flags test: "python${pybasever} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" diff --git a/python3.13.spec b/python3.13.spec index 4045e62..0879de7 100644 --- a/python3.13.spec +++ b/python3.13.spec @@ -49,7 +49,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -254,7 +254,7 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\ BuildRequires: autoconf BuildRequires: bluez-libs-devel BuildRequires: bzip2-devel -BuildRequires: expat-devel >= 2.5.0-2 +BuildRequires: expat-devel BuildRequires: findutils BuildRequires: gcc BuildRequires: gdbm-devel @@ -370,24 +370,14 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00466 # 713a1368544eddd55088d67f88a23ce31722a4cb -# Downstream only: Lower XML_COMBINED_VERSION threshold for reparse deferral +# 00466 # e10760fb955ee33d2917f8a57bb4e24d71e5341c +# Downstream only: Skip tests not working with older expat version # -# RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported -# via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. -# CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter -# as a no-op, so SetReparseDeferralEnabled silently does nothing and -# GetReparseDeferralEnabled always returns False, even though the expat -# library actually supports (and enables) reparse deferral. -# -# Lower the threshold from 20600 to 20500 so that CPython uses the -# backported function. This makes the Python API actually work on RHEL 9 -# and fixes test failures (test_reparse_deferral_disabled, -# test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). -# -# The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the -# backported function is available. -Patch466: 00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch +# We want to run these tests in Fedora and EPEL 10, but not in EPEL 9, +# which has too old version of expat. We set the upper bound version +# in the conditionalized skip to a release available in CentOS Stream 10, +# which is tested as working. +Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch # 00475 # d44fac01037662db286449a78c8fb819788f764c # CVE-2025-15367 @@ -608,12 +598,10 @@ Requires: tzdata # This breaks many things, including python -m venv. # We avoid this problem by requiring at least the same version of expat that # was used during the build time. -# We also include release, in case pyxpat uses ABI that was backported -# (e.g. XML_SetReparseDeferralEnabled was added in c9s expat 2.5.0-2). # Other subpackages (like -debug) also need this, but they all depend on -libs. # Since expat 2.7.4, the library has versioned symbols and this is no longer needed, # as the generated requirement will be in the form of libexpat.so.1(LIBEXPAT_2.7.2) etc. -%global expat_version %(LANG=C rpm -q --qf '%%{version}-%%{release}' expat.%{_target_cpu} | sed 's/.*not installed/0/') +%global expat_version %(LANG=C rpm -q --qf '%%{version}' expat.%{_target_cpu} | sed 's/.*not installed/0/') %if v"%{expat_version}" < v"2.7.4" Requires: expat%{?_isa} >= %{expat_version} %endif @@ -1371,6 +1359,7 @@ CheckPython() { # test.test_concurrent_futures.test_deadlock tends to time out on s390x and ppc64le in # freethreading{,-debug} build, skipping it to shorten the build time # see: https://github.com/python/cpython/issues/121719 + # test_subparser_inherits_reparse_deferral: https://github.com/python/cpython/issues/155485 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} \ %ifarch riscv64 @@ -1387,6 +1376,9 @@ CheckPython() { -x test_signal \ -i test_deadlock \ %endif + %if 0%{?rhel} == 9 + -i test_subparser_inherits_reparse_deferral \ + %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1818,9 +1810,6 @@ CheckPython freethreading # ====================================================== %changelog -* Wed Aug 12 2026 Miro HronĨok - 3.13.15-2 -- On EPEL 9, also supports reparse deferral in expat - * Mon Aug 10 2026 Karolina Surma - 3.13.15-1 - Update to Python 3.13.15