-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-111262: Add PyDict_Pop() function [without default value nor KeyError] #112028
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1498269
ae73490
f65c10f
9da06c8
343f75a
2170fc0
c3b8bd2
a286604
229f524
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Add :c:func:`PyDict_Pop` and :c:func:`PyDict_PopString` functions: remove a key | ||
from a dictionary and optionally return the removed value. This is similar to | ||
:meth:`dict.pop`, but without the default value and not raising :exc:`KeyError` | ||
if the key missing. Patch by Stefan Behnel and Victor Stinner. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -331,6 +331,88 @@ dict_mergefromseq2(PyObject *self, PyObject *args) | |||||
} | ||||||
|
||||||
|
||||||
static PyObject * | ||||||
dict_pop(PyObject *self, PyObject *args) | ||||||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
// Test PyDict_Pop(dict, key, &value) | ||||||
PyObject *dict, *key; | ||||||
if (!PyArg_ParseTuple(args, "OO", &dict, &key)) { | ||||||
return NULL; | ||||||
} | ||||||
NULLABLE(dict); | ||||||
NULLABLE(key); | ||||||
PyObject *result = UNINITIALIZED_PTR; | ||||||
int res = PyDict_Pop(dict, key, &result); | ||||||
if (res < 0) { | ||||||
assert(result == NULL); | ||||||
return NULL; | ||||||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
if (res == 0) { | ||||||
assert(result == NULL); | ||||||
result = Py_NewRef(Py_None); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer to return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can be confused with actual None. For example In other tests I made them returning AttributeError or KeyError, as it is less chance to confuse with real value, but I think that it would be better to use a special singleton |
||||||
} | ||||||
else { | ||||||
assert(result != NULL); | ||||||
} | ||||||
return Py_BuildValue("iN", res, result); | ||||||
} | ||||||
|
||||||
|
||||||
static PyObject * | ||||||
dict_pop_null(PyObject *self, PyObject *args) | ||||||
{ | ||||||
// Test PyDict_Pop(dict, key, NULL) | ||||||
PyObject *dict, *key; | ||||||
if (!PyArg_ParseTuple(args, "OO", &dict, &key)) { | ||||||
return NULL; | ||||||
} | ||||||
NULLABLE(dict); | ||||||
NULLABLE(key); | ||||||
RETURN_INT(PyDict_Pop(dict, key, NULL)); | ||||||
} | ||||||
|
||||||
|
||||||
static PyObject * | ||||||
dict_popstring(PyObject *self, PyObject *args) | ||||||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
PyObject *dict; | ||||||
const char *key; | ||||||
Py_ssize_t key_size; | ||||||
if (!PyArg_ParseTuple(args, "Oz#", &dict, &key, &key_size)) { | ||||||
return NULL; | ||||||
} | ||||||
NULLABLE(dict); | ||||||
PyObject *result = UNINITIALIZED_PTR; | ||||||
int res = PyDict_PopString(dict, key, &result); | ||||||
if (res < 0) { | ||||||
assert(result == NULL); | ||||||
return NULL; | ||||||
} | ||||||
if (res == 0) { | ||||||
assert(result == NULL); | ||||||
result = Py_NewRef(Py_None); | ||||||
} | ||||||
else { | ||||||
assert(result != NULL); | ||||||
} | ||||||
return Py_BuildValue("iN", res, result); | ||||||
} | ||||||
|
||||||
|
||||||
static PyObject * | ||||||
dict_popstring_null(PyObject *self, PyObject *args) | ||||||
{ | ||||||
PyObject *dict; | ||||||
const char *key; | ||||||
Py_ssize_t key_size; | ||||||
if (!PyArg_ParseTuple(args, "Oz#", &dict, &key, &key_size)) { | ||||||
return NULL; | ||||||
} | ||||||
NULLABLE(dict); | ||||||
RETURN_INT(PyDict_PopString(dict, key, NULL)); | ||||||
} | ||||||
|
||||||
|
||||||
static PyMethodDef test_methods[] = { | ||||||
{"dict_check", dict_check, METH_O}, | ||||||
{"dict_checkexact", dict_checkexact, METH_O}, | ||||||
|
@@ -358,7 +440,10 @@ static PyMethodDef test_methods[] = { | |||||
{"dict_merge", dict_merge, METH_VARARGS}, | ||||||
{"dict_update", dict_update, METH_VARARGS}, | ||||||
{"dict_mergefromseq2", dict_mergefromseq2, METH_VARARGS}, | ||||||
|
||||||
{"dict_pop", dict_pop, METH_VARARGS}, | ||||||
{"dict_pop_null", dict_pop_null, METH_VARARGS}, | ||||||
{"dict_popstring", dict_popstring, METH_VARARGS}, | ||||||
{"dict_popstring_null", dict_popstring_null, METH_VARARGS}, | ||||||
{NULL}, | ||||||
}; | ||||||
|
||||||
|
Uh oh!
There was an error while loading. Please reload this page.