[Python-checkins] cpython: Convert some OrderedDict methods to Argument Clinic

victor.stinner python-checkins at python.org
Mon Jan 16 21:47:52 EST 2017


https://hg.python.org/cpython/rev/9f7d16266928
changeset:   106183:9f7d16266928
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Jan 17 03:46:13 2017 +0100
summary:
  Convert some OrderedDict methods to Argument Clinic

Issue #29289. Convert methods:

* fromkeys() class method
* setdefault()
* popitem()
* move_to_end()

files:
  Objects/clinic/odictobject.c.h |  135 ++++++++++++++++
  Objects/odictobject.c          |  171 ++++++++++----------
  2 files changed, 219 insertions(+), 87 deletions(-)


diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h
new file mode 100644
--- /dev/null
+++ b/Objects/clinic/odictobject.c.h
@@ -0,0 +1,135 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(OrderedDict_fromkeys__doc__,
+"fromkeys($type, /, iterable, value=None)\n"
+"--\n"
+"\n"
+"New ordered dictionary with keys from S.\n"
+"\n"
+"If not specified, the value defaults to None.");
+
+#define ORDEREDDICT_FROMKEYS_METHODDEF    \
+    {"fromkeys", (PyCFunction)OrderedDict_fromkeys, METH_FASTCALL|METH_CLASS, OrderedDict_fromkeys__doc__},
+
+static PyObject *
+OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value);
+
+static PyObject *
+OrderedDict_fromkeys(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"iterable", "value", NULL};
+    static _PyArg_Parser _parser = {"O|O:fromkeys", _keywords, 0};
+    PyObject *seq;
+    PyObject *value = Py_None;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &seq, &value)) {
+        goto exit;
+    }
+    return_value = OrderedDict_fromkeys_impl(type, seq, value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(OrderedDict_setdefault__doc__,
+"setdefault($self, /, key, default=None)\n"
+"--\n"
+"\n"
+"od.get(k,d), also set od[k]=d if k not in od.");
+
+#define ORDEREDDICT_SETDEFAULT_METHODDEF    \
+    {"setdefault", (PyCFunction)OrderedDict_setdefault, METH_FASTCALL, OrderedDict_setdefault__doc__},
+
+static PyObject *
+OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
+                            PyObject *failobj);
+
+static PyObject *
+OrderedDict_setdefault(PyODictObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"key", "default", NULL};
+    static _PyArg_Parser _parser = {"O|O:setdefault", _keywords, 0};
+    PyObject *key;
+    PyObject *failobj = Py_None;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &key, &failobj)) {
+        goto exit;
+    }
+    return_value = OrderedDict_setdefault_impl(self, key, failobj);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(OrderedDict_popitem__doc__,
+"popitem($self, /, last=True)\n"
+"--\n"
+"\n"
+"Return (k, v) and remove a (key, value) pair.\n"
+"\n"
+"Pairs are returned in LIFO order if last is true or FIFO order if false.");
+
+#define ORDEREDDICT_POPITEM_METHODDEF    \
+    {"popitem", (PyCFunction)OrderedDict_popitem, METH_FASTCALL, OrderedDict_popitem__doc__},
+
+static PyObject *
+OrderedDict_popitem_impl(PyODictObject *self, int last);
+
+static PyObject *
+OrderedDict_popitem(PyODictObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"last", NULL};
+    static _PyArg_Parser _parser = {"|p:popitem", _keywords, 0};
+    int last = 1;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &last)) {
+        goto exit;
+    }
+    return_value = OrderedDict_popitem_impl(self, last);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(OrderedDict_move_to_end__doc__,
+"move_to_end($self, /, key, last=True)\n"
+"--\n"
+"\n"
+"\"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).");
+
+#define ORDEREDDICT_MOVE_TO_END_METHODDEF    \
+    {"move_to_end", (PyCFunction)OrderedDict_move_to_end, METH_FASTCALL, OrderedDict_move_to_end__doc__},
+
+static PyObject *
+OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last);
+
+static PyObject *
+OrderedDict_move_to_end(PyODictObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"key", "last", NULL};
+    static _PyArg_Parser _parser = {"O|p:move_to_end", _keywords, 0};
+    PyObject *key;
+    int last = 1;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &key, &last)) {
+        goto exit;
+    }
+    return_value = OrderedDict_move_to_end_impl(self, key, last);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=f2641e1277045b59 input=a9049054013a1b77]*/
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -474,6 +474,13 @@
 #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;
 
@@ -912,25 +919,23 @@
 
 /* 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]
+ at classmethod
+OrderedDict.fromkeys
+
+    iterable as seq: object
+    value: object = None
+
+New ordered dictionary with keys from S.
+
+If not specified, the value defaults to None.
+[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=33eefc496d5eee7b]*/
 {
-    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,32 +1005,32 @@
     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 as failobj: object = None
+
+od.get(k,d), also set od[k]=d if k not in od.
+[clinic start generated code]*/
+
 static PyObject *
-odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
+OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
+                            PyObject *failobj)
+/*[clinic end generated code: output=605d0f6f61ccb0a6 input=4ee5006f32f5691b]*/
 {
-    static char *kwlist[] = {"key", "default", 0};
-    PyObject *key, *result = NULL;
-    PyObject *failobj = Py_None;
+    PyObject *result = NULL;
 
-    /* both borrowed */
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
-                                     &key, &failobj)) {
-        return 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) {
+            assert(_odict_find_node(self, key) == NULL);
+            if (PyODict_SetItem((PyObject *)self, key, failobj) >= 0) {
                 result = failobj;
                 Py_INCREF(failobj);
             }
@@ -1035,14 +1040,14 @@
         }
     }
     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) {
+        else if (PyObject_SetItem((PyObject *)self, key, failobj) >= 0) {
             result = failobj;
             Py_INCREF(failobj);
         }
@@ -1152,39 +1157,37 @@
     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
+
+Return (k, v) and remove a (key, value) pair.
+
+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=4937da2015939126]*/
 {
-    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);
@@ -1312,36 +1315,34 @@
     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==False).
+
+    Raises KeyError if the element does not exist.
+    When last=True, acts like a fast version of self[key]=self.pop(key).
+[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=3b8283f7d0e15e43]*/
 {
-    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 +1350,16 @@
         }
         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 +1387,17 @@
      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 +1414,7 @@
     /* 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 */
 };

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list