From 1445a8d4d6df3a216519f358ad3163c72f7fe02c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Jan 2026 13:12:22 +0100 Subject: [PATCH] gh-140824: Fix _Py_DumpExtensionModules() to ignore sub-modules Ignore "math.integer" extension if "math" is in sys.stdlib_module_names. --- Lib/test/test_faulthandler.py | 17 +++++++++++++- ...-01-30-13-23-06.gh-issue-140824.J1OCrC.rst | 3 +++ Python/pylifecycle.c | 23 +++++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 874f52af857b94..9d6a787d2bec27 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -388,9 +388,11 @@ def test_disable(self): @skip_segfault_on_android def test_dump_ext_modules(self): + # Disable sys.stdlib_module_names code = """ import faulthandler import sys + import math # Don't filter stdlib module names sys.stdlib_module_names = frozenset() faulthandler.enable() @@ -403,9 +405,22 @@ def test_dump_ext_modules(self): if not match: self.fail(f"Cannot find 'Extension modules:' in {stderr!r}") modules = set(match.group(1).strip().split(', ')) - for name in ('sys', 'faulthandler'): + for name in ('sys', 'faulthandler', 'math'): self.assertIn(name, modules) + # Ignore "math.integer" sub-module if "math" package is + # in sys.stdlib_module_names + code = """ + import faulthandler + import math.integer + faulthandler.enable() + faulthandler._sigsegv() + """ + stderr, exitcode = self.get_output(code) + stderr = '\n'.join(stderr) + match = re.search(r'^Extension modules:', stderr, re.MULTILINE) + self.assertIsNone(match) + def test_is_enabled(self): orig_stderr = sys.stderr try: diff --git a/Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst b/Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst new file mode 100644 index 00000000000000..43c696f6609c5f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst @@ -0,0 +1,3 @@ +When :mod:`faulthandler` dumps the list of third-party extension modules, +ignore ``math.integer`` sub-module since ``math`` package is part of +:data:`sys.stdlib_module_names`. Patch by Victor Stinner. diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index d3ed08de1d15d3..70a74acea07207 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -3393,11 +3393,24 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) Py_hash_t hash; // if stdlib_module_names is not NULL, it is always a frozenset. while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) { - if (PyUnicode_Check(item) - && PyUnicode_Compare(key, item) == 0) - { - is_stdlib_ext = 1; - break; + if (!PyUnicode_Check(item)) { + continue; + } + Py_ssize_t len = PyUnicode_GET_LENGTH(item); + if (PyUnicode_Tailmatch(key, item, 0, len, -1) == 1) { + Py_ssize_t key_len = PyUnicode_GET_LENGTH(key); + if (key_len == len) { + is_stdlib_ext = 1; + break; + } + assert(key_len > len); + + // Ignore "math.integer" if key starts with "math." + Py_UCS4 ch = PyUnicode_ReadChar(key, len); + if (ch == '.') { + is_stdlib_ext = 1; + break; + } } } if (is_stdlib_ext) {