| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | # This script lists the names of standard library modules | 
					
						
							| 
									
										
										
										
											2023-04-28 16:17:58 -07:00
										 |  |  | # to update Python/stdlib_module_names.h | 
					
						
							| 
									
										
										
										
											2021-12-28 11:05:50 +09:00
										 |  |  | import _imp | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | import os.path | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import sysconfig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 09:25:45 +02:00
										 |  |  | from check_extension_modules import ModuleChecker | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-17 12:01:00 +02:00
										 |  |  | SCRIPT_NAME = 'Tools/build/generate_stdlib_module_names.py' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01: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 11:14:07 +01:00
										 |  |  |     # Test modules and packages | 
					
						
							|  |  |  |     '__hello__', | 
					
						
							|  |  |  |     '__phello__', | 
					
						
							| 
									
										
										
										
											2021-09-30 18:38:52 -06:00
										 |  |  |     '__hello_alias__', | 
					
						
							|  |  |  |     '__phello_alias__', | 
					
						
							|  |  |  |     '__hello_only__', | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |     '_ctypes_test', | 
					
						
							|  |  |  |     '_testbuffer', | 
					
						
							|  |  |  |     '_testcapi', | 
					
						
							| 
									
										
										
										
											2022-11-21 22:08:45 +08:00
										 |  |  |     '_testclinic', | 
					
						
							| 
									
										
										
										
											2023-08-25 23:22:08 +02:00
										 |  |  |     '_testclinic_limited', | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |     '_testconsole', | 
					
						
							|  |  |  |     '_testimportmultiple', | 
					
						
							|  |  |  |     '_testinternalcapi', | 
					
						
							| 
									
										
										
										
											2024-03-07 19:31:12 +01:00
										 |  |  |     '_testlimitedcapi', | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |     '_testmultiphase', | 
					
						
							| 
									
										
										
										
											2022-11-08 09:58:11 -07:00
										 |  |  |     '_testsinglephase', | 
					
						
							| 
									
										
										
										
											2024-02-28 10:17:34 +00:00
										 |  |  |     '_testexternalinspection', | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |     '_xxtestfuzz', | 
					
						
							|  |  |  |     'idlelib.idle_test', | 
					
						
							|  |  |  |     'test', | 
					
						
							|  |  |  |     'xxlimited', | 
					
						
							|  |  |  |     'xxlimited_35', | 
					
						
							|  |  |  |     'xxsubtype', | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 10:12:44 +02:00
										 |  |  | ALLOW_TEST_MODULES = { | 
					
						
							|  |  |  |     'doctest', | 
					
						
							|  |  |  |     'unittest', | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Built-in modules | 
					
						
							|  |  |  | def list_builtin_modules(names): | 
					
						
							|  |  |  |     names |= set(sys.builtin_module_names) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | # Pure Python modules (Lib/*.py) | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  | def list_python_modules(names): | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |     for filename in os.listdir(STDLIB_PATH): | 
					
						
							|  |  |  |         if not filename.endswith(".py"): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         name = filename.removesuffix(".py") | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |         names.add(name) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-28 00:03:23 +01:00
										 |  |  | # Packages in Lib/ | 
					
						
							|  |  |  | def list_packages(names): | 
					
						
							|  |  |  |     for name in os.listdir(STDLIB_PATH): | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |         if name in IGNORE: | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-01-28 00:03:23 +01:00
										 |  |  |         package_path = os.path.join(STDLIB_PATH, name) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |         if not os.path.isdir(package_path): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-01-28 00:03:23 +01:00
										 |  |  |         if any(package_file.endswith(".py") | 
					
						
							|  |  |  |                for package_file in os.listdir(package_path)): | 
					
						
							|  |  |  |             names.add(name) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 09:25:45 +02:00
										 |  |  | # Built-in and extension modules built by Modules/Setup* | 
					
						
							|  |  |  | # includes Windows and macOS extensions. | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  | def list_modules_setup_extensions(names): | 
					
						
							| 
									
										
										
										
											2022-07-05 09:25:45 +02:00
										 |  |  |     checker = ModuleChecker() | 
					
						
							|  |  |  |     names.update(checker.list_module_names(all=True)) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-10 11:14:07 +01: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 16:18:37 -06:00
										 |  |  |     submodules = set() | 
					
						
							| 
									
										
										
										
											2021-12-28 11:05:50 +09:00
										 |  |  |     for name in _imp._frozen_module_names(): | 
					
						
							|  |  |  |         # To skip __hello__, __hello_alias__ and etc. | 
					
						
							|  |  |  |         if name.startswith('__'): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-09-13 16:18:37 -06: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 11:14:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  | def list_modules(): | 
					
						
							| 
									
										
										
										
											2023-06-20 10:12:44 +02:00
										 |  |  |     names = set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     list_builtin_modules(names) | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     list_modules_setup_extensions(names) | 
					
						
							|  |  |  |     list_packages(names) | 
					
						
							|  |  |  |     list_python_modules(names) | 
					
						
							| 
									
										
										
										
											2021-03-10 11:14:07 +01: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 10:12:44 +02:00
										 |  |  |     # Sanity checks | 
					
						
							| 
									
										
										
										
											2021-03-10 11:14:07 +01:00
										 |  |  |     for name in names: | 
					
						
							|  |  |  |         if "." in name: | 
					
						
							| 
									
										
										
										
											2023-06-20 10:12:44 +02: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 11:14:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     return names | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  | def write_modules(fp, names): | 
					
						
							| 
									
										
										
										
											2022-10-17 12:01:00 +02:00
										 |  |  |     print(f"// Auto-generated by {SCRIPT_NAME}.", | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |           file=fp) | 
					
						
							|  |  |  |     print("// List used to create sys.stdlib_module_names.", file=fp) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  |     print(file=fp) | 
					
						
							| 
									
										
										
										
											2021-01-25 23:12:50 +01:00
										 |  |  |     print("static const char* _Py_stdlib_module_names[] = {", file=fp) | 
					
						
							| 
									
										
										
										
											2021-01-25 13:24:42 +01:00
										 |  |  |     for name in sorted(names): | 
					
						
							|  |  |  |         print(f'"{name}",', file=fp) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01: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 13:24:42 +01:00
										 |  |  |     fp = sys.stdout | 
					
						
							|  |  |  |     names = list_modules() | 
					
						
							|  |  |  |     write_modules(fp, names) | 
					
						
							| 
									
										
										
										
											2021-01-19 23:04:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     main() |