bpo-34170: Rework _PyCoreConfig_Read() to avoid side effect (GH-8353)

Rework _PyCoreConfig_Read() function which *reads* core configuration
to not *modify* the path configuration.

A new _PyCoreConfig_SetPathConfig() function now recreates the path
configuration from the core configuration. This function is now
called very late in _Py_InitializeCore(), just before calling
initimport().

Changes:

* Add _PyCoreConfig.dll_path
* Py_SetPath() now fails with a fatal python error on memory
   allocation failure.
* Rename _PyPathConfig_Calculate() to _PyPathConfig_Calculate_impl()
* Replace _PyPathConfig_Init() with _PyPathConfig_Calculate(): the
  function now requires a _PyPathConfig
* Add _PyPathConfig_SetGlobal() to set the _Py_path_config global
  variable.
* Add _PyCoreConfig_InitPathConfig(): compute the path configuration
* Add _PyCoreConfig_SetPathConfig(): set path configuration from core
  configuration
* Rename wstrlist_append() to _Py_wstrlist_append()
* _Py_wstrlist_append() now handles integer overflow.
diff --git a/Include/internal/pystate.h b/Include/internal/pystate.h
index 70e0666..83fa7dc 100644
--- a/Include/internal/pystate.h
+++ b/Include/internal/pystate.h
@@ -37,7 +37,7 @@
 #define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled
 
 
-typedef struct {
+typedef struct _PyPathConfig {
     /* Full path to the Python program */
     wchar_t *program_full_path;
     wchar_t *prefix;
@@ -59,11 +59,15 @@
 
 PyAPI_DATA(_PyPathConfig) _Py_path_config;
 
-PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate(
+PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl(
     _PyPathConfig *config,
     const _PyCoreConfig *core_config);
-PyAPI_FUNC(void) _PyPathConfig_Clear(_PyPathConfig *config);
+PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void);
 
+PyAPI_FUNC(_PyInitError) _Py_wstrlist_append(
+    int *len,
+    wchar_t ***list,
+    const wchar_t *str);
 
 /* interpreter state */
 
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index 95dd55b..9644116 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -59,6 +59,9 @@
 PyAPI_FUNC(int) _PyCoreConfig_Copy(
     _PyCoreConfig *config,
     const _PyCoreConfig *config2);
+PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config);
+PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig(
+    const _PyCoreConfig *config);
 
 PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(
     _PyMainInterpreterConfig *config,
@@ -116,7 +119,11 @@
 PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
 PyAPI_FUNC(wchar_t *) Py_GetPath(void);
 #ifdef Py_BUILD_CORE
-PyAPI_FUNC(_PyInitError) _PyPathConfig_Init(const _PyCoreConfig *core_config);
+struct _PyPathConfig;
+typedef struct _PyPathConfig _PyPathConfig;
+
+PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
+    const _PyPathConfig *config);
 PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv);
 PyAPI_FUNC(int) _Py_FindEnvConfigValue(
     FILE *env_file,
diff --git a/Include/pystate.h b/Include/pystate.h
index 8158cab..ac09dc3 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -71,6 +71,9 @@
     wchar_t *base_prefix;   /* sys.base_prefix */
     wchar_t *exec_prefix;   /* sys.exec_prefix */
     wchar_t *base_exec_prefix;  /* sys.base_exec_prefix */
+#ifdef MS_WINDOWS
+    wchar_t *dll_path;      /* Windows DLL path */
+#endif
 
     /* Private fields */
     int _disable_importlib; /* Needed by freeze_importlib */