diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index 1efe4fa2bdef94..1b09a2e32c7d31 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -67,6 +67,9 @@ struct _Py_tuple_state { extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t); extern PyObject *_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyTuple_BorrowPack2(PyObject *ob1, PyObject *ob2); +PyAPI_FUNC(PyObject *) _PyTuple_BorrowPack3(PyObject *ob1, PyObject *ob2, PyObject *ob3); + #ifdef __cplusplus } #endif diff --git a/Modules/_json.c b/Modules/_json.c index 1c39b46937d792..1039eef05f12b8 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -353,14 +353,12 @@ _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { Py_DECREF(rval); return NULL; } - tpl = PyTuple_New(2); + tpl = _PyTuple_BorrowPack2(rval, pyidx); if (tpl == NULL) { Py_DECREF(pyidx); Py_DECREF(rval); return NULL; } - PyTuple_SET_ITEM(tpl, 0, rval); - PyTuple_SET_ITEM(tpl, 1, pyidx); return tpl; } @@ -1530,7 +1528,7 @@ encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *fir if (*first) { *first = false; - } + } else { if (_PyUnicodeWriter_WriteStr(writer, s->item_separator) < 0) { Py_DECREF(keystr); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 0cb95d52360ef1..946777115e1386 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4281,11 +4281,9 @@ dictiter_iternextitem(dictiterobject *di) } } else { - result = PyTuple_New(2); + result = _PyTuple_BorrowPack2(key, value); if (result == NULL) return NULL; - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ } return result; @@ -4415,12 +4413,10 @@ dictreviter_iternext(dictiterobject *di) } } else { - result = PyTuple_New(2); + result = _PyTuple_BorrowPack2(key, value); if (result == NULL) { return NULL; } - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ } return result; } diff --git a/Objects/enumobject.c b/Objects/enumobject.c index d84bac6f4c9af2..6be7862e38ba81 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -207,14 +207,12 @@ enum_next_long(enumobject *en, PyObject* next_item) } return result; } - result = PyTuple_New(2); + result = _PyTuple_BorrowPack2(next_index, next_item); if (result == NULL) { Py_DECREF(next_index); Py_DECREF(next_item); return NULL; } - PyTuple_SET_ITEM(result, 0, next_index); - PyTuple_SET_ITEM(result, 1, next_item); return result; } @@ -257,14 +255,12 @@ enum_next(enumobject *en) } return result; } - result = PyTuple_New(2); + result = _PyTuple_BorrowPack2(next_index, next_item); if (result == NULL) { Py_DECREF(next_index); Py_DECREF(next_item); return NULL; } - PyTuple_SET_ITEM(result, 0, next_index); - PyTuple_SET_ITEM(result, 1, next_item); return result; } diff --git a/Objects/longobject.c b/Objects/longobject.c index 90ed02b8c27a19..dcf42bbb45a4f3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4249,12 +4249,8 @@ long_divmod(PyObject *a, PyObject *b) if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, &mod) < 0) { return NULL; } - z = PyTuple_New(2); - if (z != NULL) { - PyTuple_SET_ITEM(z, 0, (PyObject *) div); - PyTuple_SET_ITEM(z, 1, (PyObject *) mod); - } - else { + z = _PyTuple_BorrowPack2(div, mod); + if (z == NULL) { Py_DECREF(div); Py_DECREF(mod); } @@ -5544,13 +5540,10 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) goto error; } - result = PyTuple_New(2); + result = _PyTuple_BorrowPack2(quo, rem); if (result == NULL) goto error; - /* PyTuple_SET_ITEM steals references */ - PyTuple_SET_ITEM(result, 0, (PyObject *)quo); - PyTuple_SET_ITEM(result, 1, (PyObject *)rem); return result; error: diff --git a/Objects/odictobject.c b/Objects/odictobject.c index bd2a7677fe1cf4..800e21a256c293 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1768,9 +1768,10 @@ odictiter_iternext(odictiterobject *di) if (!_PyObject_GC_IS_TRACKED(result)) { _PyObject_GC_TRACK(result); } - } - else { - result = PyTuple_New(2); + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + } else { + result = _PyTuple_BorrowPack2(key, value); if (result == NULL) { Py_DECREF(key); Py_DECREF(value); @@ -1778,8 +1779,6 @@ odictiter_iternext(odictiterobject *di) } } - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ return result; done: diff --git a/Objects/stringlib/partition.h b/Objects/stringlib/partition.h index bcc217697b2e9c..9569602b799684 100644 --- a/Objects/stringlib/partition.h +++ b/Objects/stringlib/partition.h @@ -23,17 +23,18 @@ STRINGLIB(partition)(PyObject* str_obj, return NULL; } - out = PyTuple_New(3); - if (!out) - return NULL; - pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_SEARCH); if (pos < 0) { #if STRINGLIB_MUTABLE - PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len)); - PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0)); - PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0)); + out = _PyTuple_BorrowPack3( + STRINGLIB_NEW(str, str_len), + STRINGLIB_NEW(NULL, 0), + STRINGLIB_NEW(NULL, 0) + ); + if (out == NULL) { + return NULL; + } if (PyErr_Occurred()) { Py_DECREF(out); @@ -41,25 +42,36 @@ STRINGLIB(partition)(PyObject* str_obj, } #else Py_INCREF(str_obj); - PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj); PyObject *empty = (PyObject*)STRINGLIB_GET_EMPTY(); assert(empty != NULL); Py_INCREF(empty); - PyTuple_SET_ITEM(out, 1, empty); Py_INCREF(empty); - PyTuple_SET_ITEM(out, 2, empty); + + out = _PyTuple_BorrowPack3(str_obj, empty, empty); + if (out == NULL) { + Py_DECREF(str_obj); + Py_DECREF(empty); + Py_DECREF(empty); + return NULL; + } #endif return out; } - PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos)); + PyObject *a = STRINGLIB_NEW(str, pos); Py_INCREF(sep_obj); - PyTuple_SET_ITEM(out, 1, sep_obj); pos += sep_len; - PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos)); + PyObject *b = STRINGLIB_NEW(str + pos, str_len - pos); if (PyErr_Occurred()) { - Py_DECREF(out); + return NULL; + } + + out = _PyTuple_BorrowPack3(a, sep_obj, b); + if (out == NULL) { + Py_DECREF(a); + Py_DECREF(sep_len); + Py_DECREF(b); return NULL; } @@ -122,4 +134,3 @@ STRINGLIB(rpartition)(PyObject* str_obj, return out; } - diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 240af0a9075271..bf7a35aef088ae 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -179,6 +179,40 @@ PyTuple_Pack(Py_ssize_t n, ...) return (PyObject *)result; } +PyObject * +_PyTuple_BorrowPack2(PyObject *a, PyObject *b) +{ + PyTupleObject *result; + result = tuple_alloc(2); + if (result == NULL) { + return NULL; + } + + result->ob_item[0] = a; + result->ob_item[1] = b; + + _PyObject_GC_TRACK(result); + return (PyObject *)result; +} + + +PyObject * +_PyTuple_BorrowPack3(PyObject *a, PyObject *b, PyObject *c) +{ + PyTupleObject *result; + result = tuple_alloc(3); + if (result == NULL) { + return NULL; + } + + result->ob_item[0] = a; + result->ob_item[1] = b; + result->ob_item[2] = c; + + _PyObject_GC_TRACK(result); + return (PyObject *)result; +} + /* Methods */