diff -r acd31653e3b4 Modules/selectmodule.c --- a/Modules/selectmodule.c Thu Jan 16 06:53:54 2014 +0100 +++ b/Modules/selectmodule.c Thu Jan 16 09:29:58 2014 +0100 @@ -54,6 +54,14 @@ extern void bzero(void *, int); # define SOCKET int #endif +/*[clinic input] +module select +class select.poll +class select.epoll +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /* list of Python objects and their file descriptor */ typedef struct { PyObject *obj; /* owned reference */ @@ -176,8 +184,90 @@ set2list(fd_set *set, pylist fd2obj[FD_S #define SELECT_USES_HEAP #endif /* FD_SETSIZE > 1024 */ +/*[clinic input] +select.select + + rlist: 'O' + wlist: 'O' + xlist: 'O' + timeout: 'O' = None + / + +Wait until one or more file descriptors are ready for some kind of I/O. + +The first three arguments are sequences of file descriptors to be waited for: + rlist -- wait until ready for reading + wlist -- wait until ready for writing + xlist -- wait for an ``exceptional condition'' +If only one kind of condition is required, pass [] for the other lists. +A file descriptor is either a socket or file object, or a small integer +gotten from a fileno() method call on one of those. + +The optional 4th argument specifies a timeout in seconds; it may be +a floating point number to specify fractions of seconds. If it is absent +or None, the call will never time out. + +The return value is a tuple of three lists corresponding to the first three +arguments; each contains the subset of the corresponding file descriptors +that are ready. + +*** IMPORTANT NOTICE *** +On Windows only sockets are supported; on Unix, all file descriptors +can be used. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_select__doc__, +"select(rlist, wlist, xlist, timeout=None)\n" +"Wait until one or more file descriptors are ready for some kind of I/O.\n" +"\n" +"The first three arguments are sequences of file descriptors to be waited for:\n" +" rlist -- wait until ready for reading\n" +" wlist -- wait until ready for writing\n" +" xlist -- wait for an ``exceptional condition\'\'\n" +"If only one kind of condition is required, pass [] for the other lists.\n" +"A file descriptor is either a socket or file object, or a small integer\n" +"gotten from a fileno() method call on one of those.\n" +"\n" +"The optional 4th argument specifies a timeout in seconds; it may be\n" +"a floating point number to specify fractions of seconds. If it is absent\n" +"or None, the call will never time out.\n" +"\n" +"The return value is a tuple of three lists corresponding to the first three\n" +"arguments; each contains the subset of the corresponding file descriptors\n" +"that are ready.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"On Windows only sockets are supported; on Unix, all file descriptors\n" +"can be used."); + +#define SELECT_SELECT_METHODDEF \ + {"select", (PyCFunction)select_select, METH_VARARGS, select_select__doc__}, + static PyObject * -select_select(PyObject *self, PyObject *args) +select_select_impl(PyModuleDef *module, PyObject *rlist, PyObject *wlist, PyObject *xlist, PyObject *timeout); + +static PyObject * +select_select(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *rlist; + PyObject *wlist; + PyObject *xlist; + PyObject *timeout = Py_None; + + if (!PyArg_ParseTuple(args, + "OOO|O:select", + &rlist, &wlist, &xlist, &timeout)) + goto exit; + return_value = select_select_impl(module, rlist, wlist, xlist, timeout); + +exit: + return return_value; +} + +static PyObject * +select_select_impl(PyModuleDef *module, PyObject *rlist, PyObject *wlist, PyObject *xlist, PyObject *timeout) +/*[clinic end generated code: checksum=0849f41f3f65701ae89999a50c5af0f51e67b719]*/ { #ifdef SELECT_USES_HEAP pylist *rfd2obj, *wfd2obj, *efd2obj; @@ -192,22 +282,15 @@ select_select(PyObject *self, PyObject * pylist wfd2obj[FD_SETSIZE + 1]; pylist efd2obj[FD_SETSIZE + 1]; #endif /* SELECT_USES_HEAP */ - PyObject *ifdlist, *ofdlist, *efdlist; PyObject *ret = NULL; - PyObject *tout = Py_None; fd_set ifdset, ofdset, efdset; struct timeval tv, *tvp; int imax, omax, emax, max; int n; - /* convert arguments */ - if (!PyArg_UnpackTuple(args, "select", 3, 4, - &ifdlist, &ofdlist, &efdlist, &tout)) - return NULL; - - if (tout == Py_None) + if (timeout == Py_None) tvp = (struct timeval *)0; - else if (!PyNumber_Check(tout)) { + else if (!PyNumber_Check(timeout)) { PyErr_SetString(PyExc_TypeError, "timeout must be a float or None"); return NULL; @@ -215,7 +298,7 @@ select_select(PyObject *self, PyObject * else { #ifdef MS_WINDOWS time_t sec; - if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1) + if (_PyTime_ObjectToTimeval(timeout, &sec, &tv.tv_usec) == -1) return NULL; assert(sizeof(tv.tv_sec) == sizeof(long)); #if SIZEOF_TIME_T > SIZEOF_LONG @@ -230,7 +313,7 @@ select_select(PyObject *self, PyObject * /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4 bytes as required), but no longer defined by a long. */ long tv_usec; - if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1) + if (_PyTime_ObjectToTimeval(timeout, &tv.tv_sec, &tv_usec) == -1) return NULL; tv.tv_usec = tv_usec; #endif @@ -260,11 +343,11 @@ select_select(PyObject *self, PyObject * rfd2obj[0].sentinel = -1; wfd2obj[0].sentinel = -1; efd2obj[0].sentinel = -1; - if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) + if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0) goto finally; - if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) + if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0) goto finally; - if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) + if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0) goto finally; max = imax; if (omax > max) max = omax; @@ -288,17 +371,17 @@ select_select(PyObject *self, PyObject * convenient to test for this after all three calls... but is that acceptable? */ - ifdlist = set2list(&ifdset, rfd2obj); - ofdlist = set2list(&ofdset, wfd2obj); - efdlist = set2list(&efdset, efd2obj); + rlist = set2list(&ifdset, rfd2obj); + wlist = set2list(&ofdset, wfd2obj); + xlist = set2list(&efdset, efd2obj); if (PyErr_Occurred()) ret = NULL; else - ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist); - - Py_XDECREF(ifdlist); - Py_XDECREF(ofdlist); - Py_XDECREF(efdlist); + ret = PyTuple_Pack(3, rlist, wlist, xlist); + + Py_XDECREF(rlist); + Py_XDECREF(wlist); + Py_XDECREF(xlist); } finally: @@ -379,33 +462,72 @@ ushort_converter(PyObject *obj, void *pt return 1; } -PyDoc_STRVAR(poll_register_doc, -"register(fd [, eventmask] ) -> None\n\n\ -Register a file descriptor with the polling object.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); + +/*[clinic input] +select.poll.register + + self: self(type="pollObject *") + fd: object + either an integer, or an object with a fileno() method returning + an int + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT + an optional bitmask describing the type of events to check for + / + +Register a file descriptor with the polling object. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_poll_register__doc__, +"register(fd, eventmask=select.POLLIN | select.POLLPRI | select.POLLOUT)\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_POLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_poll_register, METH_VARARGS, select_poll_register__doc__}, static PyObject * -poll_register(pollObject *self, PyObject *args) +select_poll_register_impl(pollObject *self, PyObject *fd, unsigned short eventmask); + +static PyObject * +select_poll_register(PyObject *self, PyObject *args) { - PyObject *o, *key, *value; - int fd; - unsigned short events = POLLIN | POLLPRI | POLLOUT; + PyObject *return_value = NULL; + PyObject *fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!PyArg_ParseTuple(args, + "O|O&:register", + &fd, ushort_converter, &eventmask)) + goto exit; + return_value = select_poll_register_impl((pollObject *)self, fd, eventmask); + +exit: + return return_value; +} + +static PyObject * +select_poll_register_impl(pollObject *self, PyObject *fd, unsigned short eventmask) +/*[clinic end generated code: checksum=a7916f3fa269c291cac27f7417705eda9732c0b7]*/ +{ + PyObject *key, *value; + int real_fd; int err; - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) + real_fd = PyObject_AsFileDescriptor(fd); + if (real_fd == -1) return NULL; - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; - /* Add entry to the internal dictionary: the key is the file descriptor, and the value is the event mask. */ - key = PyLong_FromLong(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -422,29 +544,67 @@ poll_register(pollObject *self, PyObject return Py_None; } -PyDoc_STRVAR(poll_modify_doc, -"modify(fd, eventmask) -> None\n\n\ -Modify an already registered file descriptor.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); + +/*[clinic input] +select.poll.modify + + self: self(type="pollObject *") + fd: object + either an integer, or an object with a fileno() method returning + an int + eventmask: object(converter="ushort_converter", type="unsigned short") + an optional bitmask describing the type of events to check for + / + +Modify an already registered file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_poll_modify__doc__, +"modify(fd, eventmask)\n" +"Modify an already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_POLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_poll_modify, METH_VARARGS, select_poll_modify__doc__}, static PyObject * -poll_modify(pollObject *self, PyObject *args) +select_poll_modify_impl(pollObject *self, PyObject *fd, unsigned short eventmask); + +static PyObject * +select_poll_modify(PyObject *self, PyObject *args) { - PyObject *o, *key, *value; - int fd; - unsigned short events; + PyObject *return_value = NULL; + PyObject *fd; + unsigned short eventmask; + + if (!PyArg_ParseTuple(args, + "OO&:modify", + &fd, ushort_converter, &eventmask)) + goto exit; + return_value = select_poll_modify_impl((pollObject *)self, fd, eventmask); + +exit: + return return_value; +} + +static PyObject * +select_poll_modify_impl(pollObject *self, PyObject *fd, unsigned short eventmask) +/*[clinic end generated code: checksum=c1a30146241bbc9531dc946e4efd8853c92e09eb]*/ +{ + PyObject *key, *value; + int real_fd; int err; - if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events)) - return NULL; - - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; + real_fd = PyObject_AsFileDescriptor(fd); + if (real_fd == -1) return NULL; /* Modify registered fd */ - key = PyLong_FromLong(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; if (PyDict_GetItem(self->dict, key) == NULL) { @@ -453,7 +613,7 @@ poll_modify(pollObject *self, PyObject * Py_DECREF(key); return NULL; } - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -471,22 +631,36 @@ poll_modify(pollObject *self, PyObject * } -PyDoc_STRVAR(poll_unregister_doc, -"unregister(fd) -> None\n\n\ -Remove a file descriptor being tracked by the polling object."); +/*[clinic input] +select.poll.unregister + + self: self(type="pollObject *") + fd: 'O' + / + +Remove a file descriptor being tracked by the polling object. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_poll_unregister__doc__, +"unregister(fd)\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_POLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_poll_unregister, METH_O, select_poll_unregister__doc__}, static PyObject * -poll_unregister(pollObject *self, PyObject *o) +select_poll_unregister(pollObject *self, PyObject *fd) +/*[clinic end generated code: checksum=ab41f26d982beaa0127298fdc45ebbb7c11d1229]*/ { PyObject *key; - int fd; - - fd = PyObject_AsFileDescriptor( o ); - if (fd == -1) + int real_fd; + + real_fd = PyObject_AsFileDescriptor(fd); + if (real_fd == -1) return NULL; /* Check whether the fd is already in the array */ - key = PyLong_FromLong(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; @@ -504,37 +678,71 @@ poll_unregister(pollObject *self, PyObje return Py_None; } -PyDoc_STRVAR(poll_poll_doc, -"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\ -Polls the set of registered file descriptors, returning a list containing \n\ -any descriptors that have events or errors to report."); +/*[clinic input] +select.poll.poll + + self: self(type="pollObject *") + timeout: 'O' = None + / + +Polls the set of registered file descriptors. + +Return value is a list containing any descriptors that have events +or errors to report, in the form of tuples (fd, event). +[clinic start generated code]*/ + +PyDoc_STRVAR(select_poll_poll__doc__, +"poll(timeout=None)\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Return value is a list containing any descriptors that have events\n" +"or errors to report, in the form of tuples (fd, event)."); + +#define SELECT_POLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll_poll, METH_VARARGS, select_poll_poll__doc__}, static PyObject * -poll_poll(pollObject *self, PyObject *args) +select_poll_poll_impl(pollObject *self, PyObject *timeout); + +static PyObject * +select_poll_poll(PyObject *self, PyObject *args) { - PyObject *result_list = NULL, *tout = NULL; - int timeout = 0, poll_result, i, j; + PyObject *return_value = NULL; + PyObject *timeout = Py_None; + + if (!PyArg_ParseTuple(args, + "|O:poll", + &timeout)) + goto exit; + return_value = select_poll_poll_impl((pollObject *)self, timeout); + +exit: + return return_value; +} + +static PyObject * +select_poll_poll_impl(pollObject *self, PyObject *timeout) +/*[clinic end generated code: checksum=7dc0b33e2aa6619735c5281cdb008157961afae9]*/ +{ + PyObject *result_list = NULL; + int itimeout = 0, poll_result, i, j; PyObject *value = NULL, *num = NULL; - if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { - return NULL; - } - /* Check values for timeout */ - if (tout == NULL || tout == Py_None) - timeout = -1; - else if (!PyNumber_Check(tout)) { + if (timeout == NULL || timeout == Py_None) + itimeout = -1; + else if (!PyNumber_Check(timeout)) { PyErr_SetString(PyExc_TypeError, "timeout must be an integer or None"); return NULL; } else { - tout = PyNumber_Long(tout); - if (!tout) + timeout = PyNumber_Long(timeout); + if (timeout) return NULL; - timeout = _PyLong_AsInt(tout); - Py_DECREF(tout); - if (timeout == -1 && PyErr_Occurred()) + itimeout = _PyLong_AsInt(timeout); + Py_DECREF(timeout); + if (itimeout == -1 && PyErr_Occurred()) return NULL; } @@ -554,7 +762,7 @@ poll_poll(pollObject *self, PyObject *ar /* call poll() */ Py_BEGIN_ALLOW_THREADS - poll_result = poll(self->ufds, self->ufd_len, timeout); + poll_result = poll(self->ufds, self->ufd_len, itimeout); Py_END_ALLOW_THREADS self->poll_running = 0; @@ -613,15 +821,11 @@ poll_poll(pollObject *self, PyObject *ar } static PyMethodDef poll_methods[] = { - {"register", (PyCFunction)poll_register, - METH_VARARGS, poll_register_doc}, - {"modify", (PyCFunction)poll_modify, - METH_VARARGS, poll_modify_doc}, - {"unregister", (PyCFunction)poll_unregister, - METH_O, poll_unregister_doc}, - {"poll", (PyCFunction)poll_poll, - METH_VARARGS, poll_poll_doc}, - {NULL, NULL} /* sentinel */ + SELECT_POLL_REGISTER_METHODDEF + SELECT_POLL_MODIFY_METHODDEF + SELECT_POLL_UNREGISTER_METHODDEF + SELECT_POLL_POLL_METHODDEF + {NULL, NULL} /* sentinel */ }; static pollObject * @@ -1097,24 +1301,82 @@ static PyTypeObject devpoll_Type = { #endif /* HAVE_SYS_DEVPOLL_H */ - -PyDoc_STRVAR(poll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); +/*[clinic input] +select.poll + +Returns a polling object. + +The object supports registering and unregistering file descriptors, +and then polling them for I/O events. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_poll__doc__, +"poll()\n" +"Returns a polling object.\n" +"\n" +"The object supports registering and unregistering file descriptors,\n" +"and then polling them for I/O events."); + +#define SELECT_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll, METH_NOARGS, select_poll__doc__}, static PyObject * -select_poll(PyObject *self, PyObject *unused) +select_poll_impl(PyModuleDef *module); + +static PyObject * +select_poll(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = select_poll_impl(module); + + return return_value; +} + +static PyObject * +select_poll_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=d0c3aa9278cd36d3c7f7669e1e4e394bf87be09f]*/ { return (PyObject *)newPollObject(); } #ifdef HAVE_SYS_DEVPOLL_H -PyDoc_STRVAR(devpoll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); + +/*[clinic input] +select.devpoll + +Returns a polling object using /dev/poll. + +The object supports registering and unregistering file descriptors, +and then polling them for I/O events. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_devpoll__doc__, +"devpoll()\n" +"Returns a polling object using /dev/poll.\n" +"\n" +"The object supports registering and unregistering file descriptors,\n" +"and then polling them for I/O events."); + +#define SELECT_DEVPOLL_METHODDEF \ + {"devpoll", (PyCFunction)select_devpoll, METH_NOARGS, select_devpoll__doc__}, static PyObject * -select_devpoll(PyObject *self, PyObject *unused) +select_devpoll_impl(PyModuleDef *module); + +static PyObject * +select_devpoll(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = select_devpoll_impl(module); + + return return_value; +} + +static PyObject * +select_devpoll_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=6f91e95ba479bd17349f25396ee0a57e5807bc18]*/ { return (PyObject *)newDevPollObject(); } @@ -1236,15 +1498,53 @@ newPyEpoll_Object(PyTypeObject *type, in } +/*[clinic input] +@classmethod +select.epoll.__new__ + + sizehint: int(c_default="FD_SETSIZE - 1") = -1 + flags: int = 0 + +Returns an epolling object. + +sizehint must be a positive integer or -1 for the default size. The +sizehint is used to optimize internal data structures. It doesn't limit +the maximum number of monitored events. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll__doc__, +"__new__(sizehint=-1, flags=0)\n" +"Returns an epolling object.\n" +"\n" +"sizehint must be a positive integer or -1 for the default size. The\n" +"sizehint is used to optimize internal data structures. It doesn\'t limit\n" +"the maximum number of monitored events."); + static PyObject * -pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +select_epoll_impl(PyTypeObject *type, int sizehint, int flags); + +static PyObject * +select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - int flags = 0, sizehint = FD_SETSIZE - 1; - static char *kwlist[] = {"sizehint", "flags", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist, - &sizehint, &flags)) - return NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"sizehint", "flags", NULL}; + int sizehint = FD_SETSIZE - 1; + int flags = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|ii:__new__", _keywords, + &sizehint, &flags)) + goto exit; + return_value = select_epoll_impl(type, sizehint, flags); + +exit: + return return_value; +} + +static PyObject * +select_epoll_impl(PyTypeObject *type, int sizehint, int flags) +/*[clinic end generated code: checksum=39e15cd852412132f9005ad909fd3beba12fbae2]*/ +{ if (sizehint < 0) { PyErr_SetString(PyExc_ValueError, "negative sizehint"); return NULL; @@ -1261,8 +1561,41 @@ pyepoll_dealloc(pyEpoll_Object *self) Py_TYPE(self)->tp_free(self); } -static PyObject* -pyepoll_close(pyEpoll_Object *self) +/*[clinic input] +select.epoll.close + + self: self(type="pyEpoll_Object *") + +Close the epoll control file descriptor. + +Further operations on the epoll object will raise an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_close__doc__, +"close()\n" +"Close the epoll control file descriptor.\n" +"\n" +"Further operations on the epoll object will raise an exception."); + +#define SELECT_EPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_epoll_close, METH_NOARGS, select_epoll_close__doc__}, + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_close(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = select_epoll_close_impl((pyEpoll_Object *)self); + + return return_value; +} + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self) +/*[clinic end generated code: checksum=b87aa1dec4a6a11ed664b9d978bb2dd827021a12]*/ { errno = pyepoll_internal_close(self); if (errno < 0) { @@ -1272,11 +1605,6 @@ pyepoll_close(pyEpoll_Object *self) Py_RETURN_NONE; } -PyDoc_STRVAR(pyepoll_close_doc, -"close() -> None\n\ -\n\ -Close the epoll control file descriptor. Further operations on the epoll\n\ -object will raise an exception."); static PyObject* pyepoll_get_closed(pyEpoll_Object *self) @@ -1287,34 +1615,88 @@ pyepoll_get_closed(pyEpoll_Object *self) Py_RETURN_FALSE; } -static PyObject* -pyepoll_fileno(pyEpoll_Object *self) +/*[clinic input] +select.epoll.fileno + + self: self(type="pyEpoll_Object *") + +Return the epoll control file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_fileno__doc__, +"fileno()\n" +"Return the epoll control file descriptor."); + +#define SELECT_EPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_epoll_fileno, METH_NOARGS, select_epoll_fileno__doc__}, + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = select_epoll_fileno_impl((pyEpoll_Object *)self); + + return return_value; +} + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self) +/*[clinic end generated code: checksum=e97ed02b8a24ed12eaea36a443a8635b0a1b0482]*/ { if (self->epfd < 0) return pyepoll_err_closed(); return PyLong_FromLong(self->epfd); } -PyDoc_STRVAR(pyepoll_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the epoll control file descriptor."); - -static PyObject* -pyepoll_fromfd(PyObject *cls, PyObject *args) + +/*[clinic input] +@classmethod +select.epoll.fromfd + + fd: 'i' + / + +Create an epoll object from a given control fd. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_fromfd__doc__, +"fromfd(fd)\n" +"Create an epoll object from a given control fd."); + +#define SELECT_EPOLL_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_epoll_fromfd, METH_VARARGS|METH_CLASS, select_epoll_fromfd__doc__}, + +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *cls, int fd); + +static PyObject * +select_epoll_fromfd(PyTypeObject *cls, PyObject *args) { - SOCKET fd; - - if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) - return NULL; - - return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd); + PyObject *return_value = NULL; + int fd; + + if (!PyArg_ParseTuple(args, + "i:fromfd", + &fd)) + goto exit; + return_value = select_epoll_fromfd_impl(cls, fd); + +exit: + return return_value; } -PyDoc_STRVAR(pyepoll_fromfd_doc, -"fromfd(fd) -> epoll\n\ -\n\ -Create an epoll object from a given control fd."); +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *cls, int fd) +/*[clinic end generated code: checksum=2bf67395423af02ae66535bd55ccaf3c6a6f8f5a]*/ +{ + SOCKET s_fd = (SOCKET)fd; + return newPyEpoll_Object((PyTypeObject *)cls, FD_SETSIZE - 1, 0, s_fd); +} + static PyObject * pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) @@ -1365,100 +1747,238 @@ pyepoll_internal_ctl(int epfd, int op, P Py_RETURN_NONE; } +/* XXX wrong default below */ + +/*[clinic input] +select.epoll.register + + self: self(type="pyEpoll_Object *") + fd: object() + eventmask: unsigned_int(c_default="EPOLLIN | EPOLLOUT | EPOLLPRI", bitwise=True) = select.EPOLLIN | select.EPOLLOUT | select.EPOLLPRI + +Registers a new fd or raises an OSError if the fd is already registered. + +fd is the target file descriptor of the operation. +events is a bit set composed of the various EPOLL constants; the default +is EPOLLIN | EPOLLOUT | EPOLLPRI. + +The epoll interface supports all file descriptors that support poll. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_register__doc__, +"register(fd, eventmask=select.EPOLLIN | select.EPOLLOUT | select.EPOLLPRI)\n" +"Registers a new fd or raises an OSError if the fd is already registered.\n" +"\n" +"fd is the target file descriptor of the operation.\n" +"events is a bit set composed of the various EPOLL constants; the default\n" +"is EPOLLIN | EPOLLOUT | EPOLLPRI.\n" +"\n" +"The epoll interface supports all file descriptors that support poll."); + +#define SELECT_EPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_epoll_register, METH_VARARGS|METH_KEYWORDS, select_epoll_register__doc__}, + static PyObject * -pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_register_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask); + +static PyObject * +select_epoll_register(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *pfd; - unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI; - static char *kwlist[] = {"fd", "eventmask", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist, - &pfd, &events)) { - return NULL; - } - - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events); + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "eventmask", NULL}; + PyObject *fd; + unsigned int eventmask = EPOLLIN | EPOLLOUT | EPOLLPRI; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|I:register", _keywords, + &fd, &eventmask)) + goto exit; + return_value = select_epoll_register_impl((pyEpoll_Object *)self, fd, eventmask); + +exit: + return return_value; } -PyDoc_STRVAR(pyepoll_register_doc, -"register(fd[, eventmask]) -> None\n\ -\n\ -Registers a new fd or raises an OSError if the fd is already registered.\n\ -fd is the target file descriptor of the operation.\n\ -events is a bit set composed of the various EPOLL constants; the default\n\ -is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -\n\ -The epoll interface supports all file descriptors that support poll."); - static PyObject * -pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_register_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask) +/*[clinic end generated code: checksum=84a9052d2e10c0f59198785a7bf9bd96897616c2]*/ { - PyObject *pfd; - unsigned int events; - static char *kwlist[] = {"fd", "eventmask", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist, - &pfd, &events)) { - return NULL; - } - - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events); + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } -PyDoc_STRVAR(pyepoll_modify_doc, -"modify(fd, eventmask) -> None\n\ -\n\ -fd is the target file descriptor of the operation\n\ -events is a bit set composed of the various EPOLL constants"); + +/*[clinic input] +select.epoll.modify + + self: self(type="pyEpoll_Object *") + fd: object() + eventmask: unsigned_int(bitwise=True) + +Modify event mask for a registered file descriptor. + +fd is the target file descriptor of the operation, and +events is a bit set composed of the various EPOLL constants. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_modify__doc__, +"modify(fd, eventmask)\n" +"Modify event mask for a registered file descriptor.\n" +"\n" +"fd is the target file descriptor of the operation, and\n" +"events is a bit set composed of the various EPOLL constants."); + +#define SELECT_EPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_epoll_modify, METH_VARARGS|METH_KEYWORDS, select_epoll_modify__doc__}, static PyObject * -pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_modify_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask); + +static PyObject * +select_epoll_modify(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *pfd; - static char *kwlist[] = {"fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist, - &pfd)) { - return NULL; - } - - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0); + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "eventmask", NULL}; + PyObject *fd; + unsigned int eventmask; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OI:modify", _keywords, + &fd, &eventmask)) + goto exit; + return_value = select_epoll_modify_impl((pyEpoll_Object *)self, fd, eventmask); + +exit: + return return_value; } -PyDoc_STRVAR(pyepoll_unregister_doc, -"unregister(fd) -> None\n\ -\n\ -fd is the target file descriptor of the operation."); - static PyObject * -pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_modify_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask) +/*[clinic end generated code: checksum=97fa04b66f49550c9b7f5c252e71881e17215f08]*/ { - double dtimeout = -1.; - int timeout; + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); +} + + +/*[clinic input] +select.epoll.unregister + + self: self(type="pyEpoll_Object *") + fd: object() + +Remove a registered file descriptor from the epoll object. + +fd is the target file descriptor of the operation. +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_unregister__doc__, +"unregister(fd)\n" +"Remove a registered file descriptor from the epoll object.\n" +"\n" +"fd is the target file descriptor of the operation."); + +#define SELECT_EPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_epoll_unregister, METH_VARARGS|METH_KEYWORDS, select_epoll_unregister__doc__}, + +static PyObject * +select_epoll_unregister_impl(pyEpoll_Object *self, PyObject *fd); + +static PyObject * +select_epoll_unregister(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + PyObject *fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:unregister", _keywords, + &fd)) + goto exit; + return_value = select_epoll_unregister_impl((pyEpoll_Object *)self, fd); + +exit: + return return_value; +} + +static PyObject * +select_epoll_unregister_impl(pyEpoll_Object *self, PyObject *fd) +/*[clinic end generated code: checksum=091e4198401979f0b59c349cc2475547f0b5bb45]*/ +{ + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); +} + + +/*[clinic input] +select.epoll.poll + + self: self(type="pyEpoll_Object *") + timeout: double = -1.0 + maxevents: int = -1 + +Wait for events on the epoll file descriptor. + +timeout gives the maximum time to wait in seconds (as float). +A timeout of -1 makes poll wait indefinitely. +Up to maxevents are returned to the caller. + +The return value is a list of tuples of the form (fd, events). +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll_poll__doc__, +"poll(timeout=-1.0, maxevents=-1)\n" +"Wait for events on the epoll file descriptor.\n" +"\n" +"timeout gives the maximum time to wait in seconds (as float).\n" +"A timeout of -1 makes poll wait indefinitely.\n" +"Up to maxevents are returned to the caller.\n" +"\n" +"The return value is a list of tuples of the form (fd, events)."); + +#define SELECT_EPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_epoll_poll, METH_VARARGS|METH_KEYWORDS, select_epoll_poll__doc__}, + +static PyObject * +select_epoll_poll_impl(pyEpoll_Object *self, double timeout, int maxevents); + +static PyObject * +select_epoll_poll(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"timeout", "maxevents", NULL}; + double timeout = -1.0; int maxevents = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|di:poll", _keywords, + &timeout, &maxevents)) + goto exit; + return_value = select_epoll_poll_impl((pyEpoll_Object *)self, timeout, maxevents); + +exit: + return return_value; +} + +static PyObject * +select_epoll_poll_impl(pyEpoll_Object *self, double timeout, int maxevents) +/*[clinic end generated code: checksum=0a7a8f87de5ce350b221d215945cdd07bae1195d]*/ +{ + int itimeout; int nfds, i; PyObject *elist = NULL, *etuple = NULL; struct epoll_event *evs = NULL; - static char *kwlist[] = {"timeout", "maxevents", NULL}; if (self->epfd < 0) return pyepoll_err_closed(); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist, - &dtimeout, &maxevents)) { - return NULL; + if (timeout < 0) { + itimeout = -1; } - - if (dtimeout < 0) { - timeout = -1; - } - else if (dtimeout * 1000.0 > INT_MAX) { + else if (timeout * 1000.0 > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "timeout is too large"); return NULL; } else { - timeout = (int)(dtimeout * 1000.0); + itimeout = (int)(timeout * 1000.0); } if (maxevents == -1) { @@ -1478,7 +1998,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObj } Py_BEGIN_ALLOW_THREADS - nfds = epoll_wait(self->epfd, evs, maxevents, timeout); + nfds = epoll_wait(self->epfd, evs, maxevents, itimeout); Py_END_ALLOW_THREADS if (nfds < 0) { PyErr_SetFromErrno(PyExc_OSError); @@ -1499,20 +2019,41 @@ pyepoll_poll(pyEpoll_Object *self, PyObj PyList_SET_ITEM(elist, i, etuple); } - error: + error: PyMem_Free(evs); return elist; } -PyDoc_STRVAR(pyepoll_poll_doc, -"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\ -\n\ -Wait for events on the epoll file descriptor for a maximum time of timeout\n\ -in seconds (as float). -1 makes poll wait indefinitely.\n\ -Up to maxevents are returned to the caller."); + +/*[clinic input] +select.epoll.__enter__ + + self: self(type="pyEpoll_Object *") + +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll___enter____doc__, +"__enter__()"); + +#define SELECT_EPOLL___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)select_epoll___enter__, METH_NOARGS, select_epoll___enter____doc__}, static PyObject * -pyepoll_enter(pyEpoll_Object *self, PyObject *args) +select_epoll___enter___impl(pyEpoll_Object *self); + +static PyObject * +select_epoll___enter__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = select_epoll___enter___impl((pyEpoll_Object *)self); + + return return_value; +} + +static PyObject * +select_epoll___enter___impl(pyEpoll_Object *self) +/*[clinic end generated code: checksum=ba95397e909daa4dce9c3876c3089900a6ce26e8]*/ { if (self->epfd < 0) return pyepoll_err_closed(); @@ -1521,8 +2062,47 @@ pyepoll_enter(pyEpoll_Object *self, PyOb return (PyObject *)self; } +/*[clinic input] +select.epoll.__exit__ + + self: self(type="pyEpoll_Object *") + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +[clinic start generated code]*/ + +PyDoc_STRVAR(select_epoll___exit____doc__, +"__exit__(exc_type=None, exc_value=None, exc_tb=None)"); + +#define SELECT_EPOLL___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)select_epoll___exit__, METH_VARARGS, select_epoll___exit____doc__}, + static PyObject * -pyepoll_exit(PyObject *self, PyObject *args) +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +select_epoll___exit__(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!PyArg_ParseTuple(args, + "|OOO:__exit__", + &exc_type, &exc_value, &exc_tb)) + goto exit; + return_value = select_epoll___exit___impl((pyEpoll_Object *)self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +static PyObject * +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: checksum=4fc95860173d89b718b9fb765f84c29fa6bc85e7]*/ { _Py_IDENTIFIER(close); @@ -1530,24 +2110,15 @@ pyepoll_exit(PyObject *self, PyObject *a } static PyMethodDef pyepoll_methods[] = { - {"fromfd", (PyCFunction)pyepoll_fromfd, - METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc}, - {"close", (PyCFunction)pyepoll_close, METH_NOARGS, - pyepoll_close_doc}, - {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS, - pyepoll_fileno_doc}, - {"modify", (PyCFunction)pyepoll_modify, - METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc}, - {"register", (PyCFunction)pyepoll_register, - METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc}, - {"unregister", (PyCFunction)pyepoll_unregister, - METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc}, - {"poll", (PyCFunction)pyepoll_poll, - METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc}, - {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS, - NULL}, - {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS, - NULL}, + SELECT_EPOLL_FROMFD_METHODDEF + SELECT_EPOLL_CLOSE_METHODDEF + SELECT_EPOLL_FILENO_METHODDEF + SELECT_EPOLL_MODIFY_METHODDEF + SELECT_EPOLL_REGISTER_METHODDEF + SELECT_EPOLL_UNREGISTER_METHODDEF + SELECT_EPOLL_POLL_METHODDEF + SELECT_EPOLL___ENTER___METHODDEF + SELECT_EPOLL___EXIT___METHODDEF {NULL, NULL}, }; @@ -1557,14 +2128,6 @@ static PyGetSetDef pyepoll_getsetlist[] {0}, }; -PyDoc_STRVAR(pyepoll_doc, -"select.epoll(sizehint=-1, flags=0)\n\ -\n\ -Returns an epolling object\n\ -\n\ -sizehint must be a positive integer or -1 for the default size. The\n\ -sizehint is used to optimize internal data structures. It doesn't limit\n\ -the maximum number of monitored events."); static PyTypeObject pyEpoll_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -1587,7 +2150,7 @@ static PyTypeObject pyEpoll_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - pyepoll_doc, /* tp_doc */ + select_epoll__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -1604,7 +2167,7 @@ static PyTypeObject pyEpoll_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - pyepoll_new, /* tp_new */ + select_epoll, /* tp_new */ 0, /* tp_free */ }; @@ -2229,37 +2792,14 @@ static PyTypeObject kqueue_queue_Type = /* ************************************************************************ */ -PyDoc_STRVAR(select_doc, -"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\ -\n\ -Wait until one or more file descriptors are ready for some kind of I/O.\n\ -The first three arguments are sequences of file descriptors to be waited for:\n\ -rlist -- wait until ready for reading\n\ -wlist -- wait until ready for writing\n\ -xlist -- wait for an ``exceptional condition''\n\ -If only one kind of condition is required, pass [] for the other lists.\n\ -A file descriptor is either a socket or file object, or a small integer\n\ -gotten from a fileno() method call on one of those.\n\ -\n\ -The optional 4th argument specifies a timeout in seconds; it may be\n\ -a floating point number to specify fractions of seconds. If it is absent\n\ -or None, the call will never time out.\n\ -\n\ -The return value is a tuple of three lists corresponding to the first three\n\ -arguments; each contains the subset of the corresponding file descriptors\n\ -that are ready.\n\ -\n\ -*** IMPORTANT NOTICE ***\n\ -On Windows only sockets are supported; on Unix, all file\n\ -descriptors can be used."); static PyMethodDef select_methods[] = { - {"select", select_select, METH_VARARGS, select_doc}, + SELECT_SELECT_METHODDEF #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) - {"poll", select_poll, METH_NOARGS, poll_doc}, + SELECT_POLL_METHODDEF #endif /* HAVE_POLL */ #ifdef HAVE_SYS_DEVPOLL_H - {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc}, + SELECT_DEVPOLL_METHODDEF #endif {0, 0}, /* sentinel */ }; diff -r acd31653e3b4 Modules/signalmodule.c --- a/Modules/signalmodule.c Thu Jan 16 06:53:54 2014 +0100 +++ b/Modules/signalmodule.c Thu Jan 16 09:29:58 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,89 @@ signal_handler(int sig_num) #ifdef HAVE_ALARM + +/*[clinic input] +signal.alarm -> long + + 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 long +signal_alarm_impl(PyModuleDef *module, int seconds); + static PyObject * -signal_alarm(PyObject *self, PyObject *args) +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; + long _return_value; + + if (!PyArg_ParseTuple(args, + "i:alarm", + &seconds)) + goto exit; + _return_value = signal_alarm_impl(module, seconds); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; } -PyDoc_STRVAR(alarm_doc, -"alarm(seconds)\n\ -\n\ -Arrange for SIGALRM to arrive after the given number of seconds."); +static long +signal_alarm_impl(PyModuleDef *module, int seconds) +/*[clinic end generated code: checksum=9f32401d1b613122fc6d7a82e69ebecb2ed5154e]*/ +{ + /* alarm() returns the number of seconds remaining */ + return (long)alarm(seconds); +} + +#else +#define SIGNAL_ALARM_METHODDEF #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 +342,74 @@ 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."); +#else +#define SIGNAL_PAUSE_METHODDEF #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 +433,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,77 +531,142 @@ 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; } +#else +#define SIGNAL_SIGINTERRUPT_METHODDEF #endif + +/*[clinic input] +signal.set_wakeup_fd -> long + + 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 long +signal_set_wakeup_fd_impl(PyModuleDef *module, int fd); + static PyObject * -signal_set_wakeup_fd(PyObject *self, PyObject *args) +signal_set_wakeup_fd(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + long _return_value; + + if (!PyArg_ParseTuple(args, + "i:set_wakeup_fd", + &fd)) + goto exit; + _return_value = signal_set_wakeup_fd_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +signal_set_wakeup_fd_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: checksum=0d55ec181f8b3dba9e1213de329645452782993a]*/ { 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, "set_wakeup_fd only works in main thread"); - return NULL; + return -1; } #endif if (fd != -1 && (!_PyVerify_fd(fd) || fstat(fd, &buf) != 0)) { PyErr_SetString(PyExc_ValueError, "invalid fd"); - return NULL; + return -1; } old_fd = wakeup_fd; wakeup_fd = fd; - return PyLong_FromLong(old_fd); + return 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,62 +681,131 @@ PySignal_SetWakeupFd(int fd) #ifdef HAVE_SETITIMER + +/*[clinic input] +signal.setitimer + + which: 'i' + seconds: 'd' + interval: 'd' = 0.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.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; - double interval = 0; + PyObject *return_value = NULL; int which; + double seconds; + double interval = 0.0; + + 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=1a9a2b16df63f9eae76c60d8d40d5f74767707f7]*/ +{ 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) { - PyErr_SetFromErrno(ItimerError); - return NULL; + PyErr_SetFromErrno(ItimerError); + return NULL; } 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)."); +#else +#define SIGNAL_SETITIMER_METHODDEF #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."); +#else +#define SIGNAL_GETITIMER_METHODDEF #endif #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ @@ -614,21 +896,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 +958,48 @@ 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."); +#else +#define SIGNAL_PTHREAD_SIGMASK_METHODDEF #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 +1009,45 @@ signal_sigpending(PyObject *self) return sigset_to_set(mask); } -PyDoc_STRVAR(signal_sigpending_doc, -"sigpending() -> list\n\ -\n\ -Examine pending signals."); +#else +#define SIGNAL_SIGPENDING_METHODDEF #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,11 +1061,10 @@ 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 */ +#else +#define SIGNAL_SIGWAIT_METHODDEF +#endif /* #ifdef HAVE_SIGWAIT */ + #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) static int initialized; @@ -752,18 +1119,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 +1164,58 @@ 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."); +#else +#define SIGNAL_SIGWAITINFO_METHODDEF #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 +1223,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 +1233,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 +1249,57 @@ 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)."); +#else +#define SIGNAL_SIGTIMEDWAIT_METHODDEF #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,62 +1313,31 @@ 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."); +#else +#define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */ -/* List of functions defined in the module */ +/* List of functions defined in the module -- some of the methoddefs are + defined to nothing if the corresponding C function is not available. */ static PyMethodDef signal_methods[] = { -#ifdef HAVE_ALARM - {"alarm", signal_alarm, METH_VARARGS, alarm_doc}, -#endif -#ifdef HAVE_SETITIMER - {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc}, -#endif -#ifdef HAVE_GETITIMER - {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, -#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}, -#ifdef HAVE_SIGINTERRUPT - {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, -#endif -#ifdef HAVE_PAUSE - {"pause", (PyCFunction)signal_pause, - METH_NOARGS, pause_doc}, -#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}, -#endif -#ifdef PYPTHREAD_SIGMASK - {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, - METH_VARARGS, signal_pthread_sigmask_doc}, -#endif -#ifdef HAVE_SIGPENDING - {"sigpending", (PyCFunction)signal_sigpending, - METH_NOARGS, signal_sigpending_doc}, -#endif -#ifdef HAVE_SIGWAIT - {"sigwait", (PyCFunction)signal_sigwait, - METH_VARARGS, signal_sigwait_doc}, -#endif -#ifdef HAVE_SIGWAITINFO - {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, - METH_VARARGS, signal_sigwaitinfo_doc}, -#endif -#ifdef HAVE_SIGTIMEDWAIT - {"sigtimedwait", (PyCFunction)signal_sigtimedwait, - METH_VARARGS, signal_sigtimedwait_doc}, -#endif - {NULL, NULL} /* sentinel */ + {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, + SIGNAL_ALARM_METHODDEF + SIGNAL_SETITIMER_METHODDEF + SIGNAL_GETITIMER_METHODDEF + SIGNAL_SIGNAL_METHODDEF + SIGNAL_GETSIGNAL_METHODDEF + SIGNAL_SET_WAKEUP_FD_METHODDEF + SIGNAL_SIGINTERRUPT_METHODDEF + SIGNAL_PAUSE_METHODDEF + SIGNAL_PTHREAD_KILL_METHODDEF + SIGNAL_PTHREAD_SIGMASK_METHODDEF + SIGNAL_SIGPENDING_METHODDEF + SIGNAL_SIGWAIT_METHODDEF + SIGNAL_SIGWAITINFO_METHODDEF + SIGNAL_SIGTIMEDWAIT_METHODDEF + {NULL, NULL} /* sentinel */ }; diff -r acd31653e3b4 Python/sysmodule.c --- a/Python/sysmodule.c Thu Jan 16 06:53:54 2014 +0100 +++ b/Python/sysmodule.c Thu Jan 16 09:29:58 2014 +0100 @@ -37,6 +37,11 @@ extern const char *PyWin_DLLVersionStrin #include #endif +/*[clinic input] +module sys +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + _Py_IDENTIFIER(_); _Py_IDENTIFIER(__sizeof__); _Py_IDENTIFIER(buffer); @@ -159,8 +164,25 @@ finally: return ret; } +/*[clinic input] +sys.displayhook + + object: 'O' + / + +Print an object to sys.stdout and also save it in builtins._ +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_displayhook__doc__, +"displayhook(object)\n" +"Print an object to sys.stdout and also save it in builtins._"); + +#define SYS_DISPLAYHOOK_METHODDEF \ + {"displayhook", (PyCFunction)sys_displayhook, METH_O, sys_displayhook__doc__}, + static PyObject * -sys_displayhook(PyObject *self, PyObject *o) +sys_displayhook(PyModuleDef *module, PyObject *object) +/*[clinic end generated code: checksum=b7e504788a4da17cdadee42be5cbd96059b1526e]*/ { PyObject *outf; PyInterpreterState *interp = PyThreadState_GET()->interp; @@ -178,7 +200,7 @@ sys_displayhook(PyObject *self, PyObject /* Print value except if None */ /* After printing, also assign to '_' */ /* Before, set '_' to None to avoid recursion */ - if (o == Py_None) { + if (object == Py_None) { Py_INCREF(Py_None); return Py_None; } @@ -189,12 +211,12 @@ sys_displayhook(PyObject *self, PyObject PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); return NULL; } - if (PyFile_WriteObject(o, outf, 0) != 0) { + if (PyFile_WriteObject(object, outf, 0) != 0) { if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - /* repr(o) is not encodable to sys.stdout.encoding with + /* repr(object) is not encodable to sys.stdout.encoding with * sys.stdout.errors error handler (which is probably 'strict') */ PyErr_Clear(); - err = sys_displayhook_unencodable(outf, o); + err = sys_displayhook_unencodable(outf, object); if (err) return NULL; } @@ -209,37 +231,97 @@ sys_displayhook(PyObject *self, PyObject } if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0) return NULL; - if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0) + if (_PyObject_SetAttrId(builtins, &PyId__, object) != 0) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(displayhook_doc, -"displayhook(object) -> None\n" + +/*[clinic input] +sys.excepthook + + exctype: 'O' + value: 'O' + traceback: 'O' + / + +Handle an exception by displaying it with a traceback on sys.stderr. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_excepthook__doc__, +"excepthook(exctype, value, traceback)\n" +"Handle an exception by displaying it with a traceback on sys.stderr."); + +#define SYS_EXCEPTHOOK_METHODDEF \ + {"excepthook", (PyCFunction)sys_excepthook, METH_VARARGS, sys_excepthook__doc__}, + +static PyObject * +sys_excepthook_impl(PyModuleDef *module, PyObject *exctype, PyObject *value, PyObject *traceback); + +static PyObject * +sys_excepthook(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *exctype; + PyObject *value; + PyObject *traceback; + + if (!PyArg_ParseTuple(args, + "OOO:excepthook", + &exctype, &value, &traceback)) + goto exit; + return_value = sys_excepthook_impl(module, exctype, value, traceback); + +exit: + return return_value; +} + +static PyObject * +sys_excepthook_impl(PyModuleDef *module, PyObject *exctype, PyObject *value, PyObject *traceback) +/*[clinic end generated code: checksum=8097306a8d8ec07d74adc4e902af54dd74d3b5bf]*/ +{ + PyErr_Display(exctype, value, traceback); + Py_RETURN_NONE; +} + + +/*[clinic input] +sys.exc_info + +Return current exception information. + +This is the type, value and traceback of the most recent exception +caught by an except clause in the current stack frame or +in an older stack frame. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_exc_info__doc__, +"exc_info()\n" +"Return current exception information.\n" "\n" -"Print an object to sys.stdout and also save it in builtins._\n" -); +"This is the type, value and traceback of the most recent exception\n" +"caught by an except clause in the current stack frame or\n" +"in an older stack frame."); + +#define SYS_EXC_INFO_METHODDEF \ + {"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, sys_exc_info__doc__}, static PyObject * -sys_excepthook(PyObject* self, PyObject* args) +sys_exc_info_impl(PyModuleDef *module); + +static PyObject * +sys_exc_info(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - PyObject *exc, *value, *tb; - if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb)) - return NULL; - PyErr_Display(exc, value, tb); - Py_INCREF(Py_None); - return Py_None; + PyObject *return_value = NULL; + + return_value = sys_exc_info_impl(module); + + return return_value; } -PyDoc_STRVAR(excepthook_doc, -"excepthook(exctype, value, traceback) -> None\n" -"\n" -"Handle an exception by displaying it with a traceback on sys.stderr.\n" -); - static PyObject * -sys_exc_info(PyObject *self, PyObject *noargs) +sys_exc_info_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=69a1f22b8b3a6d934354032cddba0e754ca52d32]*/ { PyThreadState *tstate; tstate = PyThreadState_GET(); @@ -251,50 +333,126 @@ sys_exc_info(PyObject *self, PyObject *n tstate->exc_traceback : Py_None); } -PyDoc_STRVAR(exc_info_doc, -"exc_info() -> (type, value, traceback)\n\ -\n\ -Return information about the most recent exception caught by an except\n\ -clause in the current stack frame or in an older stack frame." -); + +/*[clinic input] +sys.exit + + status: 'O' = NULL + / + +Exit the interpreter by raising SystemExit(status). + +If the status is omitted or None, it defaults to zero (i.e., success). +If the status is an integer, it will be used as the system exit status. +If it is another kind of object, it will be printed and the system +exit status will be one (i.e., failure). +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_exit__doc__, +"exit(status=None)\n" +"Exit the interpreter by raising SystemExit(status).\n" +"\n" +"If the status is omitted or None, it defaults to zero (i.e., success).\n" +"If the status is an integer, it will be used as the system exit status.\n" +"If it is another kind of object, it will be printed and the system\n" +"exit status will be one (i.e., failure)."); + +#define SYS_EXIT_METHODDEF \ + {"exit", (PyCFunction)sys_exit, METH_VARARGS, sys_exit__doc__}, static PyObject * -sys_exit(PyObject *self, PyObject *args) +sys_exit_impl(PyModuleDef *module, PyObject *status); + +static PyObject * +sys_exit(PyModuleDef *module, PyObject *args) { - PyObject *exit_code = 0; - if (!PyArg_UnpackTuple(args, "exit", 0, 1, &exit_code)) - return NULL; + PyObject *return_value = NULL; + PyObject *status = NULL; + + if (!PyArg_ParseTuple(args, + "|O:exit", + &status)) + goto exit; + return_value = sys_exit_impl(module, status); + +exit: + return return_value; +} + +static PyObject * +sys_exit_impl(PyModuleDef *module, PyObject *status) +/*[clinic end generated code: checksum=3b82a3224a8dd9aaf245cb58023789c40c222c56]*/ +{ /* Raise SystemExit so callers may catch it or clean up. */ - PyErr_SetObject(PyExc_SystemExit, exit_code); + PyErr_SetObject(PyExc_SystemExit, status); return NULL; } -PyDoc_STRVAR(exit_doc, -"exit([status])\n\ -\n\ -Exit the interpreter by raising SystemExit(status).\n\ -If the status is omitted or None, it defaults to zero (i.e., success).\n\ -If the status is an integer, it will be used as the system exit status.\n\ -If it is another kind of object, it will be printed and the system\n\ -exit status will be one (i.e., failure)." -); - + + +/*[clinic input] +sys.getdefaultencoding + +Return the current default string encoding used by the Unicode implementation. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getdefaultencoding__doc__, +"getdefaultencoding()\n" +"Return the current default string encoding used by the Unicode implementation."); + +#define SYS_GETDEFAULTENCODING_METHODDEF \ + {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS, sys_getdefaultencoding__doc__}, static PyObject * -sys_getdefaultencoding(PyObject *self) +sys_getdefaultencoding_impl(PyModuleDef *module); + +static PyObject * +sys_getdefaultencoding(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getdefaultencoding_impl(module); + + return return_value; +} + +static PyObject * +sys_getdefaultencoding_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=2c130f2056ee57c4b947cd380d8bc26a81f4c829]*/ { return PyUnicode_FromString(PyUnicode_GetDefaultEncoding()); } -PyDoc_STRVAR(getdefaultencoding_doc, -"getdefaultencoding() -> string\n\ -\n\ -Return the current default string encoding used by the Unicode \n\ -implementation." -); + +/*[clinic input] +sys.getfilesystemencoding + +Return the encoding used to convert Unicode filenames in operating system filenames. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getfilesystemencoding__doc__, +"getfilesystemencoding()\n" +"Return the encoding used to convert Unicode filenames in operating system filenames."); + +#define SYS_GETFILESYSTEMENCODING_METHODDEF \ + {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, METH_NOARGS, sys_getfilesystemencoding__doc__}, static PyObject * -sys_getfilesystemencoding(PyObject *self) +sys_getfilesystemencoding_impl(PyModuleDef *module); + +static PyObject * +sys_getfilesystemencoding(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getfilesystemencoding_impl(module); + + return return_value; +} + +static PyObject * +sys_getfilesystemencoding_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=756ec0c84b8b3d471e5fb6ca2dc3884cbd1629e1]*/ { if (Py_FileSystemDefaultEncoding) return PyUnicode_FromString(Py_FileSystemDefaultEncoding); @@ -303,39 +461,68 @@ sys_getfilesystemencoding(PyObject *self return NULL; } -PyDoc_STRVAR(getfilesystemencoding_doc, -"getfilesystemencoding() -> string\n\ -\n\ -Return the encoding used to convert Unicode filenames in\n\ -operating system filenames." -); + +/*[clinic input] +sys.intern + + string: 'U' + / + +``Intern'' the given string. + +This enters the string in the (global) table of interned strings whose purpose +is to speed up dictionary lookups. +Return the string itself or the previously interned string object with the +same value. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_intern__doc__, +"intern(string)\n" +"``Intern\'\' the given string.\n" +"\n" +"This enters the string in the (global) table of interned strings whose purpose\n" +"is to speed up dictionary lookups.\n" +"Return the string itself or the previously interned string object with the\n" +"same value."); + +#define SYS_INTERN_METHODDEF \ + {"intern", (PyCFunction)sys_intern, METH_VARARGS, sys_intern__doc__}, static PyObject * -sys_intern(PyObject *self, PyObject *args) +sys_intern_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +sys_intern(PyModuleDef *module, PyObject *args) { - PyObject *s; - if (!PyArg_ParseTuple(args, "U:intern", &s)) - return NULL; - if (PyUnicode_CheckExact(s)) { - Py_INCREF(s); - PyUnicode_InternInPlace(&s); - return s; + PyObject *return_value = NULL; + PyObject *string; + + if (!PyArg_ParseTuple(args, + "U:intern", + &string)) + goto exit; + return_value = sys_intern_impl(module, string); + +exit: + return return_value; +} + +static PyObject * +sys_intern_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: checksum=ed3ae3a42cf8272a9648ff4d9a573c2e0c9530f6]*/ +{ + if (PyUnicode_CheckExact(string)) { + Py_INCREF(string); + PyUnicode_InternInPlace(&string); + return string; } else { PyErr_Format(PyExc_TypeError, - "can't intern %.400s", s->ob_type->tp_name); + "can't intern %.400s", string->ob_type->tp_name); return NULL; } } -PyDoc_STRVAR(intern_doc, -"intern(string) -> string\n\ -\n\ -``Intern'' the given string. This enters the string in the (global)\n\ -table of interned strings whose purpose is to speed up dictionary lookups.\n\ -Return the string itself or the previously interned string object with the\n\ -same value."); - /* * Cached interned string objects used for calling the profile and @@ -446,28 +633,76 @@ trace_trampoline(PyObject *self, PyFrame return 0; } + +/*[clinic input] +sys.settrace + + function: 'O' + / + +Set the global debug tracing function. + +It will be called on each function call. +See the debugger chapter in the library manual. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_settrace__doc__, +"settrace(function)\n" +"Set the global debug tracing function.\n" +"\n" +"It will be called on each function call.\n" +"See the debugger chapter in the library manual."); + +#define SYS_SETTRACE_METHODDEF \ + {"settrace", (PyCFunction)sys_settrace, METH_O, sys_settrace__doc__}, + static PyObject * -sys_settrace(PyObject *self, PyObject *args) +sys_settrace(PyModuleDef *module, PyObject *function) +/*[clinic end generated code: checksum=100a87c90105c5373ca043036bafbda0ba81a487]*/ { if (trace_init() == -1) return NULL; - if (args == Py_None) + if (function == Py_None) PyEval_SetTrace(NULL, NULL); else - PyEval_SetTrace(trace_trampoline, args); - Py_INCREF(Py_None); - return Py_None; + PyEval_SetTrace(trace_trampoline, function); + Py_RETURN_NONE; } -PyDoc_STRVAR(settrace_doc, -"settrace(function)\n\ -\n\ -Set the global debug tracing function. It will be called on each\n\ -function call. See the debugger chapter in the library manual." -); + +/*[clinic input] +sys.gettrace + +Return the global debug tracing function set with sys.settrace(). + +See the debugger chapter in the library manual. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_gettrace__doc__, +"gettrace()\n" +"Return the global debug tracing function set with sys.settrace().\n" +"\n" +"See the debugger chapter in the library manual."); + +#define SYS_GETTRACE_METHODDEF \ + {"gettrace", (PyCFunction)sys_gettrace, METH_NOARGS, sys_gettrace__doc__}, static PyObject * -sys_gettrace(PyObject *self, PyObject *args) +sys_gettrace_impl(PyModuleDef *module); + +static PyObject * +sys_gettrace(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_gettrace_impl(module); + + return return_value; +} + +static PyObject * +sys_gettrace_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=781877b9f1d66cacc12d9265448725995fafd90f]*/ { PyThreadState *tstate = PyThreadState_GET(); PyObject *temp = tstate->c_traceobj; @@ -478,35 +713,76 @@ sys_gettrace(PyObject *self, PyObject *a return temp; } -PyDoc_STRVAR(gettrace_doc, -"gettrace()\n\ -\n\ -Return the global debug tracing function set with sys.settrace.\n\ -See the debugger chapter in the library manual." -); + +/*[clinic input] +sys.setprofile + + function: 'O' + / + +Set the profiling function. + +It will be called on each function call and return. +See the profiler chapter in the library manual. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_setprofile__doc__, +"setprofile(function)\n" +"Set the profiling function.\n" +"\n" +"It will be called on each function call and return.\n" +"See the profiler chapter in the library manual."); + +#define SYS_SETPROFILE_METHODDEF \ + {"setprofile", (PyCFunction)sys_setprofile, METH_O, sys_setprofile__doc__}, static PyObject * -sys_setprofile(PyObject *self, PyObject *args) +sys_setprofile(PyModuleDef *module, PyObject *function) +/*[clinic end generated code: checksum=0b028aa374c9946cdd1fdbebe11ad740503910a5]*/ { if (trace_init() == -1) return NULL; - if (args == Py_None) + if (function == Py_None) PyEval_SetProfile(NULL, NULL); else - PyEval_SetProfile(profile_trampoline, args); - Py_INCREF(Py_None); - return Py_None; + PyEval_SetProfile(profile_trampoline, function); + Py_RETURN_NONE; } -PyDoc_STRVAR(setprofile_doc, -"setprofile(function)\n\ -\n\ -Set the profiling function. It will be called on each function call\n\ -and return. See the profiler chapter in the library manual." -); + +/*[clinic input] +sys.getprofile + +Return the profiling function set with sys.setprofile(). + +See the profiler chapter in the library manual. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getprofile__doc__, +"getprofile()\n" +"Return the profiling function set with sys.setprofile().\n" +"\n" +"See the profiler chapter in the library manual."); + +#define SYS_GETPROFILE_METHODDEF \ + {"getprofile", (PyCFunction)sys_getprofile, METH_NOARGS, sys_getprofile__doc__}, static PyObject * -sys_getprofile(PyObject *self, PyObject *args) +sys_getprofile_impl(PyModuleDef *module); + +static PyObject * +sys_getprofile(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getprofile_impl(module); + + return return_value; +} + +static PyObject * +sys_getprofile_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=18e95ad527901b05a8f965bfa56859a43d47db19]*/ { PyThreadState *tstate = PyThreadState_GET(); PyObject *temp = tstate->c_profileobj; @@ -517,38 +793,91 @@ sys_getprofile(PyObject *self, PyObject return temp; } -PyDoc_STRVAR(getprofile_doc, -"getprofile()\n\ -\n\ -Return the profiling function set with sys.setprofile.\n\ -See the profiler chapter in the library manual." -); static int _check_interval = 100; +/*[clinic input] +sys.setcheckinterval + + n: 'i' + / + +Tell the Python interpreter to check for asynchronous events every n instructions. + +This also affects how often thread switches occur. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_setcheckinterval__doc__, +"setcheckinterval(n)\n" +"Tell the Python interpreter to check for asynchronous events every n instructions.\n" +"\n" +"This also affects how often thread switches occur."); + +#define SYS_SETCHECKINTERVAL_METHODDEF \ + {"setcheckinterval", (PyCFunction)sys_setcheckinterval, METH_VARARGS, sys_setcheckinterval__doc__}, + static PyObject * -sys_setcheckinterval(PyObject *self, PyObject *args) +sys_setcheckinterval_impl(PyModuleDef *module, int n); + +static PyObject * +sys_setcheckinterval(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int n; + + if (!PyArg_ParseTuple(args, + "i:setcheckinterval", + &n)) + goto exit; + return_value = sys_setcheckinterval_impl(module, n); + +exit: + return return_value; +} + +static PyObject * +sys_setcheckinterval_impl(PyModuleDef *module, int n) +/*[clinic end generated code: checksum=420da0ad4a9d31d249f05dcbd360a9ac778ec08b]*/ { if (PyErr_WarnEx(PyExc_DeprecationWarning, "sys.getcheckinterval() and sys.setcheckinterval() " "are deprecated. Use sys.setswitchinterval() " "instead.", 1) < 0) return NULL; - if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_check_interval)) - return NULL; - Py_INCREF(Py_None); - return Py_None; + _check_interval = n; + Py_RETURN_NONE; } -PyDoc_STRVAR(setcheckinterval_doc, -"setcheckinterval(n)\n\ -\n\ -Tell the Python interpreter to check for asynchronous events every\n\ -n instructions. This also affects how often thread switches occur." -); + +/*[clinic input] +sys.getcheckinterval + +Return the current check interval; see sys.setcheckinterval(). +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getcheckinterval__doc__, +"getcheckinterval()\n" +"Return the current check interval; see sys.setcheckinterval()."); + +#define SYS_GETCHECKINTERVAL_METHODDEF \ + {"getcheckinterval", (PyCFunction)sys_getcheckinterval, METH_NOARGS, sys_getcheckinterval__doc__}, static PyObject * -sys_getcheckinterval(PyObject *self, PyObject *args) +sys_getcheckinterval_impl(PyModuleDef *module); + +static PyObject * +sys_getcheckinterval(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getcheckinterval_impl(module); + + return return_value; +} + +static PyObject * +sys_getcheckinterval_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=9102bf2d40bc23155aba6e48dda786242d13cde9]*/ { if (PyErr_WarnEx(PyExc_DeprecationWarning, "sys.getcheckinterval() and sys.setcheckinterval() " @@ -558,102 +887,234 @@ sys_getcheckinterval(PyObject *self, PyO return PyLong_FromLong(_check_interval); } -PyDoc_STRVAR(getcheckinterval_doc, -"getcheckinterval() -> current check interval; see setcheckinterval()." -); #ifdef WITH_THREAD + +/*[clinic input] +sys.setswitchinterval + + interval: 'd' + / + +Set the ideal thread switching delay inside the Python interpreter. + +The actual frequency of switching threads can be lower if the +interpreter executes long sequences of uninterruptible code +(this is implementation-specific and workload-dependent). + +The parameter must represent the desired switching delay in seconds +A typical value is 0.005 (5 milliseconds). +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_setswitchinterval__doc__, +"setswitchinterval(interval)\n" +"Set the ideal thread switching delay inside the Python interpreter.\n" +"\n" +"The actual frequency of switching threads can be lower if the\n" +"interpreter executes long sequences of uninterruptible code\n" +"(this is implementation-specific and workload-dependent).\n" +"\n" +"The parameter must represent the desired switching delay in seconds\n" +"A typical value is 0.005 (5 milliseconds)."); + +#define SYS_SETSWITCHINTERVAL_METHODDEF \ + {"setswitchinterval", (PyCFunction)sys_setswitchinterval, METH_VARARGS, sys_setswitchinterval__doc__}, + static PyObject * -sys_setswitchinterval(PyObject *self, PyObject *args) +sys_setswitchinterval_impl(PyModuleDef *module, double interval); + +static PyObject * +sys_setswitchinterval(PyModuleDef *module, PyObject *args) { - double d; - if (!PyArg_ParseTuple(args, "d:setswitchinterval", &d)) - return NULL; - if (d <= 0.0) { + PyObject *return_value = NULL; + double interval; + + if (!PyArg_ParseTuple(args, + "d:setswitchinterval", + &interval)) + goto exit; + return_value = sys_setswitchinterval_impl(module, interval); + +exit: + return return_value; +} + +static PyObject * +sys_setswitchinterval_impl(PyModuleDef *module, double interval) +/*[clinic end generated code: checksum=166cf973cf81578b01ca42f15add07e8969af89b]*/ +{ + if (interval <= 0.0) { PyErr_SetString(PyExc_ValueError, "switch interval must be strictly positive"); return NULL; } - _PyEval_SetSwitchInterval((unsigned long) (1e6 * d)); - Py_INCREF(Py_None); - return Py_None; + _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval)); + Py_RETURN_NONE; } -PyDoc_STRVAR(setswitchinterval_doc, -"setswitchinterval(n)\n\ -\n\ -Set the ideal thread switching delay inside the Python interpreter\n\ -The actual frequency of switching threads can be lower if the\n\ -interpreter executes long sequences of uninterruptible code\n\ -(this is implementation-specific and workload-dependent).\n\ -\n\ -The parameter must represent the desired switching delay in seconds\n\ -A typical value is 0.005 (5 milliseconds)." -); + +/*[clinic input] +sys.getswitchinterval -> double + +Return the current thread switch interval; see sys.setswitchinterval(). +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getswitchinterval__doc__, +"getswitchinterval()\n" +"Return the current thread switch interval; see sys.setswitchinterval()."); + +#define SYS_GETSWITCHINTERVAL_METHODDEF \ + {"getswitchinterval", (PyCFunction)sys_getswitchinterval, METH_NOARGS, sys_getswitchinterval__doc__}, + +static double +sys_getswitchinterval_impl(PyModuleDef *module); static PyObject * -sys_getswitchinterval(PyObject *self, PyObject *args) +sys_getswitchinterval(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - return PyFloat_FromDouble(1e-6 * _PyEval_GetSwitchInterval()); + PyObject *return_value = NULL; + double _return_value; + + _return_value = sys_getswitchinterval_impl(module); + if ((_return_value == -1.0) && PyErr_Occurred()) + goto exit; + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; } -PyDoc_STRVAR(getswitchinterval_doc, -"getswitchinterval() -> current thread switch interval; see setswitchinterval()." -); - +static double +sys_getswitchinterval_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=2c6673b2f2e4956a691c4324b4cea42091597f78]*/ +{ + return 1e-6 * _PyEval_GetSwitchInterval(); +} + +#else +#define SYS_GETSWITCHINTERVAL_METHODDEF +#define SYS_SETSWITCHINTERVAL_METHODDEF #endif /* WITH_THREAD */ + #ifdef WITH_TSC + +/*[clinic input] +sys.settscdump + + on: bool + / + +If on is true, tell the Python interpreter to dump VM measurements to stderr. + +If on is false, turn off dump. The measurements are based on the +processor's time-stamp counter. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_settscdump__doc__, +"settscdump(on)\n" +"If on is true, tell the Python interpreter to dump VM measurements to stderr.\n" +"\n" +"If on is false, turn off dump. The measurements are based on the\n" +"processor\'s time-stamp counter."); + +#define SYS_SETTSCDUMP_METHODDEF \ + {"settscdump", (PyCFunction)sys_settscdump, METH_VARARGS, sys_settscdump__doc__}, + static PyObject * -sys_settscdump(PyObject *self, PyObject *args) +sys_settscdump_impl(PyModuleDef *module, int on); + +static PyObject * +sys_settscdump(PyModuleDef *module, PyObject *args) { - int bool; + PyObject *return_value = NULL; + int on; + + if (!PyArg_ParseTuple(args, + "p:settscdump", + &on)) + goto exit; + return_value = sys_settscdump_impl(module, on); + +exit: + return return_value; +} + +static PyObject * +sys_settscdump_impl(PyModuleDef *module, int on) +/*[clinic end generated code: checksum=539d2218a2ad08ba8a5af4e3dc68dcc9011dcaaf]*/ +{ PyThreadState *tstate = PyThreadState_Get(); - if (!PyArg_ParseTuple(args, "i:settscdump", &bool)) - return NULL; - if (bool) + if (on) tstate->interp->tscdump = 1; else tstate->interp->tscdump = 0; - Py_INCREF(Py_None); - return Py_None; - + Py_RETURN_NONE; } -PyDoc_STRVAR(settscdump_doc, -"settscdump(bool)\n\ -\n\ -If true, tell the Python interpreter to dump VM measurements to\n\ -stderr. If false, turn off dump. The measurements are based on the\n\ -processor's time-stamp counter." -); +#else +#define SYS_SETTSCDUMP_METHODDEF #endif /* TSC */ + +/*[clinic input] +sys.setrecursionlimit + + limit: 'i' + / + +Set the maximum depth of the Python interpreter stack to limit. + +This limit prevents infinite recursion from causing an overflow of the C +stack and crashing Python. The highest possible limit is platform-dependent. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_setrecursionlimit__doc__, +"setrecursionlimit(limit)\n" +"Set the maximum depth of the Python interpreter stack to limit.\n" +"\n" +"This limit prevents infinite recursion from causing an overflow of the C\n" +"stack and crashing Python. The highest possible limit is platform-dependent."); + +#define SYS_SETRECURSIONLIMIT_METHODDEF \ + {"setrecursionlimit", (PyCFunction)sys_setrecursionlimit, METH_VARARGS, sys_setrecursionlimit__doc__}, + static PyObject * -sys_setrecursionlimit(PyObject *self, PyObject *args) +sys_setrecursionlimit_impl(PyModuleDef *module, int limit); + +static PyObject * +sys_setrecursionlimit(PyModuleDef *module, PyObject *args) { - int new_limit; - if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit)) - return NULL; - if (new_limit <= 0) { + PyObject *return_value = NULL; + int limit; + + if (!PyArg_ParseTuple(args, + "i:setrecursionlimit", + &limit)) + goto exit; + return_value = sys_setrecursionlimit_impl(module, limit); + +exit: + return return_value; +} + +static PyObject * +sys_setrecursionlimit_impl(PyModuleDef *module, int limit) +/*[clinic end generated code: checksum=0c7f94c077eef3109b1525390a9164672afac0ca]*/ +{ + if (limit <= 0) { PyErr_SetString(PyExc_ValueError, "recursion limit must be positive"); return NULL; } - Py_SetRecursionLimit(new_limit); - Py_INCREF(Py_None); - return Py_None; + Py_SetRecursionLimit(limit); + Py_RETURN_NONE; } + static PyTypeObject Hash_InfoType; -PyDoc_STRVAR(hash_info_doc, -"hash_info\n\ -\n\ -A struct sequence providing parameters used for computing\n\ -hashes. The attributes are read only."); - static PyStructSequence_Field hash_info_fields[] = { {"width", "width of the type used for hashing, in bits"}, {"modulus", "prime number giving the modulus on which the hash " @@ -669,6 +1130,12 @@ static PyStructSequence_Field hash_info_ {NULL, NULL} }; +PyDoc_STRVAR(hash_info_doc, +"hash_info\n\ +\n\ +A struct sequence providing parameters used for computing\n\ +hashes. The attributes are read only."); + static PyStructSequence_Desc hash_info_desc = { "sys.hash_info", hash_info_doc, @@ -712,35 +1179,47 @@ get_hash_info(void) } -PyDoc_STRVAR(setrecursionlimit_doc, -"setrecursionlimit(n)\n\ -\n\ -Set the maximum depth of the Python interpreter stack to n. This\n\ -limit prevents infinite recursion from causing an overflow of the C\n\ -stack and crashing Python. The highest possible limit is platform-\n\ -dependent." -); +/*[clinic input] +sys.getrecursionlimit + +Return the current value of the recursion limit. + +See sys.setrecursionlimit() for details. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getrecursionlimit__doc__, +"getrecursionlimit()\n" +"Return the current value of the recursion limit.\n" +"\n" +"See sys.setrecursionlimit() for details."); + +#define SYS_GETRECURSIONLIMIT_METHODDEF \ + {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, sys_getrecursionlimit__doc__}, static PyObject * -sys_getrecursionlimit(PyObject *self) +sys_getrecursionlimit_impl(PyModuleDef *module); + +static PyObject * +sys_getrecursionlimit(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getrecursionlimit_impl(module); + + return return_value; +} + +static PyObject * +sys_getrecursionlimit_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=5837f140506ea95e747843897d1c27914fd3d855]*/ { return PyLong_FromLong(Py_GetRecursionLimit()); } -PyDoc_STRVAR(getrecursionlimit_doc, -"getrecursionlimit()\n\ -\n\ -Return the current value of the recursion limit, the maximum depth\n\ -of the Python interpreter stack. This limit prevents infinite\n\ -recursion from causing an overflow of the C stack and crashing Python." -); #ifdef MS_WINDOWS -PyDoc_STRVAR(getwindowsversion_doc, -"getwindowsversion()\n\ -\n\ -Return information about the running version of Windows as a named tuple.\n\ -The members are named: major, minor, build, platform, service_pack,\n\ +PyDoc_STRVAR(windows_version_doc, +"The members are named: major, minor, build, platform, service_pack,\n\ service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\ backward compatibility, only the first 5 items are available by indexing.\n\ All elements are numbers, except service_pack which is a string. Platform\n\ @@ -766,15 +1245,58 @@ static PyStructSequence_Field windows_ve static PyStructSequence_Desc windows_version_desc = { "sys.getwindowsversion", /* name */ - getwindowsversion_doc, /* doc */ + windows_version_doc, /* doc */ windows_version_fields, /* fields */ 5 /* For backward compatibility, only the first 5 items are accessible via indexing, the rest are name only */ }; +/*[clinic input] +sys.getwindowsversion + +Return information about the running version of Windows as a named tuple. + +The members are named: major, minor, build, platform, service_pack, +service_pack_major, service_pack_minor, suite_mask, and product_type. For +backward compatibility, only the first 5 items are available by indexing. +All elements are numbers, except service_pack which is a string. Platform +may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7, +3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain +controller, 3 for a server. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getwindowsversion__doc__, +"getwindowsversion()\n" +"Return information about the running version of Windows as a named tuple.\n" +"\n" +"The members are named: major, minor, build, platform, service_pack,\n" +"service_pack_major, service_pack_minor, suite_mask, and product_type. For\n" +"backward compatibility, only the first 5 items are available by indexing.\n" +"All elements are numbers, except service_pack which is a string. Platform\n" +"may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n" +"3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n" +"controller, 3 for a server."); + +#define SYS_GETWINDOWSVERSION_METHODDEF \ + {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS, sys_getwindowsversion__doc__}, + static PyObject * -sys_getwindowsversion(PyObject *self) +sys_getwindowsversion_impl(PyModuleDef *module); + +static PyObject * +sys_getwindowsversion(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getwindowsversion_impl(module); + + return return_value; +} + +static PyObject * +sys_getwindowsversion_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=741d2461c10ada26ba15453b012eea471c7ee5e0]*/ { PyObject *version; int pos = 0; @@ -804,35 +1326,106 @@ sys_getwindowsversion(PyObject *self) return version; } +#else +#define SYS_GETWINDOWSVERSION_METHODDEF #endif /* MS_WINDOWS */ #ifdef HAVE_DLOPEN + +/*[clinic input] +sys.setdlopenflags + + flags: 'i' + / + +Set the flags used by the interpreter for dlopen calls. + +This is used for example when the interpreter loads extension modules. +Among other things, this will enable a lazy resolving of symbols when +importing a module, if called as sys.setdlopenflags(0). To share symbols +across extension modules, call as sys.setdlopenflags(os.RTLD_GLOBAL). +Symbolic names for the flag modules can be found in the os module +(RTLD_xxx constants, e.g. os.RTLD_LAZY). +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_setdlopenflags__doc__, +"setdlopenflags(flags)\n" +"Set the flags used by the interpreter for dlopen calls.\n" +"\n" +"This is used for example when the interpreter loads extension modules.\n" +"Among other things, this will enable a lazy resolving of symbols when\n" +"importing a module, if called as sys.setdlopenflags(0). To share symbols\n" +"across extension modules, call as sys.setdlopenflags(os.RTLD_GLOBAL).\n" +"Symbolic names for the flag modules can be found in the os module\n" +"(RTLD_xxx constants, e.g. os.RTLD_LAZY)."); + +#define SYS_SETDLOPENFLAGS_METHODDEF \ + {"setdlopenflags", (PyCFunction)sys_setdlopenflags, METH_VARARGS, sys_setdlopenflags__doc__}, + static PyObject * -sys_setdlopenflags(PyObject *self, PyObject *args) +sys_setdlopenflags_impl(PyModuleDef *module, int flags); + +static PyObject * +sys_setdlopenflags(PyModuleDef *module, PyObject *args) { - int new_val; + PyObject *return_value = NULL; + int flags; + + if (!PyArg_ParseTuple(args, + "i:setdlopenflags", + &flags)) + goto exit; + return_value = sys_setdlopenflags_impl(module, flags); + +exit: + return return_value; +} + +static PyObject * +sys_setdlopenflags_impl(PyModuleDef *module, int flags) +/*[clinic end generated code: checksum=2a821e14ddd6643292beba377e513980b98816fb]*/ +{ PyThreadState *tstate = PyThreadState_GET(); - if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val)) - return NULL; if (!tstate) return NULL; - tstate->interp->dlopenflags = new_val; - Py_INCREF(Py_None); - return Py_None; + tstate->interp->dlopenflags = flags; + Py_RETURN_NONE; } -PyDoc_STRVAR(setdlopenflags_doc, -"setdlopenflags(n) -> None\n\ -\n\ -Set the flags used by the interpreter for dlopen calls, such as when the\n\ -interpreter loads extension modules. Among other things, this will enable\n\ -a lazy resolving of symbols when importing a module, if called as\n\ -sys.setdlopenflags(0). To share symbols across extension modules, call as\n\ -sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag modules\n\ -can be found in the os module (RTLD_xxx constants, e.g. os.RTLD_LAZY)."); + +/*[clinic input] +sys.getdlopenflags + +Return the current value of the flags that are used for dlopen calls. + +The flag constants are defined in the os module. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getdlopenflags__doc__, +"getdlopenflags()\n" +"Return the current value of the flags that are used for dlopen calls.\n" +"\n" +"The flag constants are defined in the os module."); + +#define SYS_GETDLOPENFLAGS_METHODDEF \ + {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, sys_getdlopenflags__doc__}, static PyObject * -sys_getdlopenflags(PyObject *self, PyObject *args) +sys_getdlopenflags_impl(PyModuleDef *module); + +static PyObject * +sys_getdlopenflags(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getdlopenflags_impl(module); + + return return_value; +} + +static PyObject * +sys_getdlopenflags_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=27abfaec6064a30560b11fd623d2495a671c4c17]*/ { PyThreadState *tstate = PyThreadState_GET(); if (!tstate) @@ -840,43 +1433,106 @@ sys_getdlopenflags(PyObject *self, PyObj return PyLong_FromLong(tstate->interp->dlopenflags); } -PyDoc_STRVAR(getdlopenflags_doc, -"getdlopenflags() -> int\n\ -\n\ -Return the current value of the flags that are used for dlopen calls.\n\ -The flag constants are defined in the os module."); - +#else +#define SYS_GETDLOPENFLAGS_METHODDEF +#define SYS_SETDLOPENFLAGS_METHODDEF #endif /* HAVE_DLOPEN */ + #ifdef USE_MALLOPT /* Link with -lmalloc (or -lmpc) on an SGI */ #include +/*[clinic input] +sys.mdebug + + flag: 'i' + / +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_mdebug__doc__, +"mdebug(flag)"); + +#define SYS_MDEBUG_METHODDEF \ + {"mdebug", (PyCFunction)sys_mdebug, METH_VARARGS, sys_mdebug__doc__}, + static PyObject * -sys_mdebug(PyObject *self, PyObject *args) +sys_mdebug_impl(PyModuleDef *module, int flag); + +static PyObject * +sys_mdebug(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int flag; - if (!PyArg_ParseTuple(args, "i:mdebug", &flag)) - return NULL; + + if (!PyArg_ParseTuple(args, + "i:mdebug", + &flag)) + goto exit; + return_value = sys_mdebug_impl(module, flag); + +exit: + return return_value; +} + +static PyObject * +sys_mdebug_impl(PyModuleDef *module, int flag) +/*[clinic end generated code: checksum=3b05d2e7cebec87ff3708d239b51fac960dfddcb]*/ +{ mallopt(M_DEBUG, flag); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } + +#else +#define SYS_MDEBUG_METHODDEF #endif /* USE_MALLOPT */ + +/*[clinic input] +sys.getsizeof + + object: 'O' + default: 'O' = NULL + +Return the size of object in bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getsizeof__doc__, +"getsizeof(object, default=None)\n" +"Return the size of object in bytes."); + +#define SYS_GETSIZEOF_METHODDEF \ + {"getsizeof", (PyCFunction)sys_getsizeof, METH_VARARGS|METH_KEYWORDS, sys_getsizeof__doc__}, + static PyObject * -sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) +sys_getsizeof_impl(PyModuleDef *module, PyObject *object, PyObject *default_value); + +static PyObject * +sys_getsizeof(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"object", "default", NULL}; + PyObject *object; + PyObject *default_value = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|O:getsizeof", _keywords, + &object, &default_value)) + goto exit; + return_value = sys_getsizeof_impl(module, object, default_value); + +exit: + return return_value; +} + +static PyObject * +sys_getsizeof_impl(PyModuleDef *module, PyObject *object, PyObject *default_value) +/*[clinic end generated code: checksum=50061680d59da82816905e962e99e8c0a82f4366]*/ { PyObject *res = NULL; static PyObject *gc_head_size = NULL; - static char *kwlist[] = {"object", "default", 0}; - PyObject *o, *dflt = NULL; PyObject *method; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", - kwlist, &o, &dflt)) - return NULL; - /* Initialize static variable for GC head size */ if (gc_head_size == NULL) { gc_head_size = PyLong_FromSsize_t(sizeof(PyGC_Head)); @@ -885,15 +1541,15 @@ sys_getsizeof(PyObject *self, PyObject * } /* Make sure the type is initialized. float gets initialized late */ - if (PyType_Ready(Py_TYPE(o)) < 0) + if (PyType_Ready(Py_TYPE(object)) < 0) return NULL; - method = _PyObject_LookupSpecial(o, &PyId___sizeof__); + method = _PyObject_LookupSpecial(object, &PyId___sizeof__); if (method == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, "Type %.100s doesn't define __sizeof__", - Py_TYPE(o)->tp_name); + Py_TYPE(object)->tp_name); } else { res = PyObject_CallFunctionObjArgs(method, NULL); @@ -901,18 +1557,18 @@ sys_getsizeof(PyObject *self, PyObject * } /* Has a default value been given */ - if ((res == NULL) && (dflt != NULL) && + if ((res == NULL) && (default_value != NULL) && PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Clear(); - Py_INCREF(dflt); - return dflt; + Py_INCREF(default_value); + return default_value; } else if (res == NULL) return res; /* add gc_head size */ - if (PyObject_IS_GC(o)) { + if (PyObject_IS_GC(object)) { PyObject *tmp = res; res = PyNumber_Add(tmp, gc_head_size); Py_DECREF(tmp); @@ -920,76 +1576,230 @@ sys_getsizeof(PyObject *self, PyObject * return res; } -PyDoc_STRVAR(getsizeof_doc, -"getsizeof(object, default) -> int\n\ -\n\ -Return the size of object in bytes."); + +/*[clinic input] +sys.getrefcount -> Py_ssize_t + + object: 'O' + / + +Return the reference count of object. + +The count returned is generally one higher than you might expect, +because it includes the (temporary) reference as an argument to +getrefcount(). +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getrefcount__doc__, +"getrefcount(object)\n" +"Return the reference count of object.\n" +"\n" +"The count returned is generally one higher than you might expect,\n" +"because it includes the (temporary) reference as an argument to\n" +"getrefcount()."); + +#define SYS_GETREFCOUNT_METHODDEF \ + {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, sys_getrefcount__doc__}, + +static Py_ssize_t +sys_getrefcount_impl(PyModuleDef *module, PyObject *object); static PyObject * -sys_getrefcount(PyObject *self, PyObject *arg) +sys_getrefcount(PyModuleDef *module, PyObject *object) { - return PyLong_FromSsize_t(arg->ob_refcnt); + PyObject *return_value = NULL; + Py_ssize_t _return_value; + _return_value = sys_getrefcount_impl(module, object); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; } +static Py_ssize_t +sys_getrefcount_impl(PyModuleDef *module, PyObject *object) +/*[clinic end generated code: checksum=b894517b5a2fffaba321eb2f830caa824337cca1]*/ +{ + return object->ob_refcnt; +} + + #ifdef Py_REF_DEBUG + +/*[clinic input] +sys.gettotalrefcount -> Py_ssize_t +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_gettotalrefcount__doc__, +"gettotalrefcount()"); + +#define SYS_GETTOTALREFCOUNT_METHODDEF \ + {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS, sys_gettotalrefcount__doc__}, + +static Py_ssize_t +sys_gettotalrefcount_impl(PyModuleDef *module); + static PyObject * -sys_gettotalrefcount(PyObject *self) +sys_gettotalrefcount(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - return PyLong_FromSsize_t(_Py_GetRefTotal()); + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = sys_gettotalrefcount_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; } + +static Py_ssize_t +sys_gettotalrefcount_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=e78428e76170509a7db754caee3ce21345efc486]*/ +{ + return _Py_GetRefTotal(); +} + +#else +#define SYS_GETTOTALREFCOUNT_METHODDEF #endif /* Py_REF_DEBUG */ -PyDoc_STRVAR(getrefcount_doc, -"getrefcount(object) -> integer\n\ -\n\ -Return the reference count of object. The count returned is generally\n\ -one higher than you might expect, because it includes the (temporary)\n\ -reference as an argument to getrefcount()." -); + +/*[clinic input] +sys.getallocatedblocks -> Py_ssize_t + +Return the number of memory blocks currently allocated, regardless of their size. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getallocatedblocks__doc__, +"getallocatedblocks()\n" +"Return the number of memory blocks currently allocated, regardless of their size."); + +#define SYS_GETALLOCATEDBLOCKS_METHODDEF \ + {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, sys_getallocatedblocks__doc__}, + +static Py_ssize_t +sys_getallocatedblocks_impl(PyModuleDef *module); static PyObject * -sys_getallocatedblocks(PyObject *self) +sys_getallocatedblocks(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - return PyLong_FromSsize_t(_Py_GetAllocatedBlocks()); + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = sys_getallocatedblocks_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; } -PyDoc_STRVAR(getallocatedblocks_doc, -"getallocatedblocks() -> integer\n\ -\n\ -Return the number of memory blocks currently allocated, regardless of their\n\ -size." -); +static Py_ssize_t +sys_getallocatedblocks_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=c0e3e1f0a67be5dc3526cf9db902dd96a701a5ec]*/ +{ + return _Py_GetAllocatedBlocks(); +} + #ifdef COUNT_ALLOCS + +/*[clinic input] +sys.getcounts +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_getcounts__doc__, +"getcounts()"); + +#define SYS_GETCOUNTS_METHODDEF \ + {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS, sys_getcounts__doc__}, + static PyObject * -sys_getcounts(PyObject *self) +sys_getcounts_impl(PyModuleDef *module); + +static PyObject * +sys_getcounts(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys_getcounts_impl(module); + + return return_value; +} + +static PyObject * +sys_getcounts_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=f2471715a0c89ec7adedf42f2afaed34fafce328]*/ { extern PyObject *get_counts(void); return get_counts(); } + +#else +#define SYS_GETCOUNTS_METHODDEF #endif -PyDoc_STRVAR(getframe_doc, -"_getframe([depth]) -> frameobject\n\ -\n\ -Return a frame object from the call stack. If optional integer depth is\n\ -given, return the frame object that many calls below the top of the stack.\n\ -If that is deeper than the call stack, ValueError is raised. The default\n\ -for depth is zero, returning the frame at the top of the call stack.\n\ -\n\ -This function should be used for internal and specialized\n\ -purposes only." -); + +/*[clinic input] +sys._getframe + + depth: int = -1 + / + +Return the top frame object from the call stack. + +If optional integer depth is positive, return the frame object that many +calls below the top of the stack. If that is deeper than the call stack, +ValueError is raised. The default for depth is zero, returning the frame +at the top of the call stack. + +This function should be used for internal and specialized purposes only. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys__getframe__doc__, +"_getframe(depth=-1)\n" +"Return the top frame object from the call stack.\n" +"\n" +"If optional integer depth is positive, return the frame object that many\n" +"calls below the top of the stack. If that is deeper than the call stack,\n" +"ValueError is raised. The default for depth is zero, returning the frame\n" +"at the top of the call stack.\n" +"\n" +"This function should be used for internal and specialized purposes only."); + +#define SYS__GETFRAME_METHODDEF \ + {"_getframe", (PyCFunction)sys__getframe, METH_VARARGS, sys__getframe__doc__}, static PyObject * -sys_getframe(PyObject *self, PyObject *args) +sys__getframe_impl(PyModuleDef *module, int depth); + +static PyObject * +sys__getframe(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int depth = -1; + + if (!PyArg_ParseTuple(args, + "|i:_getframe", + &depth)) + goto exit; + return_value = sys__getframe_impl(module, depth); + +exit: + return return_value; +} + +static PyObject * +sys__getframe_impl(PyModuleDef *module, int depth) +/*[clinic end generated code: checksum=bca42ebbeffde02de5df4478f13ce2265893d205]*/ { PyFrameObject *f = PyThreadState_GET()->frame; - int depth = -1; - - if (!PyArg_ParseTuple(args, "|i:_getframe", &depth)) - return NULL; while (depth > 0 && f != NULL) { f = f->f_back; @@ -1001,41 +1811,199 @@ sys_getframe(PyObject *self, PyObject *a return NULL; } Py_INCREF(f); - return (PyObject*)f; + return (PyObject *)f; } -PyDoc_STRVAR(current_frames_doc, -"_current_frames() -> dictionary\n\ -\n\ -Return a dictionary mapping each current thread T's thread id to T's\n\ -current stack frame.\n\ -\n\ -This function should be used for specialized purposes only." -); + +/*[clinic input] +sys._current_frames + +Return a dictionary mapping each current thread T's thread id to T's current stack frame. + +This function should be used for internal and specialized purposes only. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys__current_frames__doc__, +"_current_frames()\n" +"Return a dictionary mapping each current thread T\'s thread id to T\'s current stack frame.\n" +"\n" +"This function should be used for internal and specialized purposes only."); + +#define SYS__CURRENT_FRAMES_METHODDEF \ + {"_current_frames", (PyCFunction)sys__current_frames, METH_NOARGS, sys__current_frames__doc__}, static PyObject * -sys_current_frames(PyObject *self, PyObject *noargs) +sys__current_frames_impl(PyModuleDef *module); + +static PyObject * +sys__current_frames(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys__current_frames_impl(module); + + return return_value; +} + +static PyObject * +sys__current_frames_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=a13ad66ed50952ac562c47daada573758d6c1e3d]*/ { return _PyThread_CurrentFrames(); } -PyDoc_STRVAR(call_tracing_doc, -"call_tracing(func, args) -> object\n\ -\n\ -Call func(*args), while tracing is enabled. The tracing state is\n\ -saved, and restored afterwards. This is intended to be called from\n\ -a debugger from a checkpoint, to recursively debug some other code." -); + +/*[clinic input] +sys.call_tracing + + func: 'O' + args: object(subclass_of='&PyTuple_Type') + / + +Call func(*args), while tracing is enabled. + +The tracing state is saved, and restored afterwards. +This is intended to be called from a debugger from a checkpoint, +to recursively debug some other code. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_call_tracing__doc__, +"call_tracing(func, args)\n" +"Call func(*args), while tracing is enabled.\n" +"\n" +"The tracing state is saved, and restored afterwards.\n" +"This is intended to be called from a debugger from a checkpoint,\n" +"to recursively debug some other code."); + +#define SYS_CALL_TRACING_METHODDEF \ + {"call_tracing", (PyCFunction)sys_call_tracing, METH_VARARGS, sys_call_tracing__doc__}, static PyObject * -sys_call_tracing(PyObject *self, PyObject *args) +sys_call_tracing_impl(PyModuleDef *module, PyObject *func, PyObject *args_value); + +static PyObject * +sys_call_tracing(PyModuleDef *module, PyObject *args) { - PyObject *func, *funcargs; - if (!PyArg_ParseTuple(args, "OO!:call_tracing", &func, &PyTuple_Type, &funcargs)) - return NULL; - return _PyEval_CallTracing(func, funcargs); + PyObject *return_value = NULL; + PyObject *func; + PyObject *args_value; + + if (!PyArg_ParseTuple(args, + "OO!:call_tracing", + &func, &PyTuple_Type, &args_value)) + goto exit; + return_value = sys_call_tracing_impl(module, func, args_value); + +exit: + return return_value; } +static PyObject * +sys_call_tracing_impl(PyModuleDef *module, PyObject *func, PyObject *args_value) +/*[clinic end generated code: checksum=c60115329f78c461dcf2e863a9dcdb39682e79a6]*/ +{ + return _PyEval_CallTracing(func, args_value); +} + + +#ifdef __cplusplus +extern "C" { +#endif + +/*[clinic input] +sys._debugmallocstats + +Print summary info to stderr about the state of pymalloc's structures. + +In Py_DEBUG mode, also perform some expensive internal consistency checks. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys__debugmallocstats__doc__, +"_debugmallocstats()\n" +"Print summary info to stderr about the state of pymalloc\'s structures.\n" +"\n" +"In Py_DEBUG mode, also perform some expensive internal consistency checks."); + +#define SYS__DEBUGMALLOCSTATS_METHODDEF \ + {"_debugmallocstats", (PyCFunction)sys__debugmallocstats, METH_NOARGS, sys__debugmallocstats__doc__}, + +static PyObject * +sys__debugmallocstats_impl(PyModuleDef *module); + +static PyObject * +sys__debugmallocstats(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys__debugmallocstats_impl(module); + + return return_value; +} + +static PyObject * +sys__debugmallocstats_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=6d8e6012034d63e22df22afea773a3b4d3f8f3bb]*/ +{ +#ifdef WITH_PYMALLOC + _PyObject_DebugMallocStats(stderr); + fputc('\n', stderr); +#endif + _PyObject_DebugTypeStats(stderr); + + Py_RETURN_NONE; +} + + +#ifdef Py_TRACE_REFS +/* Defined in objects.c because it uses static globals if that file */ +extern PyObject *_Py_GetObjects(PyObject *, PyObject *); +#endif + +#ifdef DYNAMIC_EXECUTION_PROFILE +/* Defined in ceval.c because it uses static globals if that file */ +extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); +#endif + +#ifdef __cplusplus +} +#endif + + +/*[clinic input] +sys._clear_type_cache + +Clear the internal type lookup cache. +[clinic start generated code]*/ + +PyDoc_STRVAR(sys__clear_type_cache__doc__, +"_clear_type_cache()\n" +"Clear the internal type lookup cache."); + +#define SYS__CLEAR_TYPE_CACHE_METHODDEF \ + {"_clear_type_cache", (PyCFunction)sys__clear_type_cache, METH_NOARGS, sys__clear_type_cache__doc__}, + +static PyObject * +sys__clear_type_cache_impl(PyModuleDef *module); + +static PyObject * +sys__clear_type_cache(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = sys__clear_type_cache_impl(module); + + return return_value; +} + +static PyObject * +sys__clear_type_cache_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=7eeffc28102bd953bddb1861c744b331bffabfbc]*/ +{ + PyType_ClearCache(); + Py_RETURN_NONE; +} + + PyDoc_STRVAR(callstats_doc, "callstats() -> tuple of integers\n\ \n\ @@ -1059,131 +2027,49 @@ 9. All other calls\n\ 10. Number of stack pops performed by call_function()" ); -#ifdef __cplusplus -extern "C" { -#endif - -static PyObject * -sys_debugmallocstats(PyObject *self, PyObject *args) -{ -#ifdef WITH_PYMALLOC - _PyObject_DebugMallocStats(stderr); - fputc('\n', stderr); -#endif - _PyObject_DebugTypeStats(stderr); - - Py_RETURN_NONE; -} -PyDoc_STRVAR(debugmallocstats_doc, -"_debugmallocstats()\n\ -\n\ -Print summary info to stderr about the state of\n\ -pymalloc's structures.\n\ -\n\ -In Py_DEBUG mode, also perform some expensive internal consistency\n\ -checks.\n\ -"); - -#ifdef Py_TRACE_REFS -/* Defined in objects.c because it uses static globals if that file */ -extern PyObject *_Py_GetObjects(PyObject *, PyObject *); -#endif - -#ifdef DYNAMIC_EXECUTION_PROFILE -/* Defined in ceval.c because it uses static globals if that file */ -extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); -#endif - -#ifdef __cplusplus -} -#endif - -static PyObject * -sys_clear_type_cache(PyObject* self, PyObject* args) -{ - PyType_ClearCache(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(sys_clear_type_cache__doc__, -"_clear_type_cache() -> None\n\ -Clear the internal type lookup cache."); - static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS, callstats_doc}, - {"_clear_type_cache", sys_clear_type_cache, METH_NOARGS, - sys_clear_type_cache__doc__}, - {"_current_frames", sys_current_frames, METH_NOARGS, - current_frames_doc}, - {"displayhook", sys_displayhook, METH_O, displayhook_doc}, - {"exc_info", sys_exc_info, METH_NOARGS, exc_info_doc}, - {"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc}, - {"exit", sys_exit, METH_VARARGS, exit_doc}, - {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, - METH_NOARGS, getdefaultencoding_doc}, -#ifdef HAVE_DLOPEN - {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, - getdlopenflags_doc}, -#endif - {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, - getallocatedblocks_doc}, -#ifdef COUNT_ALLOCS - {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS}, -#endif + SYS__CLEAR_TYPE_CACHE_METHODDEF + SYS__CURRENT_FRAMES_METHODDEF + SYS_DISPLAYHOOK_METHODDEF + SYS_EXC_INFO_METHODDEF + SYS_EXCEPTHOOK_METHODDEF + SYS_EXIT_METHODDEF + SYS_GETDEFAULTENCODING_METHODDEF + SYS_GETFILESYSTEMENCODING_METHODDEF + SYS_GETDLOPENFLAGS_METHODDEF + SYS_GETALLOCATEDBLOCKS_METHODDEF + SYS_GETCOUNTS_METHODDEF #ifdef DYNAMIC_EXECUTION_PROFILE {"getdxp", _Py_GetDXProfile, METH_VARARGS}, #endif - {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, - METH_NOARGS, getfilesystemencoding_doc}, #ifdef Py_TRACE_REFS {"getobjects", _Py_GetObjects, METH_VARARGS}, #endif -#ifdef Py_REF_DEBUG - {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS}, -#endif - {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, getrefcount_doc}, - {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, - getrecursionlimit_doc}, - {"getsizeof", (PyCFunction)sys_getsizeof, - METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, - {"_getframe", sys_getframe, METH_VARARGS, getframe_doc}, -#ifdef MS_WINDOWS - {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS, - getwindowsversion_doc}, -#endif /* MS_WINDOWS */ - {"intern", sys_intern, METH_VARARGS, intern_doc}, -#ifdef USE_MALLOPT - {"mdebug", sys_mdebug, METH_VARARGS}, -#endif - {"setcheckinterval", sys_setcheckinterval, METH_VARARGS, - setcheckinterval_doc}, - {"getcheckinterval", sys_getcheckinterval, METH_NOARGS, - getcheckinterval_doc}, -#ifdef WITH_THREAD - {"setswitchinterval", sys_setswitchinterval, METH_VARARGS, - setswitchinterval_doc}, - {"getswitchinterval", sys_getswitchinterval, METH_NOARGS, - getswitchinterval_doc}, -#endif -#ifdef HAVE_DLOPEN - {"setdlopenflags", sys_setdlopenflags, METH_VARARGS, - setdlopenflags_doc}, -#endif - {"setprofile", sys_setprofile, METH_O, setprofile_doc}, - {"getprofile", sys_getprofile, METH_NOARGS, getprofile_doc}, - {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS, - setrecursionlimit_doc}, -#ifdef WITH_TSC - {"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc}, -#endif - {"settrace", sys_settrace, METH_O, settrace_doc}, - {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc}, - {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, - {"_debugmallocstats", sys_debugmallocstats, METH_NOARGS, - debugmallocstats_doc}, + SYS_GETTOTALREFCOUNT_METHODDEF + SYS_GETREFCOUNT_METHODDEF + SYS_GETRECURSIONLIMIT_METHODDEF + SYS_GETSIZEOF_METHODDEF + SYS__GETFRAME_METHODDEF + SYS_GETWINDOWSVERSION_METHODDEF + SYS_INTERN_METHODDEF + SYS_MDEBUG_METHODDEF + SYS_SETCHECKINTERVAL_METHODDEF + SYS_GETCHECKINTERVAL_METHODDEF + SYS_SETSWITCHINTERVAL_METHODDEF + SYS_GETSWITCHINTERVAL_METHODDEF + SYS_SETDLOPENFLAGS_METHODDEF + SYS_SETPROFILE_METHODDEF + SYS_GETPROFILE_METHODDEF + SYS_SETRECURSIONLIMIT_METHODDEF + SYS_SETTSCDUMP_METHODDEF + SYS_SETTRACE_METHODDEF + SYS_GETTRACE_METHODDEF + SYS_CALL_TRACING_METHODDEF + SYS__DEBUGMALLOCSTATS_METHODDEF {NULL, NULL} /* sentinel */ };