gh-67377: Document that PyErr_SetString, etc. chain exceptions by cjerdonek · Pull Request #20329 · python/cpython

The precise condition inside _PyErr_SetObject is if _PyErr_GetTopmostException returns a non-None value:

exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
if (exc_value != NULL && exc_value != Py_None) {
/* Implicit exception chaining */

However, this is a private function.

So some other ways to say this (without reference to C functions) are (1) if there's an "active exception" (the wording in do_raise()'s RuntimeError message), (2) if an exception is currently being handled (anywhere on the stack), or (3) if sys.exc_info() would return an exception.

sys.exc_info()'s documentation
https://docs.python.org/3/library/sys.html#sys.exc_info

Do you have a preference?