bpo-32030: Rewrite _PyMainInterpreterConfig (#4854)

_PyMainInterpreterConfig now contains Python objects, whereas
_PyCoreConfig contains wchar_t* strings.

Core config:

* Rename _PyMainInterpreterConfig_ReadEnv() to _PyCoreConfig_ReadEnv()
* Move 3 strings from _PyMainInterpreterConfig to _PyCoreConfig:
  module_search_path_env, home, program_name.
* Add _PyCoreConfig_Clear()
* _PyPathConfig_Calculate() now takes core config rather than main
  config
* _PyMainInterpreterConfig_Read() now requires also a core config

Main config:

* Add _PyMainInterpreterConfig.module_search_path: sys.path list
* Add _PyMainInterpreterConfig.argv: sys.argv list
* _PyMainInterpreterConfig_Read() now computes module_search_path
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index b17ae82..748084b 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -46,7 +46,7 @@
 /* Initialize paths for Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix()
    and Py_GetProgramFullPath() */
 _PyInitError
-_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
+_PyPathConfig_Init(const _PyCoreConfig *core_config)
 {
     if (_Py_path_config.module_search_path) {
         /* Already initialized */
@@ -61,15 +61,15 @@
 
     /* Calculate program_full_path, prefix, exec_prefix (Unix)
        or dll_path (Windows), and module_search_path */
-    err = _PyPathConfig_Calculate(&new_config, main_config);
+    err = _PyPathConfig_Calculate(&new_config, core_config);
     if (_Py_INIT_FAILED(err)) {
         _PyPathConfig_Clear(&new_config);
         goto done;
     }
 
-    /* Copy home and program_name from main_config */
-    if (main_config->home != NULL) {
-        new_config.home = _PyMem_RawWcsdup(main_config->home);
+    /* Copy home and program_name from core_config */
+    if (core_config->home != NULL) {
+        new_config.home = _PyMem_RawWcsdup(core_config->home);
         if (new_config.home == NULL) {
             err = _Py_INIT_NO_MEMORY();
             goto done;
@@ -79,7 +79,7 @@
         new_config.home = NULL;
     }
 
-    new_config.program_name = _PyMem_RawWcsdup(main_config->program_name);
+    new_config.program_name = _PyMem_RawWcsdup(core_config->program_name);
     if (new_config.program_name == NULL) {
         err = _Py_INIT_NO_MEMORY();
         goto done;
@@ -105,14 +105,14 @@
     }
 
     _PyInitError err;
-    _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
+    _PyCoreConfig config = _PyCoreConfig_INIT;
 
-    err = _PyMainInterpreterConfig_ReadEnv(&config);
+    err = _PyCoreConfig_ReadEnv(&config);
     if (_Py_INIT_FAILED(err)) {
         goto error;
     }
 
-    err = _PyMainInterpreterConfig_Read(&config);
+    err = _PyCoreConfig_Read(&config);
     if (_Py_INIT_FAILED(err)) {
         goto error;
     }
@@ -122,11 +122,11 @@
         goto error;
     }
 
-    _PyMainInterpreterConfig_Clear(&config);
+    _PyCoreConfig_Clear(&config);
     return;
 
 error:
-    _PyMainInterpreterConfig_Clear(&config);
+    _PyCoreConfig_Clear(&config);
     _Py_FatalInitError(err);
 }
 
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 2bac23d..31965f5 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -792,13 +792,8 @@
  */
 
 _PyInitError
-_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config)
+_PyCoreConfig_Read(_PyCoreConfig *config)
 {
-    /* Signal handlers are installed by default */
-    if (config->install_signal_handlers < 0) {
-        config->install_signal_handlers = 1;
-    }
-
     if (config->program_name == NULL) {
 #ifdef MS_WINDOWS
         const wchar_t *program_name = L"python";
@@ -814,9 +809,8 @@
     return _Py_INIT_OK();
 }
 
-
 void
-_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
+_PyCoreConfig_Clear(_PyCoreConfig *config)
 {
 #define CLEAR(ATTR) \
     do { \
@@ -831,6 +825,14 @@
 }
 
 
+void
+_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
+{
+    Py_CLEAR(config->argv);
+    Py_CLEAR(config->module_search_path);
+}
+
+
 /* Update interpreter state based on supplied configuration settings
  *
  * After calling this function, most of the restrictions on the interpreter
@@ -881,16 +883,11 @@
         return _Py_INIT_ERR("can't initialize time");
     }
 
-    /* GetPath may initialize state that _PySys_EndInit locks
-       in, and so has to be called first. */
-    err = _PyPathConfig_Init(&interp->config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    assert(interp->config.module_search_path != NULL);
+    if (PySys_SetObject("path", interp->config.module_search_path) != 0) {
+        return _Py_INIT_ERR("can't assign sys.path");
     }
-    wchar_t *sys_path = Py_GetPath();
 
-    /* Finish setting up the sys module and import system */
-    PySys_SetPath(sys_path);
     if (_PySys_EndInit(interp->sysdict) < 0)
         return _Py_INIT_ERR("can't finish initializing sys");
 
@@ -949,6 +946,12 @@
         }
     }
 
+    if (interp->config.argv != NULL) {
+        if (PySys_SetObject("argv", interp->config.argv) != 0) {
+            return _Py_INIT_ERR("can't assign sys.argv");
+        }
+    }
+
     return _Py_INIT_OK();
 }
 
@@ -970,12 +973,12 @@
         goto done;
     }
 
-    err = _PyMainInterpreterConfig_ReadEnv(&config);
+    err = _PyCoreConfig_ReadEnv(&core_config);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
 
-    err = _PyMainInterpreterConfig_Read(&config);
+    err = _PyMainInterpreterConfig_Read(&config, &core_config);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
@@ -988,6 +991,7 @@
     err = _Py_INIT_OK();
 
 done:
+    _PyCoreConfig_Clear(&core_config);
     _PyMainInterpreterConfig_Clear(&config);
     return err;
 }
@@ -1342,7 +1346,7 @@
         interp->config = main_interp->config;
     }
 
-    err = _PyPathConfig_Init(&interp->config);
+    err = _PyPathConfig_Init(&interp->core_config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }