Skip to content

Commit d12d0e7

Browse files
authored
bpo-38733: PyErr_Occurred() caller must hold the GIL (GH-17080)
bpo-3605, bpo-38733: Optimize _PyErr_Occurred(): remove "tstate == NULL" test. Py_FatalError() no longer calls PyErr_Occurred() if called without holding the GIL. So PyErr_Occurred() no longer has to support tstate==NULL case. _Py_CheckFunctionResult(): use directly _PyErr_Occurred() to avoid explicit "!= NULL" test.
1 parent 991b02d commit d12d0e7

File tree

5 files changed

+12
-7
lines changed

5 files changed

+12
-7
lines changed

Doc/c-api/exceptions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ Querying the error indicator
374374
own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
375375
it.
376376
377+
The caller must hold the GIL.
378+
377379
.. note::
378380
379381
Do not compare the return value to a specific exception; use

Include/internal/pycore_pyerrors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ extern "C" {
1010

1111
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
1212
{
13-
return tstate == NULL ? NULL : tstate->curexc_type;
13+
assert(tstate != NULL);
14+
return tstate->curexc_type;
1415
}
1516

1617

Objects/call.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ PyObject*
3030
_Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
3131
PyObject *result, const char *where)
3232
{
33-
int err_occurred = (_PyErr_Occurred(tstate) != NULL);
34-
3533
assert((callable != NULL) ^ (where != NULL));
3634

3735
if (result == NULL) {
38-
if (!err_occurred) {
36+
if (!_PyErr_Occurred(tstate)) {
3937
if (callable)
4038
_PyErr_Format(tstate, PyExc_SystemError,
4139
"%R returned NULL without setting an error",
@@ -52,7 +50,7 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
5250
}
5351
}
5452
else {
55-
if (err_occurred) {
53+
if (_PyErr_Occurred(tstate)) {
5654
Py_DECREF(result);
5755

5856
if (callable) {

Objects/obmalloc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,12 +2313,13 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
23132313
return data;
23142314
}
23152315

2316-
static void
2316+
static inline void
23172317
_PyMem_DebugCheckGIL(void)
23182318
{
2319-
if (!PyGILState_Check())
2319+
if (!PyGILState_Check()) {
23202320
Py_FatalError("Python memory allocator called "
23212321
"without holding the GIL");
2322+
}
23222323
}
23232324

23242325
static void *

Python/errors.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ PyErr_SetString(PyObject *exception, const char *string)
218218
PyObject* _Py_HOT_FUNCTION
219219
PyErr_Occurred(void)
220220
{
221+
/* The caller must hold the GIL. */
222+
assert(PyGILState_Check());
223+
221224
PyThreadState *tstate = _PyThreadState_GET();
222225
return _PyErr_Occurred(tstate);
223226
}

0 commit comments

Comments
 (0)