2021-01-19 22:04:49 +00:00
|
|
|
# This script lists the names of standard library modules
|
2021-01-25 22:12:50 +00:00
|
|
|
# to update Python/stdlib_mod_names.h
|
2021-01-19 22:04:49 +00:00
|
|
|
import os.path
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import sysconfig
|
|
|
|
|
|
|
|
|
|
|
|
SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
|
|
|
STDLIB_PATH = os.path.join(SRC_DIR, 'Lib')
|
|
|
|
MODULES_SETUP = os.path.join(SRC_DIR, 'Modules', 'Setup')
|
|
|
|
SETUP_PY = os.path.join(SRC_DIR, 'setup.py')
|
|
|
|
|
|
|
|
IGNORE = {
|
|
|
|
'__init__',
|
|
|
|
'__pycache__',
|
|
|
|
'site-packages',
|
|
|
|
|
|
|
|
# test modules
|
|
|
|
'__phello__.foo',
|
|
|
|
'_ctypes_test',
|
|
|
|
'_testbuffer',
|
|
|
|
'_testcapi',
|
|
|
|
'_testconsole',
|
|
|
|
'_testimportmultiple',
|
|
|
|
'_testinternalcapi',
|
|
|
|
'_testmultiphase',
|
|
|
|
'_xxtestfuzz',
|
|
|
|
'distutils.tests',
|
|
|
|
'idlelib.idle_test',
|
|
|
|
'lib2to3.tests',
|
|
|
|
'test',
|
|
|
|
'xxlimited',
|
|
|
|
'xxlimited_35',
|
|
|
|
'xxsubtype',
|
|
|
|
}
|
|
|
|
|
|
|
|
# Windows extension modules
|
|
|
|
WINDOWS_MODULES = (
|
|
|
|
'_msi',
|
|
|
|
'_testconsole',
|
|
|
|
'_winapi',
|
|
|
|
'msvcrt',
|
|
|
|
'nt',
|
|
|
|
'winreg',
|
|
|
|
'winsound'
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Pure Python modules (Lib/*.py)
|
2021-01-25 12:24:42 +00:00
|
|
|
def list_python_modules(names):
|
2021-01-19 22:04:49 +00:00
|
|
|
for filename in os.listdir(STDLIB_PATH):
|
|
|
|
if not filename.endswith(".py"):
|
|
|
|
continue
|
|
|
|
name = filename.removesuffix(".py")
|
2021-01-25 12:24:42 +00:00
|
|
|
names.add(name)
|
2021-01-19 22:04:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _list_sub_packages(path, names, parent=None):
|
|
|
|
for name in os.listdir(path):
|
|
|
|
if name in IGNORE:
|
|
|
|
continue
|
2021-01-25 12:24:42 +00:00
|
|
|
package_path = os.path.join(path, name)
|
2021-01-19 22:04:49 +00:00
|
|
|
if not os.path.isdir(package_path):
|
|
|
|
continue
|
|
|
|
if not any(package_file.endswith(".py")
|
|
|
|
for package_file in os.listdir(package_path)):
|
|
|
|
continue
|
|
|
|
if parent:
|
|
|
|
qualname = f"{parent}.{name}"
|
|
|
|
else:
|
|
|
|
qualname = name
|
|
|
|
if qualname in IGNORE:
|
|
|
|
continue
|
2021-01-25 12:24:42 +00:00
|
|
|
names.add(qualname)
|
2021-01-19 22:04:49 +00:00
|
|
|
_list_sub_packages(package_path, names, qualname)
|
|
|
|
|
|
|
|
|
|
|
|
# Packages and sub-packages
|
2021-01-25 12:24:42 +00:00
|
|
|
def list_packages(names):
|
2021-01-19 22:04:49 +00:00
|
|
|
_list_sub_packages(STDLIB_PATH, names)
|
|
|
|
|
|
|
|
|
|
|
|
# Extension modules built by setup.py
|
2021-01-25 12:24:42 +00:00
|
|
|
def list_setup_extensions(names):
|
2021-01-19 22:04:49 +00:00
|
|
|
cmd = [sys.executable, SETUP_PY, "-q", "build", "--list-module-names"]
|
|
|
|
output = subprocess.check_output(cmd)
|
|
|
|
output = output.decode("utf8")
|
2021-01-25 12:24:42 +00:00
|
|
|
extensions = output.splitlines()
|
|
|
|
names |= set(extensions)
|
2021-01-19 22:04:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Built-in and extension modules built by Modules/Setup
|
2021-01-25 12:24:42 +00:00
|
|
|
def list_modules_setup_extensions(names):
|
2021-01-19 22:04:49 +00:00
|
|
|
assign_var = re.compile("^[A-Z]+=")
|
|
|
|
|
|
|
|
with open(MODULES_SETUP, encoding="utf-8") as modules_fp:
|
|
|
|
for line in modules_fp:
|
|
|
|
# Strip comment
|
|
|
|
line = line.partition("#")[0]
|
|
|
|
line = line.rstrip()
|
|
|
|
if not line:
|
|
|
|
continue
|
|
|
|
if assign_var.match(line):
|
|
|
|
# Ignore "VAR=VALUE"
|
|
|
|
continue
|
|
|
|
if line in ("*disabled*", "*shared*"):
|
|
|
|
continue
|
|
|
|
parts = line.split()
|
|
|
|
if len(parts) < 2:
|
|
|
|
continue
|
|
|
|
# "errno errnomodule.c" => write "errno"
|
|
|
|
name = parts[0]
|
2021-01-25 12:24:42 +00:00
|
|
|
names.add(name)
|
2021-01-19 22:04:49 +00:00
|
|
|
|
2021-01-25 12:24:42 +00:00
|
|
|
|
|
|
|
def list_modules():
|
|
|
|
names = set(sys.builtin_module_names) | set(WINDOWS_MODULES)
|
|
|
|
list_modules_setup_extensions(names)
|
|
|
|
list_setup_extensions(names)
|
|
|
|
list_packages(names)
|
|
|
|
list_python_modules(names)
|
|
|
|
names -= set(IGNORE)
|
|
|
|
return names
|
2021-01-19 22:04:49 +00:00
|
|
|
|
|
|
|
|
2021-01-25 12:24:42 +00:00
|
|
|
def write_modules(fp, names):
|
2021-01-25 22:12:50 +00:00
|
|
|
print("// Auto-generated by Tools/scripts/generate_stdlib_module_names.py.",
|
|
|
|
file=fp)
|
|
|
|
print("// List used to create sys.stdlib_module_names.", file=fp)
|
2021-01-19 22:04:49 +00:00
|
|
|
print(file=fp)
|
2021-01-25 22:12:50 +00:00
|
|
|
print("static const char* _Py_stdlib_module_names[] = {", file=fp)
|
2021-01-25 12:24:42 +00:00
|
|
|
for name in sorted(names):
|
|
|
|
print(f'"{name}",', file=fp)
|
2021-01-19 22:04:49 +00: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 12:24:42 +00:00
|
|
|
fp = sys.stdout
|
|
|
|
names = list_modules()
|
|
|
|
write_modules(fp, names)
|
2021-01-19 22:04:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|