Skip to content

Commit 1445a8d

Browse files
committed
gh-140824: Fix _Py_DumpExtensionModules() to ignore sub-modules
Ignore "math.integer" extension if "math" is in sys.stdlib_module_names.
1 parent 5f57f69 commit 1445a8d

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

Lib/test/test_faulthandler.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,11 @@ def test_disable(self):
388388

389389
@skip_segfault_on_android
390390
def test_dump_ext_modules(self):
391+
# Disable sys.stdlib_module_names
391392
code = """
392393
import faulthandler
393394
import sys
395+
import math
394396
# Don't filter stdlib module names
395397
sys.stdlib_module_names = frozenset()
396398
faulthandler.enable()
@@ -403,9 +405,22 @@ def test_dump_ext_modules(self):
403405
if not match:
404406
self.fail(f"Cannot find 'Extension modules:' in {stderr!r}")
405407
modules = set(match.group(1).strip().split(', '))
406-
for name in ('sys', 'faulthandler'):
408+
for name in ('sys', 'faulthandler', 'math'):
407409
self.assertIn(name, modules)
408410

411+
# Ignore "math.integer" sub-module if "math" package is
412+
# in sys.stdlib_module_names
413+
code = """
414+
import faulthandler
415+
import math.integer
416+
faulthandler.enable()
417+
faulthandler._sigsegv()
418+
"""
419+
stderr, exitcode = self.get_output(code)
420+
stderr = '\n'.join(stderr)
421+
match = re.search(r'^Extension modules:', stderr, re.MULTILINE)
422+
self.assertIsNone(match)
423+
409424
def test_is_enabled(self):
410425
orig_stderr = sys.stderr
411426
try:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
When :mod:`faulthandler` dumps the list of third-party extension modules,
2+
ignore ``math.integer`` sub-module since ``math`` package is part of
3+
:data:`sys.stdlib_module_names`. Patch by Victor Stinner.

Python/pylifecycle.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,11 +3393,24 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp)
33933393
Py_hash_t hash;
33943394
// if stdlib_module_names is not NULL, it is always a frozenset.
33953395
while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) {
3396-
if (PyUnicode_Check(item)
3397-
&& PyUnicode_Compare(key, item) == 0)
3398-
{
3399-
is_stdlib_ext = 1;
3400-
break;
3396+
if (!PyUnicode_Check(item)) {
3397+
continue;
3398+
}
3399+
Py_ssize_t len = PyUnicode_GET_LENGTH(item);
3400+
if (PyUnicode_Tailmatch(key, item, 0, len, -1) == 1) {
3401+
Py_ssize_t key_len = PyUnicode_GET_LENGTH(key);
3402+
if (key_len == len) {
3403+
is_stdlib_ext = 1;
3404+
break;
3405+
}
3406+
assert(key_len > len);
3407+
3408+
// Ignore "math.integer" if key starts with "math."
3409+
Py_UCS4 ch = PyUnicode_ReadChar(key, len);
3410+
if (ch == '.') {
3411+
is_stdlib_ext = 1;
3412+
break;
3413+
}
34013414
}
34023415
}
34033416
if (is_stdlib_ext) {

0 commit comments

Comments
 (0)