@@ -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 */
419419typedef 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+
450457static void
451458pymain_optlist_clear (_Py_OptList * list )
452459{
@@ -526,7 +533,6 @@ pymain_clear_cmdline(_PyMain *pymain)
526533 cmdline -> argv = NULL ;
527534}
528535
529-
530536static void
531537pymain_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)
11741177static void
11751178pymain_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
12931295static 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 */
13611369static void
13621370pymain_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
14661474static 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
14971505static 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) */
19891998static int
19901999pymain_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
24362457static void
24372458pymain_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
24782500static 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