Skip to content

Commit d3b1919

Browse files
authored
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
1 parent 1dc6e39 commit d3b1919

1 file changed

Lines changed: 67 additions & 107 deletions

File tree

‎Modules/main.c‎

Lines changed: 67 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,6 @@ typedef struct {
442442
wchar_t *filename; /* Trailing arg without -c or -m */
443443
wchar_t *command; /* -c argument */
444444
wchar_t *module; /* -m argument */
445-
446-
PyObject *main_importer_path;
447445
} _PyMain;
448446

449447
#define _PyMain_INIT {.err = _Py_INIT_OK()}
@@ -815,26 +813,6 @@ pymain_clear_config(_PyCoreConfig *config)
815813
}
816814

817815

818-
static void
819-
pymain_free_python(_PyMain *pymain)
820-
{
821-
Py_CLEAR(pymain->main_importer_path);
822-
823-
#ifdef __INSURE__
824-
/* Insure++ is a memory analysis tool that aids in discovering
825-
* memory leaks and other memory problems. On Python exit, the
826-
* interned string dictionaries are flagged as being in use at exit
827-
* (which it is). Under normal circumstances, this is fine because
828-
* the memory will be automatically reclaimed by the system. Under
829-
* memory debugging, it's a huge source of useless noise, so we
830-
* trade off slower shutdown for less distraction in the memory
831-
* reports. -baw
832-
*/
833-
_Py_ReleaseInternedUnicodeStrings();
834-
#endif /* __INSURE__ */
835-
}
836-
837-
838816
static void
839817
pymain_free_raw(_PyMain *pymain)
840818
{
@@ -863,33 +841,47 @@ pymain_free_raw(_PyMain *pymain)
863841
static void
864842
pymain_free(_PyMain *pymain)
865843
{
866-
pymain_free_python(pymain);
867844
pymain_free_raw(pymain);
845+
846+
#ifdef __INSURE__
847+
/* Insure++ is a memory analysis tool that aids in discovering
848+
* memory leaks and other memory problems. On Python exit, the
849+
* interned string dictionaries are flagged as being in use at exit
850+
* (which it is). Under normal circumstances, this is fine because
851+
* the memory will be automatically reclaimed by the system. Under
852+
* memory debugging, it's a huge source of useless noise, so we
853+
* trade off slower shutdown for less distraction in the memory
854+
* reports. -baw
855+
*/
856+
_Py_ReleaseInternedUnicodeStrings();
857+
#endif /* __INSURE__ */
868858
}
869859

870860

871861
static int
872-
pymain_run_main_from_importer(_PyMain *pymain)
862+
pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
873863
{
874-
/* Assume sys_path0 has already been checked by pymain_get_importer(),
875-
* so put it in sys.path[0] and import __main__ */
876-
PyObject *sys_path = PySys_GetObject("path");
864+
PyObject *sys_path;
865+
PyObject *sysdict = interp->sysdict;
866+
if (sysdict != NULL) {
867+
sys_path = PyDict_GetItemString(sysdict, "path");
868+
}
869+
else {
870+
sys_path = NULL;
871+
}
877872
if (sys_path == NULL) {
878873
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
879874
goto error;
880875
}
881876

882-
if (PyList_Insert(sys_path, 0, pymain->main_importer_path)) {
877+
if (PyList_Insert(sys_path, 0, path0)) {
883878
goto error;
884879
}
885-
886-
int sts = pymain_run_module(L"__main__", 0);
887-
return (sts != 0);
880+
return 0;
888881

889882
error:
890-
Py_CLEAR(pymain->main_importer_path);
891883
PyErr_Print();
892-
return 1;
884+
return -1;
893885
}
894886

895887

@@ -1495,50 +1487,6 @@ wstrlist_as_pylist(int len, wchar_t **list)
14951487
}
14961488

14971489

1498-
static int
1499-
pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, PyObject **path0)
1500-
{
1501-
if (pymain->main_importer_path != NULL) {
1502-
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
1503-
*path0 = NULL;
1504-
return 0;
1505-
}
1506-
1507-
if (Py_IsolatedFlag) {
1508-
*path0 = NULL;
1509-
return 0;
1510-
}
1511-
1512-
*path0 = _PyPathConfig_ComputeArgv0(config->argc,
1513-
config->argv);
1514-
if (*path0 == NULL) {
1515-
pymain->err = _Py_INIT_NO_MEMORY();
1516-
return -1;
1517-
}
1518-
return 0;
1519-
}
1520-
1521-
1522-
static int
1523-
pymain_update_sys_path(_PyMain *pymain, PyObject *path0)
1524-
{
1525-
/* Prepend argv[0] to sys.path.
1526-
If argv[0] is a symlink, use the real path. */
1527-
PyObject *sys_path = PySys_GetObject("path");
1528-
if (sys_path == NULL) {
1529-
pymain->err = _Py_INIT_ERR("can't get sys.path");
1530-
return -1;
1531-
}
1532-
1533-
/* Prepend path0 to sys.path */
1534-
if (PyList_Insert(sys_path, 0, path0) < 0) {
1535-
pymain->err = _Py_INIT_ERR("sys.path.insert(0, path0) failed");
1536-
return -1;
1537-
}
1538-
return 0;
1539-
}
1540-
1541-
15421490
static void
15431491
pymain_import_readline(_PyMain *pymain)
15441492
{
@@ -1639,19 +1587,15 @@ pymain_run_startup(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
16391587

16401588

16411589
static void
1642-
pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
1590+
pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config,
1591+
PyCompilerFlags *cf)
16431592
{
16441593
if (pymain->filename == NULL && pymain->stdin_is_interactive) {
16451594
Py_InspectFlag = 0; /* do exit on SystemExit */
16461595
pymain_run_startup(pymain, config, cf);
16471596
pymain_run_interactive_hook();
16481597
}
16491598

1650-
if (pymain->main_importer_path != NULL) {
1651-
pymain->status = pymain_run_main_from_importer(pymain);
1652-
return;
1653-
}
1654-
16551599
FILE *fp;
16561600
if (pymain->filename != NULL) {
16571601
fp = pymain_open_filename(pymain, config);
@@ -2480,37 +2424,45 @@ pymain_init_python_main(_PyMain *pymain, _PyCoreConfig *config,
24802424

24812425

24822426
static int
2483-
pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
2427+
pymain_run_python(_PyMain *pymain, PyInterpreterState *interp)
24842428
{
2429+
int res = 0;
2430+
_PyCoreConfig *config = &interp->core_config;
2431+
2432+
PyObject *main_importer_path = NULL;
24852433
if (pymain->filename != NULL) {
24862434
/* If filename is a package (ex: directory or ZIP file) which contains
24872435
__main__.py, main_importer_path is set to filename and will be
2488-
prepended to sys.path by pymain_run_main_from_importer(). Otherwise,
2489-
main_importer_path is set to NULL. */
2490-
pymain->main_importer_path = pymain_get_importer(pymain->filename);
2436+
prepended to sys.path.
2437+
2438+
Otherwise, main_importer_path is set to NULL. */
2439+
main_importer_path = pymain_get_importer(pymain->filename);
24912440
}
24922441

2493-
PyObject *path0;
2494-
if (pymain_compute_path0(pymain, config, &path0) < 0) {
2495-
return -1;
2442+
if (main_importer_path != NULL) {
2443+
if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
2444+
pymain->status = 1;
2445+
goto done;
2446+
}
24962447
}
2448+
else if (!config->isolated) {
2449+
PyObject *path0 = _PyPathConfig_ComputeArgv0(config->argc,
2450+
config->argv);
2451+
if (path0 == NULL) {
2452+
pymain->err = _Py_INIT_NO_MEMORY();
2453+
res = -1;
2454+
goto done;
2455+
}
24972456

2498-
if (path0 != NULL) {
2499-
if (pymain_update_sys_path(pymain, path0) < 0) {
2457+
if (pymain_sys_path_add_path0(interp, path0) < 0) {
25002458
Py_DECREF(path0);
2501-
return -1;
2459+
pymain->status = 1;
2460+
goto done;
25022461
}
25032462
Py_DECREF(path0);
25042463
}
2505-
return 0;
2506-
}
2507-
25082464

2509-
static void
2510-
pymain_run_python(_PyMain *pymain)
2511-
{
25122465
PyCompilerFlags cf = {.cf_flags = 0};
2513-
_PyCoreConfig *config = &PyThreadState_GET()->interp->core_config;
25142466

25152467
pymain_header(pymain);
25162468
pymain_import_readline(pymain);
@@ -2521,11 +2473,19 @@ pymain_run_python(_PyMain *pymain)
25212473
else if (pymain->module) {
25222474
pymain->status = (pymain_run_module(pymain->module, 1) != 0);
25232475
}
2476+
else if (main_importer_path != NULL) {
2477+
int sts = pymain_run_module(L"__main__", 0);
2478+
pymain->status = (sts != 0);
2479+
}
25242480
else {
25252481
pymain_run_filename(pymain, config, &cf);
25262482
}
25272483

25282484
pymain_repl(pymain, config, &cf);
2485+
2486+
done:
2487+
Py_XDECREF(main_importer_path);
2488+
return res;
25292489
}
25302490

25312491

@@ -2617,7 +2577,7 @@ pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
26172577

26182578

26192579
static int
2620-
pymain_init(_PyMain *pymain)
2580+
pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
26212581
{
26222582
/* 754 requires that FP exceptions run in "no stop" mode by default,
26232583
* and until C vendors implement C99's ways to control FP exceptions,
@@ -2652,27 +2612,27 @@ pymain_init(_PyMain *pymain)
26522612
if (_Py_INIT_FAILED(pymain->err)) {
26532613
_Py_FatalInitError(pymain->err);
26542614
}
2615+
*interp_p = interp;
26552616

26562617
pymain_clear_config(config);
26572618
config = &interp->core_config;
26582619

26592620
if (pymain_init_python_main(pymain, config, interp) < 0) {
26602621
_Py_FatalInitError(pymain->err);
26612622
}
2662-
2663-
if (pymain_init_sys_path(pymain, config) < 0) {
2664-
_Py_FatalInitError(pymain->err);
2665-
}
26662623
return 0;
26672624
}
26682625

26692626

26702627
static int
26712628
pymain_main(_PyMain *pymain)
26722629
{
2673-
int res = pymain_init(pymain);
2630+
PyInterpreterState *interp;
2631+
int res = pymain_init(pymain, &interp);
26742632
if (res != 1) {
2675-
pymain_run_python(pymain);
2633+
if (pymain_run_python(pymain, interp) < 0) {
2634+
_Py_FatalInitError(pymain->err);
2635+
}
26762636

26772637
if (Py_FinalizeEx() < 0) {
26782638
/* Value unlikely to be confused with a non-error exit status or

0 commit comments

Comments
 (0)