summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-07-25 08:21:03 (GMT)
committerGitHub <noreply@github.com>2018-07-25 08:21:03 (GMT)
commitd3b191992e0f3c1eb27cb68478b875d60e859976 (patch)
treea432ab9a717ef44e5dd12c95735a5b3eec5b6e98
parent1dc6e3906acb81163725e98378bf4d1bd1ce771a (diff)
downloadcpython-d3b191992e0f3c1eb27cb68478b875d60e859976.zip
cpython-d3b191992e0f3c1eb27cb68478b875d60e859976.tar.gz
cpython-d3b191992e0f3c1eb27cb68478b875d60e859976.tar.bz2
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
-rw-r--r--Modules/main.c174
1 files changed, 67 insertions, 107 deletions
diff --git a/Modules/main.c b/Modules/main.c
index 8c29ef8..a16c340 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()}
@@ -816,26 +814,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)
{
_PyImport_Fini2();
@@ -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