Skip to content

Commit cad1f74

Browse files
authored
bpo-36142: Add _PyPreConfig structure (GH-12172)
* Add _PyPreConfig structure * Move 'ignored' and 'use_environment' fields from _PyCoreConfig to _PyPreConfig * Add a new "_PyPreConfig preconfig;" field to _PyCoreConfig
1 parent 7e9ce4c commit cad1f74

File tree

9 files changed

+193
-52
lines changed

9 files changed

+193
-52
lines changed

Include/cpython/coreconfig.h

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,35 @@ typedef struct {
4646
#define _Py_INIT_FAILED(err) \
4747
(err.msg != NULL || err.exitcode != -1)
4848

49-
/* --- _PyCoreConfig ---------------------------------------------- */
49+
/* --- _PyPreConfig ----------------------------------------------- */
5050

5151
typedef struct {
52-
/* Install signal handlers? Yes by default. */
53-
int install_signal_handlers;
52+
/* If greater than 0, enable isolated mode: sys.path contains
53+
neither the script's directory nor the user's site-packages directory.
54+
55+
Set to 1 by the -I command line option. If set to -1 (default), inherit
56+
Py_IsolatedFlag value. */
57+
int isolated;
5458

5559
/* If greater than 0: use environment variables.
5660
Set to 0 by -E command line option. If set to -1 (default), it is
5761
set to !Py_IgnoreEnvironmentFlag. */
5862
int use_environment;
63+
} _PyPreConfig;
64+
65+
#define _PyPreConfig_INIT \
66+
(_PyPreConfig){ \
67+
.isolated = -1, \
68+
.use_environment = -1}
69+
70+
71+
/* --- _PyCoreConfig ---------------------------------------------- */
72+
73+
typedef struct {
74+
_PyPreConfig preconfig;
75+
76+
/* Install signal handlers? Yes by default. */
77+
int install_signal_handlers;
5978

6079
int use_hash_seed; /* PYTHONHASHSEED=x */
6180
unsigned long hash_seed;
@@ -152,13 +171,6 @@ typedef struct {
152171
wchar_t *dll_path; /* Windows DLL path */
153172
#endif
154173

155-
/* If greater than 0, enable isolated mode: sys.path contains
156-
neither the script's directory nor the user's site-packages directory.
157-
158-
Set to 1 by the -I command line option. If set to -1 (default), inherit
159-
Py_IsolatedFlag value. */
160-
int isolated;
161-
162174
/* If equal to zero, disable the import of the module site and the
163175
site-dependent manipulations of sys.path that it entails. Also disable
164176
these manipulations if site is explicitly imported later (call
@@ -336,16 +348,15 @@ typedef struct {
336348

337349
#define _PyCoreConfig_INIT \
338350
(_PyCoreConfig){ \
351+
.preconfig = _PyPreConfig_INIT, \
339352
.install_signal_handlers = 1, \
340-
.use_environment = -1, \
341353
.use_hash_seed = -1, \
342354
.faulthandler = -1, \
343355
.tracemalloc = -1, \
344356
.coerce_c_locale = -1, \
345357
.utf8_mode = -1, \
346358
.argc = -1, \
347359
.nmodule_search_path = -1, \
348-
.isolated = -1, \
349360
.site_import = -1, \
350361
.bytes_warning = -1, \
351362
.inspect = -1, \

Include/internal/pycore_coreconfig.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ PyAPI_FUNC(_PyInitError) _PyArgv_Decode(const _PyArgv *args,
3434
PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
3535
PyAPI_FUNC(int) _Py_SetArgcArgv(int argc, wchar_t * const *argv);
3636

37+
/* --- _PyPreConfig ----------------------------------------------- */
38+
39+
PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config);
40+
PyAPI_FUNC(int) _PyPreConfig_Copy(_PyPreConfig *config,
41+
const _PyPreConfig *config2);
42+
PyAPI_FUNC(void) _PyPreConfig_GetGlobalConfig(_PyPreConfig *config);
43+
PyAPI_FUNC(void) _PyPreConfig_SetGlobalConfig(const _PyPreConfig *config);
44+
PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config);
45+
PyAPI_FUNC(int) _PyPreConfig_AsDict(const _PyPreConfig *config,
46+
PyObject *dict);
47+
48+
49+
3750
/* --- _PyCoreConfig ---------------------------------------------- */
3851

3952
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);

Modules/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ pymain_header(const _PyCoreConfig *config)
487487
static void
488488
pymain_import_readline(const _PyCoreConfig *config)
489489
{
490-
if (config->isolated) {
490+
if (config->preconfig.isolated) {
491491
return;
492492
}
493493
if (!config->inspect && RUN_CODE(config)) {
@@ -779,7 +779,7 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode)
779779
goto done;
780780
}
781781
}
782-
else if (!config->isolated) {
782+
else if (!config->preconfig.isolated) {
783783
PyObject *path0 = _PyPathConfig_ComputeArgv0(config->argc,
784784
config->argv);
785785
if (path0 == NULL) {

Programs/_freeze_importlib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ main(int argc, char *argv[])
7777
text[text_size] = '\0';
7878

7979
_PyCoreConfig config = _PyCoreConfig_INIT;
80+
config.preconfig.use_environment = 0;
8081
config.user_site_directory = 0;
8182
config.site_import = 0;
82-
config.use_environment = 0;
8383
config.program_name = L"./_freeze_importlib";
8484
/* Don't install importlib, since it could execute outdated bytecode. */
8585
config._install_importlib = 0;

Programs/_testembed.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -606,15 +606,15 @@ static int test_init_isolated(void)
606606
/* Test _PyCoreConfig.isolated=1 */
607607
_PyCoreConfig config = _PyCoreConfig_INIT;
608608

609+
Py_IsolatedFlag = 0;
610+
config.preconfig.isolated = 1;
611+
609612
/* Set coerce_c_locale and utf8_mode to not depend on the locale */
610613
config.coerce_c_locale = 0;
611614
config.utf8_mode = 0;
612615
/* Use path starting with "./" avoids a search along the PATH */
613616
config.program_name = L"./_testembed";
614617

615-
Py_IsolatedFlag = 0;
616-
config.isolated = 1;
617-
618618
test_init_env_putenvs();
619619
_PyInitError err = _Py_InitializeFromConfig(&config);
620620
if (_Py_INIT_FAILED(err)) {

Python/coreconfig.c

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv)
439439
void
440440
_PyCoreConfig_Clear(_PyCoreConfig *config)
441441
{
442+
_PyPreConfig_Clear(&config->preconfig);
443+
442444
#define CLEAR(ATTR) \
443445
do { \
444446
PyMem_RawFree(ATTR); \
@@ -488,6 +490,10 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
488490
{
489491
_PyCoreConfig_Clear(config);
490492

493+
if (_PyPreConfig_Copy(&config->preconfig, &config2->preconfig) < 0) {
494+
return -1;
495+
}
496+
491497
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
492498
#define COPY_STR_ATTR(ATTR) \
493499
do { \
@@ -519,7 +525,6 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
519525
} while (0)
520526

521527
COPY_ATTR(install_signal_handlers);
522-
COPY_ATTR(use_environment);
523528
COPY_ATTR(use_hash_seed);
524529
COPY_ATTR(hash_seed);
525530
COPY_ATTR(_install_importlib);
@@ -557,7 +562,6 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
557562
#endif
558563
COPY_WSTR_ATTR(base_exec_prefix);
559564

560-
COPY_ATTR(isolated);
561565
COPY_ATTR(site_import);
562566
COPY_ATTR(bytes_warning);
563567
COPY_ATTR(inspect);
@@ -595,9 +599,9 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
595599
const char*
596600
_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
597601
{
598-
assert(config->use_environment >= 0);
602+
assert(config->preconfig.use_environment >= 0);
599603

600-
if (!config->use_environment) {
604+
if (!config->preconfig.use_environment) {
601605
return NULL;
602606
}
603607

@@ -616,9 +620,9 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
616620
wchar_t **dest,
617621
wchar_t *wname, char *name)
618622
{
619-
assert(config->use_environment >= 0);
623+
assert(config->preconfig.use_environment >= 0);
620624

621-
if (!config->use_environment) {
625+
if (!config->preconfig.use_environment) {
622626
*dest = NULL;
623627
return 0;
624628
}
@@ -662,6 +666,8 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
662666
void
663667
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
664668
{
669+
_PyPreConfig_GetGlobalConfig(&config->preconfig);
670+
665671
#define COPY_FLAG(ATTR, VALUE) \
666672
if (config->ATTR == -1) { \
667673
config->ATTR = VALUE; \
@@ -672,7 +678,6 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
672678
}
673679

674680
COPY_FLAG(utf8_mode, Py_UTF8Mode);
675-
COPY_FLAG(isolated, Py_IsolatedFlag);
676681
COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
677682
COPY_FLAG(inspect, Py_InspectFlag);
678683
COPY_FLAG(interactive, Py_InteractiveFlag);
@@ -686,7 +691,6 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
686691
#endif
687692
COPY_FLAG(_frozen, Py_FrozenFlag);
688693

689-
COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
690694
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
691695
COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
692696
COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
@@ -701,6 +705,8 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
701705
void
702706
_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
703707
{
708+
_PyPreConfig_SetGlobalConfig(&config->preconfig);
709+
704710
#define COPY_FLAG(ATTR, VAR) \
705711
if (config->ATTR != -1) { \
706712
VAR = config->ATTR; \
@@ -711,7 +717,6 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
711717
}
712718

713719
COPY_FLAG(utf8_mode, Py_UTF8Mode);
714-
COPY_FLAG(isolated, Py_IsolatedFlag);
715720
COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
716721
COPY_FLAG(inspect, Py_InspectFlag);
717722
COPY_FLAG(interactive, Py_InteractiveFlag);
@@ -725,7 +730,6 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
725730
#endif
726731
COPY_FLAG(_frozen, Py_FrozenFlag);
727732

728-
COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
729733
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
730734
COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
731735
COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
@@ -1497,10 +1501,15 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
14971501
_PyInitError err;
14981502

14991503
_PyCoreConfig_GetGlobalConfig(config);
1500-
assert(config->use_environment >= 0);
15011504

1502-
if (config->isolated > 0) {
1503-
config->use_environment = 0;
1505+
err = _PyPreConfig_Read(&config->preconfig);
1506+
if (_Py_INIT_FAILED(err)) {
1507+
return err;
1508+
}
1509+
1510+
assert(config->preconfig.use_environment >= 0);
1511+
1512+
if (config->preconfig.isolated > 0) {
15041513
config->user_site_directory = 0;
15051514
}
15061515

@@ -1510,7 +1519,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
15101519
}
15111520
#endif
15121521

1513-
if (config->use_environment) {
1522+
if (config->preconfig.use_environment) {
15141523
err = config_read_env_vars(config);
15151524
if (_Py_INIT_FAILED(err)) {
15161525
return err;
@@ -1611,7 +1620,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
16111620
}
16121621

16131622
assert(config->coerce_c_locale >= 0);
1614-
assert(config->use_environment >= 0);
1623+
assert(config->preconfig.use_environment >= 0);
16151624
assert(config->filesystem_encoding != NULL);
16161625
assert(config->filesystem_errors != NULL);
16171626
assert(config->stdio_encoding != NULL);
@@ -1679,18 +1688,23 @@ _PyCoreConfig_Write(const _PyCoreConfig *config)
16791688
PyObject *
16801689
_PyCoreConfig_AsDict(const _PyCoreConfig *config)
16811690
{
1682-
PyObject *dict, *obj;
1691+
PyObject *dict;
16831692

16841693
dict = PyDict_New();
16851694
if (dict == NULL) {
16861695
return NULL;
16871696
}
16881697

1698+
if (_PyPreConfig_AsDict(&config->preconfig, dict) < 0) {
1699+
Py_DECREF(dict);
1700+
return NULL;
1701+
}
1702+
16891703
#define SET_ITEM(KEY, EXPR) \
16901704
do { \
1691-
obj = (EXPR); \
1705+
PyObject *obj = (EXPR); \
16921706
if (obj == NULL) { \
1693-
return NULL; \
1707+
goto fail; \
16941708
} \
16951709
int res = PyDict_SetItemString(dict, (KEY), obj); \
16961710
Py_DECREF(obj); \
@@ -1718,7 +1732,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
17181732
SET_ITEM(#OPTIONS, _Py_wstrlist_as_pylist(config->NOPTION, config->OPTIONS))
17191733

17201734
SET_ITEM_INT(install_signal_handlers);
1721-
SET_ITEM_INT(use_environment);
17221735
SET_ITEM_INT(use_hash_seed);
17231736
SET_ITEM_UINT(hash_seed);
17241737
SET_ITEM_STR(allocator);
@@ -1752,7 +1765,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
17521765
#ifdef MS_WINDOWS
17531766
SET_ITEM_WSTR(dll_path);
17541767
#endif
1755-
SET_ITEM_INT(isolated);
17561768
SET_ITEM_INT(site_import);
17571769
SET_ITEM_INT(bytes_warning);
17581770
SET_ITEM_INT(inspect);
@@ -1828,14 +1840,6 @@ cmdline_clear(_PyCmdline *cmdline)
18281840
}
18291841

18301842

1831-
static _PyInitError
1832-
cmdline_decode_argv(_PyCmdline *cmdline)
1833-
{
1834-
assert(cmdline->argv == NULL);
1835-
return _PyArgv_Decode(cmdline->args, &cmdline->argv);
1836-
}
1837-
1838-
18391843
/* --- _PyCoreConfig command line parser -------------------------- */
18401844

18411845
/* Parse the command line arguments */
@@ -1912,7 +1916,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
19121916
break;
19131917

19141918
case 'I':
1915-
config->isolated++;
1919+
config->preconfig.isolated++;
19161920
break;
19171921

19181922
/* case 'J': reserved for Jython */
@@ -1934,7 +1938,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
19341938
break;
19351939

19361940
case 'E':
1937-
config->use_environment = 0;
1941+
config->preconfig.use_environment = 0;
19381942
break;
19391943

19401944
case 't':
@@ -2272,7 +2276,7 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline)
22722276
return err;
22732277
}
22742278

2275-
if (config->use_environment) {
2279+
if (config->preconfig.use_environment) {
22762280
err = cmdline_init_env_warnoptions(cmdline, config);
22772281
if (_Py_INIT_FAILED(err)) {
22782282
return err;

Python/pathconfig.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
330330
#endif
331331

332332
if (path_config.isolated != -1) {
333-
config->isolated = path_config.isolated;
333+
config->preconfig.isolated = path_config.isolated;
334334
}
335335
if (path_config.site_import != -1) {
336336
config->site_import = path_config.site_import;

0 commit comments

Comments
 (0)