diff -r 1638360eea41 Modules/_heapqmodule.c --- a/Modules/_heapqmodule.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/_heapqmodule.c Sun Jan 12 10:04:51 2014 +0100 @@ -8,6 +8,11 @@ annotated by François Pinard, and conve #include "Python.h" +/*[clinic input] +module _heapq +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + static int _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { @@ -123,14 +128,48 @@ static int return _siftdown(heap, startpos, pos); } + +/*[clinic input] +_heapq.heappush + + heap: 'O' + item: 'O' + / + +Push item onto heap, maintaining the heap invariant. +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_heappush__doc__, +"heappush(heap, item)\n" +"Push item onto heap, maintaining the heap invariant."); + +#define _HEAPQ_HEAPPUSH_METHODDEF \ + {"heappush", (PyCFunction)_heapq_heappush, METH_VARARGS, _heapq_heappush__doc__}, + static PyObject * -heappush(PyObject *self, PyObject *args) +_heapq_heappush_impl(PyModuleDef *module, PyObject *heap, PyObject *item); + +static PyObject * +_heapq_heappush(PyModuleDef *module, PyObject *args) { - PyObject *heap, *item; + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; - if (!PyArg_UnpackTuple(args, "heappush", 2, 2, &heap, &item)) - return NULL; + if (!PyArg_ParseTuple(args, + "OO:heappush", + &heap, &item)) + goto exit; + return_value = _heapq_heappush_impl(module, heap, item); +exit: + return return_value; +} + +static PyObject * +_heapq_heappush_impl(PyModuleDef *module, PyObject *heap, PyObject *item) +/*[clinic end generated code: checksum=80572d1f7060375f70a4c7f9a05552ada33d04fc]*/ +{ if (!PyList_Check(heap)) { PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); return NULL; @@ -145,11 +184,26 @@ heappush(PyObject *self, PyObject *args) return Py_None; } -PyDoc_STRVAR(heappush_doc, -"heappush(heap, item) -> None. Push item onto heap, maintaining the heap invariant."); + +/*[clinic input] +_heapq.heappop + + heap: 'O' + / + +Pop the smallest item off the heap, maintaining the heap invariant. +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_heappop__doc__, +"heappop(heap)\n" +"Pop the smallest item off the heap, maintaining the heap invariant."); + +#define _HEAPQ_HEAPPOP_METHODDEF \ + {"heappop", (PyCFunction)_heapq_heappop, METH_O, _heapq_heappop__doc__}, static PyObject * -heappop(PyObject *self, PyObject *heap) +_heapq_heappop(PyModuleDef *module, PyObject *heap) +/*[clinic end generated code: checksum=63ad63d108b19e637fc9a90afd9da280d36f2a42]*/ { PyObject *lastelt, *returnitem; Py_ssize_t n; @@ -185,16 +239,65 @@ heappop(PyObject *self, PyObject *heap) return returnitem; } -PyDoc_STRVAR(heappop_doc, -"Pop the smallest item off the heap, maintaining the heap invariant."); + +/*[clinic input] +_heapq.heapreplace + + heap: 'O' + item: 'O' + / + +Pop and return the current smallest value, and add the new item. + +This is more efficient than heappop() followed by heappush(), and can be +more appropriate when using a fixed-size heap. Note that the value +returned may be larger than item! That constrains reasonable uses of +this routine unless written as part of a conditional replacement: + + if item > heap[0]: + item = heapreplace(heap, item) +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_heapreplace__doc__, +"heapreplace(heap, item)\n" +"Pop and return the current smallest value, and add the new item.\n" +"\n" +"This is more efficient than heappop() followed by heappush(), and can be\n" +"more appropriate when using a fixed-size heap. Note that the value\n" +"returned may be larger than item! That constrains reasonable uses of\n" +"this routine unless written as part of a conditional replacement:\n" +"\n" +" if item > heap[0]:\n" +" item = heapreplace(heap, item)"); + +#define _HEAPQ_HEAPREPLACE_METHODDEF \ + {"heapreplace", (PyCFunction)_heapq_heapreplace, METH_VARARGS, _heapq_heapreplace__doc__}, static PyObject * -heapreplace(PyObject *self, PyObject *args) +_heapq_heapreplace_impl(PyModuleDef *module, PyObject *heap, PyObject *item); + +static PyObject * +_heapq_heapreplace(PyModuleDef *module, PyObject *args) { - PyObject *heap, *item, *returnitem; + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; - if (!PyArg_UnpackTuple(args, "heapreplace", 2, 2, &heap, &item)) - return NULL; + if (!PyArg_ParseTuple(args, + "OO:heapreplace", + &heap, &item)) + goto exit; + return_value = _heapq_heapreplace_impl(module, heap, item); + +exit: + return return_value; +} + +static PyObject * +_heapq_heapreplace_impl(PyModuleDef *module, PyObject *heap, PyObject *item) +/*[clinic end generated code: checksum=cec5f5b001d24ef1b1992dd896b0b3056bbb386d]*/ +{ + PyObject *returnitem; if (!PyList_Check(heap)) { PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); @@ -216,25 +319,57 @@ heapreplace(PyObject *self, PyObject *ar return returnitem; } -PyDoc_STRVAR(heapreplace_doc, -"heapreplace(heap, item) -> value. Pop and return the current smallest value, and add the new item.\n\ -\n\ -This is more efficient than heappop() followed by heappush(), and can be\n\ -more appropriate when using a fixed-size heap. Note that the value\n\ -returned may be larger than item! That constrains reasonable uses of\n\ -this routine unless written as part of a conditional replacement:\n\n\ - if item > heap[0]:\n\ - item = heapreplace(heap, item)\n"); + +/*[clinic input] +_heapq.heappushpop + + heap: 'O' + item: 'O' + / + +Push item on the heap, then pop and return the smallest item from the heap. + +The combined action runs more efficiently than heappush() followed by +a separate call to heappop(). +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_heappushpop__doc__, +"heappushpop(heap, item)\n" +"Push item on the heap, then pop and return the smallest item from the heap.\n" +"\n" +"The combined action runs more efficiently than heappush() followed by\n" +"a separate call to heappop()."); + +#define _HEAPQ_HEAPPUSHPOP_METHODDEF \ + {"heappushpop", (PyCFunction)_heapq_heappushpop, METH_VARARGS, _heapq_heappushpop__doc__}, static PyObject * -heappushpop(PyObject *self, PyObject *args) +_heapq_heappushpop_impl(PyModuleDef *module, PyObject *heap, PyObject *item); + +static PyObject * +_heapq_heappushpop(PyModuleDef *module, PyObject *args) { - PyObject *heap, *item, *returnitem; + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; + + if (!PyArg_ParseTuple(args, + "OO:heappushpop", + &heap, &item)) + goto exit; + return_value = _heapq_heappushpop_impl(module, heap, item); + +exit: + return return_value; +} + +static PyObject * +_heapq_heappushpop_impl(PyModuleDef *module, PyObject *heap, PyObject *item) +/*[clinic end generated code: checksum=e99e216a662a5981193f30edffc01a2b6de78488]*/ +{ + PyObject *returnitem; int cmp; - if (!PyArg_UnpackTuple(args, "heappushpop", 2, 2, &heap, &item)) - return NULL; - if (!PyList_Check(heap)) { PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); return NULL; @@ -263,13 +398,26 @@ heappushpop(PyObject *self, PyObject *ar return returnitem; } -PyDoc_STRVAR(heappushpop_doc, -"heappushpop(heap, item) -> value. Push item on the heap, then pop and return the smallest item\n\ -from the heap. The combined action runs more efficiently than\n\ -heappush() followed by a separate call to heappop()."); + +/*[clinic input] +_heapq.heapify + + heap: 'O' + / + +Transform list into a heap, in-place, in O(len(heap)) time. +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_heapify__doc__, +"heapify(heap)\n" +"Transform list into a heap, in-place, in O(len(heap)) time."); + +#define _HEAPQ_HEAPIFY_METHODDEF \ + {"heapify", (PyCFunction)_heapq_heapify, METH_O, _heapq_heapify__doc__}, static PyObject * -heapify(PyObject *self, PyObject *heap) +_heapq_heapify(PyModuleDef *module, PyObject *heap) +/*[clinic end generated code: checksum=2822933dfd076ea525d8943d0ecd801c8c35c9fd]*/ { Py_ssize_t i, n; @@ -289,23 +437,59 @@ heapify(PyObject *self, PyObject *heap) for (i=n/2-1 ; i>=0 ; i--) if(_siftup((PyListObject *)heap, i) == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(heapify_doc, -"Transform list into a heap, in-place, in O(len(heap)) time."); + +/*[clinic input] +_heapq.nlargest + + n: 'n' + iterable: 'O' + / + +Find the n largest elements in a dataset. + +Equivalent to: sorted(iterable, reverse=True)[:n] +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_nlargest__doc__, +"nlargest(n, iterable)\n" +"Find the n largest elements in a dataset.\n" +"\n" +"Equivalent to: sorted(iterable, reverse=True)[:n]"); + +#define _HEAPQ_NLARGEST_METHODDEF \ + {"nlargest", (PyCFunction)_heapq_nlargest, METH_VARARGS, _heapq_nlargest__doc__}, static PyObject * -nlargest(PyObject *self, PyObject *args) +_heapq_nlargest_impl(PyModuleDef *module, Py_ssize_t n, PyObject *iterable); + +static PyObject * +_heapq_nlargest(PyModuleDef *module, PyObject *args) { - PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem; - Py_ssize_t i, n; + PyObject *return_value = NULL; + Py_ssize_t n; + PyObject *iterable; + + if (!PyArg_ParseTuple(args, + "nO:nlargest", + &n, &iterable)) + goto exit; + return_value = _heapq_nlargest_impl(module, n, iterable); + +exit: + return return_value; +} + +static PyObject * +_heapq_nlargest_impl(PyModuleDef *module, Py_ssize_t n, PyObject *iterable) +/*[clinic end generated code: checksum=19008f634f40d48c7fd3c7aa4ede9ef527904041]*/ +{ + PyObject *heap=NULL, *elem, *sol, *it, *oldelem; + Py_ssize_t i; int cmp; - if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable)) - return NULL; - it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -374,10 +558,6 @@ fail: return NULL; } -PyDoc_STRVAR(nlargest_doc, -"Find the n largest elements in a dataset.\n\ -\n\ -Equivalent to: sorted(iterable, reverse=True)[:n]\n"); static int _siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) @@ -466,16 +646,56 @@ static int return _siftdownmax(heap, startpos, pos); } + +/*[clinic input] +_heapq.nsmallest + + n: 'n' + iterable: 'O' + / + +Find the n smallest elements in a dataset. + +Equivalent to: sorted(iterable)[:n] +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_nsmallest__doc__, +"nsmallest(n, iterable)\n" +"Find the n smallest elements in a dataset.\n" +"\n" +"Equivalent to: sorted(iterable)[:n]"); + +#define _HEAPQ_NSMALLEST_METHODDEF \ + {"nsmallest", (PyCFunction)_heapq_nsmallest, METH_VARARGS, _heapq_nsmallest__doc__}, + static PyObject * -nsmallest(PyObject *self, PyObject *args) +_heapq_nsmallest_impl(PyModuleDef *module, Py_ssize_t n, PyObject *iterable); + +static PyObject * +_heapq_nsmallest(PyModuleDef *module, PyObject *args) { - PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem; - Py_ssize_t i, n; + PyObject *return_value = NULL; + Py_ssize_t n; + PyObject *iterable; + + if (!PyArg_ParseTuple(args, + "nO:nsmallest", + &n, &iterable)) + goto exit; + return_value = _heapq_nsmallest_impl(module, n, iterable); + +exit: + return return_value; +} + +static PyObject * +_heapq_nsmallest_impl(PyModuleDef *module, Py_ssize_t n, PyObject *iterable) +/*[clinic end generated code: checksum=c03e555647b4ba91a6c241f9781f81b1aa73641c]*/ +{ + PyObject *heap=NULL, *elem, *los, *it, *oldelem; + Py_ssize_t i; int cmp; - if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable)) - return NULL; - it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -545,27 +765,16 @@ fail: return NULL; } -PyDoc_STRVAR(nsmallest_doc, -"Find the n smallest elements in a dataset.\n\ -\n\ -Equivalent to: sorted(iterable)[:n]\n"); static PyMethodDef heapq_methods[] = { - {"heappush", (PyCFunction)heappush, - METH_VARARGS, heappush_doc}, - {"heappushpop", (PyCFunction)heappushpop, - METH_VARARGS, heappushpop_doc}, - {"heappop", (PyCFunction)heappop, - METH_O, heappop_doc}, - {"heapreplace", (PyCFunction)heapreplace, - METH_VARARGS, heapreplace_doc}, - {"heapify", (PyCFunction)heapify, - METH_O, heapify_doc}, - {"nlargest", (PyCFunction)nlargest, - METH_VARARGS, nlargest_doc}, - {"nsmallest", (PyCFunction)nsmallest, - METH_VARARGS, nsmallest_doc}, - {NULL, NULL} /* sentinel */ + _HEAPQ_HEAPPUSH_METHODDEF + _HEAPQ_HEAPPUSHPOP_METHODDEF + _HEAPQ_HEAPPOP_METHODDEF + _HEAPQ_HEAPREPLACE_METHODDEF + _HEAPQ_HEAPIFY_METHODDEF + _HEAPQ_NLARGEST_METHODDEF + _HEAPQ_NSMALLEST_METHODDEF + {NULL, NULL} /* sentinel */ }; PyDoc_STRVAR(module_doc,