]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112050: Adapt collections.deque to Argument Clinic (#113963)
authormpage <mpage@meta.com>
Mon, 29 Jan 2024 15:08:23 +0000 (07:08 -0800)
committerGitHub <noreply@github.com>
Mon, 29 Jan 2024 15:08:23 +0000 (15:08 +0000)
Include/internal/pycore_global_objects_fini_generated.h
Include/internal/pycore_global_strings.h
Include/internal/pycore_runtime_init_generated.h
Include/internal/pycore_unicodeobject_generated.h
Misc/NEWS.d/next/Core and Builtins/2024-01-11-22-58-45.gh-issue-112050.hDuvDW.rst [new file with mode: 0644]
Modules/_collectionsmodule.c
Modules/clinic/_collectionsmodule.c.h

index e92707051c12b7fc6b0bfb382ae0a83497ff3fcb..57505b5388fd6c348268ade4acbdb417cc9bfec0 100644 (file)
@@ -1049,6 +1049,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(max_length));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxdigits));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxevents));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxlen));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxmem));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxsplit));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxvalue));
index eb60b80c964d423a1b7c73d40ed3b403621849a4..0f4f3b61910241403b6174d741a2b28018ad0e84 100644 (file)
@@ -538,6 +538,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(max_length)
         STRUCT_FOR_ID(maxdigits)
         STRUCT_FOR_ID(maxevents)
+        STRUCT_FOR_ID(maxlen)
         STRUCT_FOR_ID(maxmem)
         STRUCT_FOR_ID(maxsplit)
         STRUCT_FOR_ID(maxvalue)
index 9b39de1d69c6c7f1266306e4dd9de4c7c2fba365..63a2b54c839a4b57f6aae70df583c9785d667d95 100644 (file)
@@ -1047,6 +1047,7 @@ extern "C" {
     INIT_ID(max_length), \
     INIT_ID(maxdigits), \
     INIT_ID(maxevents), \
+    INIT_ID(maxlen), \
     INIT_ID(maxmem), \
     INIT_ID(maxsplit), \
     INIT_ID(maxvalue), \
index 898d386f4cfd05d693260eea88799c34c4abd841..bf8cdd85e4be5c12d42a3e022a1e74e96cb535ba 100644 (file)
@@ -1455,6 +1455,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(maxevents);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(maxlen);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(maxmem);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-01-11-22-58-45.gh-issue-112050.hDuvDW.rst b/Misc/NEWS.d/next/Core and Builtins/2024-01-11-22-58-45.gh-issue-112050.hDuvDW.rst
new file mode 100644 (file)
index 0000000..e5f3d5e
--- /dev/null
@@ -0,0 +1 @@
+Convert :class:`collections.deque` to use Argument Clinic.
index c8cd53de5e226224b1368dd265a15e1146a8d377..ef77d34b10e47b96e020781a56f8bf10c3887061 100644 (file)
@@ -44,8 +44,11 @@ find_module_state_by_def(PyTypeObject *type)
 /*[clinic input]
 module _collections
 class _tuplegetter "_tuplegetterobject *" "clinic_state()->tuplegetter_type"
+class _collections.deque "dequeobject *" "clinic_state()->deque_type"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7356042a89862e0e]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a033cc2a8476b3f1]*/
+
+typedef struct dequeobject dequeobject;
 
 /* We can safely assume type to be the defining class,
  * since tuplegetter is not a base type */
@@ -53,6 +56,12 @@ class _tuplegetter "_tuplegetterobject *" "clinic_state()->tuplegetter_type"
 #include "clinic/_collectionsmodule.c.h"
 #undef clinic_state
 
+/*[python input]
+class dequeobject_converter(self_converter):
+    type = "dequeobject *"
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=b6ae4a3ff852be2f]*/
+
 /* collections module implementation of a deque() datatype
    Written and maintained by Raymond D. Hettinger <python@rcn.com>
 */
@@ -121,7 +130,7 @@ typedef struct BLOCK {
     struct BLOCK *rightlink;
 } block;
 
-typedef struct {
+struct dequeobject {
     PyObject_VAR_HEAD
     block *leftblock;
     block *rightblock;
@@ -132,7 +141,7 @@ typedef struct {
     Py_ssize_t numfreeblocks;
     block *freeblocks[MAXFREEBLOCKS];
     PyObject *weakreflist;
-} dequeobject;
+};
 
 /* For debug builds, add error checking to track the endpoints
  * in the chain of links.  The goal is to make sure that link
@@ -219,8 +228,17 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     return (PyObject *)deque;
 }
 
+/*[clinic input]
+_collections.deque.pop as deque_pop
+
+    deque: dequeobject
+
+Remove and return the rightmost element.
+[clinic start generated code]*/
+
 static PyObject *
-deque_pop(dequeobject *deque, PyObject *unused)
+deque_pop_impl(dequeobject *deque)
+/*[clinic end generated code: output=2e5f7890c4251f07 input=eb6e6d020f877dec]*/
 {
     PyObject *item;
     block *prevblock;
@@ -254,10 +272,17 @@ deque_pop(dequeobject *deque, PyObject *unused)
     return item;
 }
 
-PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
+/*[clinic input]
+_collections.deque.popleft as deque_popleft
+
+     deque: dequeobject
+
+Remove and return the leftmost element.
+[clinic start generated code]*/
 
 static PyObject *
-deque_popleft(dequeobject *deque, PyObject *unused)
+deque_popleft_impl(dequeobject *deque)
+/*[clinic end generated code: output=62b154897097ff68 input=acb41b9af50a9d9b]*/
 {
     PyObject *item;
     block *prevblock;
@@ -292,8 +317,6 @@ deque_popleft(dequeobject *deque, PyObject *unused)
     return item;
 }
 
-PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
-
 /* The deque's size limit is d.maxlen.  The limit can be zero or positive.
  * If there is no limit, then d.maxlen == -1.
  *
@@ -326,7 +349,7 @@ deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
     deque->rightindex++;
     deque->rightblock->data[deque->rightindex] = item;
     if (NEEDS_TRIM(deque, maxlen)) {
-        PyObject *olditem = deque_popleft(deque, NULL);
+        PyObject *olditem = deque_popleft_impl(deque);
         Py_DECREF(olditem);
     } else {
         deque->state++;
@@ -334,16 +357,25 @@ deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
     return 0;
 }
 
+/*[clinic input]
+_collections.deque.append as deque_append
+
+    deque: dequeobject
+    item: object
+    /
+
+Add an element to the right side of the deque.
+[clinic start generated code]*/
+
 static PyObject *
 deque_append(dequeobject *deque, PyObject *item)
+/*[clinic end generated code: output=507b13efc4853ecc input=f112b83c380528e3]*/
 {
     if (deque_append_internal(deque, Py_NewRef(item), deque->maxlen) < 0)
         return NULL;
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
-
 static inline int
 deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
 {
@@ -362,7 +394,7 @@ deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
     deque->leftindex--;
     deque->leftblock->data[deque->leftindex] = item;
     if (NEEDS_TRIM(deque, deque->maxlen)) {
-        PyObject *olditem = deque_pop(deque, NULL);
+        PyObject *olditem = deque_pop_impl(deque);
         Py_DECREF(olditem);
     } else {
         deque->state++;
@@ -370,16 +402,25 @@ deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
     return 0;
 }
 
+/*[clinic input]
+_collections.deque.appendleft as deque_appendleft
+
+    deque: dequeobject
+    item: object
+    /
+
+Add an element to the left side of the deque.
+[clinic start generated code]*/
+
 static PyObject *
 deque_appendleft(dequeobject *deque, PyObject *item)
+/*[clinic end generated code: output=de0335a64800ffd8 input=bbdaa60a3e956062]*/
 {
     if (deque_appendleft_internal(deque, Py_NewRef(item), deque->maxlen) < 0)
         return NULL;
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
-
 static PyObject*
 finalize_iterator(PyObject *it)
 {
@@ -410,8 +451,19 @@ consume_iterator(PyObject *it)
     return finalize_iterator(it);
 }
 
+/*[clinic input]
+_collections.deque.extend as deque_extend
+
+    deque: dequeobject
+    iterable: object
+    /
+
+Extend the right side of the deque with elements from the iterable.
+[clinic start generated code]*/
+
 static PyObject *
 deque_extend(dequeobject *deque, PyObject *iterable)
+/*[clinic end generated code: output=a3a6e74d17063f8d input=cfebfd34d5383339]*/
 {
     PyObject *it, *item;
     PyObject *(*iternext)(PyObject *);
@@ -454,11 +506,19 @@ deque_extend(dequeobject *deque, PyObject *iterable)
     return finalize_iterator(it);
 }
 
-PyDoc_STRVAR(extend_doc,
-"Extend the right side of the deque with elements from the iterable");
+/*[clinic input]
+_collections.deque.extendleft as deque_extendleft
+
+    deque: dequeobject
+    iterable: object
+    /
+
+Extend the left side of the deque with elements from the iterable.
+[clinic start generated code]*/
 
 static PyObject *
 deque_extendleft(dequeobject *deque, PyObject *iterable)
+/*[clinic end generated code: output=2dba946c50498c67 input=f4820e695a6f9416]*/
 {
     PyObject *it, *item;
     PyObject *(*iternext)(PyObject *);
@@ -501,9 +561,6 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
     return finalize_iterator(it);
 }
 
-PyDoc_STRVAR(extendleft_doc,
-"Extend the left side of the deque with elements from the iterable");
-
 static PyObject *
 deque_inplace_concat(dequeobject *deque, PyObject *other)
 {
@@ -517,8 +574,17 @@ deque_inplace_concat(dequeobject *deque, PyObject *other)
     return (PyObject *)deque;
 }
 
+/*[clinic input]
+_collections.deque.copy as deque_copy
+
+    deque: dequeobject
+
+Return a shallow copy of a deque.
+[clinic start generated code]*/
+
 static PyObject *
-deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
+deque_copy_impl(dequeobject *deque)
+/*[clinic end generated code: output=6409b3d1ad2898b5 input=0e22f138bc1fcbee]*/
 {
     PyObject *result;
     dequeobject *old_deque = (dequeobject *)deque;
@@ -537,7 +603,7 @@ deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
             PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
             rv = deque_append(new_deque, item);
         } else {
-            rv = deque_extend(new_deque, deque);
+            rv = deque_extend(new_deque, (PyObject *)deque);
         }
         if (rv != NULL) {
             Py_DECREF(rv);
@@ -547,7 +613,8 @@ deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
         return NULL;
     }
     if (old_deque->maxlen < 0)
-        result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque);
+        result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)),
+                                     (PyObject *)deque);
     else
         result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
                                        deque, old_deque->maxlen, NULL);
@@ -561,7 +628,18 @@ deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
     return result;
 }
 
-PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
+/*[clinic input]
+_collections.deque.__copy__ as deque___copy__ = _collections.deque.copy
+
+Return a shallow copy of a deque.
+[clinic start generated code]*/
+
+static PyObject *
+deque___copy___impl(dequeobject *deque)
+/*[clinic end generated code: output=7c5821504342bf23 input=fce05df783e7912b]*/
+{
+    return deque_copy_impl(deque);
+}
 
 static PyObject *
 deque_concat(dequeobject *deque, PyObject *other)
@@ -580,7 +658,7 @@ deque_concat(dequeobject *deque, PyObject *other)
         return NULL;
     }
 
-    new_deque = deque_copy((PyObject *)deque, NULL);
+    new_deque = deque_copy_impl(deque);
     if (new_deque == NULL)
         return NULL;
     result = deque_extend((dequeobject *)new_deque, other);
@@ -669,22 +747,29 @@ deque_clear(dequeobject *deque)
 
   alternate_method:
     while (Py_SIZE(deque)) {
-        item = deque_pop(deque, NULL);
+        item = deque_pop_impl(deque);
         assert (item != NULL);
         Py_DECREF(item);
     }
     return 0;
 }
 
+/*[clinic input]
+_collections.deque.clear as deque_clearmethod
+
+    deque: dequeobject
+
+Remove all elements from the deque.
+[clinic start generated code]*/
+
 static PyObject *
-deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+deque_clearmethod_impl(dequeobject *deque)
+/*[clinic end generated code: output=79b2513e097615c1 input=20488eb932f89f9e]*/
 {
     deque_clear(deque);
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
-
 static PyObject *
 deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
 {
@@ -768,7 +853,7 @@ deque_repeat(dequeobject *deque, Py_ssize_t n)
     dequeobject *new_deque;
     PyObject *rv;
 
-    new_deque = (dequeobject *)deque_copy((PyObject *) deque, NULL);
+    new_deque = (dequeobject *)deque_copy_impl(deque);
     if (new_deque == NULL)
         return NULL;
     rv = deque_inplace_repeat(new_deque, n);
@@ -925,36 +1010,36 @@ done:
     return rv;
 }
 
-static PyObject *
-deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
-{
-    Py_ssize_t n=1;
+/*[clinic input]
+_collections.deque.rotate as deque_rotate
 
-    if (!_PyArg_CheckPositional("deque.rotate", nargs, 0, 1)) {
-        return NULL;
-    }
-    if (nargs) {
-        PyObject *index = _PyNumber_Index(args[0]);
-        if (index == NULL) {
-            return NULL;
-        }
-        n = PyLong_AsSsize_t(index);
-        Py_DECREF(index);
-        if (n == -1 && PyErr_Occurred()) {
-            return NULL;
-        }
-    }
+    deque: dequeobject
+    n: Py_ssize_t = 1
+    /
 
+Rotate the deque n steps to the right.  If n is negative, rotates left.
+[clinic start generated code]*/
+
+static PyObject *
+deque_rotate_impl(dequeobject *deque, Py_ssize_t n)
+/*[clinic end generated code: output=96c2402a371eb15d input=d22070f49cc06c76]*/
+{
     if (!_deque_rotate(deque, n))
         Py_RETURN_NONE;
     return NULL;
 }
 
-PyDoc_STRVAR(rotate_doc,
-"Rotate the deque n steps to the right (default n=1).  If n is negative, rotates left.");
+/*[clinic input]
+_collections.deque.reverse as deque_reverse
+
+    deque: dequeobject
+
+Reverse *IN PLACE*.
+[clinic start generated code]*/
 
 static PyObject *
-deque_reverse(dequeobject *deque, PyObject *unused)
+deque_reverse_impl(dequeobject *deque)
+/*[clinic end generated code: output=bdeebc2cf8c1f064 input=f139787f406101c9]*/
 {
     block *leftblock = deque->leftblock;
     block *rightblock = deque->rightblock;
@@ -991,11 +1076,19 @@ deque_reverse(dequeobject *deque, PyObject *unused)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(reverse_doc,
-"D.reverse() -- reverse *IN PLACE*");
+/*[clinic input]
+_collections.deque.count as deque_count
+
+    deque: dequeobject
+    value as v: object
+    /
+
+Return number of occurrences of value.
+[clinic start generated code]*/
 
 static PyObject *
 deque_count(dequeobject *deque, PyObject *v)
+/*[clinic end generated code: output=7405d289d94d7b9b input=1892925260ff5d78]*/
 {
     block *b = deque->leftblock;
     Py_ssize_t index = deque->leftindex;
@@ -1030,9 +1123,6 @@ deque_count(dequeobject *deque, PyObject *v)
     return PyLong_FromSsize_t(count);
 }
 
-PyDoc_STRVAR(count_doc,
-"D.count(value) -- return number of occurrences of value");
-
 static int
 deque_contains(dequeobject *deque, PyObject *v)
 {
@@ -1071,22 +1161,33 @@ deque_len(dequeobject *deque)
     return Py_SIZE(deque);
 }
 
+/*[clinic input]
+@text_signature "($self, value, [start, [stop]])"
+_collections.deque.index as deque_index
+
+    deque: dequeobject
+    value as v: object
+    start: object(converter='_PyEval_SliceIndexNotNone', type='Py_ssize_t', c_default='0') = NULL
+    stop: object(converter='_PyEval_SliceIndexNotNone', type='Py_ssize_t', c_default='Py_SIZE(deque)') = NULL
+    /
+
+Return first index of value.
+
+Raises ValueError if the value is not present.
+[clinic start generated code]*/
+
 static PyObject *
-deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
+deque_index_impl(dequeobject *deque, PyObject *v, Py_ssize_t start,
+                 Py_ssize_t stop)
+/*[clinic end generated code: output=df45132753175ef9 input=140210c099830f64]*/
 {
-    Py_ssize_t i, n, start=0, stop=Py_SIZE(deque);
-    PyObject *v, *item;
+    Py_ssize_t i, n;
+    PyObject *item;
     block *b = deque->leftblock;
     Py_ssize_t index = deque->leftindex;
     size_t start_state = deque->state;
     int cmp;
 
-    if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v,
-                           _PyEval_SliceIndexNotNone, &start,
-                           _PyEval_SliceIndexNotNone, &stop)) {
-        return NULL;
-    }
-
     if (start < 0) {
         start += Py_SIZE(deque);
         if (start < 0)
@@ -1138,10 +1239,6 @@ deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
     return NULL;
 }
 
-PyDoc_STRVAR(index_doc,
-"D.index(value, [start, [stop]]) -- return first index of value.\n"
-"Raises ValueError if the value is not present.");
-
 /* insert(), remove(), and delitem() are implemented in terms of
    rotate() for simplicity and reasonable performance near the end
    points.  If for some reason these methods become popular, it is not
@@ -1150,18 +1247,24 @@ PyDoc_STRVAR(index_doc,
    boost (by moving each pointer only once instead of twice).
 */
 
+/*[clinic input]
+_collections.deque.insert as deque_insert
+
+    deque: dequeobject
+    index: Py_ssize_t
+    value: object
+    /
+
+Insert value before index.
+[clinic start generated code]*/
+
 static PyObject *
-deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
+deque_insert_impl(dequeobject *deque, Py_ssize_t index, PyObject *value)
+/*[clinic end generated code: output=ef4d2c15d5532b80 input=3e5c1c120d70c0e6]*/
 {
-    Py_ssize_t index;
     Py_ssize_t n = Py_SIZE(deque);
-    PyObject *value;
     PyObject *rv;
 
-    if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) {
-        return NULL;
-    }
-
     if (deque->maxlen == Py_SIZE(deque)) {
         PyErr_SetString(PyExc_IndexError, "deque already at its maximum size");
         return NULL;
@@ -1184,12 +1287,6 @@ deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(insert_doc,
-"D.insert(index, object) -- insert object before index");
-
-PyDoc_STRVAR(remove_doc,
-"D.remove(value) -- remove first occurrence of value.");
-
 static int
 valid_index(Py_ssize_t i, Py_ssize_t limit)
 {
@@ -1246,15 +1343,26 @@ deque_del_item(dequeobject *deque, Py_ssize_t i)
     assert (i >= 0 && i < Py_SIZE(deque));
     if (_deque_rotate(deque, -i))
         return -1;
-    item = deque_popleft(deque, NULL);
+    item = deque_popleft_impl(deque);
     rv = _deque_rotate(deque, i);
     assert (item != NULL);
     Py_DECREF(item);
     return rv;
 }
 
+/*[clinic input]
+_collections.deque.remove as deque_remove
+
+    deque: dequeobject
+    value: object
+    /
+
+Remove first occurrence of value.
+[clinic start generated code]*/
+
 static PyObject *
 deque_remove(dequeobject *deque, PyObject *value)
+/*[clinic end generated code: output=49e1666d612fe911 input=d972f32d15990880]*/
 {
     PyObject *item;
     block *b = deque->leftblock;
@@ -1375,8 +1483,17 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg)
     return 0;
 }
 
+/*[clinic input]
+_collections.deque.__reduce__ as deque___reduce__
+
+    deque: dequeobject
+
+Return state information for pickling.
+[clinic start generated code]*/
+
 static PyObject *
-deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+deque___reduce___impl(dequeobject *deque)
+/*[clinic end generated code: output=cb85d9e0b7d2c5ad input=991a933a5bc7a526]*/
 {
     PyObject *state, *it;
 
@@ -1510,26 +1627,23 @@ done:
     return NULL;
 }
 
+/*[clinic input]
+@text_signature "([iterable[, maxlen]])"
+_collections.deque.__init__ as deque_init
+
+    deque: dequeobject
+    iterable: object = NULL
+    maxlen as maxlenobj: object = NULL
+
+A list-like sequence optimized for data accesses near its endpoints.
+[clinic start generated code]*/
+
 static int
-deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
+deque_init_impl(dequeobject *deque, PyObject *iterable, PyObject *maxlenobj)
+/*[clinic end generated code: output=7084a39d71218dcd input=5ebdffc48a2d27ae]*/
+
 {
-    PyObject *iterable = NULL;
-    PyObject *maxlenobj = NULL;
     Py_ssize_t maxlen = -1;
-    char *kwlist[] = {"iterable", "maxlen", 0};
-
-    if (kwdargs == NULL && PyTuple_GET_SIZE(args) <= 2) {
-        if (PyTuple_GET_SIZE(args) > 0) {
-            iterable = PyTuple_GET_ITEM(args, 0);
-        }
-        if (PyTuple_GET_SIZE(args) > 1) {
-            maxlenobj = PyTuple_GET_ITEM(args, 1);
-        }
-    } else {
-        if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist,
-                                         &iterable, &maxlenobj))
-            return -1;
-    }
     if (maxlenobj != NULL && maxlenobj != Py_None) {
         maxlen = PyLong_AsSsize_t(maxlenobj);
         if (maxlen == -1 && PyErr_Occurred())
@@ -1551,8 +1665,17 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
     return 0;
 }
 
+/*[clinic input]
+_collections.deque.__sizeof__ as deque___sizeof__
+
+    deque: dequeobject
+
+Return the size of the deque in memory, in bytes.
+[clinic start generated code]*/
+
 static PyObject *
-deque_sizeof(dequeobject *deque, void *unused)
+deque___sizeof___impl(dequeobject *deque)
+/*[clinic end generated code: output=4d36e9fb4f30bbaf input=4e7c9a00c03c3290]*/
 {
     size_t res = _PyObject_SIZE(Py_TYPE(deque));
     size_t blocks;
@@ -1563,9 +1686,6 @@ deque_sizeof(dequeobject *deque, void *unused)
     return PyLong_FromSize_t(res);
 }
 
-PyDoc_STRVAR(sizeof_doc,
-"D.__sizeof__() -- size of D in memory, in bytes");
-
 static PyObject *
 deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored))
 {
@@ -1574,6 +1694,22 @@ deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored))
     return PyLong_FromSsize_t(deque->maxlen);
 }
 
+static PyObject *deque_reviter(dequeobject *deque);
+
+/*[clinic input]
+_collections.deque.__reversed__ as deque___reversed__
+
+    deque: dequeobject
+
+Return a reverse iterator over the deque.
+[clinic start generated code]*/
+
+static PyObject *
+deque___reversed___impl(dequeobject *deque)
+/*[clinic end generated code: output=3e7e7e715883cf2e input=3d494c25a6fe5c7e]*/
+{
+    return deque_reviter(deque);
+}
 
 /* deque object ********************************************************/
 
@@ -1584,47 +1720,26 @@ static PyGetSetDef deque_getset[] = {
 };
 
 static PyObject *deque_iter(dequeobject *deque);
-static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored));
-PyDoc_STRVAR(reversed_doc,
-    "D.__reversed__() -- return a reverse iterator over the deque");
 
 static PyMethodDef deque_methods[] = {
-    {"append",                  (PyCFunction)deque_append,
-        METH_O,                  append_doc},
-    {"appendleft",              (PyCFunction)deque_appendleft,
-        METH_O,                  appendleft_doc},
-    {"clear",                   (PyCFunction)deque_clearmethod,
-        METH_NOARGS,             clear_doc},
-    {"__copy__",                deque_copy,
-        METH_NOARGS,             copy_doc},
-    {"copy",                    deque_copy,
-        METH_NOARGS,             copy_doc},
-    {"count",                   (PyCFunction)deque_count,
-        METH_O,                  count_doc},
-    {"extend",                  (PyCFunction)deque_extend,
-        METH_O,                  extend_doc},
-    {"extendleft",              (PyCFunction)deque_extendleft,
-        METH_O,                  extendleft_doc},
-    {"index",                   _PyCFunction_CAST(deque_index),
-        METH_FASTCALL,            index_doc},
-    {"insert",                  _PyCFunction_CAST(deque_insert),
-        METH_FASTCALL,            insert_doc},
-    {"pop",                     (PyCFunction)deque_pop,
-        METH_NOARGS,             pop_doc},
-    {"popleft",                 (PyCFunction)deque_popleft,
-        METH_NOARGS,             popleft_doc},
-    {"__reduce__",              (PyCFunction)deque_reduce,
-        METH_NOARGS,             reduce_doc},
-    {"remove",                  (PyCFunction)deque_remove,
-        METH_O,                  remove_doc},
-    {"__reversed__",            (PyCFunction)deque_reviter,
-        METH_NOARGS,             reversed_doc},
-    {"reverse",                 (PyCFunction)deque_reverse,
-        METH_NOARGS,             reverse_doc},
-    {"rotate",                  _PyCFunction_CAST(deque_rotate),
-        METH_FASTCALL,            rotate_doc},
-    {"__sizeof__",              (PyCFunction)deque_sizeof,
-        METH_NOARGS,             sizeof_doc},
+    DEQUE_APPEND_METHODDEF
+    DEQUE_APPENDLEFT_METHODDEF
+    DEQUE_CLEARMETHOD_METHODDEF
+    DEQUE___COPY___METHODDEF
+    DEQUE_COPY_METHODDEF
+    DEQUE_COUNT_METHODDEF
+    DEQUE_EXTEND_METHODDEF
+    DEQUE_EXTENDLEFT_METHODDEF
+    DEQUE_INDEX_METHODDEF
+    DEQUE_INSERT_METHODDEF
+    DEQUE_POP_METHODDEF
+    DEQUE_POPLEFT_METHODDEF
+    DEQUE___REDUCE___METHODDEF
+    DEQUE_REMOVE_METHODDEF
+    DEQUE___REVERSED___METHODDEF
+    DEQUE_REVERSE_METHODDEF
+    DEQUE_ROTATE_METHODDEF
+    DEQUE___SIZEOF___METHODDEF
     {"__class_getitem__",       Py_GenericAlias,
         METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
     {NULL,              NULL}   /* sentinel */
@@ -1635,17 +1750,12 @@ static PyMemberDef deque_members[] = {
     {NULL},
 };
 
-PyDoc_STRVAR(deque_doc,
-"deque([iterable[, maxlen]]) --> deque object\n\
-\n\
-A list-like sequence optimized for data accesses near its endpoints.");
-
 static PyType_Slot deque_slots[] = {
     {Py_tp_dealloc, deque_dealloc},
     {Py_tp_repr, deque_repr},
     {Py_tp_hash, PyObject_HashNotImplemented},
     {Py_tp_getattro, PyObject_GenericGetAttr},
-    {Py_tp_doc, (void *)deque_doc},
+    {Py_tp_doc, (void *)deque_init__doc__},
     {Py_tp_traverse, deque_traverse},
     {Py_tp_clear, deque_clear},
     {Py_tp_richcompare, deque_richcompare},
@@ -1834,7 +1944,7 @@ static PyType_Spec dequeiter_spec = {
 /*********************** Deque Reverse Iterator **************************/
 
 static PyObject *
-deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+deque_reviter(dequeobject *deque)
 {
     dequeiterobject *it;
     collections_state *state = find_module_state_by_def(Py_TYPE(deque));
@@ -1889,7 +1999,7 @@ dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return NULL;
     assert(type == state->dequereviter_type);
 
-    it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL);
+    it = (dequeiterobject *)deque_reviter((dequeobject *)deque);
     if (!it)
         return NULL;
     /* consume items from the queue */
index 591ab50c76a8e8f629e5ebfbbbdd2fe22426cc9c..60fb12a22316195c55224f732b4180a7a43395af 100644 (file)
@@ -2,9 +2,425 @@
 preserve
 [clinic start generated code]*/
 
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+#  include "pycore_gc.h"          // PyGC_Head
+#  include "pycore_runtime.h"     // _Py_ID()
+#endif
 #include "pycore_abstract.h"      // _PyNumber_Index()
 #include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 
+PyDoc_STRVAR(deque_pop__doc__,
+"pop($self, /)\n"
+"--\n"
+"\n"
+"Remove and return the rightmost element.");
+
+#define DEQUE_POP_METHODDEF    \
+    {"pop", (PyCFunction)deque_pop, METH_NOARGS, deque_pop__doc__},
+
+static PyObject *
+deque_pop_impl(dequeobject *deque);
+
+static PyObject *
+deque_pop(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque_pop_impl(deque);
+}
+
+PyDoc_STRVAR(deque_popleft__doc__,
+"popleft($self, /)\n"
+"--\n"
+"\n"
+"Remove and return the leftmost element.");
+
+#define DEQUE_POPLEFT_METHODDEF    \
+    {"popleft", (PyCFunction)deque_popleft, METH_NOARGS, deque_popleft__doc__},
+
+static PyObject *
+deque_popleft_impl(dequeobject *deque);
+
+static PyObject *
+deque_popleft(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque_popleft_impl(deque);
+}
+
+PyDoc_STRVAR(deque_append__doc__,
+"append($self, item, /)\n"
+"--\n"
+"\n"
+"Add an element to the right side of the deque.");
+
+#define DEQUE_APPEND_METHODDEF    \
+    {"append", (PyCFunction)deque_append, METH_O, deque_append__doc__},
+
+PyDoc_STRVAR(deque_appendleft__doc__,
+"appendleft($self, item, /)\n"
+"--\n"
+"\n"
+"Add an element to the left side of the deque.");
+
+#define DEQUE_APPENDLEFT_METHODDEF    \
+    {"appendleft", (PyCFunction)deque_appendleft, METH_O, deque_appendleft__doc__},
+
+PyDoc_STRVAR(deque_extend__doc__,
+"extend($self, iterable, /)\n"
+"--\n"
+"\n"
+"Extend the right side of the deque with elements from the iterable.");
+
+#define DEQUE_EXTEND_METHODDEF    \
+    {"extend", (PyCFunction)deque_extend, METH_O, deque_extend__doc__},
+
+PyDoc_STRVAR(deque_extendleft__doc__,
+"extendleft($self, iterable, /)\n"
+"--\n"
+"\n"
+"Extend the left side of the deque with elements from the iterable.");
+
+#define DEQUE_EXTENDLEFT_METHODDEF    \
+    {"extendleft", (PyCFunction)deque_extendleft, METH_O, deque_extendleft__doc__},
+
+PyDoc_STRVAR(deque_copy__doc__,
+"copy($self, /)\n"
+"--\n"
+"\n"
+"Return a shallow copy of a deque.");
+
+#define DEQUE_COPY_METHODDEF    \
+    {"copy", (PyCFunction)deque_copy, METH_NOARGS, deque_copy__doc__},
+
+static PyObject *
+deque_copy_impl(dequeobject *deque);
+
+static PyObject *
+deque_copy(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque_copy_impl(deque);
+}
+
+PyDoc_STRVAR(deque___copy____doc__,
+"__copy__($self, /)\n"
+"--\n"
+"\n"
+"Return a shallow copy of a deque.");
+
+#define DEQUE___COPY___METHODDEF    \
+    {"__copy__", (PyCFunction)deque___copy__, METH_NOARGS, deque___copy____doc__},
+
+static PyObject *
+deque___copy___impl(dequeobject *deque);
+
+static PyObject *
+deque___copy__(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque___copy___impl(deque);
+}
+
+PyDoc_STRVAR(deque_clearmethod__doc__,
+"clear($self, /)\n"
+"--\n"
+"\n"
+"Remove all elements from the deque.");
+
+#define DEQUE_CLEARMETHOD_METHODDEF    \
+    {"clear", (PyCFunction)deque_clearmethod, METH_NOARGS, deque_clearmethod__doc__},
+
+static PyObject *
+deque_clearmethod_impl(dequeobject *deque);
+
+static PyObject *
+deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque_clearmethod_impl(deque);
+}
+
+PyDoc_STRVAR(deque_rotate__doc__,
+"rotate($self, n=1, /)\n"
+"--\n"
+"\n"
+"Rotate the deque n steps to the right.  If n is negative, rotates left.");
+
+#define DEQUE_ROTATE_METHODDEF    \
+    {"rotate", _PyCFunction_CAST(deque_rotate), METH_FASTCALL, deque_rotate__doc__},
+
+static PyObject *
+deque_rotate_impl(dequeobject *deque, Py_ssize_t n);
+
+static PyObject *
+deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t n = 1;
+
+    if (!_PyArg_CheckPositional("rotate", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(args[0]);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        n = ival;
+    }
+skip_optional:
+    return_value = deque_rotate_impl(deque, n);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(deque_reverse__doc__,
+"reverse($self, /)\n"
+"--\n"
+"\n"
+"Reverse *IN PLACE*.");
+
+#define DEQUE_REVERSE_METHODDEF    \
+    {"reverse", (PyCFunction)deque_reverse, METH_NOARGS, deque_reverse__doc__},
+
+static PyObject *
+deque_reverse_impl(dequeobject *deque);
+
+static PyObject *
+deque_reverse(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque_reverse_impl(deque);
+}
+
+PyDoc_STRVAR(deque_count__doc__,
+"count($self, value, /)\n"
+"--\n"
+"\n"
+"Return number of occurrences of value.");
+
+#define DEQUE_COUNT_METHODDEF    \
+    {"count", (PyCFunction)deque_count, METH_O, deque_count__doc__},
+
+PyDoc_STRVAR(deque_index__doc__,
+"index($self, value, [start, [stop]])\n"
+"--\n"
+"\n"
+"Return first index of value.\n"
+"\n"
+"Raises ValueError if the value is not present.");
+
+#define DEQUE_INDEX_METHODDEF    \
+    {"index", _PyCFunction_CAST(deque_index), METH_FASTCALL, deque_index__doc__},
+
+static PyObject *
+deque_index_impl(dequeobject *deque, PyObject *v, Py_ssize_t start,
+                 Py_ssize_t stop);
+
+static PyObject *
+deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *v;
+    Py_ssize_t start = 0;
+    Py_ssize_t stop = Py_SIZE(deque);
+
+    if (!_PyArg_CheckPositional("index", nargs, 1, 3)) {
+        goto exit;
+    }
+    v = args[0];
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    if (!_PyEval_SliceIndexNotNone(args[1], &start)) {
+        goto exit;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    if (!_PyEval_SliceIndexNotNone(args[2], &stop)) {
+        goto exit;
+    }
+skip_optional:
+    return_value = deque_index_impl(deque, v, start, stop);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(deque_insert__doc__,
+"insert($self, index, value, /)\n"
+"--\n"
+"\n"
+"Insert value before index.");
+
+#define DEQUE_INSERT_METHODDEF    \
+    {"insert", _PyCFunction_CAST(deque_insert), METH_FASTCALL, deque_insert__doc__},
+
+static PyObject *
+deque_insert_impl(dequeobject *deque, Py_ssize_t index, PyObject *value);
+
+static PyObject *
+deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t index;
+    PyObject *value;
+
+    if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) {
+        goto exit;
+    }
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(args[0]);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        index = ival;
+    }
+    value = args[1];
+    return_value = deque_insert_impl(deque, index, value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(deque_remove__doc__,
+"remove($self, value, /)\n"
+"--\n"
+"\n"
+"Remove first occurrence of value.");
+
+#define DEQUE_REMOVE_METHODDEF    \
+    {"remove", (PyCFunction)deque_remove, METH_O, deque_remove__doc__},
+
+PyDoc_STRVAR(deque___reduce____doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n"
+"Return state information for pickling.");
+
+#define DEQUE___REDUCE___METHODDEF    \
+    {"__reduce__", (PyCFunction)deque___reduce__, METH_NOARGS, deque___reduce____doc__},
+
+static PyObject *
+deque___reduce___impl(dequeobject *deque);
+
+static PyObject *
+deque___reduce__(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque___reduce___impl(deque);
+}
+
+PyDoc_STRVAR(deque_init__doc__,
+"deque([iterable[, maxlen]])\n"
+"--\n"
+"\n"
+"A list-like sequence optimized for data accesses near its endpoints.");
+
+static int
+deque_init_impl(dequeobject *deque, PyObject *iterable, PyObject *maxlenobj);
+
+static int
+deque_init(PyObject *deque, PyObject *args, PyObject *kwargs)
+{
+    int return_value = -1;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 2
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(iterable), &_Py_ID(maxlen), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"iterable", "maxlen", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "deque",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0;
+    PyObject *iterable = NULL;
+    PyObject *maxlenobj = NULL;
+
+    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (fastargs[0]) {
+        iterable = fastargs[0];
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    maxlenobj = fastargs[1];
+skip_optional_pos:
+    return_value = deque_init_impl((dequeobject *)deque, iterable, maxlenobj);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(deque___sizeof____doc__,
+"__sizeof__($self, /)\n"
+"--\n"
+"\n"
+"Return the size of the deque in memory, in bytes.");
+
+#define DEQUE___SIZEOF___METHODDEF    \
+    {"__sizeof__", (PyCFunction)deque___sizeof__, METH_NOARGS, deque___sizeof____doc__},
+
+static PyObject *
+deque___sizeof___impl(dequeobject *deque);
+
+static PyObject *
+deque___sizeof__(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque___sizeof___impl(deque);
+}
+
+PyDoc_STRVAR(deque___reversed____doc__,
+"__reversed__($self, /)\n"
+"--\n"
+"\n"
+"Return a reverse iterator over the deque.");
+
+#define DEQUE___REVERSED___METHODDEF    \
+    {"__reversed__", (PyCFunction)deque___reversed__, METH_NOARGS, deque___reversed____doc__},
+
+static PyObject *
+deque___reversed___impl(dequeobject *deque);
+
+static PyObject *
+deque___reversed__(dequeobject *deque, PyObject *Py_UNUSED(ignored))
+{
+    return deque___reversed___impl(deque);
+}
+
 PyDoc_STRVAR(_collections__count_elements__doc__,
 "_count_elements($module, mapping, iterable, /)\n"
 "--\n"
@@ -72,4 +488,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=c896a72f8c45930d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3633a5cbc23e8440 input=a9049054013a1b77]*/