diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 9383ef3..7289b79 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 15 Feb 2021 12:19:27 +0100 -Subject: [PATCH] 00251: Change user install location +Subject: 00251: Change user install location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -25,15 +25,15 @@ Co-authored-by: Michal Cyprian Co-authored-by: Lumír Balhar --- Lib/site.py | 9 ++++++- - Lib/sysconfig/__init__.py | 49 +++++++++++++++++++++++++++++++++++++- + Lib/sysconfig/__init__.py | 50 +++++++++++++++++++++++++++++++++++++- Lib/test/test_sysconfig.py | 17 +++++++++++-- - 3 files changed, 71 insertions(+), 4 deletions(-) + 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Lib/site.py b/Lib/site.py -index 672fa7b000..0a9c5be53e 100644 +index 041dca113a..ca6320df2f 100644 --- a/Lib/site.py +++ b/Lib/site.py -@@ -377,8 +377,15 @@ def getsitepackages(prefixes=None): +@@ -415,8 +415,15 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): @@ -51,10 +51,10 @@ index 672fa7b000..0a9c5be53e 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py -index 2a7fa45be0..7b75228fb3 100644 +index 43edebce34..40e85568ea 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py -@@ -104,6 +104,11 @@ +@@ -106,6 +106,12 @@ else: _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] @@ -63,10 +63,11 @@ index 2a7fa45be0..7b75228fb3 100644 +# For backwards compatibility, we keep it here (at least on 3.10 and 3.11). +_INSTALL_SCHEMES['rpm_prefix'] = _INSTALL_SCHEMES['posix_prefix'] + ++ + def _get_implementation(): + return 'Python' - # NOTE: site.py has copy of this function. - # Sync it when modify this function. -@@ -163,6 +168,19 @@ def joinuser(*args): +@@ -167,6 +173,19 @@ def joinuser(*args): }, } @@ -86,7 +87,7 @@ index 2a7fa45be0..7b75228fb3 100644 _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 'scripts', 'data') -@@ -257,11 +275,40 @@ def _extend_dict(target_dict, other_dict): +@@ -266,11 +285,40 @@ def _extend_dict(target_dict, other_dict): target_dict[key] = value @@ -119,7 +120,7 @@ index 2a7fa45be0..7b75228fb3 100644 + # we only change the defaults here, so explicit --prefix will take precedence + # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe + if (scheme == 'posix_prefix' and -+ _PREFIX == '/usr' and ++ sys.prefix == '/usr' and + 'RPM_BUILD_ROOT' not in os.environ): + _extend_dict(vars, _config_vars_local()) + else: @@ -129,10 +130,10 @@ index 2a7fa45be0..7b75228fb3 100644 # On Windows we want to substitute 'lib' for schemes rather # than the native value (without modifying vars, in case it diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py -index 2a6813f00b..00d7034801 100644 +index ce17206a3c..fd95071099 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py -@@ -113,8 +113,19 @@ def test_get_path(self): +@@ -130,8 +130,19 @@ def test_get_path(self): for scheme in _INSTALL_SCHEMES: for name in _INSTALL_SCHEMES[scheme]: expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars) @@ -153,7 +154,7 @@ index 2a6813f00b..00d7034801 100644 os.path.normpath(expected), ) -@@ -338,7 +349,7 @@ def test_get_config_h_filename(self): +@@ -395,7 +406,7 @@ def test_get_config_h_filename(self): self.assertTrue(os.path.isfile(config_h), config_h) def test_get_scheme_names(self): @@ -162,7 +163,7 @@ index 2a6813f00b..00d7034801 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -350,6 +361,8 @@ def test_symlink(self): # Issue 7880 +@@ -407,6 +418,8 @@ def test_symlink(self): # Issue 7880 cmd = "-c", "import sysconfig; print(sysconfig.get_platform())" self.assertEqual(py.call_real(*cmd), py.call_link(*cmd)) diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch deleted file mode 100644 index b536ae0..0000000 --- a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= -Date: Tue, 25 Oct 2022 12:02:33 +0200 -Subject: [PATCH] 00371: Revert "bpo-1596321: Fix threading._shutdown() for the - main thread (GH-28549) (GH-28589)" - -This reverts commit 38c67738c64304928c68d5c2bd78bbb01d979b94. It -introduced regression causing FreeIPA's tests to fail. - -For more info see: -https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 -https://github.com/GrahamDumpleton/mod_wsgi/issues/730 ---- - Lib/test/test_threading.py | 33 --------------------------------- - Lib/threading.py | 31 +++++++++++-------------------- - 2 files changed, 11 insertions(+), 53 deletions(-) - -diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py -index 146e2dbc0f..af63422c6c 100644 ---- a/Lib/test/test_threading.py -+++ b/Lib/test/test_threading.py -@@ -1056,39 +1056,6 @@ def noop(): pass - threading.Thread(target=noop).start() - # Thread.join() is not called - -- def test_import_from_another_thread(self): -- # bpo-1596321: If the threading module is first import from a thread -- # different than the main thread, threading._shutdown() must handle -- # this case without logging an error at Python exit. -- code = textwrap.dedent(''' -- import _thread -- import sys -- -- event = _thread.allocate_lock() -- event.acquire() -- -- def import_threading(): -- import threading -- event.release() -- -- if 'threading' in sys.modules: -- raise Exception('threading is already imported') -- -- _thread.start_new_thread(import_threading, ()) -- -- # wait until the threading module is imported -- event.acquire() -- event.release() -- -- if 'threading' not in sys.modules: -- raise Exception('threading is not imported') -- -- # don't wait until the thread completes -- ''') -- rc, out, err = assert_python_ok("-c", code) -- self.assertEqual(out, b'') -- self.assertEqual(err, b'') -- - def test_start_new_thread_at_exit(self): - code = """if 1: - import atexit -diff --git a/Lib/threading.py b/Lib/threading.py -index 85aff58968..746c409c63 100644 ---- a/Lib/threading.py -+++ b/Lib/threading.py -@@ -1616,32 +1616,23 @@ def _shutdown(): - - global _SHUTTING_DOWN - _SHUTTING_DOWN = True -+ # Main thread -+ tlock = _main_thread._tstate_lock -+ # The main thread isn't finished yet, so its thread state lock can't have -+ # been released. -+ assert tlock is not None -+ if tlock.locked(): -+ # It should have been released already by -+ # _PyInterpreterState_SetNotRunningMain(), but there may be -+ # embedders that aren't calling that yet. -+ tlock.release() -+ _main_thread._stop() - - # Call registered threading atexit functions before threads are joined. - # Order is reversed, similar to atexit. - for atexit_call in reversed(_threading_atexits): - atexit_call() - -- # Main thread -- if _main_thread.ident == get_ident(): -- tlock = _main_thread._tstate_lock -- # The main thread isn't finished yet, so its thread state lock can't -- # have been released. -- assert tlock is not None -- if tlock.locked(): -- # It should have been released already by -- # _PyInterpreterState_SetNotRunningMain(), but there may be -- # embedders that aren't calling that yet. -- tlock.release() -- _main_thread._stop() -- else: -- # bpo-1596321: _shutdown() must be called in the main thread. -- # If the threading module was not imported by the main thread, -- # _main_thread is the thread which imported the threading module. -- # In this case, ignore _main_thread, similar behavior than for threads -- # spawned by C libraries or using _thread.start_new_thread(). -- pass -- - # Join all non-deamon threads - while True: - with _shutdown_locks_lock: diff --git a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch b/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch new file mode 100644 index 0000000..15de467 --- /dev/null +++ b/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch @@ -0,0 +1,133 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Wed, 12 Aug 2026 15:18:39 +0200 +Subject: 00466: Downstream only: Lower XML_COMBINED_VERSION threshold for + reparse deferral + +RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported +via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. +CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter +as a no-op, so SetReparseDeferralEnabled silently does nothing and +GetReparseDeferralEnabled always returns False, even though the expat +library actually supports (and enables) reparse deferral. + +Lower the threshold from 20600 to 20500 so that CPython uses the +backported function. This makes the Python API actually work on RHEL 9 +and fixes test failures (test_reparse_deferral_disabled, +test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). + +The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the +backported function is available. +--- + Lib/test/test_pyexpat.py | 6 +++--- + Lib/test/test_sax.py | 4 ++-- + Lib/test/test_xml_etree.py | 4 ++-- + Modules/pyexpat.c | 6 +++--- + 4 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py +index 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/00475-cve-2025-15367.patch b/00475-cve-2025-15367.patch new file mode 100644 index 0000000..2812c2d --- /dev/null +++ b/00475-cve-2025-15367.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Tue, 20 Jan 2026 14:46:32 -0600 +Subject: 00475: CVE-2025-15367 + +Reject control characters in POP3 commands +--- + Lib/poplib.py | 2 ++ + Lib/test/test_poplib.py | 8 ++++++++ + .../2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 + + 3 files changed, 11 insertions(+) + create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst + +diff --git a/Lib/poplib.py b/Lib/poplib.py +index 4469bff44b..b97274c5c3 100644 +--- a/Lib/poplib.py ++++ b/Lib/poplib.py +@@ -122,6 +122,8 @@ def _putline(self, line): + def _putcmd(self, line): + if self._debugging: print('*cmd*', repr(line)) + line = bytes(line, self.encoding) ++ if re.search(b'[\x00-\x1F\x7F]', line): ++ raise ValueError('Control characters not allowed in commands') + self._putline(line) + + +diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py +index eb6dab4015..bd621caee4 100644 +--- a/Lib/test/test_poplib.py ++++ b/Lib/test/test_poplib.py +@@ -18,6 +18,7 @@ + from test.support import asynchat + from test.support import asyncore + from test.support.testcase import ExtraAssertions ++from test.support import control_characters_c0 + + + test_support.requires_working_socket(module=True) +@@ -396,6 +397,13 @@ def test_quit(self): + self.assertIsNone(self.client.sock) + self.assertIsNone(self.client.file) + ++ def test_control_characters(self): ++ for c0 in control_characters_c0(): ++ with self.assertRaises(ValueError): ++ self.client.user(f'user{c0}') ++ with self.assertRaises(ValueError): ++ self.client.pass_(f'{c0}pass') ++ + @requires_ssl + def test_stls_capa(self): + capa = self.client.capa() +diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst +new file mode 100644 +index 0000000000..3cde4df3e0 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst +@@ -0,0 +1 @@ ++Reject control characters in POP3 commands. diff --git a/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch b/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch new file mode 100644 index 0000000..f860aa1 --- /dev/null +++ b/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch @@ -0,0 +1,173 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Petr Viktorin +Date: Mon, 9 Feb 2026 10:44:21 +0100 +Subject: 00477: Raise an error when importing stdlib modules compiled for a + different Python version + +This is a downstream workaround "implementing" python#137212 - +the mechanism for the check exists in Python 3.15+, where it needs to be +added to the standard library modules. +In Fedora, we need it also in previous Python versions, as we experience +segmentation fault when importing stdlib modules after update while +Python is running. + +_curses, _tkinter, _tracemalloc and readline are not calling PyModuleDef_Init, +which is modified with this patch, hence they need a +direct call to the check function. + +Co-Authored-By: Karolina Surma +--- + Include/moduleobject.h | 43 +++++++++++++++++++++++++++++++++++++++++ + Makefile.pre.in | 3 +++ + Modules/_cursesmodule.c | 6 ++++++ + Modules/_tkinter.c | 6 ++++++ + Modules/_tracemalloc.c | 6 ++++++ + Modules/readline.c | 6 ++++++ + Objects/moduleobject.c | 1 + + 7 files changed, 71 insertions(+) + +diff --git a/Include/moduleobject.h b/Include/moduleobject.h +index 2a17c891dd..64017c666c 100644 +--- a/Include/moduleobject.h ++++ b/Include/moduleobject.h +@@ -116,6 +116,49 @@ struct PyModuleDef { + freefunc m_free; + }; + ++#if defined(_PyHack_check_version_on_modinit) && defined(Py_BUILD_CORE) ++/* The mechanism for the check has been implemented on Python 3.15+: ++ * https://github.com/python/cpython/pull/137212. ++ * In Fedora, we need this in older Pythons too: ++ * if somebody attempts to import a module compiled for a different Python version, ++ * instead of segmentation fault a meaningful error is raised. ++ */ ++PyAPI_DATA(const unsigned long) Py_Version; ++ ++static inline int ++_PyHack_CheckInternalAPIVersion(const char *mod_name) ++{ ++ if (PY_VERSION_HEX != Py_Version) { ++ PyErr_Format( ++ PyExc_ImportError, ++ "internal Python C API version mismatch: " ++ "module %s compiled with %lu.%lu.%lu; " ++ "runtime version is %lu.%lu.%lu", ++ mod_name, ++ (const unsigned long)((PY_VERSION_HEX >> 24) & 0xFF), ++ (const unsigned long)((PY_VERSION_HEX >> 16) & 0xFF), ++ (const unsigned long)((PY_VERSION_HEX >> 8) & 0xFF), ++ (const unsigned long)((Py_Version >> 24) & 0xFF), ++ (const unsigned long)((Py_Version >> 16) & 0xFF), ++ (const unsigned long)((Py_Version >> 8) & 0xFF) ++ ); ++ return -1; ++ } ++ return 0; ++} ++ ++static inline PyObject * ++PyModuleDef_Init_with_check(PyModuleDef *def) ++{ ++ if (_PyHack_CheckInternalAPIVersion(def->m_name) < 0) { ++ return NULL; ++ } ++ return PyModuleDef_Init(def); ++} ++ ++#define PyModuleDef_Init PyModuleDef_Init_with_check ++#endif ++ + #ifdef __cplusplus + } + #endif +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 2363b99a25..f1a07645f0 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -3159,3 +3159,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h + # Local Variables: + # mode: makefile + # End: ++ ++# Fedora-specific, downstream only ++PY_STDMODULE_CFLAGS += -D_PyHack_check_version_on_modinit=1 +diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c +index 1996488a0e..cfdffd8ec4 100644 +--- a/Modules/_cursesmodule.c ++++ b/Modules/_cursesmodule.c +@@ -5011,6 +5011,12 @@ curses_destructor(PyObject *op) + PyMODINIT_FUNC + PyInit__curses(void) + { ++ #ifdef _PyHack_check_version_on_modinit ++ if (_PyHack_CheckInternalAPIVersion("_curses") < 0) { ++ return NULL; ++ } ++ #endif ++ + PyObject *m, *d, *v, *c_api_object; + + /* Initialize object type */ +diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c +index 4e8d75e8e1..32e58755aa 100644 +--- a/Modules/_tkinter.c ++++ b/Modules/_tkinter.c +@@ -3499,6 +3499,12 @@ static struct PyModuleDef _tkintermodule = { + PyMODINIT_FUNC + PyInit__tkinter(void) + { ++ #ifdef _PyHack_check_version_on_modinit ++ if (_PyHack_CheckInternalAPIVersion("_tkinter") < 0) { ++ return NULL; ++ } ++ #endif ++ + PyObject *m, *uexe, *cexe; + + tcl_lock = PyThread_allocate_lock(); +diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c +index 0b85187e5f..87f358ed07 100644 +--- a/Modules/_tracemalloc.c ++++ b/Modules/_tracemalloc.c +@@ -215,6 +215,12 @@ static struct PyModuleDef module_def = { + PyMODINIT_FUNC + PyInit__tracemalloc(void) + { ++ #ifdef _PyHack_check_version_on_modinit ++ if (_PyHack_CheckInternalAPIVersion("_tracemalloc") < 0) { ++ return NULL; ++ } ++ #endif ++ + PyObject *m; + m = PyModule_Create(&module_def); + if (m == NULL) +diff --git a/Modules/readline.c b/Modules/readline.c +index 7a612deae4..8b2f47eec1 100644 +--- a/Modules/readline.c ++++ b/Modules/readline.c +@@ -1548,6 +1548,12 @@ static struct PyModuleDef readlinemodule = { + PyMODINIT_FUNC + PyInit_readline(void) + { ++ #ifdef _PyHack_check_version_on_modinit ++ if (_PyHack_CheckInternalAPIVersion("readline") < 0) { ++ return NULL; ++ } ++ #endif ++ + const char *backend = "readline"; + PyObject *m; + readlinestate *mod_state; +diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c +index d787f29004..31175ceb3f 100644 +--- a/Objects/moduleobject.c ++++ b/Objects/moduleobject.c +@@ -43,6 +43,7 @@ _PyModule_IsExtension(PyObject *obj) + } + + ++#undef PyModuleDef_Init + PyObject* + PyModuleDef_Init(PyModuleDef* def) + { diff --git a/plan.fmf b/plan.fmf new file mode 100644 index 0000000..9c9afb8 --- /dev/null +++ b/plan.fmf @@ -0,0 +1,77 @@ +execute: + how: tmt + +provision: + hardware: + memory: '>= 3 GB' + +environment: + pybasever: '3.13' + +discover: + - name: tests_python + how: shell + url: https://src.fedoraproject.org/tests/python.git + tests: + - name: smoke + path: /smoke + test: "VERSION=${pybasever} CYTHON=false ./venv.sh" + - name: smoke_virtualenv + path: /smoke + test: "VERSION=${pybasever} METHOD=virtualenv CYTHON=false ./venv.sh" + - name: debugsmoke + path: /smoke + test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} CYTHON=false ./venv.sh" + - name: selftest + path: /selftest + test: "VERSION=${pybasever} X='-i test_check_probes' ./parallel.sh" + - name: debugtest + path: /selftest + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes' ./parallel.sh" + - name: optimizedflags + path: /flags + test: "python${pybasever} ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: debugflags + path: /flags + test: "python${pybasever}d ./assertflags.py -O0 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: freethreadingflags + path: /flags + test: "python${pybasever}t ./assertflags.py -O3 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: freethreadingdebugflags + path: /flags + test: "python${pybasever}td ./assertflags.py -O0 CFLAGS PY_BUILTIN_MODULE_CFLAGS PY_CFLAGS PY_CORE_CFLAGS PY_CFLAGS_NODIST PY_STDMODULE_CFLAGS" + - name: marshalparser + path: /marshalparser + test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh" + - name: required_symbols + path: /required-symbols + test: "VERSION=${pybasever} ./check.sh" + +prepare: + - name: Install dependencies + how: install + package: + - gcc # for extension building in venv and selftest + - gcc-c++ # for test_cppext + - gdb # for test_gdb + - "python${pybasever}" # the test subject + - "python${pybasever}-debug" # for leak testing + - "python${pybasever}-devel" # for extension building in venv and selftest + - "python${pybasever}-tkinter" # for selftest + - "python${pybasever}-test" # for selftest + - "python${pybasever}-freethreading" # for -O... flag test + - "python${pybasever}-freethreading-debug" # for -O... flag test + - tox # for venv tests + - virtualenv # for virtualenv tests + - glibc-all-langpacks # for locale tests + - marshalparser # for testing compatibility (magic numbers) with marshalparser + - binutils # for nm (symbol inspection) + - rpm # for debugging + - dnf # for upgrade and downgrade + - name: Update packages + how: shell + script: dnf upgrade -y + - name: rpm_qa + order: 100 + how: shell + script: rpm -qa | sort | tee $TMT_PLAN_DATA/rpmqa.txt diff --git a/python3.13.spec b/python3.13.spec index 8ba1c0a..4045e62 100644 --- a/python3.13.spec +++ b/python3.13.spec @@ -1,3 +1,35 @@ +# ====================== +# Bootstrap conditionals +# ====================== + +# When bootstrapping python3, we need to build python3-packaging. +# but packaging BR python3-devel and that brings in python3-rpm-generators; +# python3-rpm-generators needs python3-packaging, so we cannot have it yet. +# +# We also use the previous build of Python in "make regen-all". +# +# Procedure: https://fedoraproject.org/wiki/SIGs/Python/UpgradingPython +# +# Bootstrap enabled: +# - disables regen-all with the same Python version +# - disables dependency on python3-rpm-generators if we build with main_python +# - disables rpmwheels, optimizations and tests by default +%bcond bootstrap 0 + +# Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages +# Uses upstream bundled prebuilt wheels otherwise +%bcond rpmwheels %{without bootstrap} + +# Expensive optimizations (mainly, profile-guided optimizations) +# We don't have to switch it off for bootstrap, but it speeds up the first build, +# so we opt to only run them during the "full" build +%bcond optimizations %{without bootstrap} + +# Run the test suite in %%check +# Technically, we can run the tests even during the bootstrap build, but since +# we build Python 2x, it's better to just run it once with the "full" build +%bcond tests %{without bootstrap} + # ================== # Top-level metadata # ================== @@ -13,11 +45,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.0 -%global prerel a2 +%global general_version %{pybasever}.15 +#global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python-2.0.1 @@ -25,154 +57,123 @@ License: Python-2.0.1 # Conditionals controlling the build # ================================== -# Note that the bcond macros are named for the CLI option they create. -# "%%bcond_without" means "ENABLE by default and create a --without option" - # Main Python, i.e. whether this is the main Python version in the distribution # that owns /usr/bin/python3 and other unique paths # This also means the built subpackages are called python3 rather than python3X # By default, this is determined by the %%__default_python3_pkgversion value -%if "%{?__default_python3_pkgversion}" == "%{pybasever}" -%bcond_without main_python -%else -%bcond_with main_python -%endif +%bcond main_python %["%{?__default_python3_pkgversion}" == "%{pybasever}"] # If this is *not* Main Python, should it contain `Provides: python(abi) ...`? # In Fedora no package shall depend on an alternative Python via this tag, so we do not provide it. # In ELN/RHEL/CentOS we want to allow building against alternative stacks, so the Provide is enabled. -%if 0%{?fedora} -%bcond_with python_abi_provides_for_alt_pythons -%else -%bcond_without python_abi_provides_for_alt_pythons -%endif - -# When bootstrapping python3, we need to build setuptools. -# but setuptools BR python3-devel and that brings in python3-rpm-generators; -# python3-rpm-generators needs python3-setuptools, so we cannot have it yet. -# -# We also use the previous build of Python in "make regen-all". -# -# Procedure: https://fedoraproject.org/wiki/SIGs/Python/UpgradingPython -# -# IMPORTANT: When bootstrapping, it's very likely python-pip-wheel is -# not available. Turn off the rpmwheels bcond until -# python-pip is built with a wheel to get around the issue. -%bcond_with bootstrap - -# Whether to use RPM build wheels from the python-{pip,setuptools,wheel}-wheel packages -# Uses upstream bundled prebuilt wheels otherwise -# Only F39+ has a pip new enough to work with Python 3.12 -%if 0%{?fedora} >= 39 || 0%{?rhel} >= 10 -%bcond_without rpmwheels -%else -%bcond_with rpmwheels -%endif -# If the rpmwheels condition is disabled, we use the bundled wheel packages -# from Python with the versions below. -# This needs to be manually updated when we update Python. -%global pip_version 23.2.1 -%global setuptools_version 67.6.1 -%global wheel_version 0.40.0 -# All of those also include a list of indirect bundled libs: -# pip -# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) -%global pip_bundled_provides %{expand: -Provides: bundled(python3dist(cachecontrol)) = 0.12.11 -Provides: bundled(python3dist(certifi)) = 2023.5.7 -Provides: bundled(python3dist(chardet)) = 5.1 -Provides: bundled(python3dist(colorama)) = 0.4.6 -Provides: bundled(python3dist(distlib)) = 0.3.6 -Provides: bundled(python3dist(distro)) = 1.8 -Provides: bundled(python3dist(idna)) = 3.4 -Provides: bundled(python3dist(msgpack)) = 1.0.5 -Provides: bundled(python3dist(packaging)) = 21.3 -Provides: bundled(python3dist(platformdirs)) = 3.8.1 -Provides: bundled(python3dist(pygments)) = 2.15.1 -Provides: bundled(python3dist(pyparsing)) = 3.1 -Provides: bundled(python3dist(pyproject-hooks)) = 1 -Provides: bundled(python3dist(requests)) = 2.31 -Provides: bundled(python3dist(resolvelib)) = 1.0.1 -Provides: bundled(python3dist(rich)) = 13.4.2 -Provides: bundled(python3dist(setuptools)) = 68 -Provides: bundled(python3dist(six)) = 1.16 -Provides: bundled(python3dist(tenacity)) = 8.2.2 -Provides: bundled(python3dist(tomli)) = 2.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.7.1 -Provides: bundled(python3dist(urllib3)) = 1.26.16 -Provides: bundled(python3dist(webencodings)) = 0.5.1 -} -# setuptools -# vendor.txt files not in .whl -# $ %%{_rpmconfigdir}/pythonbundles.py \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/setuptools/_vendor/vendored.txt) \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/pkg_resources/_vendor/vendored.txt) -%global setuptools_bundled_provides %{expand: -Provides: bundled(python3dist(importlib-metadata)) = 6 -Provides: bundled(python3dist(importlib-resources)) = 5.10.2 -Provides: bundled(python3dist(jaraco-text)) = 3.7 -Provides: bundled(python3dist(more-itertools)) = 8.8 -Provides: bundled(python3dist(ordered-set)) = 3.1.1 -Provides: bundled(python3dist(packaging)) = 23 -Provides: bundled(python3dist(platformdirs)) = 2.6.2 -Provides: bundled(python3dist(tomli)) = 2.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.4 -Provides: bundled(python3dist(zipp)) = 3.7 -} -# wheel -# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheel-*.whl wheel/vendored/vendor.txt) -%global wheel_bundled_provides %{expand: -Provides: bundled(python3dist(packaging)) = 23 -} - -# Expensive optimizations (mainly, profile-guided optimizations) -%bcond_without optimizations - -# Run the test suite in %%check -%bcond_without tests +%bcond python_abi_provides_for_alt_pythons %{undefined fedora} # Extra build for debugging the interpreter or C-API extensions # (the -debug subpackages) -%bcond_without debug_build +%bcond debug_build 1 -# Support for the GDB debugger -%bcond_without gdb_hooks +# Extra build without GIL, the freethreading PEP 703 provisional way +# (the -freethreading subpackage) +%bcond freethreading_build 1 -# The dbm.gnu module (key-value database) -%bcond_without gdbm +# PEP 744: JIT Compilation +# Whether to build with the experimental JIT compiler +# We can only have this on Fedora 40+, where clang 18+ is available +# And only on certain architectures: https://peps.python.org/pep-0744/#support +# The freethreading build (when enabled) does not support JIT yet +%bcond jit %[(0%{?fedora} >= 40 || 0%{?epel} >= 10) && ("%{_arch}" == "x86_64" || "%{_arch}" == "aarch64")] +%if %{with jit} +# When built with JIT, it still needs to be enabled on runtime via PYTHON_JIT=1 +%global jit_flag --enable-experimental-jit=yes-off +%endif # Main interpreter loop optimization -%bcond_without computed_gotos - -# Support for the Valgrind debugger/profiler -%ifarch %{valgrind_arches} -%bcond_without valgrind -%else -%bcond_with valgrind -%endif +%bcond computed_gotos 1 # ===================== # General global macros # ===================== + %if %{with main_python} %global pkgname python3 %global exename python3 +%global python3_pkgversion 3 %else %global pkgname python%{pybasever} %global exename python%{pybasever} +%global python3_pkgversion %{pybasever} %endif -%global pylibdir %{_libdir}/python%{pybasever} -%global dynload_dir %{pylibdir}/lib-dynload +# If the rpmwheels condition is disabled, we use the bundled wheel packages +# from Python with the versions below. +# This needs to be manually updated when we update Python. +# Explore the sources tarball (you need the version before %%prep is executed): +# $ tar -tf Python-%%{upstream_version}.tar.xz | grep whl +%global pip_version 26.2.1 +%global setuptools_version 79.0.1 +# All of those also include a list of indirect bundled libs: +# pip +# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) +%global pip_bundled_provides %{expand: +Provides: bundled(python3dist(cachecontrol)) = 0.14.4 +Provides: bundled(python3dist(certifi)) = 2026.6.17 +Provides: bundled(python3dist(distlib)) = 0.4.2 +Provides: bundled(python3dist(distro)) = 1.9 +Provides: bundled(python3dist(idna)) = 3.18 +Provides: bundled(python3dist(msgpack)) = 1.1.2 +Provides: bundled(python3dist(packaging)) = 26.2 +Provides: bundled(python3dist(platformdirs)) = 4.10 +Provides: bundled(python3dist(pygments)) = 2.20 +Provides: bundled(python3dist(pyproject-hooks)) = 1.2 +Provides: bundled(python3dist(requests)) = 2.34.2 +Provides: bundled(python3dist(resolvelib)) = 1.2.1 +Provides: bundled(python3dist(rich)) = 14.2 +Provides: bundled(python3dist(setuptools)) = 70.3 +Provides: bundled(python3dist(tomli)) = 2.4.1 +Provides: bundled(python3dist(tomli-w)) = 1.2 +Provides: bundled(python3dist(truststore)) = 0.10.4 +Provides: bundled(python3dist(urllib3)) = 2.7 +} +# setuptools +# vendor.txt not in .whl +# %%{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') +%global setuptools_bundled_provides %{expand: +Provides: bundled(python3dist(autocommand)) = 2.2.2 +Provides: bundled(python3dist(backports-tarfile)) = 1.2 +Provides: bundled(python3dist(importlib-metadata)) = 8 +Provides: bundled(python3dist(inflect)) = 7.3.1 +Provides: bundled(python3dist(jaraco-collections)) = 5.1 +Provides: bundled(python3dist(jaraco-context)) = 5.3 +Provides: bundled(python3dist(jaraco-functools)) = 4.0.1 +Provides: bundled(python3dist(jaraco-text)) = 3.12.1 +Provides: bundled(python3dist(more-itertools)) = 10.3 +Provides: bundled(python3dist(packaging)) = 24.2 +Provides: bundled(python3dist(platformdirs)) = 4.2.2 +Provides: bundled(python3dist(tomli)) = 2.0.1 +Provides: bundled(python3dist(typeguard)) = 4.3 +Provides: bundled(python3dist(typing-extensions)) = 4.12.2 +Provides: bundled(python3dist(wheel)) = 0.45.1 +Provides: bundled(python3dist(zipp)) = 3.19.2 +} # ABIFLAGS, LDVERSION and SOABI are in the upstream configure.ac # See PEP 3149 for some background: http://www.python.org/dev/peps/pep-3149/ -%global ABIFLAGS_optimized %{nil} -%global ABIFLAGS_debug d +%global ABIFLAGS_optimized %{nil} +%global ABIFLAGS_debug d +%global ABIFLAGS_freethreading t +%global ABIFLAGS_freethreading_debug td -%global LDVERSION_optimized %{pybasever}%{ABIFLAGS_optimized} -%global LDVERSION_debug %{pybasever}%{ABIFLAGS_debug} +%global LDVERSION_optimized %{pybasever}%{ABIFLAGS_optimized} +%global LDVERSION_debug %{pybasever}%{ABIFLAGS_debug} +%global LDVERSION_freethreading %{pybasever}%{ABIFLAGS_freethreading} +%global LDVERSION_freethreading_debug %{pybasever}%{ABIFLAGS_freethreading_debug} + +%global pylibdir %{_libdir}/python%{pybasever} +%global dynload_dir %{pylibdir}/lib-dynload +# freethreading libraries are located in e.g. /usr/lib64/python3.13t/ +# https://github.com/python/cpython/issues/121103 +%global pylibdir_freethreading %{pylibdir}%{ABIFLAGS_freethreading} +%global dynload_dir_freethreading %{pylibdir_freethreading}/lib-dynload # We use the upstream arch triplets, we convert them from %%{_arch}-linux%%{_gnu} %global platform_triplet %{expand:%(echo %{_arch}-linux%{_gnu} | sed -E \\ @@ -180,8 +181,10 @@ Provides: bundled(python3dist(packaging)) = 23 -e 's/^mips64(el)?-linux-gnu$/mips64\\1-linux-gnuabi64/' \\ -e 's/^ppc(64)?(le)?-linux-gnu$/powerpc\\1\\2-linux-gnu/')} -%global SOABI_optimized cpython-%{pyshortver}%{ABIFLAGS_optimized}-%{platform_triplet} -%global SOABI_debug cpython-%{pyshortver}%{ABIFLAGS_debug}-%{platform_triplet} +%global SOABI_optimized cpython-%{pyshortver}%{ABIFLAGS_optimized}-%{platform_triplet} +%global SOABI_debug cpython-%{pyshortver}%{ABIFLAGS_debug}-%{platform_triplet} +%global SOABI_freethreading cpython-%{pyshortver}%{ABIFLAGS_freethreading}-%{platform_triplet} +%global SOABI_freethreading_debug cpython-%{pyshortver}%{ABIFLAGS_freethreading_debug}-%{platform_triplet} # All bytecode files are in a __pycache__ subdirectory, with a name # reflecting the version of the bytecode. @@ -202,8 +205,19 @@ Provides: bundled(python3dist(packaging)) = 23 # (if these get out of sync, the payload of the libs subpackage will fail # and halt the build) %global py_SOVERSION 1.0 -%global py_INSTSONAME_optimized libpython%{LDVERSION_optimized}.so.%{py_SOVERSION} -%global py_INSTSONAME_debug libpython%{LDVERSION_debug}.so.%{py_SOVERSION} +%global py_INSTSONAME_optimized libpython%{LDVERSION_optimized}.so.%{py_SOVERSION} +%global py_INSTSONAME_debug libpython%{LDVERSION_debug}.so.%{py_SOVERSION} +%global py_INSTSONAME_freethreading libpython%{LDVERSION_freethreading}.so.%{py_SOVERSION} +%global py_INSTSONAME_freethreading_debug libpython%{LDVERSION_freethreading_debug}.so.%{py_SOVERSION} + +# The -O flag for the compiler, optimized builds +# https://fedoraproject.org/wiki/Changes/Python_built_with_gcc_O3 +%global optflags_optimized -O3 +# The -O flag for the compiler, debug builds +# -Wno-cpp avoids some warnings with -O0 +%global optflags_debug -O0 -Wno-cpp +# Remove the default -O2 flag, our flags are applied in %%build/%%install +%global __global_compiler_flags %(echo '%{__global_compiler_flags}' | sed 's/-O[[:digit:]]//') # Disable automatic bytecompilation. The python3 binary is not yet be # available in /usr/bin when Python is built. Also, the bytecompilation fails @@ -235,61 +249,64 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\ # Build-time requirements # ======================= -# (keep this list alphabetized) +# (keep this list alphabetized within the %%if blocks) BuildRequires: autoconf BuildRequires: bluez-libs-devel -BuildRequires: bzip2 BuildRequires: bzip2-devel -BuildRequires: desktop-file-utils -BuildRequires: expat-devel - +BuildRequires: expat-devel >= 2.5.0-2 BuildRequires: findutils -BuildRequires: gcc-c++ -%if %{with gdbm} +BuildRequires: gcc BuildRequires: gdbm-devel -%endif BuildRequires: git-core -BuildRequires: glibc-all-langpacks BuildRequires: glibc-devel -BuildRequires: gmp-devel BuildRequires: gnupg2 -BuildRequires: libappstream-glib -%if %{undefined rhel} -BuildRequires: libb2-devel -%endif -BuildRequires: libffi-devel -BuildRequires: libGL-devel -BuildRequires: libuuid-devel BuildRequires: libX11-devel +BuildRequires: libffi-devel +BuildRequires: libuuid-devel BuildRequires: make BuildRequires: mpdecimal-devel BuildRequires: ncurses-devel - -BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: readline-devel BuildRequires: redhat-rpm-config >= 127 BuildRequires: sqlite-devel +BuildRequires: systemtap-sdt-devel +BuildRequires: tcl-devel < 1:9 +BuildRequires: tk-devel < 1:9 +BuildRequires: xz-devel +BuildRequires: zlib-devel +BuildRequires: /usr/bin/dtrace + +# Support for OpenSSL 4 only landed in Python 3.15 for now +# https://github.com/python/cpython/issues/146207 +BuildRequires: (openssl-devel < 1:4 or openssl3-devel) + +%if %{undefined rhel} +BuildRequires: libb2-devel +%endif + +%if %{with tests} +BuildRequires: gcc-c++ BuildRequires: gdb - -BuildRequires: tar -BuildRequires: tcl-devel -BuildRequires: tk-devel +BuildRequires: glibc-all-langpacks BuildRequires: tzdata +%endif -%if %{with valgrind} +%if %{with jit} +BuildRequires: clang(major) = 18 +BuildRequires: llvm(major) = 18 +%endif + +%ifarch %{valgrind_arches} BuildRequires: valgrind-devel %endif -BuildRequires: xz-devel -BuildRequires: zlib-devel - -BuildRequires: /usr/bin/dtrace - -# workaround http://bugs.python.org/issue19804 (test_uuid requires ifconfig) -BuildRequires: /usr/sbin/ifconfig +%if %{with main_python} +BuildRequires: desktop-file-utils +BuildRequires: libappstream-glib +%endif %if %{with rpmwheels} # Python 3.12 removed the deprecated imp module, @@ -297,7 +314,7 @@ BuildRequires: /usr/sbin/ifconfig BuildRequires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 %if %{with tests} BuildRequires: %{python_wheel_pkg_prefix}-setuptools-wheel -BuildRequires: %{python_wheel_pkg_prefix}-wheel-wheel +BuildRequires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) %endif %endif @@ -307,6 +324,9 @@ BuildRequires: %{python_wheel_pkg_prefix}-wheel-wheel # upgrading the main python3 to a new Python version, this would pull in the # old version instead. BuildRequires: python%{pybasever} +%endif + +%if %{without bootstrap} || %{without main_python} # for proper automatic provides BuildRequires: python3-rpm-generators %endif @@ -333,7 +353,7 @@ Source11: idle3.appdata.xml # (Patches taken from github.com/fedora-python/cpython) -# 00251 # 758eb29fbfe9253ab343e8a09a480a6b64e57df8 +# 00251 # 5ac6e7781923cbb3e4606e3bca381a1167d322e5 # Change user install location # # Set values of base and platbase in sysconfig from /usr @@ -350,16 +370,45 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00371 # 16d2d6be400cb52c0f50fa27c0e08ae63d1d3add -# Revert "bpo-1596321: Fix threading._shutdown() for the main thread (GH-28549) (GH-28589)" +# 00466 # 713a1368544eddd55088d67f88a23ce31722a4cb +# Downstream only: Lower XML_COMBINED_VERSION threshold for reparse deferral # -# This reverts commit 38c67738c64304928c68d5c2bd78bbb01d979b94. It -# introduced regression causing FreeIPA's tests to fail. +# 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. # -# For more info see: -# https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 -# https://github.com/GrahamDumpleton/mod_wsgi/issues/730 -Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +# Lower the threshold from 20600 to 20500 so that CPython uses the +# backported function. This makes the Python API actually work on RHEL 9 +# and fixes test failures (test_reparse_deferral_disabled, +# test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). +# +# The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the +# backported function is available. +Patch466: 00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch + +# 00475 # d44fac01037662db286449a78c8fb819788f764c +# CVE-2025-15367 +# +# Reject control characters in POP3 commands +Patch475: 00475-cve-2025-15367.patch + +# 00477 # 9c62c492e7f2e3b152dbf287c08d307c3f013221 +# Raise an error when importing stdlib modules compiled for a different Python version +# +# This is a downstream workaround "implementing" python#137212 - +# the mechanism for the check exists in Python 3.15+, where it needs to be +# added to the standard library modules. +# In Fedora, we need it also in previous Python versions, as we experience +# segmentation fault when importing stdlib modules after update while +# Python is running. +# +# _curses, _tkinter, _tracemalloc and readline are not calling PyModuleDef_Init, +# which is modified with this patch, hence they need a +# direct call to the check function. +Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch # (New patches go here ^^^) # @@ -481,15 +530,46 @@ This package contains /usr/bin/python - the "python" command that runs Python 3. %package -n %{pkgname}-libs Summary: Python runtime libraries +# Python is generally licensed as Python-2.0.1 but also includes incorporated software +# Combined manually from https://docs.python.org/3.13/license.html +# Hash of Doc/license.rst which is compared in %%prep, generated with: +# $ sha256sum Doc/license.rst | cut -f1 -d" " +%global license_file_hash 952ac05720d7f1dcb63589b35eb0931b1442eb250230a4ad31198eddf0ad6abc +# Licenses of incorporated software: +# Mersenne Twister in _random C extension contains code under BSD-3-Clause +# socket.getaddrinfo() and socket.getnameinfo() are BSD-3-Clause +# test.support.asynchat and test.support.asyncore are MIT-CMU +# http.cookies is MIT-CMU +# trace is HPND-SMC +# uu is MIT-CMU +# xmlrpc.client is MIT-CMU +# test.test_epoll is MIT +# select kqueue interface is BSD-2-Clause +# SipHash algorithm in Python/pyhash.c is MIT +# strtod and dtoa are dtoa +# OpenSSL is not bundled +# expat is not bundled +# libffi is not bundled +# zlib is not bundled +# cfuhash used by tracemalloc is BSD-3-Clause +# libmpdec is not bundled +# C14N test suite in Lib/test/xmltestdata/c14n-20/ is BSD-3-Clause +# mimalloc is MIT +# parts of asyncio from uvloop are MIT +# Python/qsbr.c is adapted from code under BSD-2-Clause +# An extract of the `Unicode Character Database` converted to an internal format is Unicode-3.0 +# Bundled libb2 is not declared in the upstream document, but it's: +# CC0-1.0, covered by grandfathering exception +# We don't query upstream for changes, as 3.13 is the last Python version containing it. +%global libs_license Python-2.0.1 AND CC0-1.0 AND MIT AND BSD-3-Clause AND MIT-CMU AND HPND-SMC AND BSD-2-Clause AND dtoa AND Unicode-3.0 %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 -# Bundled libb2 is CC0, covered by grandfathering exception -License: Python-2.0.1 AND CC0-1.0 +License: %{libs_license} %else Provides: bundled(python3dist(pip)) = %{pip_version} %pip_bundled_provides -# License manually combined form Python + pip -License: Python-2.0.1 AND CC0-1.0 AND MIT AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +# License combined from Python libs + pip +License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) %endif %unversioned_obsoletes_of_python3_X_if_main libs @@ -498,6 +578,11 @@ License: Python-2.0.1 AND CC0-1.0 AND MIT AND Apache-2.0 AND BSD-2-Clause AND BS # last updated by https://github.com/python/cpython/pull/6286 Provides: bundled(libb2) = 0.98.1 +# Bundled mimalloc version in Include/internal/mimalloc/mimalloc.h +# Python's version is modified, differences are listed in: +# https://github.com/python/cpython/issues/113141 +Provides: bundled(mimalloc) = 2.12 + # There are files in the standard library that have python shebang. # We've filtered the automatic requirement out so libs are installable without # the main package. This however makes it pulled in by default. @@ -512,6 +597,28 @@ Recommends: (%{pkgname}-tkinter%{?_isa} = %{version}-%{release} if tk%{?_isa}) # The zoneinfo module needs tzdata Requires: tzdata +# The requirement on libexpat is generated, but we need to version it. +# When built with a specific expat version, but installed with an older one, +# we sometimes get: +# ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so: +# undefined symbol: XML_... +# The pyexpat module has build-time checks for expat version to only use the +# available symbols. However, there is no runtime protection, so when the module +# is later installed with an older expat, it may error due to undefined symbols. +# This breaks many things, including python -m venv. +# We avoid this problem by requiring at least the same version of expat that +# was used during the build time. +# We also include release, in case pyxpat uses ABI that was backported +# (e.g. XML_SetReparseDeferralEnabled was added in c9s expat 2.5.0-2). +# Other subpackages (like -debug) also need this, but they all depend on -libs. +# Since expat 2.7.4, the library has versioned symbols and this is no longer needed, +# as the generated requirement will be in the form of libexpat.so.1(LIBEXPAT_2.7.2) etc. +%global expat_version %(LANG=C rpm -q --qf '%%{version}-%%{release}' expat.%{_target_cpu} | sed 's/.*not installed/0/') +%if v"%{expat_version}" < v"2.7.4" +Requires: expat%{?_isa} >= %{expat_version} +%endif + + %description -n %{pkgname}-libs This package contains runtime libraries for use by Python: - the majority of the Python standard library @@ -521,6 +628,8 @@ This package contains runtime libraries for use by Python: %package -n %{pkgname}-devel Summary: Libraries and header files needed for Python development +# Bundled mimalloc header files are MIT +License: Python-2.0.1 AND MIT Requires: %{pkgname} = %{version}-%{release} Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} # The RPM related dependencies bring nothing to a non-RPM Python developer @@ -543,7 +652,8 @@ Recommends: %{pkgname}-pip # tox users are likely to need the devel subpackage Supplements: tox -%if %{without bootstrap} +%if %{without bootstrap} || %{without main_python} +# Generators run on the main Python 3 so we cannot require them when bootstrapping it Requires: (python3-rpm-generators if rpm-build) %endif @@ -605,12 +715,10 @@ Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-setuptools-wheel -Requires: %{python_wheel_pkg_prefix}-wheel-wheel +Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) %else Provides: bundled(python3dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides -Provides: bundled(python3dist(wheel)) = %{wheel_version} -%wheel_bundled_provides # License manually combined from Python + setuptools + wheel License: Python-2.0.1 AND MIT AND Apache-2.0 AND (Apache-2.0 OR BSD-2-Clause) %endif @@ -628,6 +736,7 @@ you should use the unittest module from %{pkgname}-libs, or a library such as %if %{with debug_build} %package -n %{pkgname}-debug Summary: Debug version of the Python runtime +License: %{libs_license} # The debug build is an all-in-one package version of the regular build, and # shares the same .py/.pyc files and directories as the regular build. Hence @@ -659,6 +768,75 @@ The debug runtime additionally supports debug builds of C-API extensions %endif # with debug_build +%if %{with freethreading_build} +# This deliberately does not use the %%{pkgname}- prefix, +# we want to call this python3.X-threading even when built as a main Python. +# At least until the PEP 703 build remains provisional. +%package -n python%{pybasever}-freethreading +Summary: Free Threading (PEP 703) version of the Python runtime + +%if %{with rpmwheels} +Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 +Requires: %{python_wheel_pkg_prefix}-setuptools-wheel +Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) +License: %{libs_license} +%else +Provides: bundled(python3dist(pip)) = %{pip_version} +%pip_bundled_provides +Provides: bundled(python3dist(setuptools)) = %{setuptools_version} +%setuptools_bundled_provides +# License combined from Python libs + pip + setuptools +License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +%endif + +# This package doesn't depend on python3-libs, so we need to explicitly +# define the same Provides and Requires. +# See the comments in the definition of -libs subpackage for detailed explanations +Provides: bundled(libb2) = 0.98.1 +Provides: bundled(mimalloc) = 2.12 +Requires: tzdata +%if v"%{expat_version}" < v"2.7.4" +Requires: expat%{?_isa} >= %{expat_version} +%endif + +%description -n python%{pybasever}-freethreading +The provisional Free Threading (PEP 703) build of Python. + +CPython’s global interpreter lock (“GIL”) prevents multiple threads from +executing Python code at the same time. The GIL is an obstacle to using +multi-core CPUs from Python efficiently. + +This build of Python is built with the --disable-gil option. +It lets the interpreter run Python code without the global interpreter lock +and with the necessary changes needed to make the interpreter thread-safe. +%endif # with freethreading_build + + +%if %{with freethreading_build} && %{with debug_build} +%package -n python%{pybasever}-freethreading-debug +Summary: Free Threading (PEP 703) version of the Python runtime (debug build) +License: %{libs_license} + +# This uses the pure Python modules from the freethreading package +Requires: python%{pybasever}-freethreading%{?_isa} = %{version}-%{release} + +%description -n python%{pybasever}-freethreading-debug +The provisional Free Threading (PEP 703) build of Python. Debug build. + +CPython’s global interpreter lock (“GIL”) prevents multiple threads from +executing Python code at the same time. The GIL is an obstacle to using +multi-core CPUs from Python efficiently. + +This build of Python is built with the --disable-gil option. +It lets the interpreter run Python code without the global interpreter lock +and with the necessary changes needed to make the interpreter thread-safe. + +This package provides a version of the Python runtime with numerous debugging +features enabled, aimed at advanced Python users such as developers of Python +extension modules. +%endif # with freethreading_build && debug_build + + # ====================================================== # The prep phase of the build: # ====================================================== @@ -672,15 +850,22 @@ The debug runtime additionally supports debug builds of C-API extensions # setuptools.whl does not contain the vendored.txt files if [ -f %{_rpmconfigdir}/pythonbundles.py ]; then %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) --compare-with '%pip_bundled_provides' - %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheel-*.whl wheel/vendored/vendor.txt) --compare-with '%wheel_bundled_provides' + %{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') --compare-with '%setuptools_bundled_provides' fi %if %{with rpmwheels} rm Lib/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl -rm Lib/test/setuptools-%{setuptools_version}-py3-none-any.whl -rm Lib/test/wheel-%{wheel_version}-py3-none-any.whl +rm Lib/test/wheeldata/setuptools-%{setuptools_version}-py3-none-any.whl %endif +# check if there were any changes to Doc/license.rst +# if so, a review of %%libs_license and %%license_file_hash is needed +found_hash=$(sha256sum Doc/license.rst | cut -f1 -d" ") +if [ "$found_hash" != %{license_file_hash} ]; then + echo "File hash mismatch: review Doc/license.rst for changes" + exit 1 +fi + # Remove all exe files to ensure we are not shipping prebuilt binaries # note that those are only used to create Microsoft Windows installers # and that functionality is broken on Linux anyway @@ -694,6 +879,8 @@ rm -r Modules/_decimal/libmpdec # (This is after patching, so that we can use patches directly from upstream) rm configure pyconfig.h.in +# Lower the minimal required version of autoconf to enable build for EPEL 9 +sed -i "s/AC_PREREQ(\[2\.71\])/AC_PREREQ([2.69])/" configure.ac # ====================================================== # Configuring and building the code: @@ -774,7 +961,6 @@ BuildPython() { --with-computed-gotos=%{computed_gotos_flag} \ --with-dbmliborder=gdbm:ndbm:bdb \ --with-system-expat \ - --with-system-ffi \ --with-system-libmpdec \ --enable-loadable-sqlite-extensions \ --with-dtrace \ @@ -784,12 +970,23 @@ BuildPython() { %if %{with rpmwheels} --with-wheel-pkg-dir=%{python_wheel_dir} \ %endif -%if %{with valgrind} +%ifarch %{valgrind_arches} --with-valgrind \ %endif $ExtraConfigArgs \ %{nil} +%if 0%{?fedora} && 0%{?fedora} < 42 + # Statically compile the _datetime module to mitigate: + # Segfault when updating from 3.13.0 to 3.13.1 while Python is running + # https://bugzilla.redhat.com/2333852 + # Note that this is an incomplete workaround for the case we know about, + # we'd like to see the cause fixed properly in Python 3.14 upstream: + # https://github.com/python/cpython/issues/128341 + # This is only carried on Fedoras released before Python 3.13.1. + echo -e '*static*\n_datetime _datetimemodule.c' > Modules/Setup.local +%endif + %global flags_override EXTRA_CFLAGS="$MoreCFlags" CFLAGS_NODIST="$CFLAGS_NODIST $MoreCFlags" %if %{without bootstrap} @@ -812,13 +1009,25 @@ BuildPython() { # option produces too many warnings when compiling at the O0 optimization level. # See also: https://bugzilla.redhat.com/show_bug.cgi?id=1818857 BuildPython debug \ - "--without-ensurepip --with-pydebug" \ - "-O0 -Wno-cpp" + "--without-ensurepip --with-pydebug %{?jit_flag}" \ + "%{optflags_debug}" %endif # with debug_build BuildPython optimized \ - "--without-ensurepip %{optimizations_flag}" \ - "" + "--without-ensurepip %{?jit_flag} %{optimizations_flag}" \ + "%{optflags_optimized}" + +%if %{with freethreading_build} && %{with debug_build} +BuildPython freethreading-debug \ + "--without-ensurepip --with-pydebug --disable-gil" \ + "%{optflags_debug}" +%endif # with freethreading_build && debug_build + +%if %{with freethreading_build} +BuildPython freethreading \ + "--without-ensurepip %{optimizations_flag} --disable-gil" \ + "%{optflags_optimized}" +%endif # with freethreading_build # ====================================================== # Installing the built code: @@ -848,10 +1057,8 @@ topdir=$(pwd) # See https://fedoraproject.org/wiki/Features/EasierPythonDebugging for more # information -%if %{with gdb_hooks} DirHoldingGdbPy=%{_usr}/lib/debug/%{_libdir} mkdir -p %{buildroot}$DirHoldingGdbPy -%endif # with gdb_hooks # When the actual %%{dynload_dir} exists (it does when python3.X is installed for regen-all) # %%{buildroot}%%{dynload_dir} is not created by make install and the extension modules are missing @@ -888,11 +1095,9 @@ InstallPython() { popd -%if %{with gdb_hooks} # See comment on $DirHoldingGdbPy above PathOfGdbPy=$DirHoldingGdbPy/$PyInstSoName-%{version}-%{release}.%{_arch}.debug-gdb.py cp Tools/gdb/libpython.py %{buildroot}$PathOfGdbPy -%endif # with gdb_hooks # Rename the -devel script that differs on different arches to arch specific name mv %{buildroot}%{_bindir}/python${LDVersion}-{,`uname -m`-}config @@ -918,19 +1123,35 @@ EOF echo FINISHED: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName } -# Install the "debug" build first; any common files will be overridden with +# Install the "freethreading" and "debug" builds first; any common files will be overridden with # later builds +%if %{with freethreading_build} && %{with debug_build} +# Now the freethreading debug build: +InstallPython freethreading-debug \ + %{py_INSTSONAME_freethreading_debug} \ + "%{optflags_debug}" \ + %{LDVERSION_freethreading_debug} +%endif # with freethreading_build && debug_build + %if %{with debug_build} InstallPython debug \ %{py_INSTSONAME_debug} \ - -O0 \ + "%{optflags_debug}" \ %{LDVERSION_debug} %endif # with debug_build +%if %{with freethreading_build} +# Now the freethreading optimized build: +InstallPython freethreading \ + %{py_INSTSONAME_freethreading} \ + "%{optflags_optimized}" \ + %{LDVERSION_freethreading} +%endif # with freethreading_build + # Now the optimized build: InstallPython optimized \ %{py_INSTSONAME_optimized} \ - "" \ + "%{optflags_optimized}" \ %{LDVERSION_optimized} # Install directories for additional packages @@ -942,6 +1163,9 @@ install -d -m 0755 %{buildroot}%{pylibdir}/site-packages/__pycache__ # Note that rpmlint will complain about hardcoded library path; # this is intentional. install -d -m 0755 %{buildroot}%{_prefix}/lib/python%{pybasever}/site-packages/__pycache__ +%if %{with freethreading_build} +install -d -m 0755 %{buildroot}%{_prefix}/lib/python%{pybasever}%{ABIFLAGS_freethreading}/site-packages/__pycache__ +%endif # with freethreading_build %endif %if %{with main_python} @@ -980,7 +1204,7 @@ LD_LIBRARY_PATH=./build/optimized ./build/optimized/python \ -i "%{_bindir}/python%{pybasever}" -pn \ %{buildroot} \ %{buildroot}%{_bindir}/*%{pybasever}.py \ - %{?with_gdb_hooks:%{buildroot}$DirHoldingGdbPy/*.py} + %{buildroot}$DirHoldingGdbPy/*.py # Remove shebang lines from .py files that aren't executable, and # remove executability from .py files that don't have a shebang line: @@ -1008,7 +1232,7 @@ find . -name "*~" -exec rm -f {} \; %if 0%{?clamp_mtime_to_source_date_epoch} LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ PYTHONPATH="%{_rpmconfigdir}/redhat" \ -%{buildroot}%{_bindir}/python%{pybasever} -s -B -m clamp_source_mtime %{buildroot}%{pylibdir} +%{buildroot}%{_bindir}/python%{pybasever} -s -B -m clamp_source_mtime %{buildroot}%{pylibdir} %{?with_freethreading_build:%{buildroot}%{pylibdir_freethreading}} %endif # compileall CMD line options: # -f - force rebuild even if timestamps are up to date @@ -1077,6 +1301,11 @@ for file in %{buildroot}%{pylibdir}/pydoc_data/topics.py $(grep --include='*.py' rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py} done +%if %{without rpmwheels} +# Inject SBOM into the installed wheels (if the macro is available) +%{?python_wheel_inject_sbom:%python_wheel_inject_sbom %{buildroot}%{pylibdir}/ensurepip/_bundled/*.whl} +%endif + # ====================================================== # Checks for packaging issues # ====================================================== @@ -1138,16 +1367,26 @@ CheckPython() { # test_check_probes is failing since it was introduced in 3.12.0rc1, # the test is skipped until it is fixed in upstream. # see: https://github.com/python/cpython/issues/104280#issuecomment-1669249980 - # test.regrtest fails if SOURCE_DATE_EPOCH is set - # https://github.com/python/cpython/issues/110932 - unset SOURCE_DATE_EPOCH + # test_signal is skipped due to https://github.com/python/cpython/issues/118989 + # test.test_concurrent_futures.test_deadlock tends to time out on s390x and ppc64le in + # freethreading{,-debug} build, skipping it to shorten the build time + # see: https://github.com/python/cpython/issues/121719 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ - -wW --slowest %{_smp_mflags} --timeout=2700 \ + -wW --slowest %{_smp_mflags} \ + %ifarch riscv64 + --timeout=8100 \ + %else + --timeout=2700 \ + %endif -i test_freeze_simple_script \ -i test_check_probes \ %ifarch %{mips64} -x test_ctypes \ %endif + %ifarch s390x ppc64le + -x test_signal \ + -i test_deadlock \ + %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName @@ -1160,6 +1399,12 @@ CheckPython() { CheckPython debug %endif # with debug_build CheckPython optimized +%if %{with freethreading_build} && %{with debug_build} +CheckPython freethreading-debug +%endif # with freethreading_build && debug_build +%if %{with freethreading_build} +CheckPython freethreading +%endif # with freethreading_build %endif # with tests @@ -1193,221 +1438,149 @@ CheckPython optimized %license %{pylibdir}/LICENSE.txt -%dir %{pylibdir}/unittest/ -%dir %{pylibdir}/unittest/__pycache__/ -%{pylibdir}/unittest/*.py -%{pylibdir}/unittest/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/asyncio/ -%dir %{pylibdir}/asyncio/__pycache__/ -%{pylibdir}/asyncio/*.py -%{pylibdir}/asyncio/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/venv/ -%dir %{pylibdir}/venv/__pycache__/ -%{pylibdir}/venv/*.py -%{pylibdir}/venv/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/venv/scripts - -%{pylibdir}/wsgiref -%{pylibdir}/xmlrpc - -%dir %{pylibdir}/ensurepip/ -%dir %{pylibdir}/ensurepip/__pycache__/ -%{pylibdir}/ensurepip/*.py -%{pylibdir}/ensurepip/__pycache__/*%{bytecode_suffixes} - -%if %{with rpmwheels} -%exclude %{pylibdir}/ensurepip/_bundled -%else -%dir %{pylibdir}/ensurepip/_bundled -%{pylibdir}/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl +# Pure Python modules +# This is macronized for reuse in the -freethreading package +%define pure_python_modules() \ +%{1}/*.py\ +%dir %{1}/__pycache__/\ +%{1}/__pycache__/*%{bytecode_suffixes}\ +\ +%{1}/_pyrepl/\ +%{1}/asyncio/\ +%{1}/collections/\ +%{1}/concurrent/\ +%{1}/ctypes/\ +%{1}/curses/\ +%{1}/dbm/\ +%{1}/encodings/\ +%{1}/html/\ +%{1}/http/\ +%{1}/importlib/\ +%{1}/json/\ +%{1}/logging/\ +%{1}/multiprocessing/\ +%{1}/pathlib/\ +%{1}/pydoc_data/\ +%{1}/re/\ +%{1}/sqlite3/\ +%{1}/sysconfig/\ +%{1}/tomllib/\ +%{1}/unittest/\ +%{1}/urllib/\ +%{1}/venv/\ +%{1}/wsgiref/\ +%{1}/xml/\ +%{1}/xmlrpc/\ +%{1}/zipfile/\ +%{1}/zoneinfo/\ +# Handle the email module in detail to mark architecture.rst as %%doc\ +%dir %{1}/email/\ +%dir %{1}/email/__pycache__/\ +%{1}/email/*.py\ +%{1}/email/__pycache__/*%{bytecode_suffixes}\ +%{1}/email/mime/\ +%doc %{1}/email/architecture.rst\ +# Handle the ensurepip module in detail to not accidentally ship wheels\ +%dir %{1}/ensurepip/\ +%dir %{1}/ensurepip/__pycache__/\ +%{1}/ensurepip/*.py\ +%{1}/ensurepip/__pycache__/*%{bytecode_suffixes}\ +%if %{with rpmwheels}\ +%exclude %{1}/ensurepip/_bundled\ +%else\ +%dir %{1}/ensurepip/_bundled\ +%{1}/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl\ %endif -%dir %{pylibdir}/concurrent/ -%dir %{pylibdir}/concurrent/__pycache__/ -%{pylibdir}/concurrent/*.py -%{pylibdir}/concurrent/__pycache__/*%{bytecode_suffixes} +%pure_python_modules %{pylibdir} -%dir %{pylibdir}/concurrent/futures/ -%dir %{pylibdir}/concurrent/futures/__pycache__/ -%{pylibdir}/concurrent/futures/*.py -%{pylibdir}/concurrent/futures/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/sysconfig/ -%dir %{pylibdir}/sysconfig/__pycache__/ -%{pylibdir}/sysconfig/*.py -%{pylibdir}/sysconfig/__pycache__/*%{bytecode_suffixes} - -%{pylibdir}/pydoc_data - -%{dynload_dir}/_blake2.%{SOABI_optimized}.so -%{dynload_dir}/_md5.%{SOABI_optimized}.so -%{dynload_dir}/_sha1.%{SOABI_optimized}.so -%{dynload_dir}/_sha2.%{SOABI_optimized}.so -%{dynload_dir}/_sha3.%{SOABI_optimized}.so - -%{dynload_dir}/_asyncio.%{SOABI_optimized}.so -%{dynload_dir}/_bisect.%{SOABI_optimized}.so -%{dynload_dir}/_bz2.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_cn.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_hk.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_iso2022.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_jp.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_kr.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_tw.%{SOABI_optimized}.so -%{dynload_dir}/_contextvars.%{SOABI_optimized}.so -%{dynload_dir}/_csv.%{SOABI_optimized}.so -%{dynload_dir}/_ctypes.%{SOABI_optimized}.so -%{dynload_dir}/_curses.%{SOABI_optimized}.so -%{dynload_dir}/_curses_panel.%{SOABI_optimized}.so -%{dynload_dir}/_dbm.%{SOABI_optimized}.so -%{dynload_dir}/_decimal.%{SOABI_optimized}.so -%{dynload_dir}/_elementtree.%{SOABI_optimized}.so -%if %{with gdbm} -%{dynload_dir}/_gdbm.%{SOABI_optimized}.so -%endif -%{dynload_dir}/_hashlib.%{SOABI_optimized}.so -%{dynload_dir}/_heapq.%{SOABI_optimized}.so -%{dynload_dir}/_json.%{SOABI_optimized}.so -%{dynload_dir}/_lsprof.%{SOABI_optimized}.so -%{dynload_dir}/_lzma.%{SOABI_optimized}.so -%{dynload_dir}/_multibytecodec.%{SOABI_optimized}.so -%{dynload_dir}/_multiprocessing.%{SOABI_optimized}.so -%{dynload_dir}/_opcode.%{SOABI_optimized}.so -%{dynload_dir}/_pickle.%{SOABI_optimized}.so -%{dynload_dir}/_posixsubprocess.%{SOABI_optimized}.so -%{dynload_dir}/_queue.%{SOABI_optimized}.so -%{dynload_dir}/_random.%{SOABI_optimized}.so -%{dynload_dir}/_socket.%{SOABI_optimized}.so -%{dynload_dir}/_sqlite3.%{SOABI_optimized}.so -%{dynload_dir}/_ssl.%{SOABI_optimized}.so -%{dynload_dir}/_statistics.%{SOABI_optimized}.so -%{dynload_dir}/_struct.%{SOABI_optimized}.so -%{dynload_dir}/array.%{SOABI_optimized}.so -%{dynload_dir}/binascii.%{SOABI_optimized}.so -%{dynload_dir}/cmath.%{SOABI_optimized}.so -%{dynload_dir}/_datetime.%{SOABI_optimized}.so -%{dynload_dir}/fcntl.%{SOABI_optimized}.so -%{dynload_dir}/grp.%{SOABI_optimized}.so -%{dynload_dir}/math.%{SOABI_optimized}.so -%{dynload_dir}/mmap.%{SOABI_optimized}.so -%{dynload_dir}/_posixshmem.%{SOABI_optimized}.so -%{dynload_dir}/pyexpat.%{SOABI_optimized}.so -%{dynload_dir}/readline.%{SOABI_optimized}.so -%{dynload_dir}/resource.%{SOABI_optimized}.so -%{dynload_dir}/select.%{SOABI_optimized}.so -%{dynload_dir}/syslog.%{SOABI_optimized}.so -%{dynload_dir}/termios.%{SOABI_optimized}.so -%{dynload_dir}/unicodedata.%{SOABI_optimized}.so -%{dynload_dir}/_uuid.%{SOABI_optimized}.so -%{dynload_dir}/xxlimited.%{SOABI_optimized}.so -%{dynload_dir}/xxlimited_35.%{SOABI_optimized}.so -%{dynload_dir}/_xxsubinterpreters.%{SOABI_optimized}.so -%{dynload_dir}/xxsubtype.%{SOABI_optimized}.so -%{dynload_dir}/zlib.%{SOABI_optimized}.so -%{dynload_dir}/_zoneinfo.%{SOABI_optimized}.so - -%dir %{pylibdir}/site-packages/ -%dir %{pylibdir}/site-packages/__pycache__/ -%{pylibdir}/site-packages/README.txt +# This will be in the tkinter package +%exclude %{pylibdir}/turtle.py +%exclude %{pylibdir}/__pycache__/turtle*%{bytecode_suffixes} +# This will be in the debug package %if %{with debug_build} %exclude %{pylibdir}/_sysconfigdata_%{ABIFLAGS_debug}_linux_%{platform_triplet}.py %exclude %{pylibdir}/__pycache__/_sysconfigdata_%{ABIFLAGS_debug}_linux_%{platform_triplet}%{bytecode_suffixes} %endif -%{pylibdir}/*.py -%dir %{pylibdir}/__pycache__/ -%{pylibdir}/__pycache__/*%{bytecode_suffixes} +# Extension modules +# This is macronized for reuse in the -debug package +%define extension_modules() \ +%{1}/_asyncio.%{2}.so\ +%{1}/_bisect.%{2}.so\ +%{1}/_blake2.%{2}.so\ +%{1}/_bz2.%{2}.so\ +%{1}/_codecs_cn.%{2}.so\ +%{1}/_codecs_hk.%{2}.so\ +%{1}/_codecs_iso2022.%{2}.so\ +%{1}/_codecs_jp.%{2}.so\ +%{1}/_codecs_kr.%{2}.so\ +%{1}/_codecs_tw.%{2}.so\ +%{1}/_contextvars.%{2}.so\ +%{1}/_csv.%{2}.so\ +%{1}/_ctypes.%{2}.so\ +%{1}/_curses.%{2}.so\ +%{1}/_curses_panel.%{2}.so\ +%if !(0%{?fedora} && 0%{?fedora} < 42)\ +%{1}/_datetime.%{2}.so\ +%endif\ +%{1}/_dbm.%{2}.so\ +%{1}/_gdbm.%{2}.so\ +%{1}/_decimal.%{2}.so\ +%{1}/_elementtree.%{2}.so\ +%{1}/_hashlib.%{2}.so\ +%{1}/_heapq.%{2}.so\ +%{1}/_interpchannels.%{2}.so\ +%{1}/_interpqueues.%{2}.so\ +%{1}/_interpreters.%{2}.so\ +%{1}/_json.%{2}.so\ +%{1}/_lsprof.%{2}.so\ +%{1}/_lzma.%{2}.so\ +%{1}/_md5.%{2}.so\ +%{1}/_multibytecodec.%{2}.so\ +%{1}/_multiprocessing.%{2}.so\ +%{1}/_opcode.%{2}.so\ +%{1}/_pickle.%{2}.so\ +%{1}/_posixshmem.%{2}.so\ +%{1}/_posixsubprocess.%{2}.so\ +%{1}/_queue.%{2}.so\ +%{1}/_random.%{2}.so\ +%{1}/_sha1.%{2}.so\ +%{1}/_sha2.%{2}.so\ +%{1}/_sha3.%{2}.so\ +%{1}/_socket.%{2}.so\ +%{1}/_sqlite3.%{2}.so\ +%{1}/_ssl.%{2}.so\ +%{1}/_statistics.%{2}.so\ +%{1}/_struct.%{2}.so\ +%{1}/_uuid.%{2}.so\ +%{1}/_zoneinfo.%{2}.so\ +%{1}/array.%{2}.so\ +%{1}/binascii.%{2}.so\ +%{1}/cmath.%{2}.so\ +%{1}/fcntl.%{2}.so\ +%{1}/grp.%{2}.so\ +%{1}/math.%{2}.so\ +%{1}/mmap.%{2}.so\ +%{1}/pyexpat.%{2}.so\ +%{1}/readline.%{2}.so\ +%{1}/resource.%{2}.so\ +%{1}/select.%{2}.so\ +%{1}/syslog.%{2}.so\ +%{1}/termios.%{2}.so\ +%{1}/unicodedata.%{2}.so\ +%{1}/zlib.%{2}.so -%dir %{pylibdir}/collections/ -%dir %{pylibdir}/collections/__pycache__/ -%{pylibdir}/collections/*.py -%{pylibdir}/collections/__pycache__/*%{bytecode_suffixes} +%extension_modules %{dynload_dir} %{SOABI_optimized} -%dir %{pylibdir}/ctypes/ -%dir %{pylibdir}/ctypes/__pycache__/ -%{pylibdir}/ctypes/*.py -%{pylibdir}/ctypes/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/ctypes/macholib - -%{pylibdir}/curses - -%dir %{pylibdir}/dbm/ -%dir %{pylibdir}/dbm/__pycache__/ -%{pylibdir}/dbm/*.py -%{pylibdir}/dbm/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/email/ -%dir %{pylibdir}/email/__pycache__/ -%{pylibdir}/email/*.py -%{pylibdir}/email/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/email/mime -%doc %{pylibdir}/email/architecture.rst - -%{pylibdir}/encodings - -%{pylibdir}/html -%{pylibdir}/http - -%dir %{pylibdir}/importlib/ -%dir %{pylibdir}/importlib/__pycache__/ -%{pylibdir}/importlib/*.py -%{pylibdir}/importlib/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/importlib/metadata/ -%dir %{pylibdir}/importlib/metadata/__pycache__/ -%{pylibdir}/importlib/metadata/*.py -%{pylibdir}/importlib/metadata/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/importlib/resources/ -%dir %{pylibdir}/importlib/resources/__pycache__/ -%{pylibdir}/importlib/resources/*.py -%{pylibdir}/importlib/resources/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/json/ -%dir %{pylibdir}/json/__pycache__/ -%{pylibdir}/json/*.py -%{pylibdir}/json/__pycache__/*%{bytecode_suffixes} - -%{pylibdir}/logging -%{pylibdir}/multiprocessing - -%dir %{pylibdir}/re/ -%{pylibdir}/re/*.py -%{pylibdir}/re/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/sqlite3/ -%dir %{pylibdir}/sqlite3/__pycache__/ -%{pylibdir}/sqlite3/*.py -%{pylibdir}/sqlite3/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/tomllib/ -%{pylibdir}/tomllib/*.py -%{pylibdir}/tomllib/__pycache__/*%{bytecode_suffixes} -%exclude %{pylibdir}/turtle.py -%exclude %{pylibdir}/__pycache__/turtle*%{bytecode_suffixes} - -%{pylibdir}/urllib -%{pylibdir}/xml - -%dir %{pylibdir}/zipfile/ -%{pylibdir}/zipfile/*.py -%{pylibdir}/zipfile/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/zipfile/_path/*.py -%{pylibdir}/zipfile/_path/__pycache__/*%{bytecode_suffixes} - -%{pylibdir}/zoneinfo - -%dir %{pylibdir}/__phello__ -%{pylibdir}/__phello__/__init__.py -%{pylibdir}/__phello__/spam.py -%{pylibdir}/__phello__/__pycache__/*%{bytecode_suffixes} +%dir %{pylibdir}/site-packages/ +%dir %{pylibdir}/site-packages/__pycache__/ +%{pylibdir}/site-packages/README.txt %if "%{_lib}" == "lib64" -%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever} -%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}/site-packages +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}/ +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}/site-packages/ %attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}/site-packages/__pycache__/ %endif @@ -1419,6 +1592,7 @@ CheckPython optimized %dir %{_includedir}/python%{LDVERSION_optimized}/ %{_includedir}/python%{LDVERSION_optimized}/%{_pyconfig_h} +# Finally, libpython %{_libdir}/%{py_INSTSONAME_optimized} %if %{with main_python} %{_libdir}/libpython3.so @@ -1487,25 +1661,38 @@ CheckPython optimized %files -n %{pkgname}-test -%{pylibdir}/test -%{dynload_dir}/_ctypes_test.%{SOABI_optimized}.so -%{dynload_dir}/_testbuffer.%{SOABI_optimized}.so -%{dynload_dir}/_testcapi.%{SOABI_optimized}.so -%{dynload_dir}/_testclinic.%{SOABI_optimized}.so -%{dynload_dir}/_testclinic_limited.%{SOABI_optimized}.so -%{dynload_dir}/_testimportmultiple.%{SOABI_optimized}.so -%{dynload_dir}/_testinternalcapi.%{SOABI_optimized}.so -%{dynload_dir}/_testmultiphase.%{SOABI_optimized}.so -%{dynload_dir}/_testsinglephase.%{SOABI_optimized}.so -%{dynload_dir}/_xxinterpchannels.%{SOABI_optimized}.so -%{dynload_dir}/_xxtestfuzz.%{SOABI_optimized}.so +%{pylibdir}/test/ + +# Pure Python modules +%{pylibdir}/__phello__/ + +# Extension modules +# This is macronized for reuse in the -debug package +%define extension_modules_test() \ +%{1}/_ctypes_test.%{2}.so\ +%{1}/_testbuffer.%{2}.so\ +%{1}/_testcapi.%{2}.so\ +%{1}/_testclinic.%{2}.so\ +%{1}/_testclinic_limited.%{2}.so\ +%{1}/_testexternalinspection.%{2}.so\ +%{1}/_testimportmultiple.%{2}.so\ +%{1}/_testinternalcapi.%{2}.so\ +%{1}/_testlimitedcapi.%{2}.so\ +%{1}/_testmultiphase.%{2}.so\ +%{1}/_testsinglephase.%{2}.so\ +%{1}/_xxtestfuzz.%{2}.so\ +%{1}/xxlimited.%{2}.so\ +%{1}/xxlimited_35.%{2}.so\ +%{1}/xxsubtype.%{2}.so + +%extension_modules_test %{dynload_dir} %{SOABI_optimized} + # We don't bother splitting the debug build out into further subpackages: -# if you need it, you're probably a developer. +# if you need it, you're debugging and you probably don't mind having it all. # Hence the manifest is the combination of analogous files in the manifests of # all of the other subpackages - %if %{with debug_build} %files -n %{pkgname}-debug %if %{with main_python} @@ -1516,117 +1703,100 @@ CheckPython optimized # Analog of the core subpackage's files: %{_bindir}/python%{LDVERSION_debug} -# Analog of the -libs subpackage's files: -# ...with debug builds of the built-in "extension" modules: - -%{dynload_dir}/_blake2.%{SOABI_debug}.so -%{dynload_dir}/_md5.%{SOABI_debug}.so -%{dynload_dir}/_sha1.%{SOABI_debug}.so -%{dynload_dir}/_sha2.%{SOABI_debug}.so -%{dynload_dir}/_sha3.%{SOABI_debug}.so - -%{dynload_dir}/_asyncio.%{SOABI_debug}.so -%{dynload_dir}/_bisect.%{SOABI_debug}.so -%{dynload_dir}/_bz2.%{SOABI_debug}.so -%{dynload_dir}/_codecs_cn.%{SOABI_debug}.so -%{dynload_dir}/_codecs_hk.%{SOABI_debug}.so -%{dynload_dir}/_codecs_iso2022.%{SOABI_debug}.so -%{dynload_dir}/_codecs_jp.%{SOABI_debug}.so -%{dynload_dir}/_codecs_kr.%{SOABI_debug}.so -%{dynload_dir}/_codecs_tw.%{SOABI_debug}.so -%{dynload_dir}/_contextvars.%{SOABI_debug}.so -%{dynload_dir}/_csv.%{SOABI_debug}.so -%{dynload_dir}/_ctypes.%{SOABI_debug}.so -%{dynload_dir}/_curses.%{SOABI_debug}.so -%{dynload_dir}/_curses_panel.%{SOABI_debug}.so -%{dynload_dir}/_dbm.%{SOABI_debug}.so -%{dynload_dir}/_decimal.%{SOABI_debug}.so -%{dynload_dir}/_elementtree.%{SOABI_debug}.so -%if %{with gdbm} -%{dynload_dir}/_gdbm.%{SOABI_debug}.so -%endif -%{dynload_dir}/_hashlib.%{SOABI_debug}.so -%{dynload_dir}/_heapq.%{SOABI_debug}.so -%{dynload_dir}/_json.%{SOABI_debug}.so -%{dynload_dir}/_lsprof.%{SOABI_debug}.so -%{dynload_dir}/_lzma.%{SOABI_debug}.so -%{dynload_dir}/_multibytecodec.%{SOABI_debug}.so -%{dynload_dir}/_multiprocessing.%{SOABI_debug}.so -%{dynload_dir}/_opcode.%{SOABI_debug}.so -%{dynload_dir}/_pickle.%{SOABI_debug}.so -%{dynload_dir}/_posixsubprocess.%{SOABI_debug}.so -%{dynload_dir}/_queue.%{SOABI_debug}.so -%{dynload_dir}/_random.%{SOABI_debug}.so -%{dynload_dir}/_socket.%{SOABI_debug}.so -%{dynload_dir}/_sqlite3.%{SOABI_debug}.so -%{dynload_dir}/_ssl.%{SOABI_debug}.so -%{dynload_dir}/_statistics.%{SOABI_debug}.so -%{dynload_dir}/_struct.%{SOABI_debug}.so -%{dynload_dir}/array.%{SOABI_debug}.so -%{dynload_dir}/binascii.%{SOABI_debug}.so -%{dynload_dir}/cmath.%{SOABI_debug}.so -%{dynload_dir}/_datetime.%{SOABI_debug}.so -%{dynload_dir}/fcntl.%{SOABI_debug}.so -%{dynload_dir}/grp.%{SOABI_debug}.so -%{dynload_dir}/math.%{SOABI_debug}.so -%{dynload_dir}/mmap.%{SOABI_debug}.so -%{dynload_dir}/_posixshmem.%{SOABI_debug}.so -%{dynload_dir}/pyexpat.%{SOABI_debug}.so -%{dynload_dir}/readline.%{SOABI_debug}.so -%{dynload_dir}/resource.%{SOABI_debug}.so -%{dynload_dir}/select.%{SOABI_debug}.so -%{dynload_dir}/syslog.%{SOABI_debug}.so -%{dynload_dir}/termios.%{SOABI_debug}.so -%{dynload_dir}/unicodedata.%{SOABI_debug}.so -%{dynload_dir}/_uuid.%{SOABI_debug}.so -%{dynload_dir}/xxlimited.%{SOABI_debug}.so -%{dynload_dir}/xxlimited_35.%{SOABI_debug}.so -%{dynload_dir}/_xxsubinterpreters.%{SOABI_debug}.so -%{dynload_dir}/xxsubtype.%{SOABI_debug}.so -%{dynload_dir}/zlib.%{SOABI_debug}.so -%{dynload_dir}/_zoneinfo.%{SOABI_debug}.so - -# No need to split things out the "Makefile" and the config-32/64.h file as we -# do for the regular build above (bug 531901), since they're all in one package -# now; they're listed below, under "-devel": - +# Analog to the -libs subpackage's files: %{_libdir}/%{py_INSTSONAME_debug} +# Analog of the libs, test, and tkinter extension modules: +%extension_modules %{dynload_dir} %{SOABI_debug} +%extension_modules_test %{dynload_dir} %{SOABI_debug} +%{dynload_dir}/_tkinter.%{SOABI_debug}.so + # Analog of the -devel subpackage's files: -%{pylibdir}/config-%{LDVERSION_debug}-%{platform_triplet} -%{_includedir}/python%{LDVERSION_debug} +%{pylibdir}/config-%{LDVERSION_debug}-%{platform_triplet}/ +%{_includedir}/python%{LDVERSION_debug}/ %{_bindir}/python%{LDVERSION_debug}-config %{_bindir}/python%{LDVERSION_debug}-*-config %{_libdir}/libpython%{LDVERSION_debug}.so -%{_libdir}/libpython%{LDVERSION_debug}.so.%{py_SOVERSION} %{_libdir}/pkgconfig/python-%{LDVERSION_debug}.pc %{_libdir}/pkgconfig/python-%{LDVERSION_debug}-embed.pc -# Analog of the -tools subpackage's files: -# None for now; we could build precanned versions that have the appropriate -# shebang if needed - -# Analog of the tkinter subpackage's files: -%{dynload_dir}/_tkinter.%{SOABI_debug}.so - -# Analog of the -test subpackage's files: -%{dynload_dir}/_ctypes_test.%{SOABI_debug}.so -%{dynload_dir}/_testbuffer.%{SOABI_debug}.so -%{dynload_dir}/_testcapi.%{SOABI_debug}.so -%{dynload_dir}/_testclinic.%{SOABI_debug}.so -%{dynload_dir}/_testclinic_limited.%{SOABI_debug}.so -%{dynload_dir}/_testimportmultiple.%{SOABI_debug}.so -%{dynload_dir}/_testinternalcapi.%{SOABI_debug}.so -%{dynload_dir}/_testmultiphase.%{SOABI_debug}.so -%{dynload_dir}/_testsinglephase.%{SOABI_debug}.so -%{dynload_dir}/_xxinterpchannels.%{SOABI_debug}.so -%{dynload_dir}/_xxtestfuzz.%{SOABI_debug}.so - %{pylibdir}/_sysconfigdata_%{ABIFLAGS_debug}_linux_%{platform_triplet}.py %{pylibdir}/__pycache__/_sysconfigdata_%{ABIFLAGS_debug}_linux_%{platform_triplet}%{bytecode_suffixes} %endif # with debug_build +%if %{with freethreading_build} +%files -n python%{pybasever}-freethreading +%dir %{pylibdir_freethreading} +%dir %{dynload_dir_freethreading} + +%license %{pylibdir_freethreading}/LICENSE.txt +%doc %{pylibdir_freethreading}/site-packages/README.txt + +# Pure Python modules +%pure_python_modules %{pylibdir_freethreading} + +# Modules that we separate from python3-libs, but want to ship in -freethreading +%{pylibdir_freethreading}/__phello__/ +%{pylibdir_freethreading}/idlelib/ +%{pylibdir_freethreading}/test/ +%{pylibdir_freethreading}/tkinter/ +%{pylibdir_freethreading}/turtledemo/ + +# This will be in the -freethreading-debug package +%if %{with debug_build} +%exclude %{pylibdir_freethreading}/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}.py +%exclude %{pylibdir_freethreading}/__pycache__/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}%{bytecode_suffixes} +%endif + +# Analog of the core subpackage's files: +%{_bindir}/python%{LDVERSION_freethreading} + +# Analog to the -libs subpackage's files: +%{_libdir}/%{py_INSTSONAME_freethreading} + +%extension_modules %{dynload_dir_freethreading} %{SOABI_freethreading} +%extension_modules_test %{dynload_dir_freethreading} %{SOABI_freethreading} +%{dynload_dir_freethreading}/_tkinter.%{SOABI_freethreading}.so + +# Analog of the -devel subpackage's files: +%{pylibdir_freethreading}/config-%{LDVERSION_freethreading}-%{platform_triplet}/ +%{_includedir}/python%{LDVERSION_freethreading}/ +%{_bindir}/python%{LDVERSION_freethreading}-config +%{_bindir}/python%{LDVERSION_freethreading}-*-config +%{_libdir}/libpython%{LDVERSION_freethreading}.so +%{_libdir}/pkgconfig/python-%{LDVERSION_freethreading}.pc +%{_libdir}/pkgconfig/python-%{LDVERSION_freethreading}-embed.pc + +%endif # with freethreading_build + +%if %{with freethreading_build} && %{with debug_build} +%files -n python%{pybasever}-freethreading-debug +# Analog of the core subpackage's files: +%{_bindir}/python%{LDVERSION_freethreading_debug} + +# Analog to the -libs subpackage's files: +%{_libdir}/%{py_INSTSONAME_freethreading_debug} + +# Analog of the libs, test, and tkinter extension modules: +%extension_modules %{dynload_dir_freethreading} %{SOABI_freethreading_debug} +%extension_modules_test %{dynload_dir_freethreading} %{SOABI_freethreading_debug} +%{dynload_dir_freethreading}/_tkinter.%{SOABI_freethreading_debug}.so + +# Analog of the -devel subpackage's files: +%{pylibdir_freethreading}/config-%{LDVERSION_freethreading_debug}-%{platform_triplet}/ +%{_includedir}/python%{LDVERSION_freethreading_debug}/ +%{_bindir}/python%{LDVERSION_freethreading_debug}-config +%{_bindir}/python%{LDVERSION_freethreading_debug}-*-config +%{_libdir}/libpython%{LDVERSION_freethreading_debug}.so +%{_libdir}/pkgconfig/python-%{LDVERSION_freethreading_debug}.pc +%{_libdir}/pkgconfig/python-%{LDVERSION_freethreading_debug}-embed.pc + +%{pylibdir_freethreading}/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}.py +%{pylibdir_freethreading}/__pycache__/_sysconfigdata_%{ABIFLAGS_freethreading_debug}_linux_%{platform_triplet}%{bytecode_suffixes} + +%endif # with freethreading_build && debug_build + # We put the debug-gdb.py file inside /usr/lib/debug to avoid noise from ldconfig # See https://bugzilla.redhat.com/show_bug.cgi?id=562980 # @@ -1648,6 +1818,215 @@ CheckPython optimized # ====================================================== %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 + +* Thu Jul 16 2026 Fedora Release Engineering - 3.13.14-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild + +* Thu Jun 11 2026 Karolina Surma - 3.13.14-1 +- Update to Python 3.13.14 + +* Wed Apr 08 2026 Tomáš Hrnčiar - 3.13.13-1 +- Update to 3.13.13 + +* Thu Mar 26 2026 Lumír Balhar - 3.13.12-2 +- Security fix for CVE-2026-4519 (rhbz#2449729) + +* Wed Feb 04 2026 Tomáš Hrnčiar - 3.13.12-1 +- Update to 3.13.12 + +* Sat Jan 17 2026 Fedora Release Engineering - 3.13.11-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + +* Tue Jan 06 2026 Karolina Surma - 3.13.11-2 +- Require at least the same expat version as used during the build time + +* Fri Dec 05 2025 Miro Hrončok - 3.13.11-1 +- Update to 3.13.11 + +* Wed Dec 03 2025 Tomáš Hrnčiar - 3.13.10-1 +- Update to 3.13.10 + +* Tue Oct 14 2025 Miro Hrončok - 3.13.9-1 +- Update to Python 3.13.9 + +* Tue Oct 07 2025 Karolina Surma - 3.13.8-1 +- Update to Python 3.13.8 + +* Thu Aug 14 2025 Miro Hrončok - 3.13.7-1 +- Update to 3.13.7 + +* Thu Aug 07 2025 Tomáš Hrnčiar - 3.13.5-5 +- Update to 3.13.6 + +* Mon Jul 28 2025 Miro Hrončok - 3.13.5-4 +- Fix CVE-2025-8194: Tarfile infinite loop during parsing with negative member offset + +* Fri Jul 25 2025 Fedora Release Engineering - 3.13.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Wed Jun 25 2025 Karolina Surma - 3.13.5-2 +- Conditionally skip tests not working with the older expat version + +* Thu Jun 12 2025 Miro Hrončok - 3.13.5-1 +- Update to 3.13.5 + +* Thu Jun 12 2025 Charalampos Stratakis - 3.13.4-2 +- Enable PAC and BTI hardware protections for aarch64 + +* Wed Jun 04 2025 Tomáš Hrnčiar - 3.13.4-1 +- Update to 3.13.4 + +* Mon Jun 02 2025 Python Maint - 3.13.3-4 +- Rebuilt as non-main Python on Fedora 43 + +* Tue May 06 2025 Miro Hrončok - 3.13.3-3 +- Drop requirement on python-wheel-wheel with setuptools >= 71 + +* Tue Apr 22 2025 Charalampos Stratakis - 3.13.3-2 +- Apply Intel's CET for mitigation against control-flow hijacking attacks + +* Wed Apr 09 2025 Tomáš Hrnčiar - 3.13.3-1 +- Update to 3.13.1 + +* Thu Feb 06 2025 Miro Hrončok - 3.13.2-2 +- Rebuilt with mpdecimal 4.0.0 + +* Tue Feb 04 2025 Charalampos Stratakis - 3.13.2-1 +- Update to 3.13.2 +- Security fix for CVE-2025-0938 +- Fixes: rhbz#2343274 + +* Wed Jan 29 2025 Miro Hrončok - 3.13.1-4 +- On Fedora 41 or older, statically build the _datetime module into libpython +- This fixes a segfault when importing it from Python 3.13.0 updated to 3.13.1+ while running +- Fixes: rhbz#2333852 + +* Sat Jan 18 2025 Fedora Release Engineering - 3.13.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Mon Dec 09 2024 Miro Hrončok - 3.13.1-2 +- Security fix for CVE-2024-12254 +- Fixes: rhbz#2330927 + +* Tue Dec 03 2024 Charalampos Stratakis - 3.13.1-1 +- Update to 3.13.1 +- Security fix for CVE-2024-9287 +- Fixes: rhbz#2321657 + +* Tue Oct 08 2024 Karolina Surma - 3.13.0-1 +- Update to Python 3.13.0 + +* Tue Oct 01 2024 Miro Hrončok - 3.13.0~rc3-1 +- Update to Python 3.13.0rc3 + +* Thu Sep 19 2024 Miro Hrončok - 3.13.0~rc2-3 +- Fix segfault when trying to use PyRun_SimpleString() with some imports + +* Wed Sep 18 2024 Miro Hrončok - 3.13.0~rc2-2 +- Handle an empty AST body when reporting tracebacks +- Fixes: rhbz#2311907 + +* Sat Sep 07 2024 Karolina Surma - 3.13.0~rc2-1 +- Update to Python 3.13.0rc2 + +* Fri Aug 23 2024 Charalampos Stratakis - 3.13.0~rc1-3 +- Security fix for CVE-2024-8088 +- Fixes: rhbz#2307462 + +* Tue Aug 06 2024 Miro Hrončok - 3.13.0~rc1-2 +- Fix SystemError in PyEval_GetLocals() +- Fixes: rhbz#2303107 +- Security fix for CVE-2024-6923 +- Fixes: rhbz#2303160 + +* Thu Aug 01 2024 Karolina Surma - 3.13.0~rc1-1 +- Update to Python 3.13.0rc1 + +* Tue Jul 30 2024 Miro Hrončok - 3.13.0~b4-3 +- Preserve AST nodes for f-string with single-element format specifiers +- Fixes https://github.com/python/cpython/issues/122300 + +* Tue Jul 23 2024 Miro Hrončok - 3.13.0~b4-2 +- Explicitly BuildRequire systemtap-sdt-devel + https://fedoraproject.org/wiki/Changes/Separate_dtrace_package + +* Fri Jul 19 2024 Miro Hrončok - 3.13.0~b4-1 +- Update to Python 3.13.0b4 + +* Fri Jul 19 2024 Fedora Release Engineering - 3.13.0~b3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Tue Jul 02 2024 Miro Hrončok - 3.13.0~b3-2 +- Fix a bug that emptied the command history of the Python REPL (~/.python_history) + +* Fri Jun 28 2024 Karolina Surma - 3.13.0~b3-1 +- Update to Python 3.13.0b3 + +* Tue Jun 18 2024 Miro Hrončok - 3.13.0~b2-4 +- On Fedora 40+ x86_64 and aarch64, build Python with the experimental JIT compiler +- To enable it on runtime, set the PYTHON_JIT environment variable to 1 +- https://peps.python.org/pep-0744/ + +* Thu Jun 06 2024 Python Maint - 3.13.0~b2-3 +- Rebuilt for Python 3.13 + +* Thu Jun 06 2024 Python Maint - 3.13.0~b2-2 +- Bootstrap for Python 3.13 + +* Wed Jun 05 2024 Miro Hrončok - 3.13.0~b2-1 +- Update to Python 3.13.0b2 + +* Thu May 09 2024 Karolina Surma - 3.13.0~b1-1 +- Update to Python 3.13.0b1 + +* Mon May 06 2024 Miro Hrončok - 3.13.0~a6-3 +- Build Python with -O3 +- https://fedoraproject.org/wiki/Changes/Python_built_with_gcc_O3 + +* Wed Apr 17 2024 Miro Hrončok - 3.13.0~a6-2 +- Require expat >= 2.6 to prevent errors when creating venvs with older expat + +* Wed Apr 10 2024 Karolina Surma - 3.13.0~a6-1 +- Update to Python 3.13.0a6 + +* Wed Mar 13 2024 Python Maint - 3.13.0~a5-2 +- Move all test modules to the python3.13-test package, namely: + - __phello__ + - _xxinterpqueues + - _xxsubinterpreters + - xxlimited + - xxlimited_35 + - xxsubtype +- Remove internal usage of @LIBPYTHON@ + +* Wed Mar 13 2024 Miro Hrončok - 3.13.0~a5-1 +- Update to Python 3.13.0a5 + +* Wed Feb 21 2024 Karolina Surma - 3.13.0~a4-2 +- Fix crash involving exhausted list iterator + +* Fri Feb 16 2024 Karolina Surma - 3.13.0~a4-1 +- Update to Python 3.13.0a4 + +* Fri Jan 26 2024 Fedora Release Engineering - 3.13.0~a3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Miro Hrončok - 3.13.0~a3-2 +- Enable python3.13-freethreading and python3.13-freethreading-debug on ppc64le + +* Thu Jan 18 2024 Karolina Surma - 3.13.0~a3-1 +- Update to Python 3.13.0a3 + +* Tue Dec 05 2023 Miro Hrončok - 3.13.0~a2-2 +- Add the python3.13-freethreading and python3.13-freethreading-debug packages +- See https://peps.python.org/pep-0703/ +- ppc64le and s390x are excluded for now, support is expected in 3.13.0a3 + * Fri Nov 24 2023 Karolina Surma - 3.13.0~a2-1 - Update to Python 3.13.0a2 diff --git a/rpminspect.yaml b/rpminspect.yaml index 83dfb5e..8cc18cb 100644 --- a/rpminspect.yaml +++ b/rpminspect.yaml @@ -1,22 +1,22 @@ # exclude test XML data (not always valid) from XML validity check: xml: ignore: - - /usr/lib*/python*/test/xmltestdata/* - - /usr/lib*/python*/test/xmltestdata/*/* + - '/usr/lib*/python*/test/xmltestdata/*' + - '/usr/lib*/python*/test/xmltestdata/*/*' # exclude _socket from ipv4 only functions check, it has both ipv4 and ipv6 only badfuncs: allowed: - /usr/lib*/python*/lib-dynload/_socket.*: + '/usr/lib*/python*/lib-dynload/_socket.*': - inet_aton - inet_ntoa # exclude the debug build from annocheck entirely annocheck: ignore: - - /usr/bin/python*d - - /usr/lib*/libpython*d.so.1.0 - - /usr/lib*/python*/lib-dynload/*.cpython-*d-*-*-*.so + - '/usr/bin/python*d' + - '/usr/lib*/libpython*d.so.1.0' + - '/usr/lib*/python*/lib-dynload/*.cpython-*d-*-*-*.so' # don't report changed content of compiled files # that is expected with every toolchain update and not reproducible yet diff --git a/rpmlint.toml b/rpmlint.toml index b532441..0864a1c 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -6,7 +6,7 @@ Filters = [ # TESTS: - '(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3\.\d+/test', + '(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3\.\d+t?/test', # OTHER DELIBERATES: @@ -14,7 +14,7 @@ Filters = [ 'missing-call-to-chdir-with-chroot', # gethostbyname function calls gethostbyname - '(E|W): binary-or-shlib-calls-gethostbyname /usr/lib(64)?/python3\.\d+/lib-dynload/_socket\.', + '(E|W): binary-or-shlib-calls-gethostbyname /usr/lib(64)?/python3\.\d+t?/lib-dynload/_socket\.', # intentionally unversioned and selfobsoleted 'unversioned-explicit-obsoletes python', @@ -28,18 +28,18 @@ Filters = [ 'only-non-binary-in-usr-lib', # some devel files that are deliberately needed - 'devel-file-in-non-devel-package /usr/include/python3\.\d+m?/pyconfig-(32|64)\.h', - 'devel-file-in-non-devel-package /usr/lib(64)?/python3\.\d+/distutils/tests/xxmodule\.c', + 'devel-file-in-non-devel-package /usr/include/python3\.\d+m?t?/pyconfig-(32|64)\.h', + 'devel-file-in-non-devel-package /usr/lib(64)?/python3\.\d+t?/distutils/tests/xxmodule\.c', # ...or are used as test data - 'devel-file-in-non-devel-package /usr/lib(64)?/python3\.\d+/test', + 'devel-file-in-non-devel-package /usr/lib(64)?/python3\.\d+t?/test', # some bytecode is shipped without sources on purpose, as a space optimization # if this regex needs to be relaxed in the future, make sure it **does not** match pyc files in __pycache__ - 'python-bytecode-without-source /usr/lib(64)?/python3\.\d+/(encodings|pydoc_data)/[^/]+.pyc', + 'python-bytecode-without-source /usr/lib(64)?/python3\.\d+t?/(encodings|pydoc_data)/[^/]+.pyc', # DUPLICATE FILES # test data are often duplicated - '(E|W): files-duplicate /usr/lib(64)?/python3\.\d+/(test|__phello__)/', + '(E|W): files-duplicate /usr/lib(64)?/python3\.\d+t?/(test|__phello__)/', # duplicated inits or mains are also common '(E|W): files-duplicate .+__init__\.py.+__init__\.py', '(E|W): files-duplicate .+__main__\.py.+__main__\.py', @@ -52,10 +52,10 @@ Filters = [ # manual pages 'no-manual-page-for-binary (idle|pydoc|pyvenv|2to3|python3?-debug|pathfix|msgfmt|pygettext)', 'no-manual-page-for-binary python3?.*-config$', - 'no-manual-page-for-binary python3\.\d+dm?$', + 'no-manual-page-for-binary python3\.\d+t?dm?$', # missing documentation from subpackages - '^python3(\.\d+)?-(debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation', + '^python3(\.\d+)?-(freethreading(-debug)?|debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation', # platform python is obsoleted, but not provided 'obsolete-not-provided platform-python', @@ -77,13 +77,13 @@ Filters = [ # this is OK for F28+ 'library-without-ldconfig-post', - # debug package contains devel and non-devel files - 'python3(\.\d+)?-debug\.[^:]+: (E|W): (non-)?devel-file-in-(non-)?devel-package', + # freethreading/debug package contains devel and non-devel files + 'python3(\.\d+)?-(freethreading(-debug)?|debug)\.[^:]+: (E|W): (non-)?devel-file-in-(non-)?devel-package', # this goes to other subpackage, hence not actually dangling 'dangling-relative-symlink /usr/bin/python python3', 'dangling-relative-symlink /usr/share/man/man1/python\.1\.gz python3\.1\.gz', - 'dangling-relative-symlink /usr/lib(64)?/pkgconfig/python-3\.\d+dm?(-embed)?\.pc python-3\.\d+(-embed)?\.pc', + 'dangling-relative-symlink /usr/lib(64)?/pkgconfig/python-3\.\d+t?d?m?(-embed)?\.pc python-3\.\d+t?(-embed)?\.pc', # the python-unversioned-command package contains dangling symlinks by design '^python-unversioned-command\.[^:]+: (E|W): dangling-relative-symlink (/usr/bin/python \./python3|/usr/share/man/man1/python\.1\S* ./python3\.1\S*)$', @@ -101,6 +101,6 @@ Filters = [ '\bpython3(\.\d+)?\.(src|spec): (E|W): specfile-error\s+$', # SPELLING ERRORS - 'spelling-error .* en_US (bytecode|pyc|filename|tkinter|namespaces|pytest) ', + 'spelling-error .* en_US (bytecode|pyc|filename|tkinter|namespaces|pytest|unittest|gil) ', ] diff --git a/sources b/sources index 15f25bf..d6a2436 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.13.0a2.tar.xz) = 2702f630ebb49a835c213656f2f0d41f87daf2dad6b856821f4011f4614c19279656eaa1dad9f1cbfd258992aa5f59d4571577057c6a4ad1cdcfa4d8ada3b607 -SHA512 (Python-3.13.0a2.tar.xz.asc) = c6a0101b844701fcd860a519ec4830bde0df486ea78377831544dbe0db25dd67c28360f46d5ef01db64aa4347cf7b0d489590f6dc91e768b16753228f2c93b25 +SHA512 (Python-3.13.15.tar.xz) = b0ab766a3de0b4cfdbf0b93300d7330c734d3f7057577bb03e95e39da4cdade81993e769c7fa6dfdcc13b9d43a3b399d9cd89b5477b413662e9e691c1b7886b8 +SHA512 (Python-3.13.15.tar.xz.asc) = 662c00be95f62e80db43cf42099fef91f764ff7a4433cadf7eb19dedb5e4775adb12878d5ed2295fcea187731de186163ad9672ab72cde62a2335ca58ec1ad86 diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 1a4f0f0..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,4 +0,0 @@ ---- -standard-inventory-qcow2: - qemu: - m: 3G # Amount of VM memory diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 4ba56aa..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -- hosts: localhost - tags: - - classic - tasks: - - dnf: - name: "*" - state: latest - -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - repositories: - - repo: "https://src.fedoraproject.org/tests/python.git" - dest: "python" - pybasever: "3.13" - tests: - - rpm_qa: - run: rpm -qa - - smoke: - dir: python/smoke - run: "VERSION={{ pybasever }} CYTHON=false ./venv.sh" - - smoke_virtualenv: - dir: python/smoke - run: "VERSION={{ pybasever }} METHOD=virtualenv CYTHON=false ./venv.sh" - - debugsmoke: - dir: python/smoke - run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh" - - selftest: - dir: python/selftest - run: "VERSION={{ pybasever }} X='-i test_check_probes' ./parallel.sh" - - debugtest: - dir: python/selftest - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes' ./parallel.sh" - - debugflags: - dir: python/flags - run: "python{{ pybasever }}d ./assertflags.py -O0" - - marshalparser: - dir: python/marshalparser - run: "VERSION={{ pybasever }} SAMPLE=10 test_marshalparser_compatibility.sh" - required_packages: - - gcc # for extension building in venv and selftest - - gcc-c++ # for test_cppext - - gdb # for test_gdb - - "python{{ pybasever }}" # the test subject - - "python{{ pybasever }}-debug" # for leak testing - - "python{{ pybasever }}-devel" # for extension building in venv and selftest - - "python{{ pybasever }}-tkinter" # for selftest - - "python{{ pybasever }}-test" # for selftest - - tox # for venv tests - - virtualenv # for virtualenv tests - - glibc-all-langpacks # for locale tests - - marshalparser # for testing compatibility (magic numbers) with marshalparser - - rpm # for debugging