Skip to content

Commit a6fbc4e

Browse files
authored
bpo-36301: Add _Py_PreInitializeFromConfig() (GH-12536)
* Initialize _PyPreConfig.dev_mode to -1. * _PyPreConfig_Read(): coreconfig has the priority over preconfig. * _PyCoreConfig_Read() now calls _PyPreCmdline_Read() internally. * config_from_cmdline() now pass _PyPreCmdline to config_read(). * Add _PyPreCmdline_Copy().
1 parent f72346c commit a6fbc4e

File tree

6 files changed

+155
-24
lines changed

6 files changed

+155
-24
lines changed

Include/cpython/coreconfig.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ typedef struct {
115115
.isolated = -1, \
116116
.use_environment = -1, \
117117
.coerce_c_locale = -1, \
118-
.utf8_mode = -1}
118+
.utf8_mode = -1, \
119+
.dev_mode = -1, \
120+
.allocator = NULL}
119121

120122

121123
/* --- _PyCoreConfig ---------------------------------------------- */

Include/cpython/pylifecycle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
1717
PyAPI_FUNC(_PyInitError) _Py_PreInitialize(void);
1818
PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig(
1919
_PyPreConfig *preconfig);
20+
PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromConfig(
21+
const _PyCoreConfig *coreconfig);
2022

2123
PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
2224
PyInterpreterState **interp,

Include/internal/pycore_coreconfig.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,22 @@ typedef struct {
2525
/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
2626

2727
PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
28+
PyAPI_FUNC(int) _PyPreCmdline_Copy(_PyPreCmdline *cmdline,
29+
const _PyPreCmdline *cmdline2);
2830
PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline,
2931
const _PyArgv *args);
32+
PyAPI_FUNC(void) _PyPreCmdline_GetPreConfig(
33+
_PyPreCmdline *cmdline,
34+
const _PyPreConfig *config);
3035
PyAPI_FUNC(void) _PyPreCmdline_SetPreConfig(
3136
const _PyPreCmdline *cmdline,
3237
_PyPreConfig *config);
38+
PyAPI_FUNC(void) _PyPreCmdline_GetCoreConfig(
39+
_PyPreCmdline *cmdline,
40+
const _PyCoreConfig *config);
41+
PyAPI_FUNC(void) _PyPreCmdline_SetCoreConfig(
42+
const _PyPreCmdline *cmdline,
43+
_PyCoreConfig *config);
3344
PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline);
3445

3546

@@ -77,7 +88,8 @@ PyAPI_FUNC(void) _Py_get_env_flag(_PyPreConfig *config,
7788
int *flag,
7889
const char *name);
7990
PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config,
80-
const _PyArgv *args);
91+
const _PyArgv *args,
92+
const _PyCoreConfig *coreconfig);
8193
PyAPI_FUNC(int) _PyPreConfig_AsDict(const _PyPreConfig *config,
8294
PyObject *dict);
8395
PyAPI_FUNC(_PyInitError) _PyPreConfig_ReadFromArgv(_PyPreConfig *config,

Python/coreconfig.c

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,16 +1336,30 @@ config_init_fs_encoding(_PyCoreConfig *config)
13361336
* Py_xxx global configuration variables
13371337
13381338
See _PyCoreConfig_ReadFromArgv() to parse also command line arguments. */
1339-
_PyInitError
1340-
_PyCoreConfig_Read(_PyCoreConfig *config)
1339+
static _PyInitError
1340+
config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline)
13411341
{
13421342
_PyInitError err;
13431343

1344-
err = _Py_PreInitialize();
1344+
err = _Py_PreInitializeFromConfig(config);
1345+
if (_Py_INIT_FAILED(err)) {
1346+
return err;
1347+
}
1348+
1349+
_PyPreCmdline_GetPreConfig(cmdline, &_PyRuntime.preconfig);
1350+
_PyPreCmdline_GetCoreConfig(cmdline, config);
1351+
1352+
err = _PyPreCmdline_Read(cmdline);
13451353
if (_Py_INIT_FAILED(err)) {
13461354
return err;
13471355
}
13481356

1357+
_PyPreCmdline_SetCoreConfig(cmdline, config);
1358+
1359+
if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) {
1360+
return _Py_INIT_NO_MEMORY();
1361+
}
1362+
13491363
if (_PyPreConfig_Copy(&config->preconfig, &_PyRuntime.preconfig) < 0) {
13501364
return _Py_INIT_NO_MEMORY();
13511365
}
@@ -1454,6 +1468,41 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
14541468
}
14551469

14561470

1471+
static _PyInitError
1472+
config_read(_PyCoreConfig *config, const _PyPreCmdline *src_cmdline)
1473+
{
1474+
_PyInitError err;
1475+
1476+
err = _Py_PreInitializeFromConfig(config);
1477+
if (_Py_INIT_FAILED(err)) {
1478+
return err;
1479+
}
1480+
1481+
_PyPreCmdline cmdline = _PyPreCmdline_INIT;
1482+
1483+
if (src_cmdline) {
1484+
if (_PyPreCmdline_Copy(&cmdline, src_cmdline) < 0) {
1485+
err = _Py_INIT_NO_MEMORY();
1486+
goto done;
1487+
}
1488+
}
1489+
1490+
err = config_read_impl(config, &cmdline);
1491+
1492+
done:
1493+
_PyPreCmdline_Clear(&cmdline);
1494+
return err;
1495+
1496+
}
1497+
1498+
1499+
_PyInitError
1500+
_PyCoreConfig_Read(_PyCoreConfig *config)
1501+
{
1502+
return config_read(config, NULL);
1503+
}
1504+
1505+
14571506
static void
14581507
config_init_stdio(const _PyCoreConfig *config)
14591508
{
@@ -2025,9 +2074,6 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline)
20252074
}
20262075

20272076
_PyPreCmdline_SetPreConfig(&cmdline->precmdline, &_PyRuntime.preconfig);
2028-
if (_PyWstrList_Extend(&config->xoptions, &cmdline->precmdline.xoptions) < 0) {
2029-
return _Py_INIT_NO_MEMORY();
2030-
}
20312077

20322078
err = config_parse_cmdline(config, cmdline, &need_usage);
20332079
if (_Py_INIT_FAILED(err)) {
@@ -2055,7 +2101,7 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline)
20552101
return err;
20562102
}
20572103

2058-
err = _PyCoreConfig_Read(config);
2104+
err = config_read(config, &cmdline->precmdline);
20592105
if (_Py_INIT_FAILED(err)) {
20602106
return err;
20612107
}
@@ -2090,7 +2136,7 @@ _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args)
20902136
{
20912137
_PyInitError err;
20922138

2093-
err = _Py_PreInitialize();
2139+
err = _Py_PreInitializeFromConfig(config);
20942140
if (_Py_INIT_FAILED(err)) {
20952141
return err;
20962142
}

Python/preconfig.c

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,30 @@ _PyPreCmdline_Clear(_PyPreCmdline *cmdline)
110110
}
111111

112112

113+
int
114+
_PyPreCmdline_Copy(_PyPreCmdline *cmdline, const _PyPreCmdline *cmdline2)
115+
{
116+
_PyPreCmdline_Clear(cmdline);
117+
if (_PyWstrList_Copy(&cmdline->argv, &cmdline2->argv) < 0) {
118+
return -1;
119+
}
120+
if (_PyWstrList_Copy(&cmdline->xoptions, &cmdline2->xoptions) < 0) {
121+
return -1;
122+
}
123+
cmdline->use_environment = cmdline2->use_environment;
124+
cmdline->isolated = cmdline2->isolated;
125+
return 0;
126+
}
127+
128+
113129
_PyInitError
114130
_PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args)
115131
{
116132
return _PyArgv_AsWstrList(args, &cmdline->argv);
117133
}
118134

119135

120-
static void
136+
void
121137
_PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config)
122138
{
123139
#define COPY_ATTR(ATTR) \
@@ -132,6 +148,36 @@ _PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config)
132148
}
133149

134150

151+
void
152+
_PyPreCmdline_GetCoreConfig(_PyPreCmdline *cmdline, const _PyCoreConfig *config)
153+
{
154+
#define COPY_ATTR(ATTR) \
155+
if (config->preconfig.ATTR != -1) { \
156+
cmdline->ATTR = config->preconfig.ATTR; \
157+
}
158+
159+
COPY_ATTR(use_environment);
160+
COPY_ATTR(isolated);
161+
162+
#undef COPY_ATTR
163+
}
164+
165+
166+
void
167+
_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
168+
{
169+
#define COPY_ATTR(ATTR) \
170+
if (config->preconfig.ATTR == -1 && cmdline->ATTR != -1) { \
171+
config->preconfig.ATTR = cmdline->ATTR; \
172+
}
173+
174+
COPY_ATTR(use_environment);
175+
COPY_ATTR(isolated);
176+
177+
#undef COPY_ATTR
178+
}
179+
180+
135181
/* --- _PyPreConfig ----------------------------------------------- */
136182

137183
void
@@ -628,7 +674,8 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline)
628674
629675
See _PyPreConfig_ReadFromArgv() to parse also command line arguments. */
630676
_PyInitError
631-
_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
677+
_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args,
678+
const _PyCoreConfig *coreconfig)
632679
{
633680
_PyInitError err;
634681
_PyPreCmdline cmdline = _PyPreCmdline_INIT;
@@ -642,8 +689,17 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
642689
/* Set LC_CTYPE to the user preferred locale */
643690
_Py_SetLocaleFromEnv(LC_CTYPE);
644691

692+
_PyPreConfig_GetGlobalConfig(config);
693+
645694
_PyPreCmdline_GetPreConfig(&cmdline, config);
646695

696+
if (coreconfig) {
697+
_PyPreCmdline_GetCoreConfig(&cmdline, coreconfig);
698+
if (config->dev_mode == -1) {
699+
config->dev_mode = coreconfig->preconfig.dev_mode;
700+
}
701+
}
702+
647703
if (args) {
648704
err = _PyPreCmdline_SetArgv(&cmdline, args);
649705
if (_Py_INIT_FAILED(err)) {
@@ -724,7 +780,7 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args)
724780
Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
725781
#endif
726782

727-
err = _PyPreConfig_Read(config, args);
783+
err = _PyPreConfig_Read(config, args, NULL);
728784
if (_Py_INIT_FAILED(err)) {
729785
goto done;
730786
}

Python/pylifecycle.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,9 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
715715

716716

717717
static _PyInitError
718-
pyinit_preinit(_PyPreConfig *config, const _PyPreConfig *src_config)
718+
pyinit_preinit(_PyPreConfig *config,
719+
const _PyPreConfig *src_config,
720+
const _PyCoreConfig *coreconfig)
719721
{
720722
_PyInitError err;
721723

@@ -729,13 +731,17 @@ pyinit_preinit(_PyPreConfig *config, const _PyPreConfig *src_config)
729731
return _Py_INIT_OK();
730732
}
731733

734+
if (!src_config && coreconfig) {
735+
src_config = &coreconfig->preconfig;
736+
}
737+
732738
if (src_config) {
733739
if (_PyPreConfig_Copy(config, src_config) < 0) {
734740
return _Py_INIT_ERR("failed to copy pre config");
735741
}
736742
}
737743

738-
err = _PyPreConfig_Read(config, NULL);
744+
err = _PyPreConfig_Read(config, NULL, coreconfig);
739745
if (_Py_INIT_FAILED(err)) {
740746
return err;
741747
}
@@ -750,18 +756,28 @@ pyinit_preinit(_PyPreConfig *config, const _PyPreConfig *src_config)
750756
}
751757

752758

759+
_PyInitError
760+
_Py_PreInitialize(void)
761+
{
762+
_PyPreConfig config = _PyPreConfig_INIT;
763+
_PyInitError err = pyinit_preinit(&config, NULL, NULL);
764+
_PyPreConfig_Clear(&config);
765+
return err;
766+
}
767+
768+
753769
_PyInitError
754770
_Py_PreInitializeFromPreConfig(_PyPreConfig *config)
755771
{
756-
return pyinit_preinit(config, NULL);
772+
return pyinit_preinit(config, NULL, NULL);
757773
}
758774

759775

760776
_PyInitError
761-
_Py_PreInitialize(void)
777+
_Py_PreInitializeFromConfig(const _PyCoreConfig *coreconfig)
762778
{
763779
_PyPreConfig config = _PyPreConfig_INIT;
764-
_PyInitError err = pyinit_preinit(&config, NULL);
780+
_PyInitError err = pyinit_preinit(&config, NULL, coreconfig);
765781
_PyPreConfig_Clear(&config);
766782
return err;
767783
}
@@ -814,16 +830,13 @@ _Py_InitializeCore(PyInterpreterState **interp_p,
814830

815831
assert(src_config != NULL);
816832

817-
_PyCoreConfig local_config = _PyCoreConfig_INIT;
818-
819-
err = pyinit_preinit(&local_config.preconfig, &src_config->preconfig);
833+
err = _Py_PreInitializeFromConfig(src_config);
820834
if (_Py_INIT_FAILED(err)) {
821-
goto done;
835+
return err;
822836
}
823837

838+
_PyCoreConfig local_config = _PyCoreConfig_INIT;
824839
err = pyinit_coreconfig(&local_config, src_config, interp_p);
825-
826-
done:
827840
_PyCoreConfig_Clear(&local_config);
828841
return err;
829842
}

0 commit comments

Comments
 (0)