@@ -94,8 +94,34 @@ stdin_is_interactive(const _PyCoreConfig *config)
94
94
}
95
95
96
96
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 )
99
125
{
100
126
PyObject * sys_path0 = NULL , * importer ;
101
127
@@ -112,17 +138,18 @@ pymain_get_importer(const wchar_t *filename)
112
138
if (importer == Py_None ) {
113
139
Py_DECREF (sys_path0 );
114
140
Py_DECREF (importer );
115
- return NULL ;
141
+ return 0 ;
116
142
}
117
143
118
144
Py_DECREF (importer );
119
- return sys_path0 ;
145
+ * importer_p = sys_path0 ;
146
+ return 0 ;
120
147
121
148
error :
122
149
Py_XDECREF (sys_path0 );
150
+
123
151
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 );
126
153
}
127
154
128
155
@@ -217,8 +244,7 @@ pymain_run_command(wchar_t *command, PyCompilerFlags *cf)
217
244
218
245
error :
219
246
PySys_WriteStderr ("Unable to decode the command from the command line:\n" );
220
- PyErr_Print ();
221
- return 1 ;
247
+ return pymain_exit_err_print ();
222
248
}
223
249
224
250
@@ -229,44 +255,37 @@ pymain_run_module(const wchar_t *modname, int set_argv0)
229
255
runpy = PyImport_ImportModule ("runpy" );
230
256
if (runpy == NULL ) {
231
257
fprintf (stderr , "Could not import runpy module\n" );
232
- PyErr_Print ();
233
- return -1 ;
258
+ return pymain_exit_err_print ();
234
259
}
235
260
runmodule = PyObject_GetAttrString (runpy , "_run_module_as_main" );
236
261
if (runmodule == NULL ) {
237
262
fprintf (stderr , "Could not access runpy._run_module_as_main\n" );
238
- PyErr_Print ();
239
263
Py_DECREF (runpy );
240
- return -1 ;
264
+ return pymain_exit_err_print () ;
241
265
}
242
266
module = PyUnicode_FromWideChar (modname , wcslen (modname ));
243
267
if (module == NULL ) {
244
268
fprintf (stderr , "Could not convert module name to unicode\n" );
245
- PyErr_Print ();
246
269
Py_DECREF (runpy );
247
270
Py_DECREF (runmodule );
248
- return -1 ;
271
+ return pymain_exit_err_print () ;
249
272
}
250
273
runargs = Py_BuildValue ("(Oi)" , module , set_argv0 );
251
274
if (runargs == NULL ) {
252
275
fprintf (stderr ,
253
276
"Could not create arguments for runpy._run_module_as_main\n" );
254
- PyErr_Print ();
255
277
Py_DECREF (runpy );
256
278
Py_DECREF (runmodule );
257
279
Py_DECREF (module );
258
- return -1 ;
280
+ return pymain_exit_err_print () ;
259
281
}
260
282
result = PyObject_Call (runmodule , runargs , NULL );
261
- if (result == NULL ) {
262
- PyErr_Print ();
263
- }
264
283
Py_DECREF (runpy );
265
284
Py_DECREF (runmodule );
266
285
Py_DECREF (module );
267
286
Py_DECREF (runargs );
268
287
if (result == NULL ) {
269
- return -1 ;
288
+ return pymain_exit_err_print () ;
270
289
}
271
290
Py_DECREF (result );
272
291
return 0 ;
@@ -315,9 +334,8 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
315
334
316
335
/* call pending calls like signal handlers (SIGINT) */
317
336
if (Py_MakePendingCalls () == -1 ) {
318
- PyErr_Print ();
319
337
fclose (fp );
320
- return 1 ;
338
+ return pymain_exit_err_print () ;
321
339
}
322
340
323
341
PyObject * unicode , * bytes = NULL ;
@@ -343,34 +361,36 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
343
361
}
344
362
345
363
346
- static void
347
- pymain_run_startup (_PyCoreConfig * config , PyCompilerFlags * cf )
364
+ static int
365
+ pymain_run_startup (_PyCoreConfig * config , PyCompilerFlags * cf , int * exitcode )
348
366
{
349
367
const char * startup = _Py_GetEnv (config -> use_environment , "PYTHONSTARTUP" );
350
368
if (startup == NULL ) {
351
- return ;
369
+ return 0 ;
352
370
}
353
371
354
372
FILE * fp = _Py_fopen (startup , "r" );
355
373
if (fp == NULL ) {
356
374
int save_errno = errno ;
357
375
PySys_WriteStderr ("Could not open PYTHONSTARTUP\n" );
376
+
358
377
errno = save_errno ;
378
+ PyErr_SetFromErrnoWithFilename (PyExc_OSError , startup );
359
379
360
- PyErr_SetFromErrnoWithFilename (PyExc_OSError ,
361
- startup );
362
- PyErr_Print ();
363
- return ;
380
+ return pymain_err_print (exitcode );
364
381
}
365
382
366
383
(void ) PyRun_SimpleFileExFlags (fp , startup , 0 , cf );
367
384
PyErr_Clear ();
368
385
fclose (fp );
386
+ return 0 ;
369
387
}
370
388
371
389
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 )
374
394
{
375
395
PyObject * sys , * hook , * result ;
376
396
sys = PyImport_ImportModule ("sys" );
@@ -382,7 +402,7 @@ pymain_run_interactive_hook(void)
382
402
Py_DECREF (sys );
383
403
if (hook == NULL ) {
384
404
PyErr_Clear ();
385
- return ;
405
+ return 0 ;
386
406
}
387
407
388
408
result = _PyObject_CallNoArg (hook );
@@ -392,11 +412,11 @@ pymain_run_interactive_hook(void)
392
412
}
393
413
Py_DECREF (result );
394
414
395
- return ;
415
+ return 0 ;
396
416
397
417
error :
398
418
PySys_WriteStderr ("Failed calling sys.__interactivehook__\n" );
399
- PyErr_Print ( );
419
+ return pymain_err_print ( exitcode );
400
420
}
401
421
402
422
@@ -406,14 +426,20 @@ pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf)
406
426
if (stdin_is_interactive (config )) {
407
427
config -> inspect = 0 ;
408
428
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
+ }
411
438
}
412
439
413
440
/* call pending calls like signal handlers (SIGINT) */
414
441
if (Py_MakePendingCalls () == -1 ) {
415
- PyErr_Print ();
416
- return 1 ;
442
+ return pymain_exit_err_print ();
417
443
}
418
444
419
445
int run = PyRun_AnyFileExFlags (stdin , "<stdin>" , 0 , cf );
@@ -437,7 +463,9 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
437
463
438
464
config -> inspect = 0 ;
439
465
Py_InspectFlag = 0 ;
440
- pymain_run_interactive_hook ();
466
+ if (pymain_run_interactive_hook (exitcode )) {
467
+ return ;
468
+ }
441
469
442
470
int res = PyRun_AnyFileFlags (stdin , "<stdin>" , cf );
443
471
* exitcode = (res != 0 );
@@ -457,8 +485,11 @@ pymain_run_python(int *exitcode)
457
485
__main__.py, main_importer_path is set to filename and will be
458
486
prepended to sys.path.
459
487
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
+ }
462
493
}
463
494
464
495
if (main_importer_path != NULL ) {
@@ -491,11 +522,10 @@ pymain_run_python(int *exitcode)
491
522
* exitcode = pymain_run_command (config -> run_command , & cf );
492
523
}
493
524
else if (config -> run_module ) {
494
- * exitcode = ( pymain_run_module (config -> run_module , 1 ) != 0 );
525
+ * exitcode = pymain_run_module (config -> run_module , 1 );
495
526
}
496
527
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 );
499
529
}
500
530
else if (config -> run_filename != NULL ) {
501
531
* exitcode = pymain_run_file (config , & cf );
@@ -508,8 +538,7 @@ pymain_run_python(int *exitcode)
508
538
goto done ;
509
539
510
540
error :
511
- PyErr_Print ();
512
- * exitcode = 1 ;
541
+ * exitcode = pymain_exit_err_print ();
513
542
514
543
done :
515
544
Py_XDECREF (main_importer_path );
0 commit comments