Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
gh-108082: Use PyErr_FormatUnraisable()
Replace most of calls of _PyErr_WriteUnraisableMsg() and some
calls of PyErr_WriteUnraisable(NULL) with PyErr_FormatUnraisable().
  • Loading branch information
serhiy-storchaka committed Oct 31, 2023
commit e126cd5dfb3673030ad7f7733b599951d7da8b5e
3 changes: 1 addition & 2 deletions Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ bytes(cdata)
#ifdef MS_WIN32
# include "pycore_modsupport.h" // _PyArg_NoKeywords()
#endif
#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg()


#include <ffi.h>
Expand Down Expand Up @@ -185,7 +184,7 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
DictRemoverObject *self = (DictRemoverObject *)myself;
if (self->key && self->dict) {
if (-1 == PyDict_DelItem(self->dict, self->key)) {
_PyErr_WriteUnraisableMsg("on calling _ctypes.DictRemover", NULL);
PyErr_FormatUnraisable("Exception ignored on calling _ctypes.DictRemover");
}
Py_CLEAR(self->key);
Py_CLEAR(self->dict);
Expand Down
3 changes: 1 addition & 2 deletions Modules/_lsprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_SetProfile()
#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg()
#include "pycore_pystate.h" // _PyThreadState_GET()

#include "rotatingtree.h"
Expand Down Expand Up @@ -847,7 +846,7 @@ profiler_dealloc(ProfilerObject *op)
if (op->flags & POF_ENABLED) {
PyThreadState *tstate = _PyThreadState_GET();
if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
_PyErr_WriteUnraisableMsg("When destroying _lsprof profiler", NULL);
PyErr_FormatUnraisable("Exception ignored when destroying _lsprof profiler");
}
}

Expand Down
10 changes: 5 additions & 5 deletions Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,8 +1032,8 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
Py_INCREF(op);
(void) clear(op);
if (_PyErr_Occurred(tstate)) {
_PyErr_WriteUnraisableMsg("in tp_clear of",
(PyObject*)Py_TYPE(op));
PyErr_FormatUnraisable("Exception ignored in tp_clear of %.200s",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO %.200s is a bug here. We should no longer truncate type names if they are too long. Many years ago, Python had an internal buffer of a fixed size and so the overall string must not be too long. But this has been fixed.

Please don't truncate type names.

Py_TYPE(op)->tp_name);
}
Py_DECREF(op);
}
Expand Down Expand Up @@ -1344,7 +1344,7 @@ gc_collect_main(PyThreadState *tstate, int generation,
_PyErr_Clear(tstate);
}
else {
_PyErr_WriteUnraisableMsg("in garbage collection", NULL);
PyErr_FormatUnraisable("Exception ignored in garbage collection");
}
}

Expand Down Expand Up @@ -1403,15 +1403,15 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase,
"collected", collected,
"uncollectable", uncollectable);
if (info == NULL) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks");
return;
}
}

PyObject *phase_obj = PyUnicode_FromString(phase);
if (phase_obj == NULL) {
Py_XDECREF(info);
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks");
return;
}

Expand Down
7 changes: 3 additions & 4 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "pycore_fileutils.h" // _Py_abspath()
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
#include "pycore_pathconfig.h" // _PyPathConfig_ReadGlobal()
#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg()
#include "pycore_pymem.h" // _PyMem_RawWcsdup()
#include "pycore_pystate.h" // _PyThreadState_GET()

Expand Down Expand Up @@ -911,7 +910,7 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config)
) {
Py_DECREF(co);
Py_DECREF(dict);
_PyErr_WriteUnraisableMsg("error evaluating initial values", NULL);
PyErr_FormatUnraisable("Exception ignored in evaluating initial values");
Comment thread
serhiy-storchaka marked this conversation as resolved.
Outdated
return PyStatus_Error("error evaluating initial values");
}

Expand All @@ -920,13 +919,13 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config)

if (!r) {
Py_DECREF(dict);
_PyErr_WriteUnraisableMsg("error evaluating path", NULL);
PyErr_FormatUnraisable("Exception ignored in evaluating path");
Comment thread
serhiy-storchaka marked this conversation as resolved.
Outdated
return PyStatus_Error("error evaluating path");
}
Py_DECREF(r);

if (_PyConfig_FromDict(config, configDict) < 0) {
_PyErr_WriteUnraisableMsg("reading getpath results", NULL);
PyErr_FormatUnraisable("Exception ignored in reading getpath results");
Py_DECREF(dict);
return PyStatus_Error("error getting getpath results");
}
Expand Down
5 changes: 2 additions & 3 deletions Modules/signalmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,7 @@ report_wakeup_write_error(void *data)
errno = (int) (intptr_t) data;
PyObject *exc = PyErr_GetRaisedException();
PyErr_SetFromErrno(PyExc_OSError);
_PyErr_WriteUnraisableMsg("when trying to write to the signal wakeup fd",
NULL);
PyErr_FormatUnraisable("Exception ignored when trying to write to the signal wakeup fd");
PyErr_SetRaisedException(exc);
errno = save_errno;
return 0;
Expand All @@ -262,7 +261,7 @@ report_wakeup_send_error(void* data)
recognizes the error codes used by both GetLastError() and
WSAGetLastError */
PyErr_SetExcFromWindowsErr(PyExc_OSError, send_errno);
_PyErr_WriteUnraisableMsg("when trying to send to the signal wakeup fd", NULL);
PyErr_FormatUnraisable("Exception ignored when trying to send to the signal wakeup fd");
PyErr_SetRaisedException(exc);
return 0;
}
Expand Down
20 changes: 3 additions & 17 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "clinic/codeobject.c.h"

static PyObject* code_repr(PyCodeObject *co);

static const char *
code_event_name(PyCodeEvent event) {
switch (event) {
Expand Down Expand Up @@ -41,21 +39,9 @@ notify_code_watchers(PyCodeEvent event, PyCodeObject *co)
// callback must be non-null if the watcher bit is set
assert(cb != NULL);
if (cb(event, co) < 0) {
// Don't risk resurrecting the object if an unraisablehook keeps
// a reference; pass a string as context.
PyObject *context = NULL;
PyObject *repr = code_repr(co);
if (repr) {
context = PyUnicode_FromFormat(
"%s watcher callback for %U",
code_event_name(event), repr);
Py_DECREF(repr);
}
if (context == NULL) {
context = Py_NewRef(Py_None);
}
PyErr_WriteUnraisable(context);
Py_DECREF(context);
PyErr_FormatUnraisable(
"Exception ignored in %s watcher callback for %R",
code_event_name(event), co);
}
}
i++;
Expand Down
9 changes: 2 additions & 7 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -5912,14 +5912,9 @@ _PyDict_SendEvent(int watcher_bits,
// unraisablehook keep a reference to it, so we don't pass the
// dict as context, just an informative string message. Dict
// repr can call arbitrary code, so we invent a simpler version.
PyObject *context = PyUnicode_FromFormat(
"%s watcher callback for <dict at %p>",
PyErr_FormatUnraisable(
"Exception ignored in %s watcher callback for <dict at %p>",
dict_event_name(event), mp);
if (context == NULL) {
context = Py_NewRef(Py_None);
}
PyErr_WriteUnraisable(context);
Py_DECREF(context);
}
}
watcher_bits >>= 1;
Expand Down
20 changes: 3 additions & 17 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include "pycore_pyerrors.h" // _PyErr_Occurred()


static PyObject* func_repr(PyFunctionObject *op);

static const char *
func_event_name(PyFunction_WatchEvent event) {
switch (event) {
Expand All @@ -35,21 +33,9 @@ notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event,
// callback must be non-null if the watcher bit is set
assert(cb != NULL);
if (cb(event, func, new_value) < 0) {
// Don't risk resurrecting the func if an unraisablehook keeps a
// reference; pass a string as context.
PyObject *context = NULL;
PyObject *repr = func_repr(func);
if (repr != NULL) {
context = PyUnicode_FromFormat(
"%s watcher callback for %U",
func_event_name(event), repr);
Py_DECREF(repr);
}
if (context == NULL) {
context = Py_NewRef(Py_None);
}
PyErr_WriteUnraisable(context);
Py_DECREF(context);
PyErr_FormatUnraisable(
"Exception ignored in %s watcher callback for function %U at %p",
func_event_name(event), func->func_qualname, func);
}
}
i++;
Expand Down
11 changes: 5 additions & 6 deletions Objects/moduleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ _PyModule_ClearDict(PyObject *d)
PyErr_Clear();
}
if (PyDict_SetItem(d, key, Py_None) != 0) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on clearing module dict");
}
}
}
Expand All @@ -668,7 +668,7 @@ _PyModule_ClearDict(PyObject *d)
PyErr_Clear();
}
if (PyDict_SetItem(d, key, Py_None) != 0) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on clearing module dict");
}
}
}
Expand Down Expand Up @@ -902,10 +902,9 @@ module_clear(PyModuleObject *m)
{
int res = m->md_def->m_clear((PyObject*)m);
if (PyErr_Occurred()) {
PySys_FormatStderr("Exception ignored in m_clear of module%s%V\n",
m->md_name ? " " : "",
m->md_name, "");
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored in m_clear of module%s%V\n",
m->md_name ? " " : "",
m->md_name, "");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PyErr_FormatUnraisable("Exception ignored in m_clear of module%s%V\n",
m->md_name ? " " : "",
m->md_name, "");
PyErr_FormatUnraisable("Exception ignored in m_clear of module%s%V",
m->md_name ? " " : "",
m->md_name);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last "" is not used, it can be removed.

}
if (res)
return res;
Expand Down
8 changes: 4 additions & 4 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ PyType_Modified(PyTypeObject *type)
if (bits & 1) {
PyType_WatchCallback cb = interp->type_watchers[i];
if (cb && (cb(type) < 0)) {
PyErr_WriteUnraisable((PyObject *)type);
PyErr_FormatUnraisable("Exception ignored in watcher callback for %R", i, type);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to log i variable, you should add %i somewhere.

}
}
i++;
Expand Down Expand Up @@ -9291,7 +9291,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer)
// from a Python __buffer__ function.
mv = PyMemoryView_FromBuffer(buffer);
if (mv == NULL) {
PyErr_WriteUnraisable(self);
PyErr_FormatUnraisable("Exception ignored in bf_releasebuffer of %s", Py_TYPE(self)->tp_name);
goto end;
}
// Set the memoryview to restricted mode, which forbids
Expand All @@ -9304,15 +9304,15 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer)
PyObject *stack[2] = {self, mv};
PyObject *ret = vectorcall_method(&_Py_ID(__release_buffer__), stack, 2);
if (ret == NULL) {
PyErr_WriteUnraisable(self);
PyErr_FormatUnraisable("Exception ignored in __release_buffer__ of %s", Py_TYPE(self)->tp_name);
}
else {
Py_DECREF(ret);
}
if (!is_buffer_wrapper) {
PyObject *res = PyObject_CallMethodNoArgs(mv, &_Py_ID(release));
if (res == NULL) {
PyErr_WriteUnraisable(self);
PyErr_FormatUnraisable("Exception ignored in bf_releasebuffer of %s", Py_TYPE(self)->tp_name);
}
else {
Py_DECREF(res);
Expand Down
8 changes: 4 additions & 4 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,7 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
PyThreadState *tstate = _PyThreadState_GET();
if (_PyEval_SetProfile(tstate, func, arg) < 0) {
/* Log _PySys_Audit() error */
_PyErr_WriteUnraisableMsg("in PyEval_SetProfile", NULL);
PyErr_FormatUnraisable("Exception ignored in PyEval_SetProfile");
}
}

Expand All @@ -2122,7 +2122,7 @@ PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg)

while (ts) {
if (_PyEval_SetProfile(ts, func, arg) < 0) {
_PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL);
PyErr_FormatUnraisable("Exception ignored in PyEval_SetProfileAllThreads");
}
HEAD_LOCK(runtime);
ts = PyThreadState_Next(ts);
Expand All @@ -2136,7 +2136,7 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
PyThreadState *tstate = _PyThreadState_GET();
if (_PyEval_SetTrace(tstate, func, arg) < 0) {
/* Log _PySys_Audit() error */
_PyErr_WriteUnraisableMsg("in PyEval_SetTrace", NULL);
PyErr_FormatUnraisable("Exception ignored in PyEval_SetTrace");
}
}

Expand All @@ -2153,7 +2153,7 @@ PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg)

while (ts) {
if (_PyEval_SetTrace(ts, func, arg) < 0) {
_PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL);
PyErr_FormatUnraisable("Exception ignored in PyEval_SetTraceAllThreads");
}
HEAD_LOCK(runtime);
ts = PyThreadState_Next(ts);
Expand Down
5 changes: 2 additions & 3 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#include "pycore_flowgraph.h"
#include "pycore_intrinsics.h"
#include "pycore_long.h" // _PyLong_GetZero()
#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg()
#include "pycore_pystate.h" // _Py_GetConfig()
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST()
Expand Down Expand Up @@ -1407,8 +1406,8 @@ compiler_exit_scope(struct compiler *c)
assert(c->u);
/* we are deleting from a list so this really shouldn't fail */
if (PySequence_DelItem(c->c_stack, n) < 0) {
_PyErr_WriteUnraisableMsg("on removing the last compiler "
"stack item", NULL);
PyErr_FormatUnraisable("Exception ignored on removing "
"the last compiler stack item");
}
}
else {
Expand Down
10 changes: 5 additions & 5 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp)
if (PyList_SetSlice(MODULES_BY_INDEX(interp),
0, PyList_GET_SIZE(MODULES_BY_INDEX(interp)),
NULL)) {
PyErr_WriteUnraisable(MODULES_BY_INDEX(interp));
PyErr_FormatUnraisable("Exception ignored on clearing interpreters module-list");
Comment thread
serhiy-storchaka marked this conversation as resolved.
Outdated
}
}

Expand Down Expand Up @@ -3156,13 +3156,13 @@ _PyImport_FiniCore(PyInterpreterState *interp)
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;

if (_PySys_ClearAttrString(interp, "meta_path", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on clearing sys.meta_path");
}

// XXX Pull in most of finalize_modules() in pylifecycle.c.

if (_PySys_ClearAttrString(interp, "modules", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on clearing sys.modules");
}

if (IMPORT_LOCK(interp) != NULL) {
Expand Down Expand Up @@ -3242,10 +3242,10 @@ _PyImport_FiniExternal(PyInterpreterState *interp)
// XXX Uninstall importlib metapath importers here?

if (_PySys_ClearAttrString(interp, "path_importer_cache", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on clearing sys.path_importer_cache");
}
if (_PySys_ClearAttrString(interp, "path_hooks", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
PyErr_FormatUnraisable("Exception ignored on clearing sys.path_hooks");
}
}

Expand Down
Loading