@skip_segfault_on_android
def test_dump_ext_modules(self):
+ # Don't filter stdlib module names: disable sys.stdlib_module_names
code = """
import faulthandler
import sys
- # Don't filter stdlib module names
+ import math
sys.stdlib_module_names = frozenset()
faulthandler.enable()
faulthandler._sigsegv()
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)
+ self.assertNotIn('Extension modules:', stderr)
+
def test_is_enabled(self):
orig_stderr = sys.stderr
try:
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 sub-modules of stdlib packages. For example,
+ // 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) {