diff -r 1638360eea41 Modules/_csv.c --- a/Modules/_csv.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/_csv.c Sun Jan 12 11:10:49 2014 +0100 @@ -13,6 +13,11 @@ module instead. #include "Python.h" #include "structmember.h" +/*[clinic input] +module _csv +class _csv.Dialect +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ typedef struct { PyObject *error_obj; /* CSV exception */ @@ -322,24 +327,32 @@ Dialect_dealloc(DialectObj *self) Py_TYPE(self)->tp_free((PyObject *)self); } -static char *dialect_kws[] = { - "dialect", - "delimiter", - "doublequote", - "escapechar", - "lineterminator", - "quotechar", - "quoting", - "skipinitialspace", - "strict", - NULL -}; + +/*[clinic input] +@new +_csv.Dialect.__new__ + + dialect: 'O' = NULL + delimiter: 'O' = NULL + doublequote: 'O' = NULL + escapechar: 'O' = NULL + lineterminator: 'O' = NULL + quotechar: 'O' = NULL + quoting: 'O' = NULL + skipinitialspace: 'O' = NULL + strict: 'O' = NULL + +Construct a new dialect. +[clinic start generated code]*/ static PyObject * -dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +_csv_Dialect___new___impl(PyTypeObject *type, PyObject *dialect, PyObject *delimiter, PyObject *doublequote, PyObject *escapechar, PyObject *lineterminator, PyObject *quotechar, PyObject *quoting, PyObject *skipinitialspace, PyObject *strict); + +static PyObject * +_csv_Dialect___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - DialectObj *self; - PyObject *ret = NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"dialect", "delimiter", "doublequote", "escapechar", "lineterminator", "quotechar", "quoting", "skipinitialspace", "strict", NULL}; PyObject *dialect = NULL; PyObject *delimiter = NULL; PyObject *doublequote = NULL; @@ -351,17 +364,21 @@ dialect_new(PyTypeObject *type, PyObject PyObject *strict = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|OOOOOOOOO", dialect_kws, - &dialect, - &delimiter, - &doublequote, - &escapechar, - &lineterminator, - "echar, - "ing, - &skipinitialspace, - &strict)) - return NULL; + "|OOOOOOOOO:Dialect", _keywords, + &dialect, &delimiter, &doublequote, &escapechar, &lineterminator, "echar, "ing, &skipinitialspace, &strict)) + goto exit; + return_value = _csv_Dialect___new___impl(type, dialect, delimiter, doublequote, escapechar, lineterminator, quotechar, quoting, skipinitialspace, strict); + +exit: + return return_value; +} + +static PyObject * +_csv_Dialect___new___impl(PyTypeObject *type, PyObject *dialect, PyObject *delimiter, PyObject *doublequote, PyObject *escapechar, PyObject *lineterminator, PyObject *quotechar, PyObject *quoting, PyObject *skipinitialspace, PyObject *strict) +/*[clinic end generated code: checksum=8b85a2cfc93648f9a7d135c93bdea01f12b4fd3c]*/ +{ + DialectObj *self; + PyObject *ret = NULL; if (dialect != NULL) { if (PyUnicode_Check(dialect)) { @@ -508,7 +525,7 @@ static PyTypeObject Dialect_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - dialect_new, /* tp_new */ + _csv_Dialect___new__, /* tp_new */ 0, /* tp_free */ }; @@ -1417,12 +1434,41 @@ csv_writer(PyObject *module, PyObject *a /* * DIALECT REGISTRY */ + +/*[clinic input] +_csv.list_dialects + +Return a list of all know dialect names. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_list_dialects__doc__, +"list_dialects()\n" +"Return a list of all know dialect names."); + +#define _CSV_LIST_DIALECTS_METHODDEF \ + {"list_dialects", (PyCFunction)_csv_list_dialects, METH_NOARGS, _csv_list_dialects__doc__}, + static PyObject * -csv_list_dialects(PyObject *module, PyObject *args) +_csv_list_dialects_impl(PyModuleDef *module); + +static PyObject * +_csv_list_dialects(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _csv_list_dialects_impl(module); + + return return_value; +} + +static PyObject * +_csv_list_dialects_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=2f92b96cc3faf7d0de1cc5399712510b6d043fdb]*/ { return PyDict_Keys(_csvstate_global->dialects); } + static PyObject * csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) { @@ -1450,36 +1496,110 @@ csv_register_dialect(PyObject *module, P return Py_None; } +/*[clinic input] +_csv.unregister_dialect + + name: 'O' + / + +Delete the name/dialect mapping associated with a string name. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_unregister_dialect__doc__, +"unregister_dialect(name)\n" +"Delete the name/dialect mapping associated with a string name."); + +#define _CSV_UNREGISTER_DIALECT_METHODDEF \ + {"unregister_dialect", (PyCFunction)_csv_unregister_dialect, METH_O, _csv_unregister_dialect__doc__}, + static PyObject * -csv_unregister_dialect(PyObject *module, PyObject *name_obj) +_csv_unregister_dialect(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=9c33ef47c236073b4c874918b99715d9031e16c6]*/ { - if (PyDict_DelItem(_csvstate_global->dialects, name_obj) < 0) + if (PyDict_DelItem(_csvstate_global->dialects, name) < 0) return PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; +} + + +/*[clinic input] +_csv.get_dialect + + name: 'O' + / + +Return the dialect instance associated with name. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_get_dialect__doc__, +"get_dialect(name)\n" +"Return the dialect instance associated with name."); + +#define _CSV_GET_DIALECT_METHODDEF \ + {"get_dialect", (PyCFunction)_csv_get_dialect, METH_O, _csv_get_dialect__doc__}, + +static PyObject * +_csv_get_dialect(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=239de66cde53129870e2aab2cb95daeba233ea54]*/ +{ + return get_dialect_from_registry(name); +} + + +/*[clinic input] +_csv.field_size_limit + + limit: 'O' = NULL + / + +Sets an upper limit on parsed fields. + +Returns old limit. If limit is not given, no new limit is set and +the old limit is returned. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_field_size_limit__doc__, +"field_size_limit(limit=None)\n" +"Sets an upper limit on parsed fields.\n" +"\n" +"Returns old limit. If limit is not given, no new limit is set and\n" +"the old limit is returned."); + +#define _CSV_FIELD_SIZE_LIMIT_METHODDEF \ + {"field_size_limit", (PyCFunction)_csv_field_size_limit, METH_VARARGS, _csv_field_size_limit__doc__}, + +static PyObject * +_csv_field_size_limit_impl(PyModuleDef *module, PyObject *limit); + +static PyObject * +_csv_field_size_limit(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *limit = NULL; + + if (!PyArg_ParseTuple(args, + "|O:field_size_limit", + &limit)) + goto exit; + return_value = _csv_field_size_limit_impl(module, limit); + +exit: + return return_value; } static PyObject * -csv_get_dialect(PyObject *module, PyObject *name_obj) +_csv_field_size_limit_impl(PyModuleDef *module, PyObject *limit) +/*[clinic end generated code: checksum=af1e08ed116500db157149f2c9dc991a6d6c9483]*/ { - return get_dialect_from_registry(name_obj); -} - -static PyObject * -csv_field_size_limit(PyObject *module, PyObject *args) -{ - PyObject *new_limit = NULL; long old_limit = _csvstate_global->field_limit; - if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) - return NULL; - if (new_limit != NULL) { - if (!PyLong_CheckExact(new_limit)) { + if (limit != NULL) { + if (!PyLong_CheckExact(limit)) { PyErr_Format(PyExc_TypeError, "limit must be an integer"); return NULL; } - _csvstate_global->field_limit = PyLong_AsLong(new_limit); + _csvstate_global->field_limit = PyLong_AsLong(limit); if (_csvstate_global->field_limit == -1 && PyErr_Occurred()) { _csvstate_global->field_limit = old_limit; return NULL; @@ -1579,44 +1699,22 @@ PyDoc_STRVAR(csv_writer_doc, "\n" "The \"fileobj\" argument can be any object that supports the file API.\n"); -PyDoc_STRVAR(csv_list_dialects_doc, -"Return a list of all know dialect names.\n" -" names = csv.list_dialects()"); - -PyDoc_STRVAR(csv_get_dialect_doc, -"Return the dialect instance associated with name.\n" -" dialect = csv.get_dialect(name)"); - PyDoc_STRVAR(csv_register_dialect_doc, "Create a mapping from a string name to a dialect class.\n" " dialect = csv.register_dialect(name, dialect)"); -PyDoc_STRVAR(csv_unregister_dialect_doc, -"Delete the name/dialect mapping associated with a string name.\n" -" csv.unregister_dialect(name)"); - -PyDoc_STRVAR(csv_field_size_limit_doc, -"Sets an upper limit on parsed fields.\n" -" csv.field_size_limit([limit])\n" -"\n" -"Returns old limit. If limit is not given, no new limit is set and\n" -"the old limit is returned"); static struct PyMethodDef csv_methods[] = { { "reader", (PyCFunction)csv_reader, METH_VARARGS | METH_KEYWORDS, csv_reader_doc}, { "writer", (PyCFunction)csv_writer, METH_VARARGS | METH_KEYWORDS, csv_writer_doc}, - { "list_dialects", (PyCFunction)csv_list_dialects, - METH_NOARGS, csv_list_dialects_doc}, { "register_dialect", (PyCFunction)csv_register_dialect, - METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc}, - { "unregister_dialect", (PyCFunction)csv_unregister_dialect, - METH_O, csv_unregister_dialect_doc}, - { "get_dialect", (PyCFunction)csv_get_dialect, - METH_O, csv_get_dialect_doc}, - { "field_size_limit", (PyCFunction)csv_field_size_limit, - METH_VARARGS, csv_field_size_limit_doc}, + METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc}, + _CSV_LIST_DIALECTS_METHODDEF + _CSV_UNREGISTER_DIALECT_METHODDEF + _CSV_GET_DIALECT_METHODDEF + _CSV_FIELD_SIZE_LIMIT_METHODDEF { NULL, NULL } }; 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 11:10:49 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, diff -r 1638360eea41 Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/_io/_iomodule.c Sun Jan 12 11:10:49 2014 +0100 @@ -20,6 +20,10 @@ #include #endif /* HAVE_SYS_STAT_H */ +/*[clinic input] +module _io +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ /* Various interned strings */ @@ -93,23 +97,154 @@ PyDoc_STRVAR(module_doc, /* * The main open() function */ -PyDoc_STRVAR(open_doc, -"open(file, mode='r', buffering=-1, encoding=None,\n" -" errors=None, newline=None, closefd=True, opener=None) -> file object\n" -"\n" + +/*[clinic input] +_io.open + + file: 'O' + mode: 's' = "r" + buffering: 'i' = -1 + encoding: 'z' = NULL + errors: 'z' = NULL + newline: 'z' = NULL + closefd: 'i' = 1 + opener: 'O' = None + +Open file and return a stream. Raise IOError upon failure. + +file is either a text or byte string giving the name (and the path +if the file isn't in the current working directory) of the file to +be opened or an integer file descriptor of the file to be +wrapped. (If a file descriptor is given, it is closed when the +returned I/O object is closed, unless closefd is set to False.) + +mode is an optional string that specifies the mode in which the file +is opened. It defaults to 'r' which means open for reading in text +mode. Other common values are 'w' for writing (truncating the file if +it already exists), 'x' for creating and writing to a new file, and +'a' for appending (which on some Unix systems, means that all writes +append to the end of the file regardless of the current seek position). +In text mode, if encoding is not specified the encoding used is platform +dependent: locale.getpreferredencoding(False) is called to get the +current locale encoding. (For reading and writing raw bytes use binary +mode and leave encoding unspecified.) The available modes are: + +========= =============================================================== +Character Meaning +--------- --------------------------------------------------------------- +'r' open for reading (default) +'w' open for writing, truncating the file first +'x' create a new file and open it for writing +'a' open for writing, appending to the end of the file if it exists +'b' binary mode +'t' text mode (default) +'+' open a disk file for updating (reading and writing) +'U' universal newline mode (deprecated) +========= =============================================================== + +The default mode is 'rt' (open for reading text). For binary random +access, the mode 'w+b' opens and truncates the file to 0 bytes, while +'r+b' opens the file without truncation. The 'x' mode implies 'w' and +raises an `FileExistsError` if the file already exists. + +Python distinguishes between files opened in binary and text modes, +even when the underlying operating system doesn't. Files opened in +binary mode (appending 'b' to the mode argument) return contents as +bytes objects without any decoding. In text mode (the default, or when +'t' is appended to the mode argument), the contents of the file are +returned as strings, the bytes having been first decoded using a +platform-dependent encoding or using the specified encoding if given. + +'U' mode is deprecated and will raise an exception in future versions +of Python. It has no effect in Python 3. Use newline to control +universal newlines mode. + +buffering is an optional integer used to set the buffering policy. +Pass 0 to switch buffering off (only allowed in binary mode), 1 to select +line buffering (only usable in text mode), and an integer > 1 to indicate +the size of a fixed-size chunk buffer. When no buffering argument is +given, the default buffering policy works as follows: + +* Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + +* "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. + +encoding is the name of the encoding used to decode or encode the +file. This should only be used in text mode. The default encoding is +platform dependent, but any encoding supported by Python can be +passed. See the codecs module for the list of supported encodings. + +errors is an optional string that specifies how encoding errors are to +be handled---this argument should not be used in binary mode. Pass +'strict' to raise a ValueError exception if there is an encoding error +(the default of None has the same effect), or pass 'ignore' to ignore +errors. (Note that ignoring encoding errors can lead to data loss.) +See the documentation for codecs.register or run 'help(codecs.Codec)' +for a list of the permitted encoding error strings. + +newline controls how universal newlines works (it only applies to text +mode). It can be None, '', '\n', '\r', and '\r\n'. It works as +follows: + +* On input, if newline is None, universal newlines mode is + enabled. Lines in the input can end in '\n', '\r', or '\r\n', and + these are translated into '\n' before being returned to the + caller. If it is '', universal newline mode is enabled, but line + endings are returned to the caller untranslated. If it has any of + the other legal values, input lines are only terminated by the given + string, and the line ending is returned to the caller untranslated. + +* On output, if newline is None, any '\n' characters written are + translated to the system default line separator, os.linesep. If + newline is '' or '\n', no translation takes place. If newline is any + of the other legal values, any '\n' characters written are translated + to the given string. + +If closefd is False, the underlying file descriptor will be kept open +when the file is closed. This does not work when a file name is given +and must be True in that case. + +A custom opener can be used by passing a callable as *opener*. The +underlying file descriptor for the file object is then obtained by +calling *opener* with (*file*, *flags*). *opener* must return an open +file descriptor (passing os.open as *opener* results in functionality +similar to passing None). + +open() returns a file object whose type depends on the mode, and +through which the standard file operations such as reading and writing +are performed. When open() is used to open a file in a text mode ('w', +'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open +a file in a binary mode, the returned class varies: in read binary +mode, it returns a BufferedReader; in write binary and append binary +modes, it returns a BufferedWriter, and in read/write mode, it returns +a BufferedRandom. + +It is also possible to use a string or bytearray as a file for both +reading and writing. For strings StringIO can be used like a file +opened in a text mode, and for bytes a BytesIO can be used like a file +opened in a binary mode. +[clinic start generated code]*/ + +PyDoc_STRVAR(_io_open__doc__, +"open(file, mode=\'r\', buffering=-1, encoding=None, errors=None, newline=None, closefd=1, opener=None)\n" "Open file and return a stream. Raise IOError upon failure.\n" "\n" "file is either a text or byte string giving the name (and the path\n" -"if the file isn't in the current working directory) of the file to\n" +"if the file isn\'t in the current working directory) of the file to\n" "be opened or an integer file descriptor of the file to be\n" "wrapped. (If a file descriptor is given, it is closed when the\n" "returned I/O object is closed, unless closefd is set to False.)\n" "\n" "mode is an optional string that specifies the mode in which the file\n" -"is opened. It defaults to 'r' which means open for reading in text\n" -"mode. Other common values are 'w' for writing (truncating the file if\n" -"it already exists), 'x' for creating and writing to a new file, and\n" -"'a' for appending (which on some Unix systems, means that all writes\n" +"is opened. It defaults to \'r\' which means open for reading in text\n" +"mode. Other common values are \'w\' for writing (truncating the file if\n" +"it already exists), \'x\' for creating and writing to a new file, and\n" +"\'a\' for appending (which on some Unix systems, means that all writes\n" "append to the end of the file regardless of the current seek position).\n" "In text mode, if encoding is not specified the encoding used is platform\n" "dependent: locale.getpreferredencoding(False) is called to get the\n" @@ -119,30 +254,30 @@ PyDoc_STRVAR(open_doc, "========= ===============================================================\n" "Character Meaning\n" "--------- ---------------------------------------------------------------\n" -"'r' open for reading (default)\n" -"'w' open for writing, truncating the file first\n" -"'x' create a new file and open it for writing\n" -"'a' open for writing, appending to the end of the file if it exists\n" -"'b' binary mode\n" -"'t' text mode (default)\n" -"'+' open a disk file for updating (reading and writing)\n" -"'U' universal newline mode (deprecated)\n" +"\'r\' open for reading (default)\n" +"\'w\' open for writing, truncating the file first\n" +"\'x\' create a new file and open it for writing\n" +"\'a\' open for writing, appending to the end of the file if it exists\n" +"\'b\' binary mode\n" +"\'t\' text mode (default)\n" +"\'+\' open a disk file for updating (reading and writing)\n" +"\'U\' universal newline mode (deprecated)\n" "========= ===============================================================\n" "\n" -"The default mode is 'rt' (open for reading text). For binary random\n" -"access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n" -"'r+b' opens the file without truncation. The 'x' mode implies 'w' and\n" +"The default mode is \'rt\' (open for reading text). For binary random\n" +"access, the mode \'w+b\' opens and truncates the file to 0 bytes, while\n" +"\'r+b\' opens the file without truncation. The \'x\' mode implies \'w\' and\n" "raises an `FileExistsError` if the file already exists.\n" "\n" "Python distinguishes between files opened in binary and text modes,\n" -"even when the underlying operating system doesn't. Files opened in\n" -"binary mode (appending 'b' to the mode argument) return contents as\n" +"even when the underlying operating system doesn\'t. Files opened in\n" +"binary mode (appending \'b\' to the mode argument) return contents as\n" "bytes objects without any decoding. In text mode (the default, or when\n" -"'t' is appended to the mode argument), the contents of the file are\n" +"\'t\' is appended to the mode argument), the contents of the file are\n" "returned as strings, the bytes having been first decoded using a\n" "platform-dependent encoding or using the specified encoding if given.\n" "\n" -"'U' mode is deprecated and will raise an exception in future versions\n" +"\'U\' mode is deprecated and will raise an exception in future versions\n" "of Python. It has no effect in Python 3. Use newline to control\n" "universal newlines mode.\n" "\n" @@ -153,7 +288,7 @@ PyDoc_STRVAR(open_doc, "given, the default buffering policy works as follows:\n" "\n" "* Binary files are buffered in fixed-size chunks; the size of the buffer\n" -" is chosen using a heuristic trying to determine the underlying device's\n" +" is chosen using a heuristic trying to determine the underlying device\'s\n" " \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n" " On many systems, the buffer will typically be 4096 or 8192 bytes long.\n" "\n" @@ -168,28 +303,28 @@ PyDoc_STRVAR(open_doc, "\n" "errors is an optional string that specifies how encoding errors are to\n" "be handled---this argument should not be used in binary mode. Pass\n" -"'strict' to raise a ValueError exception if there is an encoding error\n" -"(the default of None has the same effect), or pass 'ignore' to ignore\n" +"\'strict\' to raise a ValueError exception if there is an encoding error\n" +"(the default of None has the same effect), or pass \'ignore\' to ignore\n" "errors. (Note that ignoring encoding errors can lead to data loss.)\n" -"See the documentation for codecs.register or run 'help(codecs.Codec)'\n" +"See the documentation for codecs.register or run \'help(codecs.Codec)\'\n" "for a list of the permitted encoding error strings.\n" "\n" "newline controls how universal newlines works (it only applies to text\n" -"mode). It can be None, '', '\\n', '\\r', and '\\r\\n'. It works as\n" +"mode). It can be None, \'\', \'\n\', \'\r\', and \'\r\n\'. It works as\n" "follows:\n" "\n" "* On input, if newline is None, universal newlines mode is\n" -" enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n" -" these are translated into '\\n' before being returned to the\n" -" caller. If it is '', universal newline mode is enabled, but line\n" +" enabled. Lines in the input can end in \'\n\', \'\r\', or \'\r\n\', and\n" +" these are translated into \'\n\' before being returned to the\n" +" caller. If it is \'\', universal newline mode is enabled, but line\n" " endings are returned to the caller untranslated. If it has any of\n" " the other legal values, input lines are only terminated by the given\n" " string, and the line ending is returned to the caller untranslated.\n" "\n" -"* On output, if newline is None, any '\\n' characters written are\n" +"* On output, if newline is None, any \'\n\' characters written are\n" " translated to the system default line separator, os.linesep. If\n" -" newline is '' or '\\n', no translation takes place. If newline is any\n" -" of the other legal values, any '\\n' characters written are translated\n" +" newline is \'\' or \'\n\', no translation takes place. If newline is any\n" +" of the other legal values, any \'\n\' characters written are translated\n" " to the given string.\n" "\n" "If closefd is False, the underlying file descriptor will be kept open\n" @@ -204,8 +339,8 @@ PyDoc_STRVAR(open_doc, "\n" "open() returns a file object whose type depends on the mode, and\n" "through which the standard file operations such as reading and writing\n" -"are performed. When open() is used to open a file in a text mode ('w',\n" -"'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n" +"are performed. When open() is used to open a file in a text mode (\'w\',\n" +"\'r\', \'wt\', \'rt\', etc.), it returns a TextIOWrapper. When used to open\n" "a file in a binary mode, the returned class varies: in read binary\n" "mode, it returns a BufferedReader; in write binary and append binary\n" "modes, it returns a BufferedWriter, and in read/write mode, it returns\n" @@ -214,19 +349,42 @@ PyDoc_STRVAR(open_doc, "It is also possible to use a string or bytearray as a file for both\n" "reading and writing. For strings StringIO can be used like a file\n" "opened in a text mode, and for bytes a BytesIO can be used like a file\n" -"opened in a binary mode.\n" - ); +"opened in a binary mode."); + +#define _IO_OPEN_METHODDEF \ + {"open", (PyCFunction)_io_open, METH_VARARGS|METH_KEYWORDS, _io_open__doc__}, static PyObject * -io_open(PyObject *self, PyObject *args, PyObject *kwds) +_io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd, PyObject *opener); + +static PyObject * +_io_open(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - char *kwlist[] = {"file", "mode", "buffering", - "encoding", "errors", "newline", - "closefd", "opener", NULL}; - PyObject *file, *opener = Py_None; - char *mode = "r"; - int buffering = -1, closefd = 1; - char *encoding = NULL, *errors = NULL, *newline = NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; + PyObject *file; + const char *mode = "r"; + int buffering = -1; + const char *encoding = NULL; + const char *errors = NULL; + const char *newline = NULL; + int closefd = 1; + PyObject *opener = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|sizzziO:open", _keywords, + &file, &mode, &buffering, &encoding, &errors, &newline, &closefd, &opener)) + goto exit; + return_value = _io_open_impl(module, file, mode, buffering, encoding, errors, newline, closefd, opener); + +exit: + return return_value; +} + +static PyObject * +_io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd, PyObject *opener) +/*[clinic end generated code: checksum=c2d352c14c1341af5f21ea6bb5eb42df0c420dd0]*/ +{ unsigned i; int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0; @@ -241,13 +399,6 @@ io_open(PyObject *self, PyObject *args, _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(mode); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzziO:open", kwlist, - &file, &mode, &buffering, - &encoding, &errors, &newline, - &closefd, &opener)) { - return NULL; - } - if (!PyUnicode_Check(file) && !PyBytes_Check(file) && !PyNumber_Check(file)) { @@ -613,7 +764,7 @@ iomodule_free(PyObject *mod) { */ static PyMethodDef module_methods[] = { - {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc}, + _IO_OPEN_METHODDEF {NULL, NULL} }; diff -r 1638360eea41 Modules/_lsprof.c --- a/Modules/_lsprof.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/_lsprof.c Sun Jan 12 11:10:49 2014 +0100 @@ -2,6 +2,12 @@ #include "frameobject.h" #include "rotatingtree.h" +/*[clinic input] +module _lsprof +class _lsprof.Profiler +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + #if !defined(HAVE_LONG_LONG) #error "This module requires long longs!" #endif @@ -600,46 +606,86 @@ static int statsForEntry(rotating_node_t return err; } -PyDoc_STRVAR(getstats_doc, "\ -getstats() -> list of profiler_entry objects\n\ -\n\ -Return all information collected by the profiler.\n\ -Each profiler_entry is a tuple-like object with the\n\ -following attributes:\n\ -\n\ - code code object\n\ - callcount how many times this was called\n\ - reccallcount how many times called recursively\n\ - totaltime total time in this entry\n\ - inlinetime inline time in this entry (not in subcalls)\n\ - calls details of the calls\n\ -\n\ -The calls attribute is either None or a list of\n\ -profiler_subentry objects:\n\ -\n\ - code called code object\n\ - callcount how many times this is called\n\ - reccallcount how many times this is called recursively\n\ - totaltime total time spent in this call\n\ - inlinetime inline time (not in further subcalls)\n\ -"); -static PyObject* -profiler_getstats(ProfilerObject *pObj, PyObject* noarg) +/*[clinic input] +_lsprof.Profiler.getstats + + self: self(type='ProfilerObject *') + +Return all information collected by the profiler. + +Each profiler_entry is a tuple-like object with the following attributes: + + code code object + callcount how many times this was called + reccallcount how many times called recursively + totaltime total time in this entry + inlinetime inline time in this entry (not in subcalls) + calls details of the calls + +The calls attribute is either None or a list of profiler_subentry objects: + + code called code object + callcount how many times this is called + reccallcount how many times this is called recursively + totaltime total time spent in this call + inlinetime inline time (not in further subcalls) +[clinic start generated code]*/ + +PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, +"getstats()\n" +"Return all information collected by the profiler.\n" +"\n" +"Each profiler_entry is a tuple-like object with the following attributes:\n" +"\n" +" code code object\n" +" callcount how many times this was called\n" +" reccallcount how many times called recursively\n" +" totaltime total time in this entry\n" +" inlinetime inline time in this entry (not in subcalls)\n" +" calls details of the calls\n" +"\n" +"The calls attribute is either None or a list of profiler_subentry objects:\n" +"\n" +" code called code object\n" +" callcount how many times this is called\n" +" reccallcount how many times this is called recursively\n" +" totaltime total time spent in this call\n" +" inlinetime inline time (not in further subcalls)"); + +#define _LSPROF_PROFILER_GETSTATS_METHODDEF \ + {"getstats", (PyCFunction)_lsprof_Profiler_getstats, METH_NOARGS, _lsprof_Profiler_getstats__doc__}, + +static PyObject * +_lsprof_Profiler_getstats_impl(ProfilerObject *self); + +static PyObject * +_lsprof_Profiler_getstats(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _lsprof_Profiler_getstats_impl((ProfilerObject *)self); + + return return_value; +} + +static PyObject * +_lsprof_Profiler_getstats_impl(ProfilerObject *self) +/*[clinic end generated code: checksum=1f784e81fe6a6021c585f94eaff88367926b26d1]*/ { statscollector_t collect; - if (pending_exception(pObj)) + if (pending_exception(self)) return NULL; - if (!pObj->externalTimer) + if (!self->externalTimer) collect.factor = hpTimerUnit(); - else if (pObj->externalTimerUnit > 0.0) - collect.factor = pObj->externalTimerUnit; + else if (self->externalTimerUnit > 0.0) + collect.factor = self->externalTimerUnit; else collect.factor = 1.0 / DOUBLE_TIMER_PRECISION; collect.list = PyList_New(0); if (collect.list == NULL) return NULL; - if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) + if (RotatingTree_Enum(self->profilerEntries, statsForEntry, &collect) != 0) { Py_DECREF(collect.list); return NULL; @@ -674,31 +720,64 @@ setBuiltins(ProfilerObject *pObj, int nv return 0; } -PyDoc_STRVAR(enable_doc, "\ -enable(subcalls=True, builtins=True)\n\ -\n\ -Start collecting profiling information.\n\ -If 'subcalls' is True, also records for each function\n\ -statistics separated according to its current caller.\n\ -If 'builtins' is True, records the time spent in\n\ -built-in functions separately from their caller.\n\ -"); -static PyObject* -profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) +/*[clinic input] +_lsprof.Profiler.enable + + self: self(type='ProfilerObject *') + subcalls: bool = True + builtins: bool = True + / + +Start collecting profiling information. + +If 'subcalls' is True, also records for each function +statistics separated according to its current caller. +If 'builtins' is True, records the time spent in +built-in functions separately from their caller. +[clinic start generated code]*/ + +PyDoc_STRVAR(_lsprof_Profiler_enable__doc__, +"enable(subcalls=True, builtins=True)\n" +"Start collecting profiling information.\n" +"\n" +"If \'subcalls\' is True, also records for each function\n" +"statistics separated according to its current caller.\n" +"If \'builtins\' is True, records the time spent in\n" +"built-in functions separately from their caller."); + +#define _LSPROF_PROFILER_ENABLE_METHODDEF \ + {"enable", (PyCFunction)_lsprof_Profiler_enable, METH_VARARGS, _lsprof_Profiler_enable__doc__}, + +static PyObject * +_lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls, int builtins); + +static PyObject * +_lsprof_Profiler_enable(PyObject *self, PyObject *args) { - int subcalls = -1; - int builtins = -1; - static char *kwlist[] = {"subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", - kwlist, &subcalls, &builtins)) - return NULL; + PyObject *return_value = NULL; + int subcalls = 1; + int builtins = 1; + + if (!PyArg_ParseTuple(args, + "|pp:enable", + &subcalls, &builtins)) + goto exit; + return_value = _lsprof_Profiler_enable_impl((ProfilerObject *)self, subcalls, builtins); + +exit: + return return_value; +} + +static PyObject * +_lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls, int builtins) +/*[clinic end generated code: checksum=6034ac8a3c5d15647227efd5e162b325d035f098]*/ +{ if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) return NULL; PyEval_SetProfile(profiler_callback, (PyObject*)self); self->flags |= POF_ENABLED; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static void @@ -717,36 +796,82 @@ flush_unmatched(ProfilerObject *pObj) } -PyDoc_STRVAR(disable_doc, "\ -disable()\n\ -\n\ -Stop collecting profiling information.\n\ -"); -static PyObject* -profiler_disable(ProfilerObject *self, PyObject* noarg) +/*[clinic input] +_lsprof.Profiler.disable + + self: self(type='ProfilerObject *') + +Stop collecting profiling information. +[clinic start generated code]*/ + +PyDoc_STRVAR(_lsprof_Profiler_disable__doc__, +"disable()\n" +"Stop collecting profiling information."); + +#define _LSPROF_PROFILER_DISABLE_METHODDEF \ + {"disable", (PyCFunction)_lsprof_Profiler_disable, METH_NOARGS, _lsprof_Profiler_disable__doc__}, + +static PyObject * +_lsprof_Profiler_disable_impl(ProfilerObject *self); + +static PyObject * +_lsprof_Profiler_disable(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _lsprof_Profiler_disable_impl((ProfilerObject *)self); + + return return_value; +} + +static PyObject * +_lsprof_Profiler_disable_impl(ProfilerObject *self) +/*[clinic end generated code: checksum=1bbc0d91532655cc397d7cb0c204d07ea179f18f]*/ { self->flags &= ~POF_ENABLED; PyEval_SetProfile(NULL, NULL); flush_unmatched(self); if (pending_exception(self)) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(clear_doc, "\ -clear()\n\ -\n\ -Clear all profiling information collected so far.\n\ -"); -static PyObject* -profiler_clear(ProfilerObject *pObj, PyObject* noarg) +/*[clinic input] +_lsprof.Profiler.clear + + self: self(type='ProfilerObject *') + +Clear all profiling information collected so far. +[clinic start generated code]*/ + +PyDoc_STRVAR(_lsprof_Profiler_clear__doc__, +"clear()\n" +"Clear all profiling information collected so far."); + +#define _LSPROF_PROFILER_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_lsprof_Profiler_clear, METH_NOARGS, _lsprof_Profiler_clear__doc__}, + +static PyObject * +_lsprof_Profiler_clear_impl(ProfilerObject *self); + +static PyObject * +_lsprof_Profiler_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) { - clearEntries(pObj); - Py_INCREF(Py_None); - return Py_None; + PyObject *return_value = NULL; + + return_value = _lsprof_Profiler_clear_impl((ProfilerObject *)self); + + return return_value; +} + +static PyObject * +_lsprof_Profiler_clear_impl(ProfilerObject *self) +/*[clinic end generated code: checksum=a355d43a71ac5c247f34e46f2801a072ff22cb77]*/ +{ + clearEntries(self); + Py_RETURN_NONE; } static void @@ -791,14 +916,10 @@ profiler_init(ProfilerObject *pObj, PyOb } static PyMethodDef profiler_methods[] = { - {"getstats", (PyCFunction)profiler_getstats, - METH_NOARGS, getstats_doc}, - {"enable", (PyCFunction)profiler_enable, - METH_VARARGS | METH_KEYWORDS, enable_doc}, - {"disable", (PyCFunction)profiler_disable, - METH_NOARGS, disable_doc}, - {"clear", (PyCFunction)profiler_clear, - METH_NOARGS, clear_doc}, + _LSPROF_PROFILER_GETSTATS_METHODDEF + _LSPROF_PROFILER_ENABLE_METHODDEF + _LSPROF_PROFILER_DISABLE_METHODDEF + _LSPROF_PROFILER_CLEAR_METHODDEF {NULL, NULL} }; diff -r 1638360eea41 Modules/_tracemalloc.c --- a/Modules/_tracemalloc.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/_tracemalloc.c Sun Jan 12 11:10:49 2014 +0100 @@ -4,6 +4,11 @@ #include "pythread.h" #include "osdefs.h" +/*[clinic input] +module _tracemalloc +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /* Trace memory blocks allocated by PyMem_RawMalloc() */ #define TRACE_RAW_MALLOC @@ -917,25 +922,70 @@ lineno_as_obj(int lineno) Py_RETURN_NONE; } -PyDoc_STRVAR(tracemalloc_is_tracing_doc, - "is_tracing()->bool\n" - "\n" - "True if the tracemalloc module is tracing Python memory allocations,\n" - "False otherwise."); -static PyObject* -py_tracemalloc_is_tracing(PyObject *self) +/*[clinic input] +_tracemalloc.is_tracing + +True if the tracemalloc module is tracing Python memory allocations, False otherwise. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, +"is_tracing()\n" +"True if the tracemalloc module is tracing Python memory allocations, False otherwise."); + +#define _TRACEMALLOC_IS_TRACING_METHODDEF \ + {"is_tracing", (PyCFunction)_tracemalloc_is_tracing, METH_NOARGS, _tracemalloc_is_tracing__doc__}, + +static PyObject * +_tracemalloc_is_tracing_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc_is_tracing(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc_is_tracing_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc_is_tracing_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=687fdf1c4966d85d7090c2132b6bd2e18573f57d]*/ { return PyBool_FromLong(tracemalloc_config.tracing); } -PyDoc_STRVAR(tracemalloc_clear_traces_doc, - "clear_traces()\n" - "\n" - "Clear traces of memory blocks allocated by Python."); -static PyObject* -py_tracemalloc_clear_traces(PyObject *self) +/*[clinic input] +_tracemalloc.clear_traces + +Clear traces of memory blocks allocated by Python. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_clear_traces__doc__, +"clear_traces()\n" +"Clear traces of memory blocks allocated by Python."); + +#define _TRACEMALLOC_CLEAR_TRACES_METHODDEF \ + {"clear_traces", (PyCFunction)_tracemalloc_clear_traces, METH_NOARGS, _tracemalloc_clear_traces__doc__}, + +static PyObject * +_tracemalloc_clear_traces_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc_clear_traces(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc_clear_traces_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc_clear_traces_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=6bedc8aea0518dc47a981897fc2404e6ceecc58e]*/ { if (!tracemalloc_config.tracing) Py_RETURN_NONE; @@ -1073,17 +1123,46 @@ tracemalloc_pyobject_decref_cb(_Py_hasht return 0; } -PyDoc_STRVAR(tracemalloc_get_traces_doc, - "_get_traces() -> list\n" - "\n" - "Get traces of all memory blocks allocated by Python.\n" - "Return a list of (size: int, traceback: tuple) tuples.\n" - "traceback is a tuple of (filename: str, lineno: int) tuples.\n" - "\n" - "Return an empty list if the tracemalloc module is disabled."); -static PyObject* -py_tracemalloc_get_traces(PyObject *self, PyObject *obj) +/*[clinic input] +_tracemalloc._get_traces + +Get traces of all memory blocks allocated by Python. + +Return a list of (size: int, traceback: tuple) tuples. +traceback is a tuple of (filename: str, lineno: int) tuples. + +Return an empty list if the tracemalloc module is disabled. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc__get_traces__doc__, +"_get_traces()\n" +"Get traces of all memory blocks allocated by Python.\n" +"\n" +"Return a list of (size: int, traceback: tuple) tuples.\n" +"traceback is a tuple of (filename: str, lineno: int) tuples.\n" +"\n" +"Return an empty list if the tracemalloc module is disabled."); + +#define _TRACEMALLOC__GET_TRACES_METHODDEF \ + {"_get_traces", (PyCFunction)_tracemalloc__get_traces, METH_NOARGS, _tracemalloc__get_traces__doc__}, + +static PyObject * +_tracemalloc__get_traces_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc__get_traces(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc__get_traces_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc__get_traces_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=4a9720264c878c513a0dd79032a696d0050012ca]*/ { get_traces_t get_traces; int err; @@ -1140,17 +1219,53 @@ finally: return get_traces.list; } -PyDoc_STRVAR(tracemalloc_get_object_traceback_doc, - "_get_object_traceback(obj)\n" - "\n" - "Get the traceback where the Python object obj was allocated.\n" - "Return a tuple of (filename: str, lineno: int) tuples.\n" - "\n" - "Return None if the tracemalloc module is disabled or did not\n" - "trace the allocation of the object."); -static PyObject* -py_tracemalloc_get_object_traceback(PyObject *self, PyObject *obj) +/*[clinic input] +_tracemalloc._get_object_traceback + + obj: 'O' + +Get the traceback where the Python object obj was allocated. + +Return a tuple of (filename: str, lineno: int) tuples. +Return None if the tracemalloc module is disabled or did not +trace the allocation of the object. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc__get_object_traceback__doc__, +"_get_object_traceback(obj)\n" +"Get the traceback where the Python object obj was allocated.\n" +"\n" +"Return a tuple of (filename: str, lineno: int) tuples.\n" +"Return None if the tracemalloc module is disabled or did not\n" +"trace the allocation of the object."); + +#define _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF \ + {"_get_object_traceback", (PyCFunction)_tracemalloc__get_object_traceback, METH_VARARGS|METH_KEYWORDS, _tracemalloc__get_object_traceback__doc__}, + +static PyObject * +_tracemalloc__get_object_traceback_impl(PyModuleDef *module, PyObject *obj); + +static PyObject * +_tracemalloc__get_object_traceback(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", NULL}; + PyObject *obj; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:_get_object_traceback", _keywords, + &obj)) + goto exit; + return_value = _tracemalloc__get_object_traceback_impl(module, obj); + +exit: + return return_value; +} + +static PyObject * +_tracemalloc__get_object_traceback_impl(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: checksum=78d25667e4fadbe30e7296588dfaaf3989b830c1]*/ { PyTypeObject *type; void *ptr; @@ -1176,21 +1291,54 @@ py_tracemalloc_get_object_traceback(PyOb return traceback_to_pyobject(trace.traceback, NULL); } -PyDoc_STRVAR(tracemalloc_start_doc, - "start(nframe: int=1)\n" - "\n" - "Start tracing Python memory allocations. Set also the maximum number \n" - "of frames stored in the traceback of a trace to nframe."); -static PyObject* -py_tracemalloc_start(PyObject *self, PyObject *args) +/*[clinic input] +_tracemalloc.start + + nframe: 'n' = 1 + +Start tracing Python memory allocations. + +Also set the maximum number of frames stored in the traceback of a +trace to nframe. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_start__doc__, +"start(nframe=1)\n" +"Start tracing Python memory allocations.\n" +"\n" +"Also set the maximum number of frames stored in the traceback of a\n" +"trace to nframe."); + +#define _TRACEMALLOC_START_METHODDEF \ + {"start", (PyCFunction)_tracemalloc_start, METH_VARARGS|METH_KEYWORDS, _tracemalloc_start__doc__}, + +static PyObject * +_tracemalloc_start_impl(PyModuleDef *module, Py_ssize_t nframe); + +static PyObject * +_tracemalloc_start(PyModuleDef *module, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"nframe", NULL}; Py_ssize_t nframe = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|n:start", _keywords, + &nframe)) + goto exit; + return_value = _tracemalloc_start_impl(module, nframe); + +exit: + return return_value; +} + +static PyObject * +_tracemalloc_start_impl(PyModuleDef *module, Py_ssize_t nframe) +/*[clinic end generated code: checksum=921012db9ba047b98dc5ea48c306a5c4f73eb7d9]*/ +{ int nframe_int; - if (!PyArg_ParseTuple(args, "|n:start", &nframe)) - return NULL; - if (nframe < 1 || nframe > MAX_NFRAME) { PyErr_Format(PyExc_ValueError, "the number of frames must be in range [1; %i]", @@ -1205,42 +1353,119 @@ py_tracemalloc_start(PyObject *self, PyO Py_RETURN_NONE; } -PyDoc_STRVAR(tracemalloc_stop_doc, - "stop()\n" - "\n" - "Stop tracing Python memory allocations and clear traces\n" - "of memory blocks allocated by Python."); -static PyObject* -py_tracemalloc_stop(PyObject *self) +/*[clinic input] +_tracemalloc.stop + +Stop tracing Python memory allocations. + +Also clear traces of memory blocks allocated by Python. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_stop__doc__, +"stop()\n" +"Stop tracing Python memory allocations.\n" +"\n" +"Also clear traces of memory blocks allocated by Python."); + +#define _TRACEMALLOC_STOP_METHODDEF \ + {"stop", (PyCFunction)_tracemalloc_stop, METH_NOARGS, _tracemalloc_stop__doc__}, + +static PyObject * +_tracemalloc_stop_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc_stop(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc_stop_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc_stop_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=500d2baf420f0091d79ea66384f7889d48ce8afb]*/ { tracemalloc_stop(); Py_RETURN_NONE; } -PyDoc_STRVAR(tracemalloc_get_traceback_limit_doc, - "get_traceback_limit() -> int\n" - "\n" - "Get the maximum number of frames stored in the traceback\n" - "of a trace.\n" - "\n" - "By default, a trace of an allocated memory block only stores\n" - "the most recent frame: the limit is 1."); -static PyObject* -py_tracemalloc_get_traceback_limit(PyObject *self) +/*[clinic input] +_tracemalloc.get_traceback_limit + +Get the maximum number of frames stored in the traceback of a trace. + +By default, a trace of an allocated memory block only stores +the most recent frame: the limit is 1. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_get_traceback_limit__doc__, +"get_traceback_limit()\n" +"Get the maximum number of frames stored in the traceback of a trace.\n" +"\n" +"By default, a trace of an allocated memory block only stores\n" +"the most recent frame: the limit is 1."); + +#define _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF \ + {"get_traceback_limit", (PyCFunction)_tracemalloc_get_traceback_limit, METH_NOARGS, _tracemalloc_get_traceback_limit__doc__}, + +static PyObject * +_tracemalloc_get_traceback_limit_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc_get_traceback_limit(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc_get_traceback_limit_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc_get_traceback_limit_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=e4f5a68d7eefc7c8f15a1ca828d25e4cb5c4faf2]*/ { return PyLong_FromLong(tracemalloc_config.max_nframe); } -PyDoc_STRVAR(tracemalloc_get_tracemalloc_memory_doc, - "get_tracemalloc_memory() -> int\n" - "\n" - "Get the memory usage in bytes of the tracemalloc module\n" - "used internally to trace memory allocations."); -static PyObject* -tracemalloc_get_tracemalloc_memory(PyObject *self) +/*[clinic input] +_tracemalloc.get_tracemalloc_memory + +Get the memory usage in bytes of the tracemalloc module. + +This memory is used internally to trace memory allocations. +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_get_tracemalloc_memory__doc__, +"get_tracemalloc_memory()\n" +"Get the memory usage in bytes of the tracemalloc module.\n" +"\n" +"This memory is used internally to trace memory allocations."); + +#define _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF \ + {"get_tracemalloc_memory", (PyCFunction)_tracemalloc_get_tracemalloc_memory, METH_NOARGS, _tracemalloc_get_tracemalloc_memory__doc__}, + +static PyObject * +_tracemalloc_get_tracemalloc_memory_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc_get_tracemalloc_memory(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc_get_tracemalloc_memory_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc_get_tracemalloc_memory_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=edc8f026107b0abcd1cef866bdc194c5ab33fbb7]*/ { size_t size; PyObject *size_obj; @@ -1256,14 +1481,40 @@ tracemalloc_get_tracemalloc_memory(PyObj return Py_BuildValue("N", size_obj); } -PyDoc_STRVAR(tracemalloc_get_traced_memory_doc, - "get_traced_memory() -> (int, int)\n" - "\n" - "Get the current size and peak size of memory blocks traced\n" - "by the tracemalloc module as a tuple: (current: int, peak: int)."); -static PyObject* -tracemalloc_get_traced_memory(PyObject *self) +/*[clinic input] +_tracemalloc.get_traced_memory + +Get the current size and peak size of memory blocks traced by tracemalloc. + +Returns a tuple: (current: int, peak: int). +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_get_traced_memory__doc__, +"get_traced_memory()\n" +"Get the current size and peak size of memory blocks traced by tracemalloc.\n" +"\n" +"Returns a tuple: (current: int, peak: int)."); + +#define _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF \ + {"get_traced_memory", (PyCFunction)_tracemalloc_get_traced_memory, METH_NOARGS, _tracemalloc_get_traced_memory__doc__}, + +static PyObject * +_tracemalloc_get_traced_memory_impl(PyModuleDef *module); + +static PyObject * +_tracemalloc_get_traced_memory(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _tracemalloc_get_traced_memory_impl(module); + + return return_value; +} + +static PyObject * +_tracemalloc_get_traced_memory_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=ea928385668772b2d089000301353908c069ca0c]*/ { Py_ssize_t size, peak_size; PyObject *size_obj, *peak_size_obj; @@ -1282,25 +1533,15 @@ tracemalloc_get_traced_memory(PyObject * } static PyMethodDef module_methods[] = { - {"is_tracing", (PyCFunction)py_tracemalloc_is_tracing, - METH_NOARGS, tracemalloc_is_tracing_doc}, - {"clear_traces", (PyCFunction)py_tracemalloc_clear_traces, - METH_NOARGS, tracemalloc_clear_traces_doc}, - {"_get_traces", (PyCFunction)py_tracemalloc_get_traces, - METH_NOARGS, tracemalloc_get_traces_doc}, - {"_get_object_traceback", (PyCFunction)py_tracemalloc_get_object_traceback, - METH_O, tracemalloc_get_object_traceback_doc}, - {"start", (PyCFunction)py_tracemalloc_start, - METH_VARARGS, tracemalloc_start_doc}, - {"stop", (PyCFunction)py_tracemalloc_stop, - METH_NOARGS, tracemalloc_stop_doc}, - {"get_traceback_limit", (PyCFunction)py_tracemalloc_get_traceback_limit, - METH_NOARGS, tracemalloc_get_traceback_limit_doc}, - {"get_tracemalloc_memory", (PyCFunction)tracemalloc_get_tracemalloc_memory, - METH_NOARGS, tracemalloc_get_tracemalloc_memory_doc}, - {"get_traced_memory", (PyCFunction)tracemalloc_get_traced_memory, - METH_NOARGS, tracemalloc_get_traced_memory_doc}, - + _TRACEMALLOC_IS_TRACING_METHODDEF + _TRACEMALLOC_CLEAR_TRACES_METHODDEF + _TRACEMALLOC__GET_TRACES_METHODDEF + _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF + _TRACEMALLOC_START_METHODDEF + _TRACEMALLOC_STOP_METHODDEF + _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF + _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF + _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF /* sentinel */ {NULL, NULL} }; diff -r 1638360eea41 Modules/mathmodule.c --- a/Modules/mathmodule.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/mathmodule.c Sun Jan 12 11:10:49 2014 +0100 @@ -55,6 +55,12 @@ raised for division by zero and mod by z #include "Python.h" #include "_math.h" +/*[clinic input] +module math +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /* sin(pi*x), giving accurate results for all finite x (especially x integral or close to an integer). This is here for use in the @@ -698,7 +704,7 @@ is_error(double x) /* math_1 is used to wrap a libm function f that takes a double - arguments and returns a double. + argument and returns a double. The error reporting follows these rules, which are designed to do the right thing on C89/C99 platforms and IEEE 754/non IEEE 754 @@ -1057,8 +1063,29 @@ static int /* n Depends on IEEE 754 arithmetic guarantees and half-even rounding. */ -static PyObject* -math_fsum(PyObject *self, PyObject *seq) +/*[clinic input] +math.fsum + + seq: 'O' + / + +Return an accurate floating point sum of values in the iterable seq. + +Assumes IEEE-754 floating point arithmetic. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_fsum__doc__, +"fsum(seq)\n" +"Return an accurate floating point sum of values in the iterable seq.\n" +"\n" +"Assumes IEEE-754 floating point arithmetic."); + +#define MATH_FSUM_METHODDEF \ + {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__}, + +static PyObject * +math_fsum(PyModuleDef *module, PyObject *seq) +/*[clinic end generated code: checksum=525313075ab3cf5f677644c60f26c8d5f96545db]*/ { PyObject *item, *iter, *sum = NULL; Py_ssize_t i, j, n = 0, m = NUM_PARTIALS; @@ -1177,10 +1204,6 @@ math_fsum(PyObject *self, PyObject *seq) #undef NUM_PARTIALS -PyDoc_STRVAR(math_fsum_doc, -"fsum(iterable)\n\n\ -Return an accurate floating point sum of values in the iterable.\n\ -Assumes IEEE-754 floating point arithmetic."); /* Return the smallest integer k such that n < 2**k, or 0 if n == 0. * Equivalent to floor(lg(x))+1. Also equivalent to: bitwidth_of_type - @@ -1390,6 +1413,7 @@ factorial_odd_part(unsigned long n) return NULL; } + /* Lookup table for small factorial values */ static const unsigned long SmallFactorials[] = { @@ -1402,47 +1426,64 @@ static const unsigned long SmallFactoria #endif }; +/*[clinic input] +math.factorial + + x: 'O' + / + +Find x!. Raise a ValueError if x is negative or non-integral. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_factorial__doc__, +"factorial(x)\n" +"Find x!. Raise a ValueError if x is negative or non-integral."); + +#define MATH_FACTORIAL_METHODDEF \ + {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__}, + static PyObject * -math_factorial(PyObject *self, PyObject *arg) +math_factorial(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: checksum=365207eff1f89c43a76608a65fb0a68932ba20a4]*/ { - long x; + long lx; PyObject *result, *odd_part, *two_valuation; - if (PyFloat_Check(arg)) { - PyObject *lx; - double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); + if (PyFloat_Check(x)) { + PyObject *olx; + double dx = PyFloat_AS_DOUBLE((PyFloatObject *)x); if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { PyErr_SetString(PyExc_ValueError, "factorial() only accepts integral values"); return NULL; } - lx = PyLong_FromDouble(dx); - if (lx == NULL) + olx = PyLong_FromDouble(dx); + if (olx == NULL) return NULL; - x = PyLong_AsLong(lx); - Py_DECREF(lx); + lx = PyLong_AsLong(olx); + Py_DECREF(olx); } else - x = PyLong_AsLong(arg); + lx = PyLong_AsLong(x); - if (x == -1 && PyErr_Occurred()) + if (lx == -1 && PyErr_Occurred()) return NULL; - if (x < 0) { + if (lx < 0) { PyErr_SetString(PyExc_ValueError, "factorial() not defined for negative values"); return NULL; } - /* use lookup table if x is small */ - if (x < (long)Py_ARRAY_LENGTH(SmallFactorials)) - return PyLong_FromUnsignedLong(SmallFactorials[x]); + /* use lookup table if lx is small */ + if (lx < (long)Py_ARRAY_LENGTH(SmallFactorials)) + return PyLong_FromUnsignedLong(SmallFactorials[lx]); /* else express in the form odd_part * 2**two_valuation, and compute as odd_part << two_valuation. */ - odd_part = factorial_odd_part(x); + odd_part = factorial_odd_part(lx); if (odd_part == NULL) return NULL; - two_valuation = PyLong_FromLong(x - count_set_bits(x)); + two_valuation = PyLong_FromLong(lx - count_set_bits(lx)); if (two_valuation == NULL) { Py_DECREF(odd_part); return NULL; @@ -1453,28 +1494,45 @@ math_factorial(PyObject *self, PyObject return result; } -PyDoc_STRVAR(math_factorial_doc, -"factorial(x) -> Integral\n" + +/*[clinic input] +math.trunc + + x: 'O' + / + +Truncates the Real x to the nearest Integral toward 0. + +Uses the __trunc__ magic method. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_trunc__doc__, +"trunc(x)\n" +"Truncates the Real x to the nearest Integral toward 0.\n" "\n" -"Find x!. Raise a ValueError if x is negative or non-integral."); +"Uses the __trunc__ magic method."); + +#define MATH_TRUNC_METHODDEF \ + {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__}, static PyObject * -math_trunc(PyObject *self, PyObject *number) +math_trunc(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: checksum=e2fe12a1ffcf1a5bb72bd904715f8dbcabb91bdf]*/ { _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; - if (Py_TYPE(number)->tp_dict == NULL) { - if (PyType_Ready(Py_TYPE(number)) < 0) + if (Py_TYPE(x)->tp_dict == NULL) { + if (PyType_Ready(Py_TYPE(x)) < 0) return NULL; } - trunc = _PyObject_LookupSpecial(number, &PyId___trunc__); + trunc = _PyObject_LookupSpecial(x, &PyId___trunc__); if (trunc == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, "type %.100s doesn't define __trunc__ method", - Py_TYPE(number)->tp_name); + Py_TYPE(x)->tp_name); return NULL; } result = PyObject_CallFunctionObjArgs(trunc, NULL); @@ -1482,18 +1540,53 @@ math_trunc(PyObject *self, PyObject *num return result; } -PyDoc_STRVAR(math_trunc_doc, -"trunc(x:Real) -> Integral\n" + +/*[clinic input] +math.frexp + + x: 'd' + / + +Return the mantissa and exponent of x, as pair (m, e). + +m is a float and e is an int, such that x = m * 2.**e. +If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_frexp__doc__, +"frexp(x)\n" +"Return the mantissa and exponent of x, as pair (m, e).\n" "\n" -"Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method."); +"m is a float and e is an int, such that x = m * 2.**e.\n" +"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."); + +#define MATH_FREXP_METHODDEF \ + {"frexp", (PyCFunction)math_frexp, METH_VARARGS, math_frexp__doc__}, static PyObject * -math_frexp(PyObject *self, PyObject *arg) +math_frexp_impl(PyModuleDef *module, double x); + +static PyObject * +math_frexp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:frexp", + &x)) + goto exit; + return_value = math_frexp_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_frexp_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=e5447c29622eb9306d0bc9effc8b9e0ff2bfa0d1]*/ { int i; - double x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; /* deal with special cases directly, to sidestep platform differences */ if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) { @@ -1507,27 +1600,60 @@ math_frexp(PyObject *self, PyObject *arg return Py_BuildValue("(di)", x, i); } -PyDoc_STRVAR(math_frexp_doc, -"frexp(x)\n" + +/*[clinic input] +math.ldexp + + x: 'd' + i: 'O' + / + +Return x * (2**i). + +This is essentially the inverse of frexp(). +[clinic start generated code]*/ + +PyDoc_STRVAR(math_ldexp__doc__, +"ldexp(x, i)\n" +"Return x * (2**i).\n" "\n" -"Return the mantissa and exponent of x, as pair (m, e).\n" -"m is a float and e is an int, such that x = m * 2.**e.\n" -"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."); +"This is essentially the inverse of frexp()."); + +#define MATH_LDEXP_METHODDEF \ + {"ldexp", (PyCFunction)math_ldexp, METH_VARARGS, math_ldexp__doc__}, static PyObject * -math_ldexp(PyObject *self, PyObject *args) +math_ldexp_impl(PyModuleDef *module, double x, PyObject *i); + +static PyObject * +math_ldexp(PyModuleDef *module, PyObject *args) { - double x, r; - PyObject *oexp; + PyObject *return_value = NULL; + double x; + PyObject *i; + + if (!PyArg_ParseTuple(args, + "dO:ldexp", + &x, &i)) + goto exit; + return_value = math_ldexp_impl(module, x, i); + +exit: + return return_value; +} + +static PyObject * +math_ldexp_impl(PyModuleDef *module, double x, PyObject *i) +/*[clinic end generated code: checksum=f9e76dfeba901b55df962428a806e63cf34db46f]*/ +{ + double r; long exp; int overflow; - if (! PyArg_ParseTuple(args, "dO:ldexp", &x, &oexp)) - return NULL; - if (PyLong_Check(oexp)) { + if (PyLong_Check(i)) { /* on overflow, replace exponent with either LONG_MAX or LONG_MIN, depending on the sign. */ - exp = PyLong_AsLongAndOverflow(oexp, &overflow); + exp = PyLong_AsLongAndOverflow(i, &overflow); if (exp == -1 && PyErr_Occurred()) return NULL; if (overflow) @@ -1565,16 +1691,51 @@ math_ldexp(PyObject *self, PyObject *arg return PyFloat_FromDouble(r); } -PyDoc_STRVAR(math_ldexp_doc, -"ldexp(x, i)\n\n\ -Return x * (2**i)."); + +/*[clinic input] +math.modf + + x: 'd' + / + +Return the fractional and integer parts of x. + +Both results carry the sign of x and are floats. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_modf__doc__, +"modf(x)\n" +"Return the fractional and integer parts of x.\n" +"\n" +"Both results carry the sign of x and are floats."); + +#define MATH_MODF_METHODDEF \ + {"modf", (PyCFunction)math_modf, METH_VARARGS, math_modf__doc__}, static PyObject * -math_modf(PyObject *self, PyObject *arg) +math_modf_impl(PyModuleDef *module, double x); + +static PyObject * +math_modf(PyModuleDef *module, PyObject *args) { - double y, x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:modf", + &x)) + goto exit; + return_value = math_modf_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_modf_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=60e120a350cbb87449cc8601141d3c3a91c6b922]*/ +{ + double y; /* some platforms don't do the right thing for NaNs and infinities, so we take care of special cases directly. */ if (!Py_IS_FINITE(x)) { @@ -1591,11 +1752,6 @@ math_modf(PyObject *self, PyObject *arg) return Py_BuildValue("(dd)", x, y); } -PyDoc_STRVAR(math_modf_doc, -"modf(x)\n" -"\n" -"Return the fractional and integer parts of x. Both results carry the sign\n" -"of x and are floats."); /* A decent logarithm is easy to compute even for huge ints, but libm can't do that by itself -- loghelper can. func is log or log10, and name is @@ -1644,18 +1800,56 @@ loghelper(PyObject* arg, double (*func)( return math_1(arg, func, 0); } + +/*[clinic input] +math.log + + x: 'O' + base: 'O' = NULL + / + +Return the logarithm of x to the given base. + +If the base not specified, returns the natural logarithm (base e) of x. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_log__doc__, +"log(x, base=None)\n" +"Return the logarithm of x to the given base.\n" +"\n" +"If the base not specified, returns the natural logarithm (base e) of x."); + +#define MATH_LOG_METHODDEF \ + {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__}, + static PyObject * -math_log(PyObject *self, PyObject *args) +math_log_impl(PyModuleDef *module, PyObject *x, PyObject *base); + +static PyObject * +math_log(PyModuleDef *module, PyObject *args) { - PyObject *arg; + PyObject *return_value = NULL; + PyObject *x; PyObject *base = NULL; + + if (!PyArg_ParseTuple(args, + "O|O:log", + &x, &base)) + goto exit; + return_value = math_log_impl(module, x, base); + +exit: + return return_value; +} + +static PyObject * +math_log_impl(PyModuleDef *module, PyObject *x, PyObject *base) +/*[clinic end generated code: checksum=9745a04130f8d75236553afa6a0a5f6695a4eff6]*/ +{ PyObject *num, *den; PyObject *ans; - if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base)) - return NULL; - - num = loghelper(arg, m_log, "log"); + num = loghelper(x, m_log, "log"); if (num == NULL || base == NULL) return num; @@ -1671,40 +1865,101 @@ math_log(PyObject *self, PyObject *args) return ans; } -PyDoc_STRVAR(math_log_doc, -"log(x[, base])\n\n\ -Return the logarithm of x to the given base.\n\ -If the base not specified, returns the natural logarithm (base e) of x."); + +/*[clinic input] +math.log2 + + x: 'O' + / + +Return the base 2 logarithm of x. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_log2__doc__, +"log2(x)\n" +"Return the base 2 logarithm of x."); + +#define MATH_LOG2_METHODDEF \ + {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__}, static PyObject * -math_log2(PyObject *self, PyObject *arg) +math_log2(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: checksum=66b8d96da6c0838ece32b73aeebbd7fb4197d089]*/ { - return loghelper(arg, m_log2, "log2"); + return loghelper(x, m_log2, "log2"); } -PyDoc_STRVAR(math_log2_doc, -"log2(x)\n\nReturn the base 2 logarithm of x."); + +/*[clinic input] +math.log10 + + x: 'O' + / + +Return the base 10 logarithm of x. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_log10__doc__, +"log10(x)\n" +"Return the base 10 logarithm of x."); + +#define MATH_LOG10_METHODDEF \ + {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__}, static PyObject * -math_log10(PyObject *self, PyObject *arg) +math_log10(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: checksum=03f64b254a474e33cf36a9eb06a0d1a01e70d556]*/ { - return loghelper(arg, m_log10, "log10"); + return loghelper(x, m_log10, "log10"); } -PyDoc_STRVAR(math_log10_doc, -"log10(x)\n\nReturn the base 10 logarithm of x."); + +/*[clinic input] +math.fmod + + x: 'd' + y: 'd' + / + +Return fmod(x, y), according to platform C. + +x % y may differ. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_fmod__doc__, +"fmod(x, y)\n" +"Return fmod(x, y), according to platform C.\n" +"\n" +"x % y may differ."); + +#define MATH_FMOD_METHODDEF \ + {"fmod", (PyCFunction)math_fmod, METH_VARARGS, math_fmod__doc__}, static PyObject * -math_fmod(PyObject *self, PyObject *args) +math_fmod_impl(PyModuleDef *module, double x, double y); + +static PyObject * +math_fmod(PyModuleDef *module, PyObject *args) { - PyObject *ox, *oy; - double r, x, y; - if (! PyArg_UnpackTuple(args, "fmod", 2, 2, &ox, &oy)) - return NULL; - x = PyFloat_AsDouble(ox); - y = PyFloat_AsDouble(oy); - if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + double y; + + if (!PyArg_ParseTuple(args, + "dd:fmod", + &x, &y)) + goto exit; + return_value = math_fmod_impl(module, x, y); + +exit: + return return_value; +} + +static PyObject * +math_fmod_impl(PyModuleDef *module, double x, double y) +/*[clinic end generated code: checksum=d1a5eaf7b35abb104bbdfe4a270a0dc078a3f906]*/ +{ + double r; /* fmod(x, +/-Inf) returns x for finite x. */ if (Py_IS_INFINITY(y) && Py_IS_FINITE(x)) return PyFloat_FromDouble(x); @@ -1724,21 +1979,49 @@ math_fmod(PyObject *self, PyObject *args return PyFloat_FromDouble(r); } -PyDoc_STRVAR(math_fmod_doc, -"fmod(x, y)\n\nReturn fmod(x, y), according to platform C." -" x % y may differ."); + +/*[clinic input] +math.hypot + + x: 'd' + y: 'd' + / + +Return the Euclidean distance, sqrt(x*x + y*y). +[clinic start generated code]*/ + +PyDoc_STRVAR(math_hypot__doc__, +"hypot(x, y)\n" +"Return the Euclidean distance, sqrt(x*x + y*y)."); + +#define MATH_HYPOT_METHODDEF \ + {"hypot", (PyCFunction)math_hypot, METH_VARARGS, math_hypot__doc__}, static PyObject * -math_hypot(PyObject *self, PyObject *args) +math_hypot_impl(PyModuleDef *module, double x, double y); + +static PyObject * +math_hypot(PyModuleDef *module, PyObject *args) { - PyObject *ox, *oy; - double r, x, y; - if (! PyArg_UnpackTuple(args, "hypot", 2, 2, &ox, &oy)) - return NULL; - x = PyFloat_AsDouble(ox); - y = PyFloat_AsDouble(oy); - if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + double y; + + if (!PyArg_ParseTuple(args, + "dd:hypot", + &x, &y)) + goto exit; + return_value = math_hypot_impl(module, x, y); + +exit: + return return_value; +} + +static PyObject * +math_hypot_impl(PyModuleDef *module, double x, double y) +/*[clinic end generated code: checksum=3f9cd5b0fd9182f8d80949347a4f05e32200fff1]*/ +{ + double r; /* hypot(x, +/-Inf) returns Inf, even if x is a NaN. */ if (Py_IS_INFINITY(x)) return PyFloat_FromDouble(fabs(x)); @@ -1766,8 +2049,6 @@ math_hypot(PyObject *self, PyObject *arg return PyFloat_FromDouble(r); } -PyDoc_STRVAR(math_hypot_doc, -"hypot(x, y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y)."); /* pow can't use math_2, but needs its own wrapper: the problem is that an infinite result can arise either as a result of overflow @@ -1775,20 +2056,50 @@ PyDoc_STRVAR(math_hypot_doc, e.g. 0.**-5. (for which ValueError needs to be raised.) */ +/*[clinic input] +math.pow + + x: 'd' + y: 'd' + / + +Return x**y (x to the power of y). +[clinic start generated code]*/ + +PyDoc_STRVAR(math_pow__doc__, +"pow(x, y)\n" +"Return x**y (x to the power of y)."); + +#define MATH_POW_METHODDEF \ + {"pow", (PyCFunction)math_pow, METH_VARARGS, math_pow__doc__}, + static PyObject * -math_pow(PyObject *self, PyObject *args) +math_pow_impl(PyModuleDef *module, double x, double y); + +static PyObject * +math_pow(PyModuleDef *module, PyObject *args) { - PyObject *ox, *oy; - double r, x, y; + PyObject *return_value = NULL; + double x; + double y; + + if (!PyArg_ParseTuple(args, + "dd:pow", + &x, &y)) + goto exit; + return_value = math_pow_impl(module, x, y); + +exit: + return return_value; +} + +static PyObject * +math_pow_impl(PyModuleDef *module, double x, double y) +/*[clinic end generated code: checksum=13c5b8080403c6d80426125678c21de0fe143399]*/ +{ + double r; int odd_y; - if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy)) - return NULL; - x = PyFloat_AsDouble(ox); - y = PyFloat_AsDouble(oy); - if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) - return NULL; - /* deal directly with IEEE specials, to cope with problems on various platforms whose semantics don't exactly match C99 */ r = 0.; /* silence compiler warning */ @@ -1853,76 +2164,224 @@ math_pow(PyObject *self, PyObject *args) return PyFloat_FromDouble(r); } -PyDoc_STRVAR(math_pow_doc, -"pow(x, y)\n\nReturn x**y (x to the power of y)."); static const double degToRad = Py_MATH_PI / 180.0; static const double radToDeg = 180.0 / Py_MATH_PI; +/*[clinic input] +math.degrees + + x: 'd' + / + +Convert angle x from radians to degrees. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_degrees__doc__, +"degrees(x)\n" +"Convert angle x from radians to degrees."); + +#define MATH_DEGREES_METHODDEF \ + {"degrees", (PyCFunction)math_degrees, METH_VARARGS, math_degrees__doc__}, + static PyObject * -math_degrees(PyObject *self, PyObject *arg) +math_degrees_impl(PyModuleDef *module, double x); + +static PyObject * +math_degrees(PyModuleDef *module, PyObject *args) { - double x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:degrees", + &x)) + goto exit; + return_value = math_degrees_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_degrees_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=472eeb3affd8396f151fd35a62f44dad554b3b91]*/ +{ return PyFloat_FromDouble(x * radToDeg); } -PyDoc_STRVAR(math_degrees_doc, -"degrees(x)\n\n\ -Convert angle x from radians to degrees."); + +/*[clinic input] +math.radians + + x: 'd' + / + +Convert angle x from degrees to radians. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_radians__doc__, +"radians(x)\n" +"Convert angle x from degrees to radians."); + +#define MATH_RADIANS_METHODDEF \ + {"radians", (PyCFunction)math_radians, METH_VARARGS, math_radians__doc__}, static PyObject * -math_radians(PyObject *self, PyObject *arg) +math_radians_impl(PyModuleDef *module, double x); + +static PyObject * +math_radians(PyModuleDef *module, PyObject *args) { - double x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:radians", + &x)) + goto exit; + return_value = math_radians_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_radians_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=070ef2c3da4fb6f91326423cf57ea94756240093]*/ +{ return PyFloat_FromDouble(x * degToRad); } -PyDoc_STRVAR(math_radians_doc, -"radians(x)\n\n\ -Convert angle x from degrees to radians."); + +/*[clinic input] +math.isfinite + + x: 'd' + / + +Return True if x is neither an infinity nor a NaN, and False otherwise. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_isfinite__doc__, +"isfinite(x)\n" +"Return True if x is neither an infinity nor a NaN, and False otherwise."); + +#define MATH_ISFINITE_METHODDEF \ + {"isfinite", (PyCFunction)math_isfinite, METH_VARARGS, math_isfinite__doc__}, static PyObject * -math_isfinite(PyObject *self, PyObject *arg) +math_isfinite_impl(PyModuleDef *module, double x); + +static PyObject * +math_isfinite(PyModuleDef *module, PyObject *args) { - double x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:isfinite", + &x)) + goto exit; + return_value = math_isfinite_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_isfinite_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=38cc520053185db5841f7484e7552c053fea6ee6]*/ +{ return PyBool_FromLong((long)Py_IS_FINITE(x)); } -PyDoc_STRVAR(math_isfinite_doc, -"isfinite(x) -> bool\n\n\ -Return True if x is neither an infinity nor a NaN, and False otherwise."); + +/*[clinic input] +math.isnan + + x: 'd' + / + +Return True if x is a NaN (not a number), and False otherwise. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_isnan__doc__, +"isnan(x)\n" +"Return True if x is a NaN (not a number), and False otherwise."); + +#define MATH_ISNAN_METHODDEF \ + {"isnan", (PyCFunction)math_isnan, METH_VARARGS, math_isnan__doc__}, static PyObject * -math_isnan(PyObject *self, PyObject *arg) +math_isnan_impl(PyModuleDef *module, double x); + +static PyObject * +math_isnan(PyModuleDef *module, PyObject *args) { - double x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:isnan", + &x)) + goto exit; + return_value = math_isnan_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_isnan_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=74e3d28b5f36a0560f01fc2cd862835afb0a0848]*/ +{ return PyBool_FromLong((long)Py_IS_NAN(x)); } -PyDoc_STRVAR(math_isnan_doc, -"isnan(x) -> bool\n\n\ -Return True if x is a NaN (not a number), and False otherwise."); + +/*[clinic input] +math.isinf + + x: 'd' + / + +Return True if x is a positive or negative infinity, and False otherwise. +[clinic start generated code]*/ + +PyDoc_STRVAR(math_isinf__doc__, +"isinf(x)\n" +"Return True if x is a positive or negative infinity, and False otherwise."); + +#define MATH_ISINF_METHODDEF \ + {"isinf", (PyCFunction)math_isinf, METH_VARARGS, math_isinf__doc__}, static PyObject * -math_isinf(PyObject *self, PyObject *arg) +math_isinf_impl(PyModuleDef *module, double x); + +static PyObject * +math_isinf(PyModuleDef *module, PyObject *args) { - double x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; + PyObject *return_value = NULL; + double x; + + if (!PyArg_ParseTuple(args, + "d:isinf", + &x)) + goto exit; + return_value = math_isinf_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +math_isinf_impl(PyModuleDef *module, double x) +/*[clinic end generated code: checksum=2bf1422fdc9b522b641c770ad8f1463464fd8027]*/ +{ return PyBool_FromLong((long)Py_IS_INFINITY(x)); } -PyDoc_STRVAR(math_isinf_doc, -"isinf(x) -> bool\n\n\ -Return True if x is a positive or negative infinity, and False otherwise."); static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, @@ -1936,37 +2395,37 @@ static PyMethodDef math_methods[] = { {"copysign", math_copysign, METH_VARARGS, math_copysign_doc}, {"cos", math_cos, METH_O, math_cos_doc}, {"cosh", math_cosh, METH_O, math_cosh_doc}, - {"degrees", math_degrees, METH_O, math_degrees_doc}, + MATH_DEGREES_METHODDEF {"erf", math_erf, METH_O, math_erf_doc}, {"erfc", math_erfc, METH_O, math_erfc_doc}, {"exp", math_exp, METH_O, math_exp_doc}, {"expm1", math_expm1, METH_O, math_expm1_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, - {"factorial", math_factorial, METH_O, math_factorial_doc}, + MATH_FACTORIAL_METHODDEF {"floor", math_floor, METH_O, math_floor_doc}, - {"fmod", math_fmod, METH_VARARGS, math_fmod_doc}, - {"frexp", math_frexp, METH_O, math_frexp_doc}, - {"fsum", math_fsum, METH_O, math_fsum_doc}, + MATH_FMOD_METHODDEF + MATH_FREXP_METHODDEF + MATH_FSUM_METHODDEF {"gamma", math_gamma, METH_O, math_gamma_doc}, - {"hypot", math_hypot, METH_VARARGS, math_hypot_doc}, - {"isfinite", math_isfinite, METH_O, math_isfinite_doc}, - {"isinf", math_isinf, METH_O, math_isinf_doc}, - {"isnan", math_isnan, METH_O, math_isnan_doc}, - {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc}, + MATH_HYPOT_METHODDEF + MATH_ISFINITE_METHODDEF + MATH_ISINF_METHODDEF + MATH_ISNAN_METHODDEF + MATH_LDEXP_METHODDEF {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, - {"log", math_log, METH_VARARGS, math_log_doc}, + MATH_LOG_METHODDEF {"log1p", math_log1p, METH_O, math_log1p_doc}, - {"log10", math_log10, METH_O, math_log10_doc}, - {"log2", math_log2, METH_O, math_log2_doc}, - {"modf", math_modf, METH_O, math_modf_doc}, - {"pow", math_pow, METH_VARARGS, math_pow_doc}, - {"radians", math_radians, METH_O, math_radians_doc}, + MATH_LOG10_METHODDEF + MATH_LOG2_METHODDEF + MATH_MODF_METHODDEF + MATH_POW_METHODDEF + MATH_RADIANS_METHODDEF {"sin", math_sin, METH_O, math_sin_doc}, {"sinh", math_sinh, METH_O, math_sinh_doc}, {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, {"tan", math_tan, METH_O, math_tan_doc}, {"tanh", math_tanh, METH_O, math_tanh_doc}, - {"trunc", math_trunc, METH_O, math_trunc_doc}, + MATH_TRUNC_METHODDEF {NULL, NULL} /* sentinel */ }; diff -r 1638360eea41 Modules/signalmodule.c --- a/Modules/signalmodule.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/signalmodule.c Sun Jan 12 11:10:49 2014 +0100 @@ -49,6 +49,11 @@ # endif #endif +/*[clinic input] +module signal +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS @@ -244,25 +249,83 @@ signal_handler(int sig_num) #ifdef HAVE_ALARM + +/*[clinic input] +signal.alarm + + seconds: 'i' + / + +Arrange for SIGALRM to arrive after the given number of seconds. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_alarm__doc__, +"alarm(seconds)\n" +"Arrange for SIGALRM to arrive after the given number of seconds."); + +#define SIGNAL_ALARM_METHODDEF \ + {"alarm", (PyCFunction)signal_alarm, METH_VARARGS, signal_alarm__doc__}, + static PyObject * -signal_alarm(PyObject *self, PyObject *args) +signal_alarm_impl(PyModuleDef *module, int seconds); + +static PyObject * +signal_alarm(PyModuleDef *module, PyObject *args) { - int t; - if (!PyArg_ParseTuple(args, "i:alarm", &t)) - return NULL; - /* alarm() returns the number of seconds remaining */ - return PyLong_FromLong((long)alarm(t)); + PyObject *return_value = NULL; + int seconds; + + if (!PyArg_ParseTuple(args, + "i:alarm", + &seconds)) + goto exit; + return_value = signal_alarm_impl(module, seconds); + +exit: + return return_value; } -PyDoc_STRVAR(alarm_doc, -"alarm(seconds)\n\ -\n\ -Arrange for SIGALRM to arrive after the given number of seconds."); +static PyObject * +signal_alarm_impl(PyModuleDef *module, int seconds) +/*[clinic end generated code: checksum=a918bab7c47b47d42bce1fa4c2f6fa51aee05202]*/ +{ + /* alarm() returns the number of seconds remaining */ + return PyLong_FromLong((long)alarm(seconds)); +} + #endif #ifdef HAVE_PAUSE + +/*[clinic input] +signal.pause + +Wait until a signal arrives. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_pause__doc__, +"pause()\n" +"Wait until a signal arrives."); + +#define SIGNAL_PAUSE_METHODDEF \ + {"pause", (PyCFunction)signal_pause, METH_NOARGS, signal_pause__doc__}, + static PyObject * -signal_pause(PyObject *self) +signal_pause_impl(PyModuleDef *module); + +static PyObject * +signal_pause(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = signal_pause_impl(module); + + return return_value; +} + +static PyObject * +signal_pause_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=a6089ea965131411e4a81b4f2e9e0aaf7579576b]*/ { Py_BEGIN_ALLOW_THREADS (void)pause(); @@ -273,29 +336,72 @@ signal_pause(PyObject *self) if (PyErr_CheckSignals()) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(pause_doc, -"pause()\n\ -\n\ -Wait until a signal arrives."); #endif +/*[clinic input] +signal.signal + + signalnum: 'i' + handler: 'O' + / + +Set the action for the given signal. + +The action can be SIG_DFL, SIG_IGN, or a callable Python object. +The previous action is returned. See getsignal() for possible return values. + +*** IMPORTANT NOTICE *** +A signal handler function is called with two arguments: +the first is the signal number, the second is the interrupted stack frame. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_signal__doc__, +"signal(signalnum, handler)\n" +"Set the action for the given signal.\n" +"\n" +"The action can be SIG_DFL, SIG_IGN, or a callable Python object.\n" +"The previous action is returned. See getsignal() for possible return values.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"A signal handler function is called with two arguments:\n" +"the first is the signal number, the second is the interrupted stack frame."); + +#define SIGNAL_SIGNAL_METHODDEF \ + {"signal", (PyCFunction)signal_signal, METH_VARARGS, signal_signal__doc__}, + static PyObject * -signal_signal(PyObject *self, PyObject *args) +signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler); + +static PyObject * +signal_signal(PyModuleDef *module, PyObject *args) { - PyObject *obj; - int sig_num; + PyObject *return_value = NULL; + int signalnum; + PyObject *handler; + + if (!PyArg_ParseTuple(args, + "iO:signal", + &signalnum, &handler)) + goto exit; + return_value = signal_signal_impl(module, signalnum, handler); + +exit: + return return_value; +} + +static PyObject * +signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler) +/*[clinic end generated code: checksum=b43f865ccbebe175258f516006cd5f358c88aae4]*/ +{ PyObject *old_handler; void (*func)(int); - if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) - return NULL; #ifdef MS_WINDOWS - /* Validate that sig_num is one of the allowable signals */ - switch (sig_num) { + /* Validate that signalnum is one of the allowable signals */ + switch (signalnum) { case SIGABRT: break; #ifdef SIGBREAK /* Issue #10003: SIGBREAK is not documented as permitted, but works @@ -319,61 +425,95 @@ signal_signal(PyObject *self, PyObject * return NULL; } #endif - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - if (obj == IgnoreHandler) + if (handler == IgnoreHandler) func = SIG_IGN; - else if (obj == DefaultHandler) + else if (handler == DefaultHandler) func = SIG_DFL; - else if (!PyCallable_Check(obj)) { + else if (!PyCallable_Check(handler)) { PyErr_SetString(PyExc_TypeError, "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"); return NULL; } else func = signal_handler; - if (PyOS_setsig(sig_num, func) == SIG_ERR) { + if (PyOS_setsig(signalnum, func) == SIG_ERR) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - old_handler = Handlers[sig_num].func; - Handlers[sig_num].tripped = 0; - Py_INCREF(obj); - Handlers[sig_num].func = obj; + old_handler = Handlers[signalnum].func; + Handlers[signalnum].tripped = 0; + Py_INCREF(handler); + Handlers[signalnum].func = handler; if (old_handler != NULL) return old_handler; else Py_RETURN_NONE; } -PyDoc_STRVAR(signal_doc, -"signal(sig, action) -> action\n\ -\n\ -Set the action for the given signal. The action can be SIG_DFL,\n\ -SIG_IGN, or a callable Python object. The previous action is\n\ -returned. See getsignal() for possible return values.\n\ -\n\ -*** IMPORTANT NOTICE ***\n\ -A signal handler function is called with two arguments:\n\ -the first is the signal number, the second is the interrupted stack frame."); +/*[clinic input] +signal.getsignal + + signalnum: 'i' + / + +Return the current action for the given signal. + +The return value can be: + SIG_IGN -- if the signal is being ignored + SIG_DFL -- if the default action for the signal is in effect + None -- if an unknown handler is in effect + anything else -- the callable Python object used as a handler +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_getsignal__doc__, +"getsignal(signalnum)\n" +"Return the current action for the given signal.\n" +"\n" +"The return value can be:\n" +" SIG_IGN -- if the signal is being ignored\n" +" SIG_DFL -- if the default action for the signal is in effect\n" +" None -- if an unknown handler is in effect\n" +" anything else -- the callable Python object used as a handler"); + +#define SIGNAL_GETSIGNAL_METHODDEF \ + {"getsignal", (PyCFunction)signal_getsignal, METH_VARARGS, signal_getsignal__doc__}, static PyObject * -signal_getsignal(PyObject *self, PyObject *args) +signal_getsignal_impl(PyModuleDef *module, int signalnum); + +static PyObject * +signal_getsignal(PyModuleDef *module, PyObject *args) { - int sig_num; + PyObject *return_value = NULL; + int signalnum; + + if (!PyArg_ParseTuple(args, + "i:getsignal", + &signalnum)) + goto exit; + return_value = signal_getsignal_impl(module, signalnum); + +exit: + return return_value; +} + +static PyObject * +signal_getsignal_impl(PyModuleDef *module, int signalnum) +/*[clinic end generated code: checksum=91e362cf5cc41176293a9abf382ae3d8d01afab3]*/ +{ PyObject *old_handler; - if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num)) - return NULL; - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - old_handler = Handlers[sig_num].func; + old_handler = Handlers[signalnum].func; if (old_handler != NULL) { Py_INCREF(old_handler); return old_handler; @@ -383,53 +523,120 @@ signal_getsignal(PyObject *self, PyObjec } } -PyDoc_STRVAR(getsignal_doc, -"getsignal(sig) -> action\n\ -\n\ -Return the current action for the given signal. The return value can be:\n\ -SIG_IGN -- if the signal is being ignored\n\ -SIG_DFL -- if the default action for the signal is in effect\n\ -None -- if an unknown handler is in effect\n\ -anything else -- the callable Python object used as a handler"); #ifdef HAVE_SIGINTERRUPT -PyDoc_STRVAR(siginterrupt_doc, -"siginterrupt(sig, flag) -> None\n\ -change system call restart behaviour: if flag is False, system calls\n\ -will be restarted when interrupted by signal sig, else system calls\n\ -will be interrupted."); + +/*[clinic input] +signal.siginterrupt + + signalnum: 'i' + flag: 'i' + / + +Change system call restart behaviour. + +If flag is False, system calls will be restarted when interrupted by +signal sig, else system calls will be interrupted. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_siginterrupt__doc__, +"siginterrupt(signalnum, flag)\n" +"Change system call restart behaviour.\n" +"\n" +"If flag is False, system calls will be restarted when interrupted by\n" +"signal sig, else system calls will be interrupted."); + +#define SIGNAL_SIGINTERRUPT_METHODDEF \ + {"siginterrupt", (PyCFunction)signal_siginterrupt, METH_VARARGS, signal_siginterrupt__doc__}, static PyObject * -signal_siginterrupt(PyObject *self, PyObject *args) +signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag); + +static PyObject * +signal_siginterrupt(PyModuleDef *module, PyObject *args) { - int sig_num; + PyObject *return_value = NULL; + int signalnum; int flag; - if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag)) - return NULL; - if (sig_num < 1 || sig_num >= NSIG) { + if (!PyArg_ParseTuple(args, + "ii:siginterrupt", + &signalnum, &flag)) + goto exit; + return_value = signal_siginterrupt_impl(module, signalnum, flag); + +exit: + return return_value; +} + +static PyObject * +signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag) +/*[clinic end generated code: checksum=2871cd4605fb5f7ca73c0f34a7be9df5e5e5b8d0]*/ +{ + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - if (siginterrupt(sig_num, flag)<0) { + if (siginterrupt(signalnum, flag)<0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif + +/*[clinic input] +signal.set_wakeup_fd + + fd: 'i' + / + +Sets the fd to be written to (with '\0') when a signal comes in. + +A library can use this to wakeup select or poll. The previous fd is returned. + +The fd must be non-blocking. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_set_wakeup_fd__doc__, +"set_wakeup_fd(fd)\n" +"Sets the fd to be written to (with \'\0\') when a signal comes in.\n" +"\n" +"A library can use this to wakeup select or poll. The previous fd is returned.\n" +"\n" +"The fd must be non-blocking."); + +#define SIGNAL_SET_WAKEUP_FD_METHODDEF \ + {"set_wakeup_fd", (PyCFunction)signal_set_wakeup_fd, METH_VARARGS, signal_set_wakeup_fd__doc__}, + static PyObject * -signal_set_wakeup_fd(PyObject *self, PyObject *args) +signal_set_wakeup_fd_impl(PyModuleDef *module, int fd); + +static PyObject * +signal_set_wakeup_fd(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_ParseTuple(args, + "i:set_wakeup_fd", + &fd)) + goto exit; + return_value = signal_set_wakeup_fd_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +signal_set_wakeup_fd_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: checksum=dbd3a88d15c3ab4bb1bb101d2d9febf49a186021]*/ { struct stat buf; - int fd, old_fd; - if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) - return NULL; + int old_fd; #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) { PyErr_SetString(PyExc_ValueError, @@ -446,14 +653,6 @@ signal_set_wakeup_fd(PyObject *self, PyO return PyLong_FromLong(old_fd); } -PyDoc_STRVAR(set_wakeup_fd_doc, -"set_wakeup_fd(fd) -> fd\n\ -\n\ -Sets the fd to be written to (with '\\0') when a signal\n\ -comes in. A library can use this to wakeup select or poll.\n\ -The previous fd is returned.\n\ -\n\ -The fd must be non-blocking."); /* C API for the same, without all the error checking */ int @@ -468,18 +667,63 @@ PySignal_SetWakeupFd(int fd) #ifdef HAVE_SETITIMER + +/*[clinic input] +signal.setitimer + + which: 'i' + seconds: 'd' + interval: 'd' = 0 + / + +Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF). + +The timer will fire after value seconds and after that every interval seconds. +The itimer can be cleared by setting seconds to zero. + +Returns old values as a tuple: (delay, interval). +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_setitimer__doc__, +"setitimer(which, seconds, interval=0)\n" +"Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).\n" +"\n" +"The timer will fire after value seconds and after that every interval seconds.\n" +"The itimer can be cleared by setting seconds to zero.\n" +"\n" +"Returns old values as a tuple: (delay, interval)."); + +#define SIGNAL_SETITIMER_METHODDEF \ + {"setitimer", (PyCFunction)signal_setitimer, METH_VARARGS, signal_setitimer__doc__}, + static PyObject * -signal_setitimer(PyObject *self, PyObject *args) +signal_setitimer_impl(PyModuleDef *module, int which, double seconds, double interval); + +static PyObject * +signal_setitimer(PyModuleDef *module, PyObject *args) { - double first; + PyObject *return_value = NULL; + int which; + double seconds; double interval = 0; - int which; + + if (!PyArg_ParseTuple(args, + "id|d:setitimer", + &which, &seconds, &interval)) + goto exit; + return_value = signal_setitimer_impl(module, which, seconds, interval); + +exit: + return return_value; +} + +static PyObject * +signal_setitimer_impl(PyModuleDef *module, int which, double seconds, double interval) +/*[clinic end generated code: checksum=f237216382497d2d88d6b0ee2ad1c2e439359a39]*/ +{ struct itimerval new, old; - if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval)) - return NULL; - - timeval_from_double(first, &new.it_value); + timeval_from_double(seconds, &new.it_value); timeval_from_double(interval, &new.it_interval); /* Let OS check "which" value */ if (setitimer(which, &new, &old) != 0) { @@ -490,40 +734,60 @@ signal_setitimer(PyObject *self, PyObjec return itimer_retval(&old); } -PyDoc_STRVAR(setitimer_doc, -"setitimer(which, seconds[, interval])\n\ -\n\ -Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\ -or ITIMER_PROF) to fire after value seconds and after\n\ -that every interval seconds.\n\ -The itimer can be cleared by setting seconds to zero.\n\ -\n\ -Returns old values as a tuple: (delay, interval)."); #endif #ifdef HAVE_GETITIMER + +/*[clinic input] +signal.getitimer + + which: 'i' + / + +Returns current value of given itimer. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_getitimer__doc__, +"getitimer(which)\n" +"Returns current value of given itimer."); + +#define SIGNAL_GETITIMER_METHODDEF \ + {"getitimer", (PyCFunction)signal_getitimer, METH_VARARGS, signal_getitimer__doc__}, + static PyObject * -signal_getitimer(PyObject *self, PyObject *args) +signal_getitimer_impl(PyModuleDef *module, int which); + +static PyObject * +signal_getitimer(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int which; + + if (!PyArg_ParseTuple(args, + "i:getitimer", + &which)) + goto exit; + return_value = signal_getitimer_impl(module, which); + +exit: + return return_value; +} + +static PyObject * +signal_getitimer_impl(PyModuleDef *module, int which) +/*[clinic end generated code: checksum=a4047c6fa1319444723e8c6ccf33b6b53f49abbd]*/ +{ struct itimerval old; - if (!PyArg_ParseTuple(args, "i:getitimer", &which)) - return NULL; - if (getitimer(which, &old) != 0) { - PyErr_SetFromErrno(ItimerError); - return NULL; + PyErr_SetFromErrno(ItimerError); + return NULL; } return itimer_retval(&old); } -PyDoc_STRVAR(getitimer_doc, -"getitimer(which)\n\ -\n\ -Returns current value of given itimer."); #endif #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ @@ -614,21 +878,55 @@ sigset_to_set(sigset_t mask) #endif #ifdef PYPTHREAD_SIGMASK + +/*[clinic input] +signal.pthread_sigmask + + how: 'i' + mask: 'O' + / + +Fetch and/or change the signal mask of the calling thread. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_pthread_sigmask__doc__, +"pthread_sigmask(how, mask)\n" +"Fetch and/or change the signal mask of the calling thread."); + +#define SIGNAL_PTHREAD_SIGMASK_METHODDEF \ + {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, METH_VARARGS, signal_pthread_sigmask__doc__}, + static PyObject * -signal_pthread_sigmask(PyObject *self, PyObject *args) +signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask); + +static PyObject * +signal_pthread_sigmask(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int how; - PyObject *signals; - sigset_t mask, previous; + PyObject *mask; + + if (!PyArg_ParseTuple(args, + "iO:pthread_sigmask", + &how, &mask)) + goto exit; + return_value = signal_pthread_sigmask_impl(module, how, mask); + +exit: + return return_value; +} + +static PyObject * +signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask) +/*[clinic end generated code: checksum=1d4864b53f38a85e127829cd26e547dc4ea13e8d]*/ +{ + sigset_t newmask, previous; int err; - if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", &how, &signals)) + if (iterable_to_sigset(mask, &newmask)) return NULL; - if (iterable_to_sigset(signals, &mask)) - return NULL; - - err = pthread_sigmask(how, &mask, &previous); + err = pthread_sigmask(how, &newmask, &previous); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -642,16 +940,46 @@ signal_pthread_sigmask(PyObject *self, P return sigset_to_set(previous); } -PyDoc_STRVAR(signal_pthread_sigmask_doc, -"pthread_sigmask(how, mask) -> old mask\n\ -\n\ -Fetch and/or change the signal mask of the calling thread."); #endif /* #ifdef PYPTHREAD_SIGMASK */ #ifdef HAVE_SIGPENDING + +/*[clinic input] +signal.sigpending + +Examine pending signals. + +Returns a set of signal numbers that are pending for delivery to +the calling thread. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigpending__doc__, +"sigpending()\n" +"Examine pending signals.\n" +"\n" +"Returns a set of signal numbers that are pending for delivery to\n" +"the calling thread."); + +#define SIGNAL_SIGPENDING_METHODDEF \ + {"sigpending", (PyCFunction)signal_sigpending, METH_NOARGS, signal_sigpending__doc__}, + static PyObject * -signal_sigpending(PyObject *self) +signal_sigpending_impl(PyModuleDef *module); + +static PyObject * +signal_sigpending(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = signal_sigpending_impl(module); + + return return_value; +} + +static PyObject * +signal_sigpending_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=47aa01c5b3f92f3bb48f05b69941a0b8355b1865]*/ { int err; sigset_t mask; @@ -661,25 +989,43 @@ signal_sigpending(PyObject *self) return sigset_to_set(mask); } -PyDoc_STRVAR(signal_sigpending_doc, -"sigpending() -> list\n\ -\n\ -Examine pending signals."); #endif /* #ifdef HAVE_SIGPENDING */ #ifdef HAVE_SIGWAIT + +/*[clinic input] +signal.sigwait + + sigset: 'O' + / + +Wait for a signal. + +Suspend execution of the calling thread until the delivery of one of the +signals specified in the signal set sigset. The function accepts the signal +and returns the signal number. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigwait__doc__, +"sigwait(sigset)\n" +"Wait for a signal.\n" +"\n" +"Suspend execution of the calling thread until the delivery of one of the\n" +"signals specified in the signal set sigset. The function accepts the signal\n" +"and returns the signal number."); + +#define SIGNAL_SIGWAIT_METHODDEF \ + {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__}, + static PyObject * -signal_sigwait(PyObject *self, PyObject *args) +signal_sigwait(PyModuleDef *module, PyObject *sigset) +/*[clinic end generated code: checksum=ba626ba2b876050fffe53352e72a65ec27cdbde4]*/ { - PyObject *signals; sigset_t set; int err, signum; - if (!PyArg_ParseTuple(args, "O:sigwait", &signals)) - return NULL; - - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -693,10 +1039,6 @@ signal_sigwait(PyObject *self, PyObject return PyLong_FromLong(signum); } -PyDoc_STRVAR(signal_sigwait_doc, -"sigwait(sigset) -> signum\n\ -\n\ -Wait a signal."); #endif /* #ifdef HAVE_SIGPENDING */ #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) @@ -752,18 +1094,40 @@ fill_siginfo(siginfo_t *si) #endif #ifdef HAVE_SIGWAITINFO + +/*[clinic input] +signal.sigwaitinfo + + sigset: 'O' + / + +Wait for a signal and return extended info. + +Suspend execution of the calling thread until the delivery of one of the +signals specified in the signal set sigset. The function accepts the signal +and returns a struct_siginfo containing information about the signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigwaitinfo__doc__, +"sigwaitinfo(sigset)\n" +"Wait for a signal and return extended info.\n" +"\n" +"Suspend execution of the calling thread until the delivery of one of the\n" +"signals specified in the signal set sigset. The function accepts the signal\n" +"and returns a struct_siginfo containing information about the signal."); + +#define SIGNAL_SIGWAITINFO_METHODDEF \ + {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__}, + static PyObject * -signal_sigwaitinfo(PyObject *self, PyObject *args) +signal_sigwaitinfo(PyModuleDef *module, PyObject *sigset) +/*[clinic end generated code: checksum=78b37d155c7a238d619d531cd7674c386e372076]*/ { - PyObject *signals; sigset_t set; siginfo_t si; int err; - if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals)) - return NULL; - - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -775,19 +1139,55 @@ signal_sigwaitinfo(PyObject *self, PyObj return fill_siginfo(&si); } -PyDoc_STRVAR(signal_sigwaitinfo_doc, -"sigwaitinfo(sigset) -> struct_siginfo\n\ -\n\ -Wait synchronously for a signal until one of the signals in *sigset* is\n\ -delivered.\n\ -Returns a struct_siginfo containing information about the signal."); #endif /* #ifdef HAVE_SIGWAITINFO */ #ifdef HAVE_SIGTIMEDWAIT + +/*[clinic input] +signal.sigtimedwait + + sigset: 'O' + timeout: 'O' + / + +Like sigwaitinfo(), but with a timeout. + +The timeout is specified in seconds, with floating point numbers allowed. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigtimedwait__doc__, +"sigtimedwait(sigset, timeout)\n" +"Like sigwaitinfo(), but with a timeout.\n" +"\n" +"The timeout is specified in seconds, with floating point numbers allowed."); + +#define SIGNAL_SIGTIMEDWAIT_METHODDEF \ + {"sigtimedwait", (PyCFunction)signal_sigtimedwait, METH_VARARGS, signal_sigtimedwait__doc__}, + static PyObject * -signal_sigtimedwait(PyObject *self, PyObject *args) +signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset, PyObject *timeout); + +static PyObject * +signal_sigtimedwait(PyModuleDef *module, PyObject *args) { - PyObject *signals, *timeout; + PyObject *return_value = NULL; + PyObject *sigset; + PyObject *timeout; + + if (!PyArg_ParseTuple(args, + "OO:sigtimedwait", + &sigset, &timeout)) + goto exit; + return_value = signal_sigtimedwait_impl(module, sigset, timeout); + +exit: + return return_value; +} + +static PyObject * +signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset, PyObject *timeout) +/*[clinic end generated code: checksum=b0028361934fccec477792e50e002309031b5aee]*/ +{ struct timespec buf; sigset_t set; siginfo_t si; @@ -795,10 +1195,6 @@ signal_sigtimedwait(PyObject *self, PyOb long tv_nsec; int err; - if (!PyArg_ParseTuple(args, "OO:sigtimedwait", - &signals, &timeout)) - return NULL; - if (_PyTime_ObjectToTimespec(timeout, &tv_sec, &tv_nsec) == -1) return NULL; buf.tv_sec = tv_sec; @@ -809,7 +1205,7 @@ signal_sigtimedwait(PyObject *self, PyOb return NULL; } - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -825,26 +1221,55 @@ signal_sigtimedwait(PyObject *self, PyOb return fill_siginfo(&si); } -PyDoc_STRVAR(signal_sigtimedwait_doc, -"sigtimedwait(sigset, (timeout_sec, timeout_nsec)) -> struct_siginfo\n\ -\n\ -Like sigwaitinfo(), but with a timeout specified as a tuple of (seconds,\n\ -nanoseconds)."); #endif /* #ifdef HAVE_SIGTIMEDWAIT */ #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) + +/*[clinic input] +signal.pthread_kill + + thread_id: 'l' + signalnum: 'i' + / + +Send a signal to a thread. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_pthread_kill__doc__, +"pthread_kill(thread_id, signalnum)\n" +"Send a signal to a thread."); + +#define SIGNAL_PTHREAD_KILL_METHODDEF \ + {"pthread_kill", (PyCFunction)signal_pthread_kill, METH_VARARGS, signal_pthread_kill__doc__}, + static PyObject * -signal_pthread_kill(PyObject *self, PyObject *args) +signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum); + +static PyObject * +signal_pthread_kill(PyModuleDef *module, PyObject *args) { - long tid; - int signum; + PyObject *return_value = NULL; + long thread_id; + int signalnum; + + if (!PyArg_ParseTuple(args, + "li:pthread_kill", + &thread_id, &signalnum)) + goto exit; + return_value = signal_pthread_kill_impl(module, thread_id, signalnum); + +exit: + return return_value; +} + +static PyObject * +signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum) +/*[clinic end generated code: checksum=c54762f60f82fe1a9475c73e75004668c4142a7f]*/ +{ int err; - if (!PyArg_ParseTuple(args, "li:pthread_kill", &tid, &signum)) - return NULL; - - err = pthread_kill((pthread_t)tid, signum); + err = pthread_kill((pthread_t)thread_id, signalnum); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -858,10 +1283,6 @@ signal_pthread_kill(PyObject *self, PyOb Py_RETURN_NONE; } -PyDoc_STRVAR(signal_pthread_kill_doc, -"pthread_kill(thread_id, signum)\n\ -\n\ -Send a signal to a thread."); #endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */ @@ -869,49 +1290,42 @@ Send a signal to a thread."); /* List of functions defined in the module */ static PyMethodDef signal_methods[] = { #ifdef HAVE_ALARM - {"alarm", signal_alarm, METH_VARARGS, alarm_doc}, + SIGNAL_ALARM_METHODDEF #endif #ifdef HAVE_SETITIMER - {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc}, + SIGNAL_SETITIMER_METHODDEF #endif #ifdef HAVE_GETITIMER - {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, + SIGNAL_GETITIMER_METHODDEF #endif - {"signal", signal_signal, METH_VARARGS, signal_doc}, - {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, - {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, + SIGNAL_SIGNAL_METHODDEF + SIGNAL_GETSIGNAL_METHODDEF + SIGNAL_SET_WAKEUP_FD_METHODDEF #ifdef HAVE_SIGINTERRUPT - {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, + SIGNAL_SIGINTERRUPT_METHODDEF #endif #ifdef HAVE_PAUSE - {"pause", (PyCFunction)signal_pause, - METH_NOARGS, pause_doc}, + SIGNAL_PAUSE_METHODDEF #endif {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) - {"pthread_kill", (PyCFunction)signal_pthread_kill, - METH_VARARGS, signal_pthread_kill_doc}, + SIGNAL_PTHREAD_KILL_METHODDEF #endif #ifdef PYPTHREAD_SIGMASK - {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, - METH_VARARGS, signal_pthread_sigmask_doc}, + SIGNAL_PTHREAD_SIGMASK_METHODDEF #endif #ifdef HAVE_SIGPENDING - {"sigpending", (PyCFunction)signal_sigpending, - METH_NOARGS, signal_sigpending_doc}, + SIGNAL_SIGPENDING_METHODDEF #endif #ifdef HAVE_SIGWAIT - {"sigwait", (PyCFunction)signal_sigwait, - METH_VARARGS, signal_sigwait_doc}, + SIGNAL_SIGWAIT_METHODDEF #endif #ifdef HAVE_SIGWAITINFO - {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, - METH_VARARGS, signal_sigwaitinfo_doc}, + SIGNAL_SIGWAITINFO_METHODDEF #endif #ifdef HAVE_SIGTIMEDWAIT - {"sigtimedwait", (PyCFunction)signal_sigtimedwait, - METH_VARARGS, signal_sigtimedwait_doc}, + SIGNAL_SIGTIMEDWAIT_METHODDEF #endif {NULL, NULL} /* sentinel */ }; diff -r 1638360eea41 Tools/clinic/clinic.py --- a/Tools/clinic/clinic.py Sat Jan 11 22:22:21 2014 -0800 +++ b/Tools/clinic/clinic.py Sun Jan 12 11:10:49 2014 +0100 @@ -391,6 +391,8 @@ class CLanguage(Language): @staticmethod def template_base(*args): + if '__suppress__' in args: + return '' flags = '|'.join(f for f in args if f) return """ PyDoc_STRVAR({c_basename}__doc__, @@ -640,7 +642,11 @@ static {impl_return_type} full_name = f.full_name template_dict['full_name'] = full_name - name = full_name.rpartition('.')[2] + # __new__ methods get the class name as their name + if f.kind == NEW_METHOD: + name = full_name.split('.')[-2] + else: + name = full_name.rpartition('.')[2] template_dict['name'] = name c_basename = f.c_basename or full_name.replace(".", "_") @@ -1165,7 +1171,7 @@ class Class: return "" -DATA, CALLABLE, METHOD, STATIC_METHOD, CLASS_METHOD = range(5) +DATA, CALLABLE, METHOD, STATIC_METHOD, CLASS_METHOD, NEW_METHOD = range(6) class Function: """ @@ -1201,7 +1207,11 @@ class Function: @property def methoddef_flags(self): flags = [] - if self.kind == CLASS_METHOD: + # __new__ methods don't have a MethodDef entry, so we take this + # special value to suppress both it and the docstring. + if self.kind == NEW_METHOD: + flags.append('__suppress__') + elif self.kind == CLASS_METHOD: flags.append('METH_CLASS') elif self.kind == STATIC_METHOD: flags.append('METH_STATIC') @@ -1809,6 +1819,9 @@ class self_converter(CConverter): elif f.kind == CLASS_METHOD: self.name = "cls" self.type = "PyTypeObject *" + elif f.kind == NEW_METHOD: + self.name = "type" + self.type = "PyTypeObject *" if type: self.type = type @@ -2080,6 +2093,10 @@ class DSLParser: assert self.coexist == False self.coexist = True + def at_new(self): + assert self.kind is CALLABLE + self.kind = NEW_METHOD + def parse(self, block): self.reset()