https://github.com/python/cpython/commit/ef3ceab09d2d0959c343c662461123d5b0e0b64b
commit: ef3ceab09d2d0959c343c662461123d5b0e0b64b
branch: main
author: Sam Gross <[email protected]>
committer: colesbury <[email protected]>
date: 2024-02-07T13:43:18-05:00
summary:

gh-112066: Use `PyDict_SetDefaultRef` in place of `PyDict_SetDefault`. (#112211)

This changes a number of internal usages of `PyDict_SetDefault` to use 
`PyDict_SetDefaultRef`.

Co-authored-by: Erlend E. Aasland <[email protected]>

files:
M Modules/_json.c
M Modules/posixmodule.c
M Modules/pyexpat.c
M Objects/typeobject.c
M Objects/unicodeobject.c
M Python/compile.c

diff --git a/Modules/_json.c b/Modules/_json.c
index 24b292ce70e5eb..c55299899e77fe 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -691,11 +691,10 @@ _parse_object_unicode(PyScannerObject *s, PyObject *memo, 
PyObject *pystr, Py_ss
             key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
             if (key == NULL)
                 goto bail;
-            memokey = PyDict_SetDefault(memo, key, key);
-            if (memokey == NULL) {
+            if (PyDict_SetDefaultRef(memo, key, key, &memokey) < 0) {
                 goto bail;
             }
-            Py_SETREF(key, Py_NewRef(memokey));
+            Py_SETREF(key, memokey);
             idx = next_idx;
 
             /* skip whitespace between key and : delimiter, read :, skip 
whitespace */
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 22891135bde0af..e26265fc874ebb 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1627,7 +1627,7 @@ convertenviron(void)
             Py_DECREF(d);
             return NULL;
         }
-        if (PyDict_SetDefault(d, k, v) == NULL) {
+        if (PyDict_SetDefaultRef(d, k, v, NULL) < 0) {
             Py_DECREF(v);
             Py_DECREF(k);
             Py_DECREF(d);
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 7c08eda83e66b2..62cd262a7885e9 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1615,7 +1615,8 @@ static int init_handler_descrs(pyexpat_state *state)
         if (descr == NULL)
             return -1;
 
-        if (PyDict_SetDefault(state->xml_parse_type->tp_dict, 
PyDescr_NAME(descr), descr) == NULL) {
+        if (PyDict_SetDefaultRef(state->xml_parse_type->tp_dict,
+                                 PyDescr_NAME(descr), descr, NULL) < 0) {
             Py_DECREF(descr);
             return -1;
         }
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index e220d10ce563c2..c65d0ec2acae52 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -6683,7 +6683,7 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth)
     int err;
     PyObject *dict = lookup_tp_dict(type);
     if (!(meth->ml_flags & METH_COEXIST)) {
-        err = PyDict_SetDefault(dict, name, descr) == NULL;
+        err = PyDict_SetDefaultRef(dict, name, descr, NULL) < 0;
     }
     else {
         err = PyDict_SetItem(dict, name, descr) < 0;
@@ -6731,7 +6731,7 @@ type_add_members(PyTypeObject *type)
         if (descr == NULL)
             return -1;
 
-        if (PyDict_SetDefault(dict, PyDescr_NAME(descr), descr) == NULL) {
+        if (PyDict_SetDefaultRef(dict, PyDescr_NAME(descr), descr, NULL) < 0) {
             Py_DECREF(descr);
             return -1;
         }
@@ -6756,7 +6756,7 @@ type_add_getset(PyTypeObject *type)
             return -1;
         }
 
-        if (PyDict_SetDefault(dict, PyDescr_NAME(descr), descr) == NULL) {
+        if (PyDict_SetDefaultRef(dict, PyDescr_NAME(descr), descr, NULL) < 0) {
             Py_DECREF(descr);
             return -1;
         }
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index b236ddba9cdc69..0a569a950e88e2 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -14894,16 +14894,18 @@ _PyUnicode_InternInPlace(PyInterpreterState *interp, 
PyObject **p)
     PyObject *interned = get_interned_dict(interp);
     assert(interned != NULL);
 
-    PyObject *t = PyDict_SetDefault(interned, s, s);
-    if (t == NULL) {
+    PyObject *t;
+    int res = PyDict_SetDefaultRef(interned, s, s, &t);
+    if (res < 0) {
         PyErr_Clear();
         return;
     }
-
-    if (t != s) {
-        Py_SETREF(*p, Py_NewRef(t));
+    else if (res == 1) {
+        // value was already present (not inserted)
+        Py_SETREF(*p, t);
         return;
     }
+    Py_DECREF(t);
 
     if (_Py_IsImmortal(s)) {
         // XXX Restrict this to the main interpreter?
diff --git a/Python/compile.c b/Python/compile.c
index 4c1d3bb2d2b475..15e5cf38a37b97 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -958,14 +958,15 @@ merge_consts_recursive(PyObject *const_cache, PyObject *o)
         return NULL;
     }
 
-    // t is borrowed reference
-    PyObject *t = PyDict_SetDefault(const_cache, key, key);
-    if (t != key) {
-        // o is registered in const_cache.  Just use it.
-        Py_XINCREF(t);
+    PyObject *t;
+    int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
+    if (res != 0) {
+        // o was not inserted into const_cache. t is either the existing value
+        // or NULL (on error).
         Py_DECREF(key);
         return t;
     }
+    Py_DECREF(t);
 
     // We registered o in const_cache.
     // When o is a tuple or frozenset, we want to merge its
@@ -7527,22 +7528,26 @@ _PyCompile_ConstCacheMergeOne(PyObject *const_cache, 
PyObject **obj)
         return ERROR;
     }
 
-    // t is borrowed reference
-    PyObject *t = PyDict_SetDefault(const_cache, key, key);
+    PyObject *t;
+    int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
     Py_DECREF(key);
-    if (t == NULL) {
+    if (res < 0) {
         return ERROR;
     }
-    if (t == key) {  // obj is new constant.
+    if (res == 0) {  // inserted: obj is new constant.
+        Py_DECREF(t);
         return SUCCESS;
     }
 
     if (PyTuple_CheckExact(t)) {
-        // t is still borrowed reference
-        t = PyTuple_GET_ITEM(t, 1);
+        PyObject *item = PyTuple_GET_ITEM(t, 1);
+        Py_SETREF(*obj, Py_NewRef(item));
+        Py_DECREF(t);
+    }
+    else {
+        Py_SETREF(*obj, t);
     }
 
-    Py_SETREF(*obj, Py_NewRef(t));
     return SUCCESS;
 }
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to