summaryrefslogtreecommitdiff
path: root/Objects/odictobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/odictobject.c')
-rw-r--r--Objects/odictobject.c187
1 files changed, 91 insertions, 96 deletions
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index f9f1bf362e..c2cef21b49 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -474,6 +474,13 @@ later:
#include "dict-common.h"
#include <stddef.h>
+#include "clinic/odictobject.c.h"
+
+/*[clinic input]
+class OrderedDict "PyODictObject *" "&PyODict_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/
+
typedef struct _odictnode _ODictNode;
@@ -535,11 +542,11 @@ _odict_free_fast_nodes(PyODictObject *od) {
static Py_ssize_t
_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
{
- PyObject **value_addr = NULL;
+ PyObject *value = NULL;
PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
Py_ssize_t ix;
- ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value_addr, NULL);
+ ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value, NULL);
if (ix == DKIX_EMPTY) {
return keys->dk_nentries; /* index of new entry */
}
@@ -912,25 +919,21 @@ PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y");
/* fromkeys() */
-PyDoc_STRVAR(odict_fromkeys__doc__,
-"OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.\n\
- If not specified, the value defaults to None.\n\
-\n\
- ");
+/*[clinic input]
+@classmethod
+OrderedDict.fromkeys
+
+ iterable as seq: object
+ value: object = None
+
+Create a new ordered dictionary with keys from iterable and values set to value.
+[clinic start generated code]*/
static PyObject *
-odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs)
+OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value)
+/*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/
{
- static char *kwlist[] = {"iterable", "value", 0};
- PyObject *seq;
- PyObject *value = Py_None;
-
- /* both borrowed */
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist,
- &seq, &value)) {
- return NULL;
- }
- return _PyDict_FromKeys(cls, seq, value);
+ return _PyDict_FromKeys((PyObject *)type, seq, value);
}
/* __sizeof__() */
@@ -1000,34 +1003,36 @@ Done:
return result;
}
-/* setdefault() */
+/* setdefault(): Skips __missing__() calls. */
-PyDoc_STRVAR(odict_setdefault__doc__,
- "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od");
-/* Skips __missing__() calls. */
+/*[clinic input]
+OrderedDict.setdefault
+
+ key: object
+ default: object = None
+
+Insert key with a value of default if key is not in the dictionary.
+
+Return the value for key if key is in the dictionary, else default.
+[clinic start generated code]*/
+
static PyObject *
-odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
+OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
+ PyObject *default_value)
+/*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/
{
- static char *kwlist[] = {"key", "default", 0};
- PyObject *key, *result = NULL;
- PyObject *failobj = Py_None;
-
- /* both borrowed */
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
- &key, &failobj)) {
- return NULL;
- }
+ PyObject *result = NULL;
- if (PyODict_CheckExact(od)) {
- result = PyODict_GetItemWithError(od, key); /* borrowed */
+ if (PyODict_CheckExact(self)) {
+ result = PyODict_GetItemWithError(self, key); /* borrowed */
if (result == NULL) {
if (PyErr_Occurred())
return NULL;
- assert(_odict_find_node(od, key) == NULL);
- if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
- result = failobj;
- Py_INCREF(failobj);
+ assert(_odict_find_node(self, key) == NULL);
+ if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) {
+ result = default_value;
+ Py_INCREF(result);
}
}
else {
@@ -1035,16 +1040,16 @@ odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
}
}
else {
- int exists = PySequence_Contains((PyObject *)od, key);
+ int exists = PySequence_Contains((PyObject *)self, key);
if (exists < 0) {
return NULL;
}
else if (exists) {
- result = PyObject_GetItem((PyObject *)od, key);
+ result = PyObject_GetItem((PyObject *)self, key);
}
- else if (PyObject_SetItem((PyObject *)od, key, failobj) >= 0) {
- result = failobj;
- Py_INCREF(failobj);
+ else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) {
+ result = default_value;
+ Py_INCREF(result);
}
}
@@ -1152,39 +1157,37 @@ _odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
return _odict_popkey_hash(od, key, failobj, hash);
}
+
/* popitem() */
-PyDoc_STRVAR(odict_popitem__doc__,
-"od.popitem() -> (k, v), return and remove a (key, value) pair.\n\
- Pairs are returned in LIFO order if last is true or FIFO order if false.\n\
-\n\
- ");
+/*[clinic input]
+OrderedDict.popitem
+
+ last: bool = True
+
+Remove and return a (key, value) pair from the dictionary.
+
+Pairs are returned in LIFO order if last is true or FIFO order if false.
+[clinic start generated code]*/
static PyObject *
-odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs)
+OrderedDict_popitem_impl(PyODictObject *self, int last)
+/*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/
{
- static char *kwlist[] = {"last", 0};
PyObject *key, *value, *item = NULL;
_ODictNode *node;
- int last = 1;
/* pull the item */
- /* borrowed */
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:popitem", kwlist,
- &last)) {
- return NULL;
- }
-
- if (_odict_EMPTY(od)) {
+ if (_odict_EMPTY(self)) {
PyErr_SetString(PyExc_KeyError, "dictionary is empty");
return NULL;
}
- node = last ? _odict_LAST(od) : _odict_FIRST(od);
+ node = last ? _odict_LAST(self) : _odict_FIRST(self);
key = _odictnode_KEY(node);
Py_INCREF(key);
- value = _odict_popkey_hash(od, key, NULL, _odictnode_HASH(node));
+ value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
if (value == NULL)
return NULL;
item = PyTuple_Pack(2, key, value);
@@ -1256,7 +1259,7 @@ odict_copy(register PyODictObject *od)
if (PyODict_CheckExact(od))
od_copy = PyODict_New();
else
- od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL);
+ od_copy = _PyObject_CallNoArg((PyObject *)Py_TYPE(od));
if (od_copy == NULL)
return NULL;
@@ -1312,36 +1315,33 @@ odict_reversed(PyODictObject *od)
return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
}
+
/* move_to_end() */
-PyDoc_STRVAR(odict_move_to_end__doc__,
-"Move an existing element to the end (or beginning if last==False).\n\
-\n\
- Raises KeyError if the element does not exist.\n\
- When last=True, acts like a fast version of self[key]=self.pop(key).\n\
-\n\
- ");
+/*[clinic input]
+OrderedDict.move_to_end
+
+ key: object
+ last: bool = True
+
+Move an existing element to the end (or beginning if last is false).
+
+Raise KeyError if the element does not exist.
+[clinic start generated code]*/
static PyObject *
-odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
+OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last)
+/*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/
{
- static char *kwlist[] = {"key", "last", 0};
- PyObject *key;
- int last = 1;
_ODictNode *node;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p:move_to_end", kwlist,
- &key, &last)) {
- return NULL;
- }
-
- if (_odict_EMPTY(od)) {
+ if (_odict_EMPTY(self)) {
PyErr_SetObject(PyExc_KeyError, key);
return NULL;
}
- node = last ? _odict_LAST(od) : _odict_FIRST(od);
+ node = last ? _odict_LAST(self) : _odict_FIRST(self);
if (key != _odictnode_KEY(node)) {
- node = _odict_find_node(od, key);
+ node = _odict_find_node(self, key);
if (node == NULL) {
if (!PyErr_Occurred())
PyErr_SetObject(PyExc_KeyError, key);
@@ -1349,16 +1349,16 @@ odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
}
if (last) {
/* Only move if not already the last one. */
- if (node != _odict_LAST(od)) {
- _odict_remove_node(od, node);
- _odict_add_tail(od, node);
+ if (node != _odict_LAST(self)) {
+ _odict_remove_node(self, node);
+ _odict_add_tail(self, node);
}
}
else {
/* Only move if not already the first one. */
- if (node != _odict_FIRST(od)) {
- _odict_remove_node(od, node);
- _odict_add_head(od, node);
+ if (node != _odict_FIRST(self)) {
+ _odict_remove_node(self, node);
+ _odict_add_head(self, node);
}
}
}
@@ -1386,20 +1386,17 @@ static PyMethodDef odict_methods[] = {
odict_repr__doc__},
{"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
odict_setitem__doc__},
- {"fromkeys", (PyCFunction)odict_fromkeys,
- METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__},
+ ORDEREDDICT_FROMKEYS_METHODDEF
/* overridden dict methods */
{"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
odict_sizeof__doc__},
{"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
odict_reduce__doc__},
- {"setdefault", (PyCFunction)odict_setdefault,
- METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__},
+ ORDEREDDICT_SETDEFAULT_METHODDEF
{"pop", (PyCFunction)odict_pop,
METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
- {"popitem", (PyCFunction)odict_popitem,
- METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__},
+ ORDEREDDICT_POPITEM_METHODDEF
{"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
odict_keys__doc__},
{"values", (PyCFunction)odictvalues_new, METH_NOARGS,
@@ -1416,8 +1413,7 @@ static PyMethodDef odict_methods[] = {
/* new methods */
{"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
odict_reversed__doc__},
- {"move_to_end", (PyCFunction)odict_move_to_end,
- METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__},
+ ORDEREDDICT_MOVE_TO_END_METHODDEF
{NULL, NULL} /* sentinel */
};
@@ -2423,8 +2419,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
/* now handle kwargs */
assert(kwargs == NULL || PyDict_Check(kwargs));
- len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
- if (len > 0) {
+ if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
PyObject *items = PyDict_Items(kwargs);
if (items == NULL)
return NULL;