@@ -111,6 +111,7 @@ static const PyConfigSpec PYCONFIG_SPEC[] = {
111111 SPEC (base_prefix , WSTR_OPT , PUBLIC , SYS_ATTR ("base_prefix" )),
112112 SPEC (bytes_warning , UINT , PUBLIC , SYS_FLAG (9 )),
113113 SPEC (cpu_count , INT , PUBLIC , NO_SYS ),
114+ SPEC (lazy_imports , INT , PUBLIC , NO_SYS ),
114115 SPEC (exec_prefix , WSTR_OPT , PUBLIC , SYS_ATTR ("exec_prefix" )),
115116 SPEC (executable , WSTR_OPT , PUBLIC , SYS_ATTR ("executable" )),
116117 SPEC (inspect , BOOL , PUBLIC , SYS_FLAG (1 )),
@@ -317,6 +318,8 @@ The following implementation-specific options are available:\n\
317318"\
318319- X importtime [= 2 ]: show how long each import takes ; use - X importtime = 2 to \n \
319320 log imports of already - loaded modules ; also PYTHONPROFILEIMPORTTIME \n \
321+ - X lazy_imports = [on |off |default ]: control global lazy imports ; default is auto;\n \
322+ also PYTHON_LAZY_IMPORTS \n \
320323- X int_max_str_digits = N : limit the size of int < -> str conversions ;\n \
321324 0 disables the limit ; also PYTHONINTMAXSTRDIGITS \n \
322325- X no_debug_ranges : don 't include extra location information in code objects;\n\
@@ -431,6 +434,7 @@ static const char usage_envvars[] =
431434"PYTHON_PRESITE: import this module before site (-X presite)\n"
432435#endif
433436"PYTHONPROFILEIMPORTTIME: show how long each import takes (-X importtime)\n"
437+ "PYTHON_LAZY_IMPORTS: control global lazy imports (-X lazy_imports)\n"
434438"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files\n"
435439" (-X pycache_prefix)\n"
436440"PYTHONSAFEPATH : don't prepend a potentially unsafe path to sys.path.\n"
@@ -939,6 +943,8 @@ config_check_consistency(const PyConfig *config)
939943 assert (config -> int_max_str_digits >= 0 );
940944 // cpu_count can be -1 if the user doesn't override it.
941945 assert (config -> cpu_count != 0 );
946+ // lazy_imports can be -1 (default), 0 (off), or 1 (on).
947+ assert (config -> lazy_imports >= -1 && config -> lazy_imports <= 1 );
942948 // config->use_frozen_modules is initialized later
943949 // by _PyConfig_InitImportConfig().
944950 assert (config -> thread_inherit_context >= 0 );
@@ -1050,6 +1056,7 @@ _PyConfig_InitCompatConfig(PyConfig *config)
10501056 config -> _is_python_build = 0 ;
10511057 config -> code_debug_ranges = 1 ;
10521058 config -> cpu_count = -1 ;
1059+ config -> lazy_imports = -1 ;
10531060#ifdef Py_GIL_DISABLED
10541061 config -> thread_inherit_context = 1 ;
10551062 config -> context_aware_warnings = 1 ;
@@ -2284,6 +2291,49 @@ config_init_import_time(PyConfig *config)
22842291 return _PyStatus_OK ();
22852292}
22862293
2294+ static PyStatus
2295+ config_init_lazy_imports (PyConfig * config )
2296+ {
2297+ int lazy_imports = -1 ;
2298+
2299+ const char * env = config_get_env (config , "PYTHON_LAZY_IMPORTS" );
2300+ if (env ) {
2301+ if (strcmp (env , "on" ) == 0 ) {
2302+ lazy_imports = 1 ;
2303+ }
2304+ else if (strcmp (env , "off" ) == 0 ) {
2305+ lazy_imports = 0 ;
2306+ }
2307+ else if (strcmp (env , "default" ) == 0 ) {
2308+ lazy_imports = -1 ;
2309+ }
2310+ else {
2311+ return _PyStatus_ERR ("PYTHON_LAZY_IMPORTS: invalid value; "
2312+ "expected 'on', 'off', or 'default'" );
2313+ }
2314+ config -> lazy_imports = lazy_imports ;
2315+ }
2316+
2317+ const wchar_t * x_value = config_get_xoption_value (config , L"lazy_imports" );
2318+ if (x_value ) {
2319+ if (wcscmp (x_value , L"on" ) == 0 ) {
2320+ lazy_imports = 1 ;
2321+ }
2322+ else if (wcscmp (x_value , L"off" ) == 0 ) {
2323+ lazy_imports = 0 ;
2324+ }
2325+ else if (wcscmp (x_value , L"default" ) == 0 ) {
2326+ lazy_imports = -1 ;
2327+ }
2328+ else {
2329+ return _PyStatus_ERR ("-X lazy_imports: invalid value; "
2330+ "expected 'on', 'off', or 'default'" );
2331+ }
2332+ config -> lazy_imports = lazy_imports ;
2333+ }
2334+ return _PyStatus_OK ();
2335+ }
2336+
22872337static PyStatus
22882338config_read_complex_options (PyConfig * config )
22892339{
@@ -2307,6 +2357,13 @@ config_read_complex_options(PyConfig *config)
23072357 }
23082358 }
23092359
2360+ if (config -> lazy_imports < 0 ) {
2361+ status = config_init_lazy_imports (config );
2362+ if (_PyStatus_EXCEPTION (status )) {
2363+ return status ;
2364+ }
2365+ }
2366+
23102367 if (config -> tracemalloc < 0 ) {
23112368 status = config_init_tracemalloc (config );
23122369 if (_PyStatus_EXCEPTION (status )) {
@@ -2696,6 +2753,9 @@ config_read(PyConfig *config, int compute_path_config)
26962753 if (config -> tracemalloc < 0 ) {
26972754 config -> tracemalloc = 0 ;
26982755 }
2756+ if (config -> lazy_imports < 0 ) {
2757+ config -> lazy_imports = -1 ; // Default is auto/unset
2758+ }
26992759 if (config -> perf_profiling < 0 ) {
27002760 config -> perf_profiling = 0 ;
27012761 }
0 commit comments