Skip to content

Commit b893187

Browse files
committed
review comments
1 parent a31af32 commit b893187

File tree

6 files changed

+39
-26
lines changed

6 files changed

+39
-26
lines changed

Doc/c-api/code.rst

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,10 @@ bound into a function.
172172
before the destruction of *co* takes place, so the prior state of *co*
173173
can be inspected.
174174
175-
If *event* is ``PY_CODE_EVENT_DESTROY``, there may already be a pending
176-
exception set on entry to the callback; in this case, the callback may not
177-
execute Python code or otherwise disturb the pending exception. Taking a
178-
reference in the callback to an about-to-be-destroyed code object will
179-
resurrect it and prevent it from being freed.
175+
If *event* is ``PY_CODE_EVENT_DESTROY``, taking a reference in the callback
176+
to the about-to-be-destroyed code object will resurrect it and prevent it
177+
from being freed at this time. When the resurrected object is destroyed
178+
later, any watcher callbacks active at that time will be called again.
180179
181180
Users of this API should not rely on internal runtime implementation
182181
details. Such details may include, but are not limited to, the exact
@@ -187,8 +186,13 @@ bound into a function.
187186
188187
If the callback sets an exception, it must return ``-1``; this exception will
189188
be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`.
190-
Otherwise (including if an exception was already set on entry to the
191-
callback) it should return ``0``.
189+
Otherwise it should return ``0``.
190+
191+
There may already be a pending exception set on entry to the callback. In
192+
this case, the callback should return ``0`` with the same exception still
193+
set. This means the callback may not call any other API that can set an
194+
exception unless it saves and clears the exception state first, and restores
195+
it before returning.
192196
193197
.. versionadded:: 3.12
194198

Doc/c-api/dict.rst

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -301,18 +301,23 @@ Dictionary Objects
301301
unpredictable effects, including infinite recursion. Do not trigger Python
302302
code execution in the callback, as it could modify the dict as a side effect.
303303
304-
If *event* is ``PyDict_EVENT_DEALLOCATED``, there may already be a pending
305-
exception set on entry to the callback; in this case, the callback may not
306-
execute Python code or otherwise disturb the pending exception. Taking a new
307-
reference in the callback to an about-to-be-destroyed dictionary will
308-
resurrect it and prevent it from being freed.
304+
If *event* is ``PyDict_EVENT_DEALLOCATED``, taking a new reference in the
305+
callback to the about-to-be-destroyed dictionary will resurrect it and
306+
prevent it from being freed at this time. When the resurrected object is
307+
destroyed later, any watcher callbacks active at that time will be called
308+
again.
309309
310310
Callbacks occur before the notified modification to *dict* takes place, so
311311
the prior state of *dict* can be inspected.
312312
313313
If the callback sets an exception, it must return ``-1``; this exception will
314314
be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`.
315-
Otherwise (including if a pending exception was already set on entry to the
316-
callback) it should return ``0``.
315+
Otherwise it should return ``0``.
316+
317+
There may already be a pending exception set on entry to the callback. In
318+
this case, the callback should return ``0`` with the same exception still
319+
set. This means the callback may not call any other API that can set an
320+
exception unless it saves and clears the exception state first, and restores
321+
it before returning.
317322
318323
.. versionadded:: 3.12

Doc/c-api/function.rst

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,19 @@ There are a few functions specific to Python functions.
173173
runtime behavior depending on optimization decisions, it does not change
174174
the semantics of the Python code being executed.
175175
176-
If *event* is ``PyFunction_EVENT_DESTROY``, there may already be a pending
177-
exception set on entry to the callback; in this case, the callback may not
178-
execute Python code or otherwise disturb the pending exception. Taking a
179-
reference in the callback to an about-to-be-destroyed function will resurrect
180-
it, preventing it from being freed at this time. When the resurrected object is destroyed later,
181-
any watcher callbacks active at the time will be called again.
176+
If *event* is ``PyFunction_EVENT_DESTROY``, Taking a reference in the
177+
callback to the about-to-be-destroyed function will resurrect it, preventing
178+
it from being freed at this time. When the resurrected object is destroyed
179+
later, any watcher callbacks active at that time will be called again.
182180
183181
If the callback sets an exception, it must return ``-1``; this exception will
184182
be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`.
185-
Otherwise (including if a pending exception was already set on entry to the
186-
callback) it should return ``0``.
183+
Otherwise it should return ``0``.
184+
185+
There may already be a pending exception set on entry to the callback. In
186+
this case, the callback should return ``0`` with the same exception still
187+
set. This means the callback may not call any other API that can set an
188+
exception unless it saves and clears the exception state first, and restores
189+
it before returning.
187190
188191
.. versionadded:: 3.12

Objects/codeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,7 @@ code_dealloc(PyCodeObject *co)
16861686
Py_SET_REFCNT(co, 1);
16871687
notify_code_watchers(PY_CODE_EVENT_DESTROY, co);
16881688
if (Py_REFCNT(co) > 1) {
1689-
Py_DECREF(co);
1689+
Py_SET_REFCNT(co, Py_REFCNT(co) - 1);
16901690
return;
16911691
}
16921692
Py_SET_REFCNT(co, 0);

Objects/dictobject.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,7 +2312,7 @@ dict_dealloc(PyDictObject *mp)
23122312
Py_SET_REFCNT(mp, 1);
23132313
_PyDict_NotifyEvent(PyDict_EVENT_DEALLOCATED, mp, NULL, NULL);
23142314
if (Py_REFCNT(mp) > 1) {
2315-
Py_DECREF(mp);
2315+
Py_SET_REFCNT(mp, Py_REFCNT(mp) - 1);
23162316
return;
23172317
}
23182318
Py_SET_REFCNT(mp, 0);
@@ -5755,7 +5755,8 @@ _PyDict_SendEvent(int watcher_bits,
57555755
// unraisablehook keep a reference to it, so we don't pass the
57565756
// dict as context, just an informative string message. Dict
57575757
// repr can call arbitrary code, so we invent a simpler version.
5758-
PyObject *context = PyUnicode_FromFormat("watcher callback for <dict at %p>", mp);
5758+
PyObject *context = PyUnicode_FromFormat(
5759+
"watcher callback for <dict at %p>", mp);
57595760
if (context == NULL) {
57605761
context = Py_NewRef(Py_None);
57615762
}

Objects/funcobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ func_dealloc(PyFunctionObject *op)
785785
Py_SET_REFCNT(op, 1);
786786
handle_func_event(PyFunction_EVENT_DESTROY, op, NULL);
787787
if (Py_REFCNT(op) > 1) {
788-
Py_DECREF(op);
788+
Py_SET_REFCNT(op, Py_REFCNT(op) - 1);
789789
return;
790790
}
791791
Py_SET_REFCNT(op, 0);

0 commit comments

Comments
 (0)