Skip to content

Commit 307745a

Browse files
authored
bpo-43445: Add frozen modules to sys.stdlib_module_names (GH-24798)
Add frozen modules to sys.stdlib_module_names. For example, add "_frozen_importlib" and "_frozen_importlib_external" names. Add "list_frozen" command to Programs/_testembed.
1 parent b4f9089 commit 307745a

File tree

5 files changed

+53
-4
lines changed

5 files changed

+53
-4
lines changed

Makefile.pre.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ regen-keyword:
913913
$(UPDATE_FILE) $(srcdir)/Lib/keyword.py $(srcdir)/Lib/keyword.py.new
914914

915915
.PHONY: regen-stdlib-module-names
916-
regen-stdlib-module-names: build_all
916+
regen-stdlib-module-names: build_all Programs/_testembed
917917
# Regenerate Python/stdlib_module_names.h
918918
# using Tools/scripts/generate_stdlib_module_names.py
919919
$(RUNSHARED) ./$(BUILDPYTHON) \
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add frozen modules to :data:`sys.stdlib_module_names`. For example, add
2+
``"_frozen_importlib"`` and ``"_frozen_importlib_external"`` names.

Programs/_testembed.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,20 @@ static int test_unicode_id_init(void)
17211721
}
17221722

17231723

1724+
// List frozen modules.
1725+
// Command used by Tools/scripts/generate_stdlib_module_names.py script.
1726+
static int list_frozen(void)
1727+
{
1728+
const struct _frozen *p;
1729+
for (p = PyImport_FrozenModules; ; p++) {
1730+
if (p->name == NULL)
1731+
break;
1732+
printf("%s\n", p->name);
1733+
}
1734+
return 0;
1735+
}
1736+
1737+
17241738

17251739
/* *********************************************************
17261740
* List of test cases and the function that implements it.
@@ -1792,6 +1806,8 @@ static struct TestCase TestCases[] = {
17921806
{"test_audit_run_stdin", test_audit_run_stdin},
17931807

17941808
{"test_unicode_id_init", test_unicode_id_init},
1809+
1810+
{"list_frozen", list_frozen},
17951811
{NULL, NULL}
17961812
};
17971813

Python/stdlib_module_names.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ static const char* _Py_stdlib_module_names[] = {
3232
"_dbm",
3333
"_decimal",
3434
"_elementtree",
35+
"_frozen_importlib",
36+
"_frozen_importlib_external",
3537
"_functools",
3638
"_gdbm",
3739
"_hashlib",

Tools/scripts/generate_stdlib_module_names.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@
1111
STDLIB_PATH = os.path.join(SRC_DIR, 'Lib')
1212
MODULES_SETUP = os.path.join(SRC_DIR, 'Modules', 'Setup')
1313
SETUP_PY = os.path.join(SRC_DIR, 'setup.py')
14+
TEST_EMBED = os.path.join(SRC_DIR, 'Programs', '_testembed')
1415

1516
IGNORE = {
1617
'__init__',
1718
'__pycache__',
1819
'site-packages',
1920

20-
# test modules
21-
'__phello__.foo',
21+
# Test modules and packages
22+
'__hello__',
23+
'__phello__',
2224
'_ctypes_test',
2325
'_testbuffer',
2426
'_testcapi',
@@ -103,13 +105,40 @@ def list_modules_setup_extensions(names):
103105
names.add(name)
104106

105107

108+
# List frozen modules of the PyImport_FrozenModules list (Python/frozen.c).
109+
# Use the "./Programs/_testembed list_frozen" command.
110+
def list_frozen(names):
111+
args = [TEST_EMBED, 'list_frozen']
112+
proc = subprocess.run(args, stdout=subprocess.PIPE, text=True)
113+
exitcode = proc.returncode
114+
if exitcode:
115+
cmd = ' '.join(args)
116+
print(f"{cmd} failed with exitcode {exitcode}")
117+
sys.exit(exitcode)
118+
for line in proc.stdout.splitlines():
119+
name = line.strip()
120+
names.add(name)
121+
122+
106123
def list_modules():
107124
names = set(sys.builtin_module_names) | set(WINDOWS_MODULES)
108125
list_modules_setup_extensions(names)
109126
list_setup_extensions(names)
110127
list_packages(names)
111128
list_python_modules(names)
112-
names -= set(IGNORE)
129+
list_frozen(names)
130+
131+
# Remove ignored packages and modules
132+
for name in list(names):
133+
package_name = name.split('.')[0]
134+
# package_name can be equal to name
135+
if package_name in IGNORE:
136+
names.discard(name)
137+
138+
for name in names:
139+
if "." in name:
140+
raise Exception("sub-modules must not be listed")
141+
113142
return names
114143

115144

0 commit comments

Comments
 (0)