Skip to content

Commit 73de8d0

Browse files
pablogsalDinoV
authored andcommitted
Add global flag
1 parent 44a3e46 commit 73de8d0

File tree

4 files changed

+79
-1
lines changed

4 files changed

+79
-1
lines changed

Include/cpython/initconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ typedef struct PyConfig {
190190
int enable_gil;
191191
int tlbc_enabled;
192192
#endif
193+
int lazy_imports;
193194

194195
/* --- Path configuration inputs ------------ */
195196
int pathconfig_warnings;

Python/initconfig.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
22872337
static PyStatus
22882338
config_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
}

Python/pylifecycle.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,21 @@ init_interp_main(PyThreadState *tstate)
13161316
}
13171317
}
13181318

1319+
// Initialize lazy imports based on configuration
1320+
// Do this after site module is imported to avoid circular imports during startup
1321+
if (config->lazy_imports != -1) {
1322+
PyImport_LazyImportsMode lazy_mode;
1323+
if (config->lazy_imports == 1) {
1324+
lazy_mode = PyLazyImportsMode_ForcedOn;
1325+
} else {
1326+
lazy_mode = PyLazyImportsMode_ForcedOff;
1327+
}
1328+
if (PyImport_SetLazyImports(lazy_mode, NULL) < 0) {
1329+
return _PyStatus_ERR("failed to set lazy imports mode");
1330+
}
1331+
}
1332+
// If config->lazy_imports == -1, use the default mode (no change needed)
1333+
13191334
if (is_main_interp) {
13201335
#ifndef MS_WINDOWS
13211336
emit_stderr_warning_for_legacy_locale(interp->runtime);

Python/sysmodule.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3361,6 +3361,7 @@ static PyStructSequence_Field flags_fields[] = {
33613361
{"gil", "-X gil"},
33623362
{"thread_inherit_context", "-X thread_inherit_context"},
33633363
{"context_aware_warnings", "-X context_aware_warnings"},
3364+
{"lazy_imports", "-X lazy_imports"},
33643365
{0}
33653366
};
33663367

@@ -3370,7 +3371,7 @@ static PyStructSequence_Desc flags_desc = {
33703371
"sys.flags", /* name */
33713372
flags__doc__, /* doc */
33723373
flags_fields, /* fields */
3373-
18
3374+
19
33743375
};
33753376

33763377
static void
@@ -3463,6 +3464,7 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
34633464
#endif
34643465
SetFlag(config->thread_inherit_context);
34653466
SetFlag(config->context_aware_warnings);
3467+
SetFlag(config->lazy_imports);
34663468
#undef SetFlagObj
34673469
#undef SetFlag
34683470
return 0;

0 commit comments

Comments
 (0)