2021-01-19 18:04:49 -04:00
|
|
|
# This script lists the names of standard library modules
|
2023-04-28 20:17:58 -03:00
|
|
|
# to update Python/stdlib_module_names.h
|
2021-12-27 22:05:50 -04:00
|
|
|
import _imp
|
2021-01-19 18:04:49 -04:00
|
|
|
import os.path
|
|
|
|
import sys
|
|
|
|
import sysconfig
|
|
|
|
|
2022-07-05 04:25:45 -03:00
|
|
|
from check_extension_modules import ModuleChecker
|
|
|
|
|
2021-01-19 18:04:49 -04:00
|
|
|
|
2022-10-17 07:01:00 -03:00
|
|
|
SCRIPT_NAME = 'Tools/build/generate_stdlib_module_names.py'
|
|
|
|
|
2021-01-19 18:04:49 -04:00
|
|
|
SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
|
|
|
STDLIB_PATH = os.path.join(SRC_DIR, 'Lib')
|
|
|
|
|
|
|
|
IGNORE = {
|
|
|
|
'__init__',
|
|
|
|
'__pycache__',
|
|
|
|
'site-packages',
|
|
|
|
|
2021-03-10 06:14:07 -04:00
|
|
|
# Test modules and packages
|
|
|
|
'__hello__',
|
|
|
|
'__phello__',
|
2021-09-30 21:38:52 -03:00
|
|
|
'__hello_alias__',
|
|
|
|
'__phello_alias__',
|
|
|
|
'__hello_only__',
|
2021-01-19 18:04:49 -04:00
|
|
|
'_ctypes_test',
|
|
|
|
'_testbuffer',
|
|
|
|
'_testcapi',
|
2022-11-21 10:08:45 -04:00
|
|
|
'_testclinic',
|
2023-08-25 18:22:08 -03:00
|
|
|
'_testclinic_limited',
|
2021-01-19 18:04:49 -04:00
|
|
|
'_testconsole',
|
|
|
|
'_testimportmultiple',
|
|
|
|
'_testinternalcapi',
|
2024-03-07 14:31:12 -04:00
|
|
|
'_testlimitedcapi',
|
2021-01-19 18:04:49 -04:00
|
|
|
'_testmultiphase',
|
2022-11-08 12:58:11 -04:00
|
|
|
'_testsinglephase',
|
2024-02-28 06:17:34 -04:00
|
|
|
'_testexternalinspection',
|
2021-03-10 07:10:01 -04:00
|
|
|
'_xxsubinterpreters',
|
2023-02-03 21:14:43 -04:00
|
|
|
'_xxinterpchannels',
|
2023-12-12 13:43:30 -04:00
|
|
|
'_xxinterpqueues',
|
2021-01-19 18:04:49 -04:00
|
|
|
'_xxtestfuzz',
|
|
|
|
'idlelib.idle_test',
|
|
|
|
'test',
|
|
|
|
'xxlimited',
|
|
|
|
'xxlimited_35',
|
|
|
|
'xxsubtype',
|
|
|
|
}
|
|
|
|
|
2023-06-20 05:12:44 -03:00
|
|
|
ALLOW_TEST_MODULES = {
|
|
|
|
'doctest',
|
|
|
|
'unittest',
|
|
|
|
}
|
|
|
|
|
|
|
|
# Built-in modules
|
|
|
|
def list_builtin_modules(names):
|
|
|
|
names |= set(sys.builtin_module_names)
|
|
|
|
|
|
|
|
|
2021-01-19 18:04:49 -04:00
|
|
|
# Pure Python modules (Lib/*.py)
|
2021-01-25 08:24:42 -04:00
|
|
|
def list_python_modules(names):
|
2021-01-19 18:04:49 -04:00
|
|
|
for filename in os.listdir(STDLIB_PATH):
|
|
|
|
if not filename.endswith(".py"):
|
|
|
|
continue
|
|
|
|
name = filename.removesuffix(".py")
|
2021-01-25 08:24:42 -04:00
|
|
|
names.add(name)
|
2021-01-19 18:04:49 -04:00
|
|
|
|
|
|
|
|
2021-01-27 19:03:23 -04:00
|
|
|
# Packages in Lib/
|
|
|
|
def list_packages(names):
|
|
|
|
for name in os.listdir(STDLIB_PATH):
|
2021-01-19 18:04:49 -04:00
|
|
|
if name in IGNORE:
|
|
|
|
continue
|
2021-01-27 19:03:23 -04:00
|
|
|
package_path = os.path.join(STDLIB_PATH, name)
|
2021-01-19 18:04:49 -04:00
|
|
|
if not os.path.isdir(package_path):
|
|
|
|
continue
|
2021-01-27 19:03:23 -04:00
|
|
|
if any(package_file.endswith(".py")
|
|
|
|
for package_file in os.listdir(package_path)):
|
|
|
|
names.add(name)
|
2021-01-19 18:04:49 -04:00
|
|
|
|
|
|
|
|
2022-07-05 04:25:45 -03:00
|
|
|
# Built-in and extension modules built by Modules/Setup*
|
|
|
|
# includes Windows and macOS extensions.
|
2021-01-25 08:24:42 -04:00
|
|
|
def list_modules_setup_extensions(names):
|
2022-07-05 04:25:45 -03:00
|
|
|
checker = ModuleChecker()
|
|
|
|
names.update(checker.list_module_names(all=True))
|
2021-01-19 18:04:49 -04:00
|
|
|
|
2021-01-25 08:24:42 -04:00
|
|
|
|
2021-03-10 06:14:07 -04:00
|
|
|
# List frozen modules of the PyImport_FrozenModules list (Python/frozen.c).
|
|
|
|
# Use the "./Programs/_testembed list_frozen" command.
|
|
|
|
def list_frozen(names):
|
2021-09-13 19:18:37 -03:00
|
|
|
submodules = set()
|
2021-12-27 22:05:50 -04:00
|
|
|
for name in _imp._frozen_module_names():
|
|
|
|
# To skip __hello__, __hello_alias__ and etc.
|
|
|
|
if name.startswith('__'):
|
|
|
|
continue
|
2021-09-13 19:18:37 -03:00
|
|
|
if '.' in name:
|
|
|
|
submodules.add(name)
|
|
|
|
else:
|
|
|
|
names.add(name)
|
|
|
|
# Make sure all frozen submodules have a known parent.
|
|
|
|
for name in list(submodules):
|
|
|
|
if name.partition('.')[0] in names:
|
|
|
|
submodules.remove(name)
|
|
|
|
if submodules:
|
|
|
|
raise Exception(f'unexpected frozen submodules: {sorted(submodules)}')
|
2021-03-10 06:14:07 -04:00
|
|
|
|
|
|
|
|
2021-01-25 08:24:42 -04:00
|
|
|
def list_modules():
|
2023-06-20 05:12:44 -03:00
|
|
|
names = set()
|
|
|
|
|
|
|
|
list_builtin_modules(names)
|
2021-01-25 08:24:42 -04:00
|
|
|
list_modules_setup_extensions(names)
|
|
|
|
list_packages(names)
|
|
|
|
list_python_modules(names)
|
2021-03-10 06:14:07 -04:00
|
|
|
list_frozen(names)
|
|
|
|
|
|
|
|
# Remove ignored packages and modules
|
|
|
|
for name in list(names):
|
|
|
|
package_name = name.split('.')[0]
|
|
|
|
# package_name can be equal to name
|
|
|
|
if package_name in IGNORE:
|
|
|
|
names.discard(name)
|
|
|
|
|
2023-06-20 05:12:44 -03:00
|
|
|
# Sanity checks
|
2021-03-10 06:14:07 -04:00
|
|
|
for name in names:
|
|
|
|
if "." in name:
|
2023-06-20 05:12:44 -03:00
|
|
|
raise Exception(f"sub-modules must not be listed: {name}")
|
|
|
|
if ("test" in name or "xx" in name) and name not in ALLOW_TEST_MODULES:
|
|
|
|
raise Exception(f"test modules must not be listed: {name}")
|
2021-03-10 06:14:07 -04:00
|
|
|
|
2021-01-25 08:24:42 -04:00
|
|
|
return names
|
2021-01-19 18:04:49 -04:00
|
|
|
|
|
|
|
|
2021-01-25 08:24:42 -04:00
|
|
|
def write_modules(fp, names):
|
2022-10-17 07:01:00 -03:00
|
|
|
print(f"// Auto-generated by {SCRIPT_NAME}.",
|
2021-01-25 18:12:50 -04:00
|
|
|
file=fp)
|
|
|
|
print("// List used to create sys.stdlib_module_names.", file=fp)
|
2021-01-19 18:04:49 -04:00
|
|
|
print(file=fp)
|
2021-01-25 18:12:50 -04:00
|
|
|
print("static const char* _Py_stdlib_module_names[] = {", file=fp)
|
2021-01-25 08:24:42 -04:00
|
|
|
for name in sorted(names):
|
|
|
|
print(f'"{name}",', file=fp)
|
2021-01-19 18:04:49 -04:00
|
|
|
print("};", file=fp)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
if not sysconfig.is_python_build():
|
|
|
|
print(f"ERROR: {sys.executable} is not a Python build",
|
|
|
|
file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
|
2021-01-25 08:24:42 -04:00
|
|
|
fp = sys.stdout
|
|
|
|
names = list_modules()
|
|
|
|
write_modules(fp, names)
|
2021-01-19 18:04:49 -04:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|