Skip to content

Commit 61b6492

Browse files
authored
bpo-36710: Pass tstate explicitly in abstract.c (GH-21075)
In functions calling more than one PyErr function, get tstate and then pass it explicitly.
1 parent c41eed1 commit 61b6492

File tree

1 file changed

+61
-40
lines changed

1 file changed

+61
-40
lines changed

Objects/abstract.c

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "Python.h"
44
#include "pycore_abstract.h" // _PyIndex_Check()
55
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
6-
#include "pycore_pyerrors.h"
6+
#include "pycore_pyerrors.h" // _PyErr_Occurred()
77
#include "pycore_pystate.h" // _PyThreadState_GET()
88
#include <ctype.h>
99
#include <stddef.h> // offsetof()
@@ -23,9 +23,11 @@ type_error(const char *msg, PyObject *obj)
2323
static PyObject *
2424
null_error(void)
2525
{
26-
if (!PyErr_Occurred())
27-
PyErr_SetString(PyExc_SystemError,
28-
"null argument to internal routine");
26+
PyThreadState *tstate = _PyThreadState_GET();
27+
if (!_PyErr_Occurred(tstate)) {
28+
_PyErr_SetString(tstate, PyExc_SystemError,
29+
"null argument to internal routine");
30+
}
2931
return NULL;
3032
}
3133

@@ -94,11 +96,12 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
9496
if (_PyObject_HasLen(o)) {
9597
res = PyObject_Length(o);
9698
if (res < 0) {
97-
assert(PyErr_Occurred());
98-
if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
99+
PyThreadState *tstate = _PyThreadState_GET();
100+
assert(_PyErr_Occurred(tstate));
101+
if (!_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
99102
return -1;
100103
}
101-
PyErr_Clear();
104+
_PyErr_Clear(tstate);
102105
}
103106
else {
104107
return res;
@@ -114,8 +117,9 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
114117
result = _PyObject_CallNoArg(hint);
115118
Py_DECREF(hint);
116119
if (result == NULL) {
117-
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
118-
PyErr_Clear();
120+
PyThreadState *tstate = _PyThreadState_GET();
121+
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
122+
_PyErr_Clear(tstate);
119123
return defaultvalue;
120124
}
121125
return -1;
@@ -708,7 +712,7 @@ PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
708712
{
709713
if (view == NULL) {
710714
PyErr_SetString(PyExc_BufferError,
711-
"PyBuffer_FillInfo: view==NULL argument is obsolete");
715+
"PyBuffer_FillInfo: view==NULL argument is obsolete");
712716
return -1;
713717
}
714718

@@ -790,10 +794,12 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)
790794
/* Find the (unbound!) __format__ method */
791795
meth = _PyObject_LookupSpecial(obj, &PyId___format__);
792796
if (meth == NULL) {
793-
if (!PyErr_Occurred())
794-
PyErr_Format(PyExc_TypeError,
795-
"Type %.100s doesn't define __format__",
796-
Py_TYPE(obj)->tp_name);
797+
PyThreadState *tstate = _PyThreadState_GET();
798+
if (!_PyErr_Occurred(tstate)) {
799+
_PyErr_Format(tstate, PyExc_TypeError,
800+
"Type %.100s doesn't define __format__",
801+
Py_TYPE(obj)->tp_name);
802+
}
797803
goto done;
798804
}
799805

@@ -803,8 +809,8 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)
803809

804810
if (result && !PyUnicode_Check(result)) {
805811
PyErr_Format(PyExc_TypeError,
806-
"__format__ must return a str, not %.200s",
807-
Py_TYPE(result)->tp_name);
812+
"__format__ must return a str, not %.200s",
813+
Py_TYPE(result)->tp_name);
808814
Py_DECREF(result);
809815
result = NULL;
810816
goto done;
@@ -1388,17 +1394,23 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err)
13881394

13891395
/* We're done if PyLong_AsSsize_t() returns without error. */
13901396
result = PyLong_AsSsize_t(value);
1391-
if (result != -1 || !(runerr = PyErr_Occurred()))
1397+
if (result != -1)
1398+
goto finish;
1399+
1400+
PyThreadState *tstate = _PyThreadState_GET();
1401+
runerr = _PyErr_Occurred(tstate);
1402+
if (!runerr) {
13921403
goto finish;
1404+
}
13931405

13941406
/* Error handling code -- only manage OverflowError differently */
1395-
if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
1407+
if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) {
13961408
goto finish;
1409+
}
1410+
_PyErr_Clear(tstate);
13971411

1398-
PyErr_Clear();
13991412
/* If no error-handling desired then the default clipping
1400-
is sufficient.
1401-
*/
1413+
is sufficient. */
14021414
if (!err) {
14031415
assert(PyLong_Check(value));
14041416
/* Whether or not it is less than or equal to
@@ -1411,9 +1423,9 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err)
14111423
}
14121424
else {
14131425
/* Otherwise replace the error with caller's error object. */
1414-
PyErr_Format(err,
1415-
"cannot fit '%.200s' into an index-sized integer",
1416-
Py_TYPE(item)->tp_name);
1426+
_PyErr_Format(tstate, err,
1427+
"cannot fit '%.200s' into an index-sized integer",
1428+
Py_TYPE(item)->tp_name);
14171429
}
14181430

14191431
finish:
@@ -1448,8 +1460,8 @@ PyNumber_Long(PyObject *o)
14481460
return result;
14491461
if (!PyLong_Check(result)) {
14501462
PyErr_Format(PyExc_TypeError,
1451-
"__int__ returned non-int (type %.200s)",
1452-
result->ob_type->tp_name);
1463+
"__int__ returned non-int (type %.200s)",
1464+
result->ob_type->tp_name);
14531465
Py_DECREF(result);
14541466
return NULL;
14551467
}
@@ -2052,8 +2064,10 @@ PySequence_Fast(PyObject *v, const char *m)
20522064

20532065
it = PyObject_GetIter(v);
20542066
if (it == NULL) {
2055-
if (PyErr_ExceptionMatches(PyExc_TypeError))
2056-
PyErr_SetString(PyExc_TypeError, m);
2067+
PyThreadState *tstate = _PyThreadState_GET();
2068+
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
2069+
_PyErr_SetString(tstate, PyExc_TypeError, m);
2070+
}
20572071
return NULL;
20582072
}
20592073

@@ -2310,12 +2324,13 @@ method_output_as_list(PyObject *o, _Py_Identifier *meth_id)
23102324
}
23112325
it = PyObject_GetIter(meth_output);
23122326
if (it == NULL) {
2313-
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
2314-
PyErr_Format(PyExc_TypeError,
2315-
"%.200s.%U() returned a non-iterable (type %.200s)",
2316-
Py_TYPE(o)->tp_name,
2317-
_PyUnicode_FromId(meth_id),
2318-
Py_TYPE(meth_output)->tp_name);
2327+
PyThreadState *tstate = _PyThreadState_GET();
2328+
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
2329+
_PyErr_Format(tstate, PyExc_TypeError,
2330+
"%.200s.%U() returned a non-iterable (type %.200s)",
2331+
Py_TYPE(o)->tp_name,
2332+
_PyUnicode_FromId(meth_id),
2333+
Py_TYPE(meth_output)->tp_name);
23192334
}
23202335
Py_DECREF(meth_output);
23212336
return NULL;
@@ -2460,8 +2475,10 @@ check_class(PyObject *cls, const char *error)
24602475
PyObject *bases = abstract_get_bases(cls);
24612476
if (bases == NULL) {
24622477
/* Do not mask errors. */
2463-
if (!PyErr_Occurred())
2464-
PyErr_SetString(PyExc_TypeError, error);
2478+
PyThreadState *tstate = _PyThreadState_GET();
2479+
if (!_PyErr_Occurred(tstate)) {
2480+
_PyErr_SetString(tstate, PyExc_TypeError, error);
2481+
}
24652482
return 0;
24662483
}
24672484
Py_DECREF(bases);
@@ -2719,10 +2736,14 @@ PyIter_Next(PyObject *iter)
27192736
{
27202737
PyObject *result;
27212738
result = (*Py_TYPE(iter)->tp_iternext)(iter);
2722-
if (result == NULL &&
2723-
PyErr_Occurred() &&
2724-
PyErr_ExceptionMatches(PyExc_StopIteration))
2725-
PyErr_Clear();
2739+
if (result == NULL) {
2740+
PyThreadState *tstate = _PyThreadState_GET();
2741+
if (_PyErr_Occurred(tstate)
2742+
&& _PyErr_ExceptionMatches(tstate, PyExc_StopIteration))
2743+
{
2744+
_PyErr_Clear(tstate);
2745+
}
2746+
}
27262747
return result;
27272748
}
27282749

0 commit comments

Comments
 (0)