From eb71cca96b3d907943325fac24f7a9625d982f42 Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Fri, 13 Mar 2026 02:00:25 +0500 Subject: [PATCH] Use _PyTuple_FromPair[Steal] in Objects --- Objects/codeobject.c | 14 +++++++------- Objects/dictobject.c | 25 ++++++------------------- Objects/enumobject.c | 20 +++----------------- Objects/floatobject.c | 4 +++- Objects/frameobject.c | 8 +++----- Objects/listobject.c | 2 +- Objects/longobject.c | 22 ++++------------------ Objects/odictobject.c | 14 +++++--------- Objects/stringlib/unicode_format.h | 7 +++++-- Objects/typeobject.c | 5 +++-- Objects/typevarobject.c | 3 ++- 11 files changed, 42 insertions(+), 82 deletions(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index d26516f7c2ff66..4d537f329b31bf 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -3050,7 +3050,7 @@ _PyCode_ConstantKey(PyObject *op) else if (PyBool_Check(op) || PyBytes_CheckExact(op)) { /* Make booleans different from integers 0 and 1. * Avoid BytesWarning from comparing bytes with strings. */ - key = PyTuple_Pack(2, Py_TYPE(op), op); + key = _PyTuple_FromPair((PyObject *)Py_TYPE(op), op); } else if (PyFloat_CheckExact(op)) { double d = PyFloat_AS_DOUBLE(op); @@ -3060,7 +3060,7 @@ _PyCode_ConstantKey(PyObject *op) if (d == 0.0 && copysign(1.0, d) < 0.0) key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None); else - key = PyTuple_Pack(2, Py_TYPE(op), op); + key = _PyTuple_FromPair((PyObject *)Py_TYPE(op), op); } else if (PyComplex_CheckExact(op)) { Py_complex z; @@ -3084,7 +3084,7 @@ _PyCode_ConstantKey(PyObject *op) key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None); } else { - key = PyTuple_Pack(2, Py_TYPE(op), op); + key = _PyTuple_FromPair((PyObject *)Py_TYPE(op), op); } } else if (PyTuple_CheckExact(op)) { @@ -3109,7 +3109,7 @@ _PyCode_ConstantKey(PyObject *op) PyTuple_SET_ITEM(tuple, i, item_key); } - key = PyTuple_Pack(2, tuple, op); + key = _PyTuple_FromPair(tuple, op); Py_DECREF(tuple); } else if (PyFrozenSet_CheckExact(op)) { @@ -3143,7 +3143,7 @@ _PyCode_ConstantKey(PyObject *op) if (set == NULL) return NULL; - key = PyTuple_Pack(2, set, op); + key = _PyTuple_FromPair(set, op); Py_DECREF(set); return key; } @@ -3174,7 +3174,7 @@ _PyCode_ConstantKey(PyObject *op) goto slice_exit; } - key = PyTuple_Pack(2, slice_key, op); + key = _PyTuple_FromPair(slice_key, op); Py_DECREF(slice_key); slice_exit: Py_XDECREF(start_key); @@ -3188,7 +3188,7 @@ _PyCode_ConstantKey(PyObject *op) if (obj_id == NULL) return NULL; - key = PyTuple_Pack(2, obj_id, op); + key = _PyTuple_FromPair(obj_id, op); Py_DECREF(obj_id); } return key; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 842d9be73b8792..6aedc3f5fe1672 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -5439,7 +5439,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype) } if (itertype == &PyDictIterItem_Type || itertype == &PyDictRevIterItem_Type) { - di->di_result = PyTuple_Pack(2, Py_None, Py_None); + di->di_result = _PyTuple_FromPairSteal(Py_None, Py_None); if (di->di_result == NULL) { Py_DECREF(di); return NULL; @@ -6005,14 +6005,7 @@ dictiter_iternextitem(PyObject *self) _PyTuple_Recycle(result); } else { - result = PyTuple_New(2); - if (result == NULL) { - Py_DECREF(key); - Py_DECREF(value); - return NULL; - } - PyTuple_SET_ITEM(result, 0, key); - PyTuple_SET_ITEM(result, 1, value); + result = _PyTuple_FromPairSteal(key, value); } return result; } @@ -6131,12 +6124,7 @@ dictreviter_iter_lock_held(PyDictObject *d, PyObject *self) _PyTuple_Recycle(result); } else { - result = PyTuple_New(2); - if (result == NULL) { - return NULL; - } - PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); - PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); + result = _PyTuple_FromPair(key, value); } return result; } @@ -6629,6 +6617,7 @@ dictitems_xor_lock_held(PyObject *d1, PyObject *d2) else { Py_INCREF(val1); to_delete = PyObject_RichCompareBool(val1, val2, Py_EQ); + Py_DECREF(val1); if (to_delete < 0) { goto error; } @@ -6640,7 +6629,8 @@ dictitems_xor_lock_held(PyObject *d1, PyObject *d2) } } else { - PyObject *pair = PyTuple_Pack(2, key, val2); + PyObject *pair = _PyTuple_FromPairSteal(key, val2); + key = val2 = NULL; if (pair == NULL) { goto error; } @@ -6650,9 +6640,6 @@ dictitems_xor_lock_held(PyObject *d1, PyObject *d2) } Py_DECREF(pair); } - Py_DECREF(key); - Py_XDECREF(val1); - Py_DECREF(val2); } key = val1 = val2 = NULL; diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 70e7cce6aba008..d7cad67a0e30a0 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -78,7 +78,7 @@ enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start) Py_DECREF(en); return NULL; } - en->en_result = PyTuple_Pack(2, Py_None, Py_None); + en->en_result = _PyTuple_FromPairSteal(Py_None, Py_None); if (en->en_result == NULL) { Py_DECREF(en); return NULL; @@ -226,14 +226,7 @@ enum_next_long(enumobject *en, PyObject* next_item) _PyTuple_Recycle(result); return result; } - result = PyTuple_New(2); - 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); + result = _PyTuple_FromPairSteal(next_index, next_item); return result; } @@ -276,14 +269,7 @@ enum_next(PyObject *op) _PyTuple_Recycle(result); return result; } - result = PyTuple_New(2); - 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); + result = _PyTuple_FromPairSteal(next_index, next_item); return result; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 18871a4f3c51a9..33eded3acea321 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -16,6 +16,7 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_stackref.h" // PyStackRef_AsPyObjectBorrow() #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() +#include "pycore_tuple.h" // _PyTuple_FromPair #include // DBL_MAX #include // strtol() @@ -1540,7 +1541,8 @@ float_as_integer_ratio_impl(PyObject *self) goto error; } - result_pair = PyTuple_Pack(2, numerator, denominator); + result_pair = _PyTuple_FromPairSteal(numerator, denominator); + numerator = denominator = NULL; error: Py_XDECREF(py_exponent); diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 9a7abfc0ec26ab..1cfdc7105ad5f2 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -13,6 +13,7 @@ #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_opcode_metadata.h" // _PyOpcode_Caches #include "pycore_optimizer.h" // _Py_Executors_InvalidateDependency() +#include "pycore_tuple.h" // _PyTuple_FromPair #include "pycore_unicodeobject.h" // _PyUnicode_Equal() #include "frameobject.h" // PyFrameLocalsProxyObject @@ -630,22 +631,19 @@ framelocalsproxy_items(PyObject *self, PyObject *Py_UNUSED(ignored)) PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i); if (value) { - PyObject *pair = PyTuple_Pack(2, name, value); + PyObject *pair = _PyTuple_FromPairSteal(Py_NewRef(name), value); if (pair == NULL) { Py_DECREF(items); - Py_DECREF(value); return NULL; } if (PyList_Append(items, pair) < 0) { Py_DECREF(items); Py_DECREF(pair); - Py_DECREF(value); return NULL; } Py_DECREF(pair); - Py_DECREF(value); } } @@ -655,7 +653,7 @@ framelocalsproxy_items(PyObject *self, PyObject *Py_UNUSED(ignored)) PyObject *key = NULL; PyObject *value = NULL; while (PyDict_Next(frame->f_extra_locals, &j, &key, &value)) { - PyObject *pair = PyTuple_Pack(2, key, value); + PyObject *pair = _PyTuple_FromPair(key, value); if (pair == NULL) { Py_DECREF(items); return NULL; diff --git a/Objects/listobject.c b/Objects/listobject.c index 1cc62764e2fd8c..390a5899c42930 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1439,7 +1439,7 @@ list_extend_dictitems(PyListObject *self, PyDictObject *dict) Py_ssize_t i = 0; PyObject *key_value[2]; while (_PyDict_Next((PyObject *)dict, &pos, &key_value[0], &key_value[1], NULL)) { - PyObject *item = PyTuple_FromArray(key_value, 2); + PyObject *item = _PyTuple_FromPair(key_value[0], key_value[1]); if (item == NULL) { Py_SET_SIZE(self, m + i); return -1; diff --git a/Objects/longobject.c b/Objects/longobject.c index 185226db43a92a..782c102f2289fe 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -12,6 +12,7 @@ #include "pycore_runtime.h" // _PY_NSMALLPOSINTS #include "pycore_stackref.h" #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() +#include "pycore_tuple.h" // _PyTuple_FromPairSteal #include "pycore_unicodeobject.h" // _PyUnicode_Equal() #include // DBL_MANT_DIG @@ -4886,15 +4887,7 @@ 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 { - Py_DECREF(div); - Py_DECREF(mod); - } + z = _PyTuple_FromPairSteal((PyObject *)div, (PyObject *)mod); return z; } @@ -6185,13 +6178,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) goto error; } - result = PyTuple_New(2); - if (result == NULL) - goto error; - - /* PyTuple_SET_ITEM steals references */ - PyTuple_SET_ITEM(result, 0, (PyObject *)quo); - PyTuple_SET_ITEM(result, 1, (PyObject *)rem); + result = _PyTuple_FromPairSteal((PyObject *)quo, (PyObject *)rem); return result; error: @@ -6374,8 +6361,7 @@ int_as_integer_ratio_impl(PyObject *self) if (numerator == NULL) { return NULL; } - ratio_tuple = PyTuple_Pack(2, numerator, _PyLong_GetOne()); - Py_DECREF(numerator); + ratio_tuple = _PyTuple_FromPairSteal(numerator, _PyLong_GetOne()); return ratio_tuple; } diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 25928028919c9c..786e584a3b83bf 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1171,9 +1171,7 @@ OrderedDict_popitem_impl(PyODictObject *self, int last) value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node)); if (value == NULL) return NULL; - item = PyTuple_Pack(2, key, value); - Py_DECREF(key); - Py_DECREF(value); + item = _PyTuple_FromPairSteal(key, value); return item; } @@ -1828,18 +1826,16 @@ odictiter_iternext_lock_held(PyObject *op) // bpo-42536: The GC may have untracked this result tuple. Since we're // recycling it, make sure it's tracked again: _PyTuple_Recycle(result); + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ } else { - result = PyTuple_New(2); + result = _PyTuple_FromPairSteal(key, value); if (result == NULL) { - Py_DECREF(key); - Py_DECREF(value); goto done; } } - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ return result; done: @@ -1933,7 +1929,7 @@ odictiter_new(PyODictObject *od, int kind) return NULL; if ((kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) { - di->di_result = PyTuple_Pack(2, Py_None, Py_None); + di->di_result = _PyTuple_FromPairSteal(Py_None, Py_None); if (di->di_result == NULL) { Py_DECREF(di); return NULL; diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index ff32db65b11a0b..e591ce50e7d947 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -4,6 +4,7 @@ #include "pycore_complexobject.h" // _PyComplex_FormatAdvancedWriter() #include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter() +#include "pycore_tuple.h" // _PyTuple_FromPairSteal /************************************************************************/ /*********** Global data structures and forward declarations *********/ @@ -1183,7 +1184,8 @@ fieldnameiter_next(PyObject *op) goto done; /* return a tuple of values */ - result = PyTuple_Pack(2, is_attr_obj, obj); + result = _PyTuple_FromPairSteal(is_attr_obj, obj); + return result; done: Py_XDECREF(is_attr_obj); @@ -1274,7 +1276,8 @@ formatter_field_name_split(PyObject *Py_UNUSED(module), PyObject *self) goto done; /* return a tuple of values */ - result = PyTuple_Pack(2, first_obj, it); + result = _PyTuple_FromPairSteal(first_obj, (PyObject *)it); + return result; done: Py_XDECREF(it); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2a818f5f0205fd..3903efd8c1457b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -19,6 +19,7 @@ #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // _Py_Mangle() +#include "pycore_tuple.h" // _PyTuple_FromPair #include "pycore_typeobject.h" // struct type_cache #include "pycore_unicodeobject.h" // _PyUnicode_Copy #include "pycore_unionobject.h" // _Py_union_type_or @@ -1782,7 +1783,7 @@ mro_hierarchy_for_complete_type(PyTypeObject *type, PyObject *temp) tuple = PyTuple_Pack(3, type, new_mro, old_mro); } else { - tuple = PyTuple_Pack(2, type, new_mro); + tuple = _PyTuple_FromPair((PyObject *)type, new_mro); } if (tuple != NULL) { @@ -7826,7 +7827,7 @@ object_getstate_default(PyObject *obj, int required) if (PyDict_GET_SIZE(slots) > 0) { PyObject *state2; - state2 = PyTuple_Pack(2, state, slots); + state2 = _PyTuple_FromPair(state, slots); Py_DECREF(state); if (state2 == NULL) { Py_DECREF(slotnames); diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 0a260f4c10278c..a206bd7b5dd404 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_interpframe.h" // _PyInterpreterFrame #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK, PyAnnotateFormat +#include "pycore_tuple.h" // _PyTuple_FromPair #include "pycore_typevarobject.h" #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString() #include "pycore_unionobject.h" // _Py_union_type_or, _Py_union_from_tuple @@ -373,7 +374,7 @@ type_check(PyObject *arg, const char *msg) static PyObject * make_union(PyObject *self, PyObject *other) { - PyObject *args = PyTuple_Pack(2, self, other); + PyObject *args = _PyTuple_FromPair(self, other); if (args == NULL) { return NULL; }