@@ -94,8 +94,34 @@ stdin_is_interactive(const _PyCoreConfig *config)
9494}
9595
9696
97- static PyObject *
98- pymain_get_importer (const wchar_t * filename )
97+ /* Display the current Python exception and return an exitcode */
98+ static int
99+ pymain_err_print (int * exitcode_p )
100+ {
101+ int exitcode ;
102+ if (_Py_HandleSystemExit (& exitcode )) {
103+ * exitcode_p = exitcode ;
104+ return 1 ;
105+ }
106+
107+ PyErr_Print ();
108+ return 0 ;
109+ }
110+
111+
112+ static int
113+ pymain_exit_err_print (void )
114+ {
115+ int exitcode = 1 ;
116+ pymain_err_print (& exitcode );
117+ return exitcode ;
118+ }
119+
120+
121+ /* Write an exitcode into *exitcode and return 1 if we have to exit Python.
122+ Return 0 otherwise. */
123+ static int
124+ pymain_get_importer (const wchar_t * filename , PyObject * * importer_p , int * exitcode )
99125{
100126 PyObject * sys_path0 = NULL , * importer ;
101127
@@ -112,17 +138,18 @@ pymain_get_importer(const wchar_t *filename)
112138 if (importer == Py_None ) {
113139 Py_DECREF (sys_path0 );
114140 Py_DECREF (importer );
115- return NULL ;
141+ return 0 ;
116142 }
117143
118144 Py_DECREF (importer );
119- return sys_path0 ;
145+ * importer_p = sys_path0 ;
146+ return 0 ;
120147
121148error :
122149 Py_XDECREF (sys_path0 );
150+
123151 PySys_WriteStderr ("Failed checking if argv[0] is an import path entry\n" );
124- PyErr_Print ();
125- return NULL ;
152+ return pymain_err_print (exitcode );
126153}
127154
128155
@@ -217,8 +244,7 @@ pymain_run_command(wchar_t *command, PyCompilerFlags *cf)
217244
218245error :
219246 PySys_WriteStderr ("Unable to decode the command from the command line:\n" );
220- PyErr_Print ();
221- return 1 ;
247+ return pymain_exit_err_print ();
222248}
223249
224250
@@ -229,44 +255,37 @@ pymain_run_module(const wchar_t *modname, int set_argv0)
229255 runpy = PyImport_ImportModule ("runpy" );
230256 if (runpy == NULL ) {
231257 fprintf (stderr , "Could not import runpy module\n" );
232- PyErr_Print ();
233- return -1 ;
258+ return pymain_exit_err_print ();
234259 }
235260 runmodule = PyObject_GetAttrString (runpy , "_run_module_as_main" );
236261 if (runmodule == NULL ) {
237262 fprintf (stderr , "Could not access runpy._run_module_as_main\n" );
238- PyErr_Print ();
239263 Py_DECREF (runpy );
240- return -1 ;
264+ return pymain_exit_err_print () ;
241265 }
242266 module = PyUnicode_FromWideChar (modname , wcslen (modname ));
243267 if (module == NULL ) {
244268 fprintf (stderr , "Could not convert module name to unicode\n" );
245- PyErr_Print ();
246269 Py_DECREF (runpy );
247270 Py_DECREF (runmodule );
248- return -1 ;
271+ return pymain_exit_err_print () ;
249272 }
250273 runargs = Py_BuildValue ("(Oi)" , module , set_argv0 );
251274 if (runargs == NULL ) {
252275 fprintf (stderr ,
253276 "Could not create arguments for runpy._run_module_as_main\n" );
254- PyErr_Print ();
255277 Py_DECREF (runpy );
256278 Py_DECREF (runmodule );
257279 Py_DECREF (module );
258- return -1 ;
280+ return pymain_exit_err_print () ;
259281 }
260282 result = PyObject_Call (runmodule , runargs , NULL );
261- if (result == NULL ) {
262- PyErr_Print ();
263- }
264283 Py_DECREF (runpy );
265284 Py_DECREF (runmodule );
266285 Py_DECREF (module );
267286 Py_DECREF (runargs );
268287 if (result == NULL ) {
269- return -1 ;
288+ return pymain_exit_err_print () ;
270289 }
271290 Py_DECREF (result );
272291 return 0 ;
@@ -315,9 +334,8 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
315334
316335 /* call pending calls like signal handlers (SIGINT) */
317336 if (Py_MakePendingCalls () == -1 ) {
318- PyErr_Print ();
319337 fclose (fp );
320- return 1 ;
338+ return pymain_exit_err_print () ;
321339 }
322340
323341 PyObject * unicode , * bytes = NULL ;
@@ -343,34 +361,36 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
343361}
344362
345363
346- static void
347- pymain_run_startup (_PyCoreConfig * config , PyCompilerFlags * cf )
364+ static int
365+ pymain_run_startup (_PyCoreConfig * config , PyCompilerFlags * cf , int * exitcode )
348366{
349367 const char * startup = _Py_GetEnv (config -> use_environment , "PYTHONSTARTUP" );
350368 if (startup == NULL ) {
351- return ;
369+ return 0 ;
352370 }
353371
354372 FILE * fp = _Py_fopen (startup , "r" );
355373 if (fp == NULL ) {
356374 int save_errno = errno ;
357375 PySys_WriteStderr ("Could not open PYTHONSTARTUP\n" );
376+
358377 errno = save_errno ;
378+ PyErr_SetFromErrnoWithFilename (PyExc_OSError , startup );
359379
360- PyErr_SetFromErrnoWithFilename (PyExc_OSError ,
361- startup );
362- PyErr_Print ();
363- return ;
380+ return pymain_err_print (exitcode );
364381 }
365382
366383 (void ) PyRun_SimpleFileExFlags (fp , startup , 0 , cf );
367384 PyErr_Clear ();
368385 fclose (fp );
386+ return 0 ;
369387}
370388
371389
372- static void
373- pymain_run_interactive_hook (void )
390+ /* Write an exitcode into *exitcode and return 1 if we have to exit Python.
391+ Return 0 otherwise. */
392+ static int
393+ pymain_run_interactive_hook (int * exitcode )
374394{
375395 PyObject * sys , * hook , * result ;
376396 sys = PyImport_ImportModule ("sys" );
@@ -382,7 +402,7 @@ pymain_run_interactive_hook(void)
382402 Py_DECREF (sys );
383403 if (hook == NULL ) {
384404 PyErr_Clear ();
385- return ;
405+ return 0 ;
386406 }
387407
388408 result = _PyObject_CallNoArg (hook );
@@ -392,11 +412,11 @@ pymain_run_interactive_hook(void)
392412 }
393413 Py_DECREF (result );
394414
395- return ;
415+ return 0 ;
396416
397417error :
398418 PySys_WriteStderr ("Failed calling sys.__interactivehook__\n" );
399- PyErr_Print ( );
419+ return pymain_err_print ( exitcode );
400420}
401421
402422
@@ -406,14 +426,20 @@ pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf)
406426 if (stdin_is_interactive (config )) {
407427 config -> inspect = 0 ;
408428 Py_InspectFlag = 0 ; /* do exit on SystemExit */
409- pymain_run_startup (config , cf );
410- pymain_run_interactive_hook ();
429+
430+ int exitcode ;
431+ if (pymain_run_startup (config , cf , & exitcode )) {
432+ return exitcode ;
433+ }
434+
435+ if (pymain_run_interactive_hook (& exitcode )) {
436+ return exitcode ;
437+ }
411438 }
412439
413440 /* call pending calls like signal handlers (SIGINT) */
414441 if (Py_MakePendingCalls () == -1 ) {
415- PyErr_Print ();
416- return 1 ;
442+ return pymain_exit_err_print ();
417443 }
418444
419445 int run = PyRun_AnyFileExFlags (stdin , "<stdin>" , 0 , cf );
@@ -437,7 +463,9 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
437463
438464 config -> inspect = 0 ;
439465 Py_InspectFlag = 0 ;
440- pymain_run_interactive_hook ();
466+ if (pymain_run_interactive_hook (exitcode )) {
467+ return ;
468+ }
441469
442470 int res = PyRun_AnyFileFlags (stdin , "<stdin>" , cf );
443471 * exitcode = (res != 0 );
@@ -457,8 +485,11 @@ pymain_run_python(int *exitcode)
457485 __main__.py, main_importer_path is set to filename and will be
458486 prepended to sys.path.
459487
460- Otherwise, main_importer_path is set to NULL. */
461- main_importer_path = pymain_get_importer (config -> run_filename );
488+ Otherwise, main_importer_path is left unchanged. */
489+ if (pymain_get_importer (config -> run_filename , & main_importer_path ,
490+ exitcode )) {
491+ return ;
492+ }
462493 }
463494
464495 if (main_importer_path != NULL ) {
@@ -491,11 +522,10 @@ pymain_run_python(int *exitcode)
491522 * exitcode = pymain_run_command (config -> run_command , & cf );
492523 }
493524 else if (config -> run_module ) {
494- * exitcode = ( pymain_run_module (config -> run_module , 1 ) != 0 );
525+ * exitcode = pymain_run_module (config -> run_module , 1 );
495526 }
496527 else if (main_importer_path != NULL ) {
497- int sts = pymain_run_module (L"__main__" , 0 );
498- * exitcode = (sts != 0 );
528+ * exitcode = pymain_run_module (L"__main__" , 0 );
499529 }
500530 else if (config -> run_filename != NULL ) {
501531 * exitcode = pymain_run_file (config , & cf );
@@ -508,8 +538,7 @@ pymain_run_python(int *exitcode)
508538 goto done ;
509539
510540error :
511- PyErr_Print ();
512- * exitcode = 1 ;
541+ * exitcode = pymain_exit_err_print ();
513542
514543done :
515544 Py_XDECREF (main_importer_path );
0 commit comments