mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
Allow sys.excepthook and sys.exitfunc to quietly exit with a sys.exit().
sys.exitfunc gets the last word on the exit status of the program.
This commit is contained in:
parent
a9c6c8dab5
commit
26fabb0016
1 changed files with 37 additions and 32 deletions
|
@ -798,6 +798,35 @@ print_error_text(PyObject *f, int offset, char *text)
|
||||||
PyFile_WriteString("^\n", f);
|
PyFile_WriteString("^\n", f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PyRun_HandleSystemExit(PyObject* value)
|
||||||
|
{
|
||||||
|
if (Py_FlushLine())
|
||||||
|
PyErr_Clear();
|
||||||
|
fflush(stdout);
|
||||||
|
if (value == NULL || value == Py_None)
|
||||||
|
Py_Exit(0);
|
||||||
|
if (PyInstance_Check(value)) {
|
||||||
|
/* The error code should be in the `code' attribute. */
|
||||||
|
PyObject *code = PyObject_GetAttrString(value, "code");
|
||||||
|
if (code) {
|
||||||
|
Py_DECREF(value);
|
||||||
|
value = code;
|
||||||
|
if (value == Py_None)
|
||||||
|
Py_Exit(0);
|
||||||
|
}
|
||||||
|
/* If we failed to dig out the 'code' attribute,
|
||||||
|
just let the else clause below print the error. */
|
||||||
|
}
|
||||||
|
if (PyInt_Check(value))
|
||||||
|
Py_Exit((int)PyInt_AsLong(value));
|
||||||
|
else {
|
||||||
|
PyObject_Print(value, stderr, Py_PRINT_RAW);
|
||||||
|
PySys_WriteStderr("\n");
|
||||||
|
Py_Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PyErr_PrintEx(int set_sys_last_vars)
|
PyErr_PrintEx(int set_sys_last_vars)
|
||||||
{
|
{
|
||||||
|
@ -809,35 +838,7 @@ PyErr_PrintEx(int set_sys_last_vars)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
|
if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
|
||||||
if (Py_FlushLine())
|
PyRun_HandleSystemExit(v);
|
||||||
PyErr_Clear();
|
|
||||||
fflush(stdout);
|
|
||||||
if (v == NULL || v == Py_None)
|
|
||||||
Py_Exit(0);
|
|
||||||
if (PyInstance_Check(v)) {
|
|
||||||
/* we expect the error code to be store in the
|
|
||||||
`code' attribute
|
|
||||||
*/
|
|
||||||
PyObject *code = PyObject_GetAttrString(v, "code");
|
|
||||||
if (code) {
|
|
||||||
Py_DECREF(v);
|
|
||||||
v = code;
|
|
||||||
if (v == Py_None)
|
|
||||||
Py_Exit(0);
|
|
||||||
}
|
|
||||||
/* if we failed to dig out the "code" attribute,
|
|
||||||
then just let the else clause below print the
|
|
||||||
error
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
if (PyInt_Check(v))
|
|
||||||
Py_Exit((int)PyInt_AsLong(v));
|
|
||||||
else {
|
|
||||||
/* OK to use real stderr here */
|
|
||||||
PyObject_Print(v, stderr, Py_PRINT_RAW);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
Py_Exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (set_sys_last_vars) {
|
if (set_sys_last_vars) {
|
||||||
PySys_SetObject("last_type", exception);
|
PySys_SetObject("last_type", exception);
|
||||||
|
@ -853,6 +854,10 @@ PyErr_PrintEx(int set_sys_last_vars)
|
||||||
PyObject *exception2, *v2, *tb2;
|
PyObject *exception2, *v2, *tb2;
|
||||||
PyErr_Fetch(&exception2, &v2, &tb2);
|
PyErr_Fetch(&exception2, &v2, &tb2);
|
||||||
PyErr_NormalizeException(&exception2, &v2, &tb2);
|
PyErr_NormalizeException(&exception2, &v2, &tb2);
|
||||||
|
if (PyErr_GivenExceptionMatches(
|
||||||
|
exception2, PyExc_SystemExit)) {
|
||||||
|
PyRun_HandleSystemExit(v2);
|
||||||
|
}
|
||||||
if (Py_FlushLine())
|
if (Py_FlushLine())
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -1254,11 +1259,11 @@ call_sys_exitfunc(void)
|
||||||
PyObject *res, *f;
|
PyObject *res, *f;
|
||||||
Py_INCREF(exitfunc);
|
Py_INCREF(exitfunc);
|
||||||
PySys_SetObject("exitfunc", (PyObject *)NULL);
|
PySys_SetObject("exitfunc", (PyObject *)NULL);
|
||||||
f = PySys_GetObject("stderr");
|
|
||||||
res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
|
res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
if (f)
|
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||||
PyFile_WriteString("Error in sys.exitfunc:\n", f);
|
PySys_WriteStderr("Error in sys.exitfunc:\n");
|
||||||
|
}
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
}
|
}
|
||||||
Py_DECREF(exitfunc);
|
Py_DECREF(exitfunc);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue