diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 8ee351918006e4b..cfa9b56f60be4a5 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -173,6 +173,16 @@ Dictionary Objects .. versionadded:: 3.4 + +.. c:function:: PyObject* PyDict_Pop(PyObject *p, PyObject *key, PyObject *defaultobj) + + This is the same as the Python-level :meth:`dict.pop`. It removes the *key* + from the dictionary *p* and returns its value. If the key is not in the dict, + the value *defaultobj* is returned instead if it is not ``NULL``, or otherwise a + :exc:`KeyError` is raised and ``NULL`` is returned. + + .. versionadded:: 3.13 + .. c:function:: PyObject* PyDict_Items(PyObject *p) Return a :c:type:`PyListObject` containing all the items from the dictionary. diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index b05ca3ef4538165..742b53e8abb3b4f 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -45,7 +45,7 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { #define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op)) PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key); - +PyAPI_FUNC(PyObject *) PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value); /* Dictionary watchers */ diff --git a/Misc/NEWS.d/next/C API/2023-10-24-12-12-44.gh-issue-106320.UkK3x-.rst b/Misc/NEWS.d/next/C API/2023-10-24-12-12-44.gh-issue-106320.UkK3x-.rst new file mode 100644 index 000000000000000..8416085f2396250 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-10-24-12-12-44.gh-issue-106320.UkK3x-.rst @@ -0,0 +1 @@ +Add a new C-API function PyDict_Pop to replace a previously removed underscore function. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 361f8e93064b25b..a554857ec9c9377 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2272,6 +2272,16 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) return _PyDict_Pop_KnownHash(dict, key, hash, deflt); } +PyObject * +PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) +{ + if (!PyDict_Check(dict)) { + PyErr_BadInternalCall(); + return -1; + } + return _PyDict_Pop(dict, key, deflt); +} + /* Internal version of dict.from_keys(). It is subclass-friendly. */ PyObject * _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)