Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1976086

Browse files
authored
bpo-32030: Cleanup pymain_main() (#4935)
* Reorganize pymain_main() to make the code more flat * Clear configurations before pymain_update_sys_path() * Mark Py_FatalError() and _Py_FatalInitError() with _Py_NO_RETURN * Replace _PyMain.run_code variable with a new RUN_CODE() macro * Move _PyMain.cf into a local variable in pymain_run_python()
1 parent c4bca95 commit 1976086

2 files changed

Lines changed: 95 additions & 73 deletions

File tree

Modules/main.c

Lines changed: 93 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ typedef struct {
389389
wchar_t *command; /* -c argument */
390390
const wchar_t *module; /* -m argument */
391391
_Py_OptList warning_options; /* -W options */
392+
_Py_OptList env_warning_options; /* PYTHONWARNINGS env var */
392393
int print_help; /* -h, -? options */
393394
int print_version; /* -V option */
394395
int bytes_warning; /* Py_BytesWarningFlag, -b */
@@ -412,41 +413,47 @@ typedef struct {
412413
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
413414
PYTHONLEGACYWINDOWSSTDIO */
414415
#endif
415-
_Py_OptList env_warning_options; /* PYTHONWARNINGS env var */
416416
} _Py_CommandLineDetails;
417417

418418
/* Structure used by Py_Main() to pass data to subfunctions */
419419
typedef struct {
420-
/* Exit status ("exit code") */
420+
/* Input arguments */
421+
int argc;
422+
int use_bytes_argv;
423+
char **bytes_argv;
424+
wchar_t **wchar_argv;
425+
426+
/* Exit status or "exit code": result of pymain_main() */
421427
int status;
422-
PyCompilerFlags cf;
428+
/* Error message if a function failed */
429+
_PyInitError err;
430+
431+
_Py_CommandLineDetails cmdline;
423432
/* non-zero is stdin is a TTY or if -i option is used */
424433
int stdin_is_interactive;
434+
425435
_PyCoreConfig core_config;
426436
_PyMainInterpreterConfig config;
427-
_Py_CommandLineDetails cmdline;
428-
PyObject *main_importer_path;
429-
/* non-zero if filename, command (-c) or module (-m) is set
430-
on the command line */
431-
int run_code;
432-
/* Error message if a function failed */
433-
_PyInitError err;
434437

435-
int argc;
436-
int use_bytes_argv;
437-
char **bytes_argv;
438-
wchar_t **wchar_argv;
438+
PyObject *main_importer_path;
439439
} _PyMain;
440440

441441
/* .cmdline is initialized to zeros */
442442
#define _PyMain_INIT \
443443
{.core_config = _PyCoreConfig_INIT, \
444444
.config = _PyMainInterpreterConfig_INIT, \
445-
.run_code = -1, \
446445
.err = _Py_INIT_OK()}
447446
/* Note: _PyMain_INIT sets other fields to 0/NULL */
448447

449448

449+
/* Non-zero if filename, command (-c) or module (-m) is set
450+
on the command line */
451+
#define RUN_CODE(pymain) \
452+
(pymain->cmdline.command != NULL \
453+
|| pymain->cmdline.filename != NULL \
454+
|| pymain->cmdline.module != NULL)
455+
456+
450457
static void
451458
pymain_optlist_clear(_Py_OptList *list)
452459
{
@@ -526,7 +533,6 @@ pymain_clear_cmdline(_PyMain *pymain)
526533
cmdline->argv = NULL;
527534
}
528535

529-
530536
static void
531537
pymain_clear_configs(_PyMain *pymain)
532538
{
@@ -816,9 +822,6 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
816822
cmdline->filename = cmdline->argv[_PyOS_optind];
817823
}
818824

819-
pymain->run_code = (cmdline->command != NULL || cmdline->filename != NULL
820-
|| cmdline->module != NULL);
821-
822825
/* -c and -m options are exclusive */
823826
assert(!(cmdline->command != NULL && cmdline->module != NULL));
824827

@@ -1174,12 +1177,11 @@ pymain_get_program_name(_PyMain *pymain)
11741177
static void
11751178
pymain_header(_PyMain *pymain)
11761179
{
1177-
/* TODO: Move this to _PyRun_PrepareMain */
11781180
if (Py_QuietFlag) {
11791181
return;
11801182
}
11811183

1182-
if (!Py_VerboseFlag && (pymain->run_code || !pymain->stdin_is_interactive)) {
1184+
if (!Py_VerboseFlag && (RUN_CODE(pymain) || !pymain->stdin_is_interactive)) {
11831185
return;
11841186
}
11851187

@@ -1291,17 +1293,32 @@ config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_con
12911293

12921294

12931295
static int
1294-
pymain_update_sys_path(_PyMain *pymain)
1296+
pymain_init_path0(_PyMain *pymain, PyObject **path0)
12951297
{
12961298
if (pymain->main_importer_path != NULL) {
12971299
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
1300+
*path0 = NULL;
12981301
return 0;
12991302
}
13001303

13011304
if (Py_IsolatedFlag) {
1305+
*path0 = NULL;
13021306
return 0;
13031307
}
13041308

1309+
*path0 = _PyPathConfig_ComputeArgv0(pymain->core_config.argc,
1310+
pymain->core_config.argv);
1311+
if (*path0 == NULL) {
1312+
pymain->err = _Py_INIT_NO_MEMORY();
1313+
return -1;
1314+
}
1315+
return 0;
1316+
}
1317+
1318+
1319+
static int
1320+
pymain_update_sys_path(_PyMain *pymain, PyObject *path0)
1321+
{
13051322
/* Prepend argv[0] to sys.path.
13061323
If argv[0] is a symlink, use the real path. */
13071324
PyObject *sys_path = PySys_GetObject("path");
@@ -1310,20 +1327,11 @@ pymain_update_sys_path(_PyMain *pymain)
13101327
return -1;
13111328
}
13121329

1313-
PyObject *path0 = _PyPathConfig_ComputeArgv0(pymain->core_config.argc, pymain->core_config.argv);
1314-
if (path0 == NULL) {
1315-
pymain->err = _Py_INIT_NO_MEMORY();
1316-
return -1;
1317-
}
1318-
13191330
/* Prepend path0 to sys.path */
13201331
if (PyList_Insert(sys_path, 0, path0) < 0) {
1321-
Py_DECREF(path0);
13221332
pymain->err = _Py_INIT_ERR("sys.path.insert(0, path0) failed");
13231333
return -1;
13241334
}
1325-
Py_DECREF(path0);
1326-
13271335
return 0;
13281336
}
13291337

@@ -1357,7 +1365,7 @@ pymain_get_global_config(_PyMain *pymain)
13571365
}
13581366

13591367

1360-
/* Set Py_XXX global configuration variables */
1368+
/* Set Py_xxx global configuration variables */
13611369
static void
13621370
pymain_set_global_config(_PyMain *pymain)
13631371
{
@@ -1396,7 +1404,7 @@ pymain_import_readline(_PyMain *pymain)
13961404
if (Py_IsolatedFlag) {
13971405
return;
13981406
}
1399-
if (!Py_InspectFlag && pymain->run_code) {
1407+
if (!Py_InspectFlag && RUN_CODE(pymain)) {
14001408
return;
14011409
}
14021410
if (!isatty(fileno(stdin))) {
@@ -1464,13 +1472,13 @@ pymain_open_filename(_PyMain *pymain)
14641472

14651473

14661474
static void
1467-
pymain_run_filename(_PyMain *pymain)
1475+
pymain_run_filename(_PyMain *pymain, PyCompilerFlags *cf)
14681476
{
14691477
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
14701478

14711479
if (cmdline->filename == NULL && pymain->stdin_is_interactive) {
14721480
Py_InspectFlag = 0; /* do exit on SystemExit */
1473-
pymain_run_startup(&pymain->cf);
1481+
pymain_run_startup(cf);
14741482
pymain_run_interactive_hook();
14751483
}
14761484

@@ -1490,28 +1498,27 @@ pymain_run_filename(_PyMain *pymain)
14901498
fp = stdin;
14911499
}
14921500

1493-
pymain->status = pymain_run_file(fp, cmdline->filename, &pymain->cf);
1501+
pymain->status = pymain_run_file(fp, cmdline->filename, cf);
14941502
}
14951503

14961504

14971505
static void
1498-
pymain_repl(_PyMain *pymain)
1506+
pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
14991507
{
15001508
/* Check this environment variable at the end, to give programs the
15011509
opportunity to set it from Python. */
15021510
if (!Py_InspectFlag && pymain_get_env_var("PYTHONINSPECT")) {
15031511
Py_InspectFlag = 1;
15041512
}
15051513

1506-
if (!(Py_InspectFlag && pymain->stdin_is_interactive
1507-
&& pymain->run_code)) {
1514+
if (!(Py_InspectFlag && pymain->stdin_is_interactive && RUN_CODE(pymain))) {
15081515
return;
15091516
}
15101517

15111518
Py_InspectFlag = 0;
15121519
pymain_run_interactive_hook();
15131520

1514-
int res = PyRun_AnyFileFlags(stdin, "<stdin>", &pymain->cf);
1521+
int res = PyRun_AnyFileFlags(stdin, "<stdin>", cf);
15151522
pymain->status = (res != 0);
15161523
}
15171524

@@ -1966,17 +1973,17 @@ pymain_read_conf_impl(_PyMain *pymain)
19661973
return res;
19671974
}
19681975

1976+
if (pymain_init_core_argv(pymain) < 0) {
1977+
return -1;
1978+
}
1979+
19691980
/* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
19701981
Py_IgnoreEnvironmentFlag = pymain->core_config.ignore_environment;
19711982

19721983
if (pymain_parse_envvars(pymain) < 0) {
19731984
return -1;
19741985
}
19751986

1976-
if (pymain_init_core_argv(pymain) < 0) {
1977-
return -1;
1978-
}
1979-
19801987
_PyInitError err = _PyCoreConfig_Read(&pymain->core_config);
19811988
if (_Py_INIT_FAILED(err)) {
19821989
pymain->err = err;
@@ -1986,6 +1993,8 @@ pymain_read_conf_impl(_PyMain *pymain)
19861993
}
19871994

19881995

1996+
/* Read the configuration, but initialize also the LC_CTYPE locale:
1997+
enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
19891998
static int
19901999
pymain_read_conf(_PyMain *pymain)
19912000
{
@@ -2426,31 +2435,44 @@ pymain_init_python_main(_PyMain *pymain)
24262435
pymain->main_importer_path = pymain_get_importer(pymain->cmdline.filename);
24272436
}
24282437

2429-
if (pymain_update_sys_path(pymain) < 0) {
2438+
PyObject *path0;
2439+
if (pymain_init_path0(pymain, &path0) < 0) {
24302440
return -1;
24312441
}
2442+
2443+
pymain_clear_configs(pymain);
2444+
2445+
if (path0 != NULL) {
2446+
if (pymain_update_sys_path(pymain, path0) < 0) {
2447+
Py_DECREF(path0);
2448+
return -1;
2449+
}
2450+
Py_DECREF(path0);
2451+
}
2452+
24322453
return 0;
24332454
}
24342455

24352456

24362457
static void
24372458
pymain_run_python(_PyMain *pymain)
24382459
{
2460+
PyCompilerFlags cf = {.cf_flags = 0};
24392461
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
24402462

24412463
pymain_header(pymain);
24422464
pymain_import_readline(pymain);
24432465

24442466
if (cmdline->command) {
2445-
pymain->status = pymain_run_command(cmdline->command, &pymain->cf);
2467+
pymain->status = pymain_run_command(cmdline->command, &cf);
24462468
}
24472469
else if (cmdline->module) {
24482470
pymain->status = (pymain_run_module(cmdline->module, 1) != 0);
24492471
}
24502472
else {
2451-
pymain_run_filename(pymain);
2473+
pymain_run_filename(pymain, &cf);
24522474
}
2453-
pymain_repl(pymain);
2475+
pymain_repl(pymain, &cf);
24542476
}
24552477

24562478

@@ -2476,51 +2498,61 @@ pymain_init(_PyMain *pymain)
24762498

24772499

24782500
static int
2479-
pymain_impl(_PyMain *pymain)
2501+
pymain_init_cmdline(_PyMain *pymain)
24802502
{
24812503
pymain->err = _PyRuntime_Initialize();
24822504
if (_Py_INIT_FAILED(pymain->err)) {
24832505
return -1;
24842506
}
24852507

2486-
/* Read the configuration, but initialize also the LC_CTYPE locale:
2487-
enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
24882508
int res = pymain_read_conf(pymain);
24892509
if (res < 0) {
24902510
return -1;
24912511
}
24922512
if (res > 0) {
24932513
/* --help or --version command: we are done */
2494-
return 0;
2514+
return 1;
24952515
}
24962516

24972517
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
24982518
if (cmdline->print_help) {
24992519
pymain_usage(0, cmdline->argv[0]);
2500-
return 0;
2520+
return 1;
25012521
}
25022522

25032523
if (cmdline->print_version) {
25042524
printf("Python %s\n",
25052525
(cmdline->print_version >= 2) ? Py_GetVersion() : PY_VERSION);
2506-
return 0;
2526+
return 1;
25072527
}
25082528

25092529
/* For Py_GetArgcArgv(). Cleared by pymain_free(). */
25102530
orig_argc = pymain->argc;
25112531
orig_argv = cmdline->argv;
2532+
return 0;
2533+
}
25122534

2513-
res = pymain_init_python_core(pymain);
2535+
2536+
static int
2537+
pymain_main(_PyMain *pymain)
2538+
{
2539+
pymain_init(pymain);
2540+
2541+
int res = pymain_init_cmdline(pymain);
25142542
if (res < 0) {
2515-
return -1;
2543+
_Py_FatalInitError(pymain->err);
2544+
}
2545+
if (res == 1) {
2546+
goto done;
25162547
}
25172548

2518-
res = pymain_init_python_main(pymain);
2519-
if (res < 0) {
2520-
return -1;
2549+
if (pymain_init_python_core(pymain) < 0) {
2550+
_Py_FatalInitError(pymain->err);
25212551
}
25222552

2523-
pymain_clear_configs(pymain);
2553+
if (pymain_init_python_main(pymain) < 0) {
2554+
_Py_FatalInitError(pymain->err);
2555+
}
25242556

25252557
pymain_run_python(pymain);
25262558

@@ -2529,18 +2561,8 @@ pymain_impl(_PyMain *pymain)
25292561
other special meaning */
25302562
pymain->status = 120;
25312563
}
2532-
return 0;
2533-
}
2534-
25352564

2536-
static int
2537-
pymain_main(_PyMain *pymain)
2538-
{
2539-
pymain_init(pymain);
2540-
2541-
if (pymain_impl(pymain) < 0) {
2542-
_Py_FatalInitError(pymain->err);
2543-
}
2565+
done:
25442566
pymain_free(pymain);
25452567

25462568
return pymain->status;

0 commit comments

Comments
 (0)