Patch by Stefan Behnel and I.
:c:type:`char\*`, rather than a :c:type:`PyObject\*`.
+.. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *default)
+
+ This is the same the Python-level :meth:`dict.setdefault`. If present, it
+ returns the value corresponding to *key* from the dictionary *p*. If the key
+ is not in the dict, it is inserted with value *defaultobj* and *defaultobj*
+ is inserted. This function evaluates the hash function of *key* only once,
+ instead of evaluating it independently for the lookup and the insertion.
+
+
.. c:function:: PyObject* PyDict_Items(PyObject *p)
Return a :c:type:`PyListObject` containing all the items from the dictionary.
PyDict_GetItemString:PyObject*:p:0:
PyDict_GetItemString:char*:key::
+PyDict_SetDefault:PyObject*::0:
+PyDict_SetDefault:PyObject*:p:0:
+PyDict_SetDefault:PyObject*:key:0:conditionally +1 if inserted into the dict
+PyDict_SetDefault:PyObject*:default:0:conditionally +1 if inserted into the dict
+
PyDict_Items:PyObject*::+1:
PyDict_Items:PyObject*:p:0:
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
struct _Py_Identifier *key);
+PyAPI_FUNC(PyObject *) PyDict_SetDefault(
+ PyObject *mp, PyObject *key, PyObject *defaultobj);
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
Core and Builtins
-----------------
+- Issue #17327: Add PyDict_SetDefault.
+
- Issue #17032: The "global" in the "NameError: global name 'x' is not defined"
error message has been removed. Patch by Ram Rachum.
return val;
}
-static PyObject *
-dict_setdefault(register PyDictObject *mp, PyObject *args)
+PyObject *
+PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
{
- PyObject *key;
- PyObject *failobj = Py_None;
+ PyDictObject *mp = (PyDictObject *)d;
PyObject *val = NULL;
Py_hash_t hash;
PyDictKeyEntry *ep;
PyObject **value_addr;
- if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
+ if (!PyDict_Check(d)) {
+ PyErr_BadInternalCall();
return NULL;
-
+ }
if (!PyUnicode_CheckExact(key) ||
(hash = ((PyASCIIObject *) key)->hash) == -1) {
hash = PyObject_Hash(key);
return NULL;
ep = find_empty_slot(mp, key, hash, &value_addr);
}
- Py_INCREF(failobj);
+ Py_INCREF(defaultobj);
Py_INCREF(key);
- MAINTAIN_TRACKING(mp, key, failobj);
+ MAINTAIN_TRACKING(mp, key, defaultobj);
ep->me_key = key;
ep->me_hash = hash;
- *value_addr = failobj;
- val = failobj;
+ *value_addr = defaultobj;
+ val = defaultobj;
mp->ma_keys->dk_usable--;
mp->ma_used++;
}
- Py_INCREF(val);
return val;
}
+static PyObject *
+dict_setdefault(PyDictObject *mp, PyObject *args)
+{
+ PyObject *key, *val;
+ PyObject *defaultobj = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &defaultobj))
+ return NULL;
+
+ val = PyDict_SetDefault(mp, key, defaultobj);
+ Py_XINCREF(val);
+ return val;
+}
static PyObject *
dict_clear(register PyDictObject *mp)