diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-05-17 21:05:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-17 21:05:29 (GMT) |
commit | 12083284c54be25abadd85781d36b63731dc1f0c (patch) | |
tree | 5fdc2c6a606cd0d166562db7a07f96f3ae601e74 /Python/pythonrun.c | |
parent | bcfbbd704646622e919c1306a91fba61d603483d (diff) | |
download | cpython-12083284c54be25abadd85781d36b63731dc1f0c.zip cpython-12083284c54be25abadd85781d36b63731dc1f0c.tar.gz cpython-12083284c54be25abadd85781d36b63731dc1f0c.tar.bz2 |
bpo-36763: _Py_RunMain() doesn't call Py_Exit() anymore (GH-13390)
Py_Main() and _Py_RunMain() now return the exitcode rather than
calling Py_Exit(exitcode) when calling PyErr_Print() if the current
exception type is SystemExit.
* Add _Py_HandleSystemExit().
* Add pymain_exit_err_print().
* Add pymain_exit_print().
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r-- | Python/pythonrun.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index bc131fd..d2b2761 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -585,23 +585,31 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj) PyFile_WriteString("^\n", f); } -static void -handle_system_exit(void) -{ - PyObject *exception, *value, *tb; - int exitcode = 0; +int +_Py_HandleSystemExit(int *exitcode_p) +{ int inspect = _PyInterpreterState_GET_UNSAFE()->core_config.inspect; if (inspect) { /* Don't exit if -i flag was given. This flag is set to 0 * when entering interactive mode for inspecting. */ - return; + return 0; } + if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { + return 0; + } + + PyObject *exception, *value, *tb; PyErr_Fetch(&exception, &value, &tb); + fflush(stdout); - if (value == NULL || value == Py_None) + + int exitcode = 0; + if (value == NULL || value == Py_None) { goto done; + } + if (PyExceptionInstance_Check(value)) { /* The error code should be in the `code' attribute. */ _Py_IDENTIFIER(code); @@ -615,8 +623,10 @@ handle_system_exit(void) /* If we failed to dig out the 'code' attribute, just let the else clause below print the error. */ } - if (PyLong_Check(value)) + + if (PyLong_Check(value)) { exitcode = (int)PyLong_AsLong(value); + } else { PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr); /* We clear the exception here to avoid triggering the assertion @@ -633,6 +643,7 @@ handle_system_exit(void) PySys_WriteStderr("\n"); exitcode = 1; } + done: /* Restore and clear the exception info, in order to properly decref * the exception, value, and traceback. If we just exit instead, @@ -641,18 +652,28 @@ handle_system_exit(void) */ PyErr_Restore(exception, value, tb); PyErr_Clear(); - Py_Exit(exitcode); - /* NOTREACHED */ + *exitcode_p = exitcode; + return 1; } + +static void +handle_system_exit(void) +{ + int exitcode; + if (_Py_HandleSystemExit(&exitcode)) { + Py_Exit(exitcode); + } +} + + void PyErr_PrintEx(int set_sys_last_vars) { PyObject *exception, *v, *tb, *hook; - if (PyErr_ExceptionMatches(PyExc_SystemExit)) { - handle_system_exit(); - } + handle_system_exit(); + PyErr_Fetch(&exception, &v, &tb); if (exception == NULL) return; @@ -686,10 +707,9 @@ PyErr_PrintEx(int set_sys_last_vars) stack[2] = tb; result = _PyObject_FastCall(hook, stack, 3); if (result == NULL) { + handle_system_exit(); + PyObject *exception2, *v2, *tb2; - if (PyErr_ExceptionMatches(PyExc_SystemExit)) { - handle_system_exit(); - } PyErr_Fetch(&exception2, &v2, &tb2); PyErr_NormalizeException(&exception2, &v2, &tb2); /* It should not be possible for exception2 or v2 |