From 6b9e4ae1fd9db88a79069b9d1f6c17caec1e77d6 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 5 Oct 2026 14:11:09 +0200 Subject: [PATCH] Drop redundant incref/decref pair in dict_dict_merge() On the override path insertdict() receives its own references to key and value via Py_NewRef(), and nothing in the loop body uses them afterwards, so the outer Py_INCREF/Py_DECREF pair was pure overhead. Keep it only on the non-override path, where _PyDict_Contains_KnownHash() can run arbitrary __eq__ code and *dupkey needs a live reference. Co-Authored-By: Claude Fable 5.1 --- Objects/dictobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index bab983c2509c2c..eed9bd92c55bf2 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4269,12 +4269,12 @@ dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override, PyObject ** while (_PyDict_Next((PyObject*)other, &pos, &key, &value, &hash)) { int err = 0; - Py_INCREF(key); - Py_INCREF(value); if (override == 1) { err = insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value)); } else { + Py_INCREF(key); + Py_INCREF(value); err = _PyDict_Contains_KnownHash((PyObject *)mp, key, hash); if (err == 0) { err = insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value)); @@ -4287,9 +4287,9 @@ dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override, PyObject ** } err = 0; } + Py_DECREF(value); + Py_DECREF(key); } - Py_DECREF(value); - Py_DECREF(key); if (err != 0) return -1;