[Python-checkins] bpo-34170: Cleanup pymain_run_python() (GH-8455)

Victor Stinner webhook-mailer at python.org
Wed Jul 25 04:21:11 EDT 2018


https://github.com/python/cpython/commit/d3b191992e0f3c1eb27cb68478b875d60e859976
commit: d3b191992e0f3c1eb27cb68478b875d60e859976
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2018-07-25T10:21:03+02:00
summary:

bpo-34170: Cleanup pymain_run_python() (GH-8455)

* Move _PyMain.main_importer_path inside pymain_run_python
* If main_importer_path is non-NULL, update sys.path[0] earlier

files:
M Modules/main.c

diff --git a/Modules/main.c b/Modules/main.c
index 8c29ef8b89fa..a16c34019146 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -442,8 +442,6 @@ typedef struct {
     wchar_t *filename;           /* Trailing arg without -c or -m */
     wchar_t *command;            /* -c argument */
     wchar_t *module;             /* -m argument */
-
-    PyObject *main_importer_path;
 } _PyMain;
 
 #define _PyMain_INIT {.err = _Py_INIT_OK()}
@@ -815,26 +813,6 @@ pymain_clear_config(_PyCoreConfig *config)
 }
 
 
-static void
-pymain_free_python(_PyMain *pymain)
-{
-    Py_CLEAR(pymain->main_importer_path);
-
-#ifdef __INSURE__
-    /* Insure++ is a memory analysis tool that aids in discovering
-     * memory leaks and other memory problems.  On Python exit, the
-     * interned string dictionaries are flagged as being in use at exit
-     * (which it is).  Under normal circumstances, this is fine because
-     * the memory will be automatically reclaimed by the system.  Under
-     * memory debugging, it's a huge source of useless noise, so we
-     * trade off slower shutdown for less distraction in the memory
-     * reports.  -baw
-     */
-    _Py_ReleaseInternedUnicodeStrings();
-#endif /* __INSURE__ */
-}
-
-
 static void
 pymain_free_raw(_PyMain *pymain)
 {
@@ -863,33 +841,47 @@ pymain_free_raw(_PyMain *pymain)
 static void
 pymain_free(_PyMain *pymain)
 {
-    pymain_free_python(pymain);
     pymain_free_raw(pymain);
+
+#ifdef __INSURE__
+    /* Insure++ is a memory analysis tool that aids in discovering
+     * memory leaks and other memory problems.  On Python exit, the
+     * interned string dictionaries are flagged as being in use at exit
+     * (which it is).  Under normal circumstances, this is fine because
+     * the memory will be automatically reclaimed by the system.  Under
+     * memory debugging, it's a huge source of useless noise, so we
+     * trade off slower shutdown for less distraction in the memory
+     * reports.  -baw
+     */
+    _Py_ReleaseInternedUnicodeStrings();
+#endif /* __INSURE__ */
 }
 
 
 static int
-pymain_run_main_from_importer(_PyMain *pymain)
+pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
 {
-    /* Assume sys_path0 has already been checked by pymain_get_importer(),
-     * so put it in sys.path[0] and import __main__ */
-    PyObject *sys_path = PySys_GetObject("path");
+    PyObject *sys_path;
+    PyObject *sysdict = interp->sysdict;
+    if (sysdict != NULL) {
+        sys_path = PyDict_GetItemString(sysdict, "path");
+    }
+    else {
+        sys_path = NULL;
+    }
     if (sys_path == NULL) {
         PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
         goto error;
     }
 
-    if (PyList_Insert(sys_path, 0, pymain->main_importer_path)) {
+    if (PyList_Insert(sys_path, 0, path0)) {
         goto error;
     }
-
-    int sts = pymain_run_module(L"__main__", 0);
-    return (sts != 0);
+    return 0;
 
 error:
-    Py_CLEAR(pymain->main_importer_path);
     PyErr_Print();
-    return 1;
+    return -1;
 }
 
 
@@ -1495,50 +1487,6 @@ wstrlist_as_pylist(int len, wchar_t **list)
 }
 
 
-static int
-pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, PyObject **path0)
-{
-    if (pymain->main_importer_path != NULL) {
-        /* Let pymain_run_main_from_importer() adjust sys.path[0] later */
-        *path0 = NULL;
-        return 0;
-    }
-
-    if (Py_IsolatedFlag) {
-        *path0 = NULL;
-        return 0;
-    }
-
-    *path0 = _PyPathConfig_ComputeArgv0(config->argc,
-                                        config->argv);
-    if (*path0 == NULL) {
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
-    }
-    return 0;
-}
-
-
-static int
-pymain_update_sys_path(_PyMain *pymain, PyObject *path0)
-{
-    /* Prepend argv[0] to sys.path.
-       If argv[0] is a symlink, use the real path. */
-    PyObject *sys_path = PySys_GetObject("path");
-    if (sys_path == NULL) {
-        pymain->err = _Py_INIT_ERR("can't get sys.path");
-        return -1;
-    }
-
-    /* Prepend path0 to sys.path */
-    if (PyList_Insert(sys_path, 0, path0) < 0) {
-        pymain->err = _Py_INIT_ERR("sys.path.insert(0, path0) failed");
-        return -1;
-    }
-    return 0;
-}
-
-
 static void
 pymain_import_readline(_PyMain *pymain)
 {
@@ -1639,7 +1587,8 @@ pymain_run_startup(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
 
 
 static void
-pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
+pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config,
+                    PyCompilerFlags *cf)
 {
     if (pymain->filename == NULL && pymain->stdin_is_interactive) {
         Py_InspectFlag = 0; /* do exit on SystemExit */
@@ -1647,11 +1596,6 @@ pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
         pymain_run_interactive_hook();
     }
 
-    if (pymain->main_importer_path != NULL) {
-        pymain->status = pymain_run_main_from_importer(pymain);
-        return;
-    }
-
     FILE *fp;
     if (pymain->filename != NULL) {
         fp = pymain_open_filename(pymain, config);
@@ -2480,37 +2424,45 @@ pymain_init_python_main(_PyMain *pymain, _PyCoreConfig *config,
 
 
 static int
-pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
+pymain_run_python(_PyMain *pymain, PyInterpreterState *interp)
 {
+    int res = 0;
+    _PyCoreConfig *config = &interp->core_config;
+
+    PyObject *main_importer_path = NULL;
     if (pymain->filename != NULL) {
         /* If filename is a package (ex: directory or ZIP file) which contains
            __main__.py, main_importer_path is set to filename and will be
-           prepended to sys.path by pymain_run_main_from_importer(). Otherwise,
-           main_importer_path is set to NULL. */
-        pymain->main_importer_path = pymain_get_importer(pymain->filename);
+           prepended to sys.path.
+
+           Otherwise, main_importer_path is set to NULL. */
+        main_importer_path = pymain_get_importer(pymain->filename);
     }
 
-    PyObject *path0;
-    if (pymain_compute_path0(pymain, config, &path0) < 0) {
-        return -1;
+    if (main_importer_path != NULL) {
+        if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
+            pymain->status = 1;
+            goto done;
+        }
     }
+    else if (!config->isolated) {
+        PyObject *path0 = _PyPathConfig_ComputeArgv0(config->argc,
+                                                     config->argv);
+        if (path0 == NULL) {
+            pymain->err = _Py_INIT_NO_MEMORY();
+            res = -1;
+            goto done;
+        }
 
-    if (path0 != NULL) {
-        if (pymain_update_sys_path(pymain, path0) < 0) {
+        if (pymain_sys_path_add_path0(interp, path0) < 0) {
             Py_DECREF(path0);
-            return -1;
+            pymain->status = 1;
+            goto done;
         }
         Py_DECREF(path0);
     }
-    return 0;
-}
-
 
-static void
-pymain_run_python(_PyMain *pymain)
-{
     PyCompilerFlags cf = {.cf_flags = 0};
-    _PyCoreConfig *config = &PyThreadState_GET()->interp->core_config;
 
     pymain_header(pymain);
     pymain_import_readline(pymain);
@@ -2521,11 +2473,19 @@ pymain_run_python(_PyMain *pymain)
     else if (pymain->module) {
         pymain->status = (pymain_run_module(pymain->module, 1) != 0);
     }
+    else if (main_importer_path != NULL) {
+        int sts = pymain_run_module(L"__main__", 0);
+        pymain->status = (sts != 0);
+    }
     else {
         pymain_run_filename(pymain, config, &cf);
     }
 
     pymain_repl(pymain, config, &cf);
+
+done:
+    Py_XDECREF(main_importer_path);
+    return res;
 }
 
 
@@ -2617,7 +2577,7 @@ pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
 
 
 static int
-pymain_init(_PyMain *pymain)
+pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
 {
     /* 754 requires that FP exceptions run in "no stop" mode by default,
      * and until C vendors implement C99's ways to control FP exceptions,
@@ -2652,6 +2612,7 @@ pymain_init(_PyMain *pymain)
     if (_Py_INIT_FAILED(pymain->err)) {
         _Py_FatalInitError(pymain->err);
     }
+    *interp_p = interp;
 
     pymain_clear_config(config);
     config = &interp->core_config;
@@ -2659,10 +2620,6 @@ pymain_init(_PyMain *pymain)
     if (pymain_init_python_main(pymain, config, interp) < 0) {
         _Py_FatalInitError(pymain->err);
     }
-
-    if (pymain_init_sys_path(pymain, config) < 0) {
-        _Py_FatalInitError(pymain->err);
-    }
     return 0;
 }
 
@@ -2670,9 +2627,12 @@ pymain_init(_PyMain *pymain)
 static int
 pymain_main(_PyMain *pymain)
 {
-    int res = pymain_init(pymain);
+    PyInterpreterState *interp;
+    int res = pymain_init(pymain, &interp);
     if (res != 1) {
-        pymain_run_python(pymain);
+        if (pymain_run_python(pymain, interp) < 0) {
+            _Py_FatalInitError(pymain->err);
+        }
 
         if (Py_FinalizeEx() < 0) {
             /* Value unlikely to be confused with a non-error exit status or



More information about the Python-checkins mailing list