summaryrefslogtreecommitdiffstats
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2023-03-08 04:05:16 (GMT)
committerThomas Wouters <thomas@python.org>2023-03-08 04:05:16 (GMT)
commit8fd55dd78ec0f66a375f1c0a4b649871ee182929 (patch)
treeb7d74170291113ca6e2ea7cc8a248f2285785e52 /Objects/codeobject.c
parent02b9a921cb3e6308ad300ee9c398b24998220931 (diff)
parente499680100a9d4fa4b673cbcfebc32212b4f848a (diff)
downloadcpython-8fd55dd78ec0f66a375f1c0a4b649871ee182929.zip
cpython-8fd55dd78ec0f66a375f1c0a4b649871ee182929.tar.gz
cpython-8fd55dd78ec0f66a375f1c0a4b649871ee182929.tar.bz2
Merge in the release of Python 3.12.0a6.
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 175bd57..65b1d25 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -11,9 +11,24 @@
#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) {
+ #define CASE(op) \
+ case PY_CODE_EVENT_##op: \
+ return "PY_CODE_EVENT_" #op;
+ PY_FOREACH_CODE_EVENT(CASE)
+ #undef CASE
+ }
+ Py_UNREACHABLE();
+}
+
static void
notify_code_watchers(PyCodeEvent event, PyCodeObject *co)
{
+ assert(Py_REFCNT(co) > 0);
PyInterpreterState *interp = _PyInterpreterState_GET();
assert(interp->_initialized);
uint8_t bits = interp->active_code_watchers;
@@ -25,7 +40,21 @@ 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) {
- PyErr_WriteUnraisable((PyObject *) co);
+ // 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);
}
}
i++;
@@ -1667,7 +1696,14 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
static void
code_dealloc(PyCodeObject *co)
{
+ assert(Py_REFCNT(co) == 0);
+ Py_SET_REFCNT(co, 1);
notify_code_watchers(PY_CODE_EVENT_DESTROY, co);
+ if (Py_REFCNT(co) > 1) {
+ Py_SET_REFCNT(co, Py_REFCNT(co) - 1);
+ return;
+ }
+ Py_SET_REFCNT(co, 0);
if (co->co_extra != NULL) {
PyInterpreterState *interp = _PyInterpreterState_GET();