bpo-36763: Fix Python preinitialization (GH-13432)
* Add _PyPreConfig.parse_argv
* Add _PyCoreConfig._config_init field and _PyCoreConfigInitEnum enum
type
* Initialization functions: reject preconfig=NULL and config=NULL
* Add config parameter to _PyCoreConfig_DecodeLocaleErr(): pass
config->argv to _Py_PreInitializeFromPyArgv(), to parse config
command line arguments in preinitialization.
* Add config parameter to _PyCoreConfig_SetString(). It now
preinitializes Python.
* _PyCoreConfig_SetPyArgv() now also preinitializes Python for wide
argv
* Fix _Py_PreInitializeFromCoreConfig(): don't pass args to
_Py_PreInitializeFromPyArgv() if config.parse_argv=0.
* Use "char * const *" and "wchar_t * const *" types for 'argv'
parameters and _PyArgv.argv.
* Add unit test on preinitialization from argv.
* _PyPreConfig.allocator type becomes int
* Add _PyPreConfig_InitFromPreConfig() and
_PyPreConfig_InitFromCoreConfig() helper functions
diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h
index a71f161..decfb70 100644
--- a/Include/cpython/coreconfig.h
+++ b/Include/cpython/coreconfig.h
@@ -44,6 +44,10 @@
int _config_version; /* Internal configuration version,
used for ABI compatibility */
+ /* Parse _Py_PreInitializeFromArgs() arguments?
+ See _PyCoreConfig.parse_argv */
+ int parse_argv;
+
/* If greater than 0, enable isolated mode: sys.path contains
neither the script's directory nor the user's site-packages directory.
@@ -111,8 +115,9 @@
int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */
- /* Memory allocator: PYTHONMALLOC env var */
- PyMemAllocatorName allocator;
+ /* Memory allocator: PYTHONMALLOC env var.
+ See PyMemAllocatorName for valid values. */
+ int allocator;
} _PyPreConfig;
PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config);
@@ -121,9 +126,16 @@
/* --- _PyCoreConfig ---------------------------------------------- */
+typedef enum {
+ _PyCoreConfig_INIT = 0,
+ _PyCoreConfig_INIT_PYTHON = 1,
+ _PyCoreConfig_INIT_ISOLATED = 2
+} _PyCoreConfigInitEnum;
+
typedef struct {
int _config_version; /* Internal configuration version,
used for ABI compatibility */
+ int _config_init; /* _PyCoreConfigInitEnum value */
int isolated; /* Isolated mode? see _PyPreConfig.isolated */
int use_environment; /* Use environment variables? see _PyPreConfig.use_environment */
@@ -401,19 +413,21 @@
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config);
PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString(
+ _PyCoreConfig *config,
wchar_t **config_str,
const wchar_t *str);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale(
+ _PyCoreConfig *config,
wchar_t **config_str,
const char *str);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv(
_PyCoreConfig *config,
Py_ssize_t argc,
- char **argv);
+ char * const *argv);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config,
Py_ssize_t argc,
- wchar_t **argv);
+ wchar_t * const *argv);
#ifdef __cplusplus
}
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
index 8fc809d..1e1dabe 100644
--- a/Include/cpython/pylifecycle.h
+++ b/Include/cpython/pylifecycle.h
@@ -35,11 +35,11 @@
PyAPI_FUNC(_PyInitError) _Py_InitializeFromArgs(
const _PyCoreConfig *config,
Py_ssize_t argc,
- char **argv);
+ char * const *argv);
PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs(
const _PyCoreConfig *config,
Py_ssize_t argc,
- wchar_t **argv);
+ wchar_t * const *argv);
PyAPI_FUNC(_PyInitError) _Py_InitializeMain(void);
PyAPI_FUNC(int) _Py_RunMain(void);
diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h
index edde7b1..324e0b8 100644
--- a/Include/internal/pycore_coreconfig.h
+++ b/Include/internal/pycore_coreconfig.h
@@ -63,8 +63,8 @@
typedef struct {
Py_ssize_t argc;
int use_bytes_argv;
- char **bytes_argv;
- wchar_t **wchar_argv;
+ char * const *bytes_argv;
+ wchar_t * const *wchar_argv;
} _PyArgv;
PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args,
@@ -121,6 +121,12 @@
/* --- _PyPreConfig ----------------------------------------------- */
PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config);
+PyAPI_FUNC(void) _PyPreConfig_InitFromCoreConfig(
+ _PyPreConfig *config,
+ const _PyCoreConfig *coreconfig);
+PyAPI_FUNC(void) _PyPreConfig_InitFromPreConfig(
+ _PyPreConfig *config,
+ const _PyPreConfig *config2);
PyAPI_FUNC(void) _PyPreConfig_Copy(_PyPreConfig *config,
const _PyPreConfig *config2);
PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config);