bpo-29587: _PyErr_ChainExceptions() checks exception (GH-19902)

_PyErr_ChainExceptions() now ensures that the first parameter is an
exception type, as done by _PyErr_SetObject().

* The following function now check PyExceptionInstance_Check() in an
  assertion using a new _PyBaseExceptionObject_cast() helper
  function:

  * PyException_GetTraceback(), PyException_SetTraceback()
  * PyException_GetCause(), PyException_SetCause()
  * PyException_GetContext(), PyException_SetContext()

* PyExceptionClass_Name() now checks PyExceptionClass_Check() with an
  assertion.

* Remove XXX comment and add gi_exc_state variable to _gen_throw().

* Remove comment from test_generators
This commit is contained in:
Victor Stinner 2020-05-05 17:07:41 +02:00 committed by GitHub
parent 4e30ed3af0
commit b0be6b3b94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 24 deletions

View file

@ -512,15 +512,15 @@ throw_here:
}
PyErr_Restore(typ, val, tb);
/* XXX It seems like we shouldn't have to check not equal to Py_None
here because exc_type should only ever be a class. But not including
this check was causing crashes on certain tests e.g. on Fedora. */
if (gen->gi_exc_state.exc_type && gen->gi_exc_state.exc_type != Py_None) {
Py_INCREF(gen->gi_exc_state.exc_type);
Py_XINCREF(gen->gi_exc_state.exc_value);
Py_XINCREF(gen->gi_exc_state.exc_traceback);
_PyErr_ChainExceptions(gen->gi_exc_state.exc_type,
gen->gi_exc_state.exc_value, gen->gi_exc_state.exc_traceback);
_PyErr_StackItem *gi_exc_state = &gen->gi_exc_state;
if (gi_exc_state->exc_type != NULL && gi_exc_state->exc_type != Py_None) {
Py_INCREF(gi_exc_state->exc_type);
Py_XINCREF(gi_exc_state->exc_value);
Py_XINCREF(gi_exc_state->exc_traceback);
_PyErr_ChainExceptions(gi_exc_state->exc_type,
gi_exc_state->exc_value,
gi_exc_state->exc_traceback);
}
return gen_send_ex(gen, Py_None, 1, 0);