bpo-36763: Add _Py_InitializeMain() (GH-13362)

* Add a private _Py_InitializeMain() function.
* Add again _PyCoreConfig._init_main.
* _Py_InitializeFromConfig() now uses _init_main to decide
  if _Py_InitializeMainInterpreter() should be called.
* _PyCoreConfig: rename _frozen to pathconfig_warnings, its value is
  now the opposite of Py_FrozenFlag.
* Add an unit test for _init_main=0 and _Py_InitializeMain().
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index 2b13c5f..8a5e5d5 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -667,7 +667,8 @@
     COPY_WSTR_ATTR(run_module);
     COPY_WSTR_ATTR(run_filename);
     COPY_WSTR_ATTR(check_hash_pycs_mode);
-    COPY_ATTR(_frozen);
+    COPY_ATTR(pathconfig_warnings);
+    COPY_ATTR(_init_main);
 
 #undef COPY_ATTR
 #undef COPY_WSTR_ATTR
@@ -766,7 +767,8 @@
     SET_ITEM_WSTR(run_filename);
     SET_ITEM_INT(_install_importlib);
     SET_ITEM_WSTR(check_hash_pycs_mode);
-    SET_ITEM_INT(_frozen);
+    SET_ITEM_INT(pathconfig_warnings);
+    SET_ITEM_INT(_init_main);
 
     return dict;
 
@@ -855,7 +857,7 @@
 #ifdef MS_WINDOWS
     COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
 #endif
-    COPY_FLAG(_frozen, Py_FrozenFlag);
+    COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
 
     COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
     COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
@@ -892,7 +894,7 @@
 #ifdef MS_WINDOWS
     COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
 #endif
-    COPY_FLAG(_frozen, Py_FrozenFlag);
+    COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
 
     COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
     COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
@@ -2253,7 +2255,7 @@
     assert(!(config->run_command != NULL && config->run_module != NULL));
     assert(config->check_hash_pycs_mode != NULL);
     assert(config->_install_importlib >= 0);
-    assert(config->_frozen >= 0);
+    assert(config->pathconfig_warnings >= 0);
 
     err = _Py_INIT_OK();
 
diff --git a/Python/frozenmain.c b/Python/frozenmain.c
index a777576..f2499ef 100644
--- a/Python/frozenmain.c
+++ b/Python/frozenmain.c
@@ -40,7 +40,7 @@
     }
 
     _PyCoreConfig config = _PyCoreConfig_INIT;
-    config._frozen = 1;   /* Suppress errors from getpath.c */
+    config.pathconfig_warnings = 0;   /* Suppress errors from getpath.c */
 
     if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
         inspect = 1;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index a173eb3..e891526 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -970,6 +970,21 @@
     return _Py_INIT_OK();
 }
 
+
+_PyInitError
+_Py_InitializeMain(void)
+{
+    _PyInitError err = _PyRuntime_Initialize();
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
+    _PyRuntimeState *runtime = &_PyRuntime;
+    PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
+
+    return _Py_InitializeMainInterpreter(runtime, interp);
+}
+
+
 #undef _INIT_DEBUG_PRINT
 
 static _PyInitError
@@ -990,7 +1005,7 @@
     }
     config = &interp->core_config;
 
-    if (!config->_frozen) {
+    if (config->_init_main) {
         err = _Py_InitializeMainInterpreter(runtime, interp);
         if (_Py_INIT_FAILED(err)) {
             return err;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 3d83044..bc131fd 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1046,6 +1046,15 @@
      * Py_Main() based one.
      */
     _Py_UnhandledKeyboardInterrupt = 0;
+
+    /* Set globals['__builtins__'] if it doesn't exist */
+    if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) {
+        PyInterpreterState *interp = _PyInterpreterState_Get();
+        if (PyDict_SetItemString(globals, "__builtins__", interp->builtins) < 0) {
+            return NULL;
+        }
+    }
+
     v = PyEval_EvalCode((PyObject*)co, globals, locals);
     if (!v && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
         _Py_UnhandledKeyboardInterrupt = 1;