bpo-32030: Don't call _PyPathConfig_Fini() in Py_FinalizeEx() (#4667)

Changes:

* _PyPathConfig_Fini() cannot be called in Py_FinalizeEx().
  Py_Initialize() and Py_Finalize() can be called multiple times, but
  it must not "forget" parameters set by Py_SetProgramName(),
  Py_SetPath() or Py_SetPythonHome(), whereas _PyPathConfig_Fini()
  clear all these parameters.
* config_get_program_name() and calculate_program_full_path() now
  also decode paths using Py_DecodeLocale() to use the
  surrogateescape error handler, rather than decoding using
  mbstowcs() which is strict.
* Change _Py_CheckPython3() prototype: () => (void)
* Truncate a few lines which were too long
diff --git a/Modules/getpath.c b/Modules/getpath.c
index 183717d..235bada 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -625,11 +625,13 @@
     else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
             execpath[0] == SEP)
     {
-        size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1);
-        if (r == (size_t)-1 || r > MAXPATHLEN) {
-            /* Could not convert execpath, or it's too long. */
-            program_full_path[0] = '\0';
+        size_t len;
+        wchar_t *path = Py_DecodeLocale(execpath, &len);
+        if (path == NULL) {
+            return DECODE_LOCALE_ERR("executable path", len);
         }
+        wcsncpy(program_full_path, path, MAXPATHLEN);
+        PyMem_RawFree(path);
     }
 #endif /* __APPLE__ */
     else if (calculate->path_env) {
diff --git a/Modules/main.c b/Modules/main.c
index caec97f..4659c5d 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -888,15 +888,12 @@
        See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
        script. */
     if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
-        wchar_t* buffer;
-        size_t len = strlen(p) + 1;
-
-        buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
-        if (buffer == NULL) {
-            return _Py_INIT_NO_MEMORY();
+        size_t len;
+        wchar_t* program_name = Py_DecodeLocale(p, &len);
+        if (program_name == NULL) {
+            return SET_DECODE_ERROR("PYTHONEXECUTABLE environment "
+                                    "variable", len);
         }
-
-        mbstowcs(buffer, p, len);
         pymain->config.program_name = buffer;
     }
 #ifdef WITH_NEXT_FRAMEWORK
@@ -907,11 +904,12 @@
              * the argv0 of the stub executable
              */
             size_t len;
-            wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, &len);
-            if (wbuf == NULL) {
-                return SET_DECODE_ERROR("__PYVENV_LAUNCHER__", len);
+            wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
+            if (program_name == NULL) {
+                return SET_DECODE_ERROR("__PYVENV_LAUNCHER__ environment "
+                                        "variable", len);
             }
-            pymain->config.program_name = wbuf;
+            pymain->config.program_name = program_name;
         }
     }
 #endif   /* WITH_NEXT_FRAMEWORK */
@@ -1666,6 +1664,14 @@
            other special meaning */
         pymain->status = 120;
     }
+
+    /* _PyPathConfig_Fini() cannot be called in Py_FinalizeEx().
+       Py_Initialize() and Py_Finalize() can be called multiple times, but it
+       must not "forget" parameters set by Py_SetProgramName(), Py_SetPath() or
+       Py_SetPythonHome(), whereas _PyPathConfig_Fini() clear all these
+       parameters. */
+    _PyPathConfig_Fini();
+
     return 0;
 }