mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									1dc6e3906a
								
							
						
					
					
						commit
						d3b191992e
					
				
					 1 changed files with 67 additions and 107 deletions
				
			
		
							
								
								
									
										174
									
								
								Modules/main.c
									
										
									
									
									
								
							
							
						
						
									
										174
									
								
								Modules/main.c
									
										
									
									
									
								
							| 
						 | 
					@ -442,8 +442,6 @@ typedef struct {
 | 
				
			||||||
    wchar_t *filename;           /* Trailing arg without -c or -m */
 | 
					    wchar_t *filename;           /* Trailing arg without -c or -m */
 | 
				
			||||||
    wchar_t *command;            /* -c argument */
 | 
					    wchar_t *command;            /* -c argument */
 | 
				
			||||||
    wchar_t *module;             /* -m argument */
 | 
					    wchar_t *module;             /* -m argument */
 | 
				
			||||||
 | 
					 | 
				
			||||||
    PyObject *main_importer_path;
 | 
					 | 
				
			||||||
} _PyMain;
 | 
					} _PyMain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _PyMain_INIT {.err = _Py_INIT_OK()}
 | 
					#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
 | 
					static void
 | 
				
			||||||
pymain_free_raw(_PyMain *pymain)
 | 
					pymain_free_raw(_PyMain *pymain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -863,33 +841,47 @@ pymain_free_raw(_PyMain *pymain)
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
pymain_free(_PyMain *pymain)
 | 
					pymain_free(_PyMain *pymain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    pymain_free_python(pymain);
 | 
					 | 
				
			||||||
    pymain_free_raw(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
 | 
					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(),
 | 
					    PyObject *sys_path;
 | 
				
			||||||
     * so put it in sys.path[0] and import __main__ */
 | 
					    PyObject *sysdict = interp->sysdict;
 | 
				
			||||||
    PyObject *sys_path = PySys_GetObject("path");
 | 
					    if (sysdict != NULL) {
 | 
				
			||||||
 | 
					        sys_path = PyDict_GetItemString(sysdict, "path");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sys_path = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (sys_path == NULL) {
 | 
					    if (sys_path == NULL) {
 | 
				
			||||||
        PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
 | 
					        PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (PyList_Insert(sys_path, 0, pymain->main_importer_path)) {
 | 
					    if (PyList_Insert(sys_path, 0, path0)) {
 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
    int sts = pymain_run_module(L"__main__", 0);
 | 
					 | 
				
			||||||
    return (sts != 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
error:
 | 
					error:
 | 
				
			||||||
    Py_CLEAR(pymain->main_importer_path);
 | 
					 | 
				
			||||||
    PyErr_Print();
 | 
					    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
 | 
					static void
 | 
				
			||||||
pymain_import_readline(_PyMain *pymain)
 | 
					pymain_import_readline(_PyMain *pymain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1639,7 +1587,8 @@ pymain_run_startup(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					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) {
 | 
					    if (pymain->filename == NULL && pymain->stdin_is_interactive) {
 | 
				
			||||||
        Py_InspectFlag = 0; /* do exit on SystemExit */
 | 
					        Py_InspectFlag = 0; /* do exit on SystemExit */
 | 
				
			||||||
| 
						 | 
					@ -1647,11 +1596,6 @@ pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
 | 
				
			||||||
        pymain_run_interactive_hook();
 | 
					        pymain_run_interactive_hook();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pymain->main_importer_path != NULL) {
 | 
					 | 
				
			||||||
        pymain->status = pymain_run_main_from_importer(pymain);
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    FILE *fp;
 | 
					    FILE *fp;
 | 
				
			||||||
    if (pymain->filename != NULL) {
 | 
					    if (pymain->filename != NULL) {
 | 
				
			||||||
        fp = pymain_open_filename(pymain, config);
 | 
					        fp = pymain_open_filename(pymain, config);
 | 
				
			||||||
| 
						 | 
					@ -2480,37 +2424,45 @@ pymain_init_python_main(_PyMain *pymain, _PyCoreConfig *config,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					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 (pymain->filename != NULL) {
 | 
				
			||||||
        /* If filename is a package (ex: directory or ZIP file) which contains
 | 
					        /* If filename is a package (ex: directory or ZIP file) which contains
 | 
				
			||||||
           __main__.py, main_importer_path is set to filename and will be
 | 
					           __main__.py, main_importer_path is set to filename and will be
 | 
				
			||||||
           prepended to sys.path by pymain_run_main_from_importer(). Otherwise,
 | 
					           prepended to sys.path.
 | 
				
			||||||
           main_importer_path is set to NULL. */
 | 
					
 | 
				
			||||||
        pymain->main_importer_path = pymain_get_importer(pymain->filename);
 | 
					           Otherwise, main_importer_path is set to NULL. */
 | 
				
			||||||
 | 
					        main_importer_path = pymain_get_importer(pymain->filename);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PyObject *path0;
 | 
					    if (main_importer_path != NULL) {
 | 
				
			||||||
    if (pymain_compute_path0(pymain, config, &path0) < 0) {
 | 
					        if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
 | 
				
			||||||
        return -1;
 | 
					            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_sys_path_add_path0(interp, path0) < 0) {
 | 
				
			||||||
        if (pymain_update_sys_path(pymain, path0) < 0) {
 | 
					 | 
				
			||||||
            Py_DECREF(path0);
 | 
					            Py_DECREF(path0);
 | 
				
			||||||
            return -1;
 | 
					            pymain->status = 1;
 | 
				
			||||||
 | 
					            goto done;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Py_DECREF(path0);
 | 
					        Py_DECREF(path0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
pymain_run_python(_PyMain *pymain)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    PyCompilerFlags cf = {.cf_flags = 0};
 | 
					    PyCompilerFlags cf = {.cf_flags = 0};
 | 
				
			||||||
    _PyCoreConfig *config = &PyThreadState_GET()->interp->core_config;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pymain_header(pymain);
 | 
					    pymain_header(pymain);
 | 
				
			||||||
    pymain_import_readline(pymain);
 | 
					    pymain_import_readline(pymain);
 | 
				
			||||||
| 
						 | 
					@ -2521,11 +2473,19 @@ pymain_run_python(_PyMain *pymain)
 | 
				
			||||||
    else if (pymain->module) {
 | 
					    else if (pymain->module) {
 | 
				
			||||||
        pymain->status = (pymain_run_module(pymain->module, 1) != 0);
 | 
					        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 {
 | 
					    else {
 | 
				
			||||||
        pymain_run_filename(pymain, config, &cf);
 | 
					        pymain_run_filename(pymain, config, &cf);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pymain_repl(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
 | 
					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,
 | 
					    /* 754 requires that FP exceptions run in "no stop" mode by default,
 | 
				
			||||||
     * and until C vendors implement C99's ways to control FP exceptions,
 | 
					     * 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)) {
 | 
					    if (_Py_INIT_FAILED(pymain->err)) {
 | 
				
			||||||
        _Py_FatalInitError(pymain->err);
 | 
					        _Py_FatalInitError(pymain->err);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    *interp_p = interp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pymain_clear_config(config);
 | 
					    pymain_clear_config(config);
 | 
				
			||||||
    config = &interp->core_config;
 | 
					    config = &interp->core_config;
 | 
				
			||||||
| 
						 | 
					@ -2659,10 +2620,6 @@ pymain_init(_PyMain *pymain)
 | 
				
			||||||
    if (pymain_init_python_main(pymain, config, interp) < 0) {
 | 
					    if (pymain_init_python_main(pymain, config, interp) < 0) {
 | 
				
			||||||
        _Py_FatalInitError(pymain->err);
 | 
					        _Py_FatalInitError(pymain->err);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (pymain_init_sys_path(pymain, config) < 0) {
 | 
					 | 
				
			||||||
        _Py_FatalInitError(pymain->err);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2670,9 +2627,12 @@ pymain_init(_PyMain *pymain)
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
pymain_main(_PyMain *pymain)
 | 
					pymain_main(_PyMain *pymain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int res = pymain_init(pymain);
 | 
					    PyInterpreterState *interp;
 | 
				
			||||||
 | 
					    int res = pymain_init(pymain, &interp);
 | 
				
			||||||
    if (res != 1) {
 | 
					    if (res != 1) {
 | 
				
			||||||
        pymain_run_python(pymain);
 | 
					        if (pymain_run_python(pymain, interp) < 0) {
 | 
				
			||||||
 | 
					            _Py_FatalInitError(pymain->err);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Py_FinalizeEx() < 0) {
 | 
					        if (Py_FinalizeEx() < 0) {
 | 
				
			||||||
            /* Value unlikely to be confused with a non-error exit status or
 | 
					            /* Value unlikely to be confused with a non-error exit status or
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue