diff options
author | Dino Viehland <dinoviehland@gmail.com> | 2019-09-14 14:20:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-14 14:20:27 (GMT) |
commit | f919054e539a5c1afde1b31c9fd7a8f5b2313311 (patch) | |
tree | a33e0c84afbaaab56ac7f3c1cd4e13b53faf4424 | |
parent | 0247e80f3c529900689425676342cb70ea31a13d (diff) | |
download | cpython-f919054e539a5c1afde1b31c9fd7a8f5b2313311.zip cpython-f919054e539a5c1afde1b31c9fd7a8f5b2313311.tar.gz cpython-f919054e539a5c1afde1b31c9fd7a8f5b2313311.tar.bz2 |
bpo-38116: Convert select module to PEP-384 (#15971)
* Convert select module to PEP-384
Summary: Do the necessary versions to be Pyro-compatible, including migrating `PyType_Ready` to `PyType_FromSpec` and moving static data into a new `_selectstate` struct.
* 📜🤖 Added by blurb_it.
* Fixup Mac OS/X build
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116.KDwmwt.rst | 1 | ||||
-rw-r--r-- | Modules/clinic/selectmodule.c.h | 6 | ||||
-rw-r--r-- | Modules/selectmodule.c | 449 |
3 files changed, 211 insertions, 245 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116.KDwmwt.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116.KDwmwt.rst new file mode 100644 index 0000000..d6d630b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116.KDwmwt.rst @@ -0,0 +1 @@ +The select module is now PEP-384 compliant and no longer has static state
\ No newline at end of file diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 9015816..670af6a 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -959,11 +959,11 @@ select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - if ((type == &kqueue_queue_Type) && + if ((type == _selectstate_global->kqueue_queue_Type) && !_PyArg_NoPositional("kqueue", args)) { goto exit; } - if ((type == &kqueue_queue_Type) && + if ((type == _selectstate_global->kqueue_queue_Type) && !_PyArg_NoKeywords("kqueue", kwargs)) { goto exit; } @@ -1215,4 +1215,4 @@ exit: #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=03041f3d09b04a3d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=26bb05e5fba2bfd1 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 2e06a89..98da7d5 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -58,14 +58,28 @@ extern void bzero(void *, int); # define SOCKET int #endif +typedef struct { + PyObject *close; + PyTypeObject *poll_Type; + PyTypeObject *devpoll_Type; + PyTypeObject *pyEpoll_Type; + PyTypeObject *kqueue_event_Type; + PyTypeObject *kqueue_queue_Type; +} _selectstate; + +static struct PyModuleDef selectmodule; + +#define _selectstate(o) ((_selectstate *)PyModule_GetState(o)) +#define _selectstate_global _selectstate(PyState_FindModule(&selectmodule)) + /*[clinic input] module select class select.poll "pollObject *" "&poll_Type" class select.devpoll "devpollObject *" "&devpoll_Type" class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" -class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" +class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/ static int fildes_converter(PyObject *o, void *p) @@ -400,8 +414,6 @@ typedef struct { int poll_running; } pollObject; -static PyTypeObject poll_Type; - /* Update the malloc'ed array of pollfds to match the dictionary contained within a pollObject. Return 1 on success, 0 on an error. */ @@ -709,7 +721,7 @@ static pollObject * newPollObject(void) { pollObject *self; - self = PyObject_New(pollObject, &poll_Type); + self = PyObject_New(pollObject, _selectstate_global->poll_Type); if (self == NULL) return NULL; /* ufd_uptodate is a Boolean, denoting whether the @@ -725,13 +737,22 @@ newPollObject(void) return self; } +static PyObject * +poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type)); + return NULL; +} + static void poll_dealloc(pollObject *self) { + PyObject* type = (PyObject *)Py_TYPE(self); if (self->ufds != NULL) PyMem_DEL(self->ufds); Py_XDECREF(self->dict); PyObject_Del(self); + Py_DECREF(type); } @@ -744,8 +765,6 @@ typedef struct { struct pollfd *fds; } devpollObject; -static PyTypeObject devpoll_Type; - static PyObject * devpoll_err_closed(void) { @@ -1091,7 +1110,7 @@ newDevPollObject(void) return NULL; } - self = PyObject_New(devpollObject, &devpoll_Type); + self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type); if (self == NULL) { close(fd_devpoll); PyMem_DEL(fds); @@ -1105,14 +1124,39 @@ newDevPollObject(void) return self; } +static PyObject * +devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type)); + return NULL; +} + static void devpoll_dealloc(devpollObject *self) { + PyObject *type = (PyObject *)Py_TYPE(self); (void)devpoll_internal_close(self); PyMem_DEL(self->fds); PyObject_Del(self); + Py_DECREF(type); } +static PyType_Slot devpoll_Type_slots[] = { + {Py_tp_dealloc, devpoll_dealloc}, + {Py_tp_getset, devpoll_getsetlist}, + {Py_tp_methods, devpoll_methods}, + {Py_tp_new, devpoll_new}, + {0, 0}, +}; + +static PyType_Spec devpoll_Type_spec = { + "select.devpoll", + sizeof(devpollObject), + 0, + Py_TPFLAGS_DEFAULT, + devpoll_Type_slots +}; + #endif /* HAVE_SYS_DEVPOLL_H */ @@ -1201,8 +1245,7 @@ typedef struct { SOCKET epfd; /* epoll control file descriptor */ } pyEpoll_Object; -static PyTypeObject pyEpoll_Type; -#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type)) +#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type)) static PyObject * pyepoll_err_closed(void) @@ -1230,9 +1273,10 @@ static PyObject * newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) { pyEpoll_Object *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (pyEpoll_Object *) type->tp_alloc(type, 0); + assert(type != NULL); + allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc); + assert(epoll_alloc != NULL); + self = (pyEpoll_Object *) epoll_alloc(type, 0); if (self == NULL) return NULL; @@ -1307,8 +1351,11 @@ select_epoll_impl(PyTypeObject *type, int sizehint, int flags) static void pyepoll_dealloc(pyEpoll_Object *self) { + PyTypeObject* type = Py_TYPE(self); (void)pyepoll_internal_close(self); - Py_TYPE(self)->tp_free(self); + freefunc epoll_free = PyType_GetSlot(type, Py_tp_free); + epoll_free((PyObject *)self); + Py_DECREF((PyObject *)type); } /*[clinic input] @@ -1632,9 +1679,7 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb) /*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/ { - _Py_IDENTIFIER(close); - - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_close); + return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL); } static PyGetSetDef pyepoll_getsetlist[] = { @@ -1643,6 +1688,15 @@ 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."); + #endif /* HAVE_EPOLL */ #ifdef HAVE_KQUEUE @@ -1699,18 +1753,14 @@ typedef struct { struct kevent e; } kqueue_event_Object; -static PyTypeObject kqueue_event_Type; - -#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type)) +#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type)) typedef struct { PyObject_HEAD SOCKET kqfd; /* kqueue control fd */ } kqueue_queue_Object; -static PyTypeObject kqueue_queue_Type; - -#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type)) +#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type)) #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) # error uintptr_t does not match void *! @@ -1870,6 +1920,24 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, Py_RETURN_RICHCOMPARE(result, 0, op); } +static PyType_Slot kqueue_event_Type_slots[] = { + {Py_tp_doc, (void*)kqueue_event_doc}, + {Py_tp_init, kqueue_event_init}, + {Py_tp_members, kqueue_event_members}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_repr, kqueue_event_repr}, + {Py_tp_richcompare, kqueue_event_richcompare}, + {0, 0}, +}; + +static PyType_Spec kqueue_event_Type_spec = { + "select.kevent", + sizeof(kqueue_event_Object), + 0, + Py_TPFLAGS_DEFAULT, + kqueue_event_Type_slots +}; + static PyObject * kqueue_queue_err_closed(void) { @@ -1896,8 +1964,10 @@ static PyObject * newKqueue_Object(PyTypeObject *type, SOCKET fd) { kqueue_queue_Object *self; - assert(type != NULL && type->tp_alloc != NULL); - self = (kqueue_queue_Object *) type->tp_alloc(type, 0); + assert(type != NULL); + allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc); + assert(queue_alloc != NULL); + self = (kqueue_queue_Object *) queue_alloc(type, 0); if (self == NULL) { return NULL; } @@ -1954,8 +2024,11 @@ select_kqueue_impl(PyTypeObject *type) static void kqueue_queue_dealloc(kqueue_queue_Object *self) { + PyTypeObject* type = Py_TYPE(self); kqueue_queue_internal_close(self); - Py_TYPE(self)->tp_free(self); + freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free); + kqueue_free((PyObject *)self); + Py_DECREF((PyObject *)type); } /*[clinic input] @@ -2072,7 +2145,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, PyErr_Format(PyExc_TypeError, "timeout argument must be a number " "or None, got %.200s", - Py_TYPE(otimeout)->tp_name); + _PyType_Name(Py_TYPE(otimeout))); return NULL; } @@ -2168,7 +2241,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, for (i = 0; i < gotevents; i++) { kqueue_event_Object *ch; - ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type); + ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type); if (ch == NULL) { goto error; } @@ -2210,38 +2283,20 @@ static PyMethodDef poll_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject poll_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "select.poll", /*tp_name*/ - sizeof(pollObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)poll_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - poll_methods, /*tp_methods*/ + +static PyType_Slot poll_Type_slots[] = { + {Py_tp_dealloc, poll_dealloc}, + {Py_tp_methods, poll_methods}, + {Py_tp_new, poll_new}, + {0, 0}, +}; + +static PyType_Spec poll_Type_spec = { + "select.poll", + sizeof(pollObject), + 0, + Py_TPFLAGS_DEFAULT, + poll_Type_slots }; #ifdef HAVE_SYS_DEVPOLL_H @@ -2256,42 +2311,6 @@ static PyMethodDef devpoll_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject devpoll_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "select.devpoll", /*tp_name*/ - sizeof(devpollObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)devpoll_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - devpoll_methods, /*tp_methods*/ - 0, /* tp_members */ - devpoll_getsetlist, /* tp_getset */ -}; - #endif /* HAVE_SYS_DEVPOLL_H */ #endif /* HAVE_POLL */ @@ -2311,94 +2330,28 @@ static PyMethodDef pyepoll_methods[] = { {NULL, NULL}, }; -static PyTypeObject pyEpoll_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "select.epoll", /* tp_name */ - sizeof(pyEpoll_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pyepoll_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - select_epoll__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pyepoll_methods, /* tp_methods */ - 0, /* tp_members */ - pyepoll_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - select_epoll, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot pyEpoll_Type_slots[] = { + {Py_tp_dealloc, pyepoll_dealloc}, + {Py_tp_doc, (void*)pyepoll_doc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_getset, pyepoll_getsetlist}, + {Py_tp_methods, pyepoll_methods}, + {Py_tp_new, select_epoll}, + {0, 0}, +}; + +static PyType_Spec pyEpoll_Type_spec = { + "select.epoll", + sizeof(pyEpoll_Object), + 0, + Py_TPFLAGS_DEFAULT, + pyEpoll_Type_slots }; #endif /* HAVE_EPOLL */ #ifdef HAVE_KQUEUE -static PyTypeObject kqueue_event_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "select.kevent", /* tp_name */ - sizeof(kqueue_event_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)kqueue_event_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - kqueue_event_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - kqueue_event_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)kqueue_event_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ -}; - static PyMethodDef kqueue_queue_methods[] = { SELECT_KQUEUE_FROMFD_METHODDEF SELECT_KQUEUE_CLOSE_METHODDEF @@ -2407,46 +2360,21 @@ static PyMethodDef kqueue_queue_methods[] = { {NULL, NULL}, }; -static PyTypeObject kqueue_queue_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "select.kqueue", /* tp_name */ - sizeof(kqueue_queue_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)kqueue_queue_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - select_kqueue__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - kqueue_queue_methods, /* tp_methods */ - 0, /* tp_members */ - kqueue_queue_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - select_kqueue, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot kqueue_queue_Type_slots[] = { + {Py_tp_dealloc, kqueue_queue_dealloc}, + {Py_tp_doc, select_kqueue__doc__}, + {Py_tp_getset, kqueue_queue_getsetlist}, + {Py_tp_methods, kqueue_queue_methods}, + {Py_tp_new, select_kqueue}, + {0, 0}, +}; + +static PyType_Spec kqueue_queue_Type_spec = { + "select.kqueue", + sizeof(kqueue_queue_Object), + 0, + Py_TPFLAGS_DEFAULT, + kqueue_queue_Type_slots }; #endif /* HAVE_KQUEUE */ @@ -2472,21 +2400,49 @@ PyDoc_STRVAR(module_doc, On Windows, only sockets are supported; on Unix, all file descriptors."); + +static int +_select_traverse(PyObject *module, visitproc visit, void *arg) +{ + Py_VISIT(_selectstate(module)->close); + Py_VISIT(_selectstate(module)->poll_Type); + Py_VISIT(_selectstate(module)->devpoll_Type); + Py_VISIT(_selectstate(module)->pyEpoll_Type); + Py_VISIT(_selectstate(module)->kqueue_event_Type); + Py_VISIT(_selectstate(module)->kqueue_queue_Type); + return 0; +} + +static int +_select_clear(PyObject *module) +{ + Py_CLEAR(_selectstate(module)->close); + Py_CLEAR(_selectstate(module)->poll_Type); + Py_CLEAR(_selectstate(module)->devpoll_Type); + Py_CLEAR(_selectstate(module)->pyEpoll_Type); + Py_CLEAR(_selectstate(module)->kqueue_event_Type); + Py_CLEAR(_selectstate(module)->kqueue_queue_Type); + return 0; +} + +static void +_select_free(void *module) +{ + _select_clear((PyObject *)module); +} + static struct PyModuleDef selectmodule = { PyModuleDef_HEAD_INIT, "select", module_doc, - -1, + sizeof(_selectstate), select_methods, NULL, - NULL, - NULL, - NULL + _select_traverse, + _select_clear, + _select_free, }; - - - PyMODINIT_FUNC PyInit_select(void) { @@ -2495,6 +2451,8 @@ PyInit_select(void) if (m == NULL) return NULL; + _selectstate(m)->close = PyUnicode_InternFromString("close"); + Py_INCREF(PyExc_OSError); PyModule_AddObject(m, "error", PyExc_OSError); @@ -2516,8 +2474,12 @@ PyInit_select(void) #else { #endif - if (PyType_Ready(&poll_Type) < 0) + PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec); + if (poll_Type == NULL) return NULL; + _selectstate(m)->poll_Type = (PyTypeObject *)poll_Type; + Py_INCREF(poll_Type); + PyModule_AddIntMacro(m, POLLIN); PyModule_AddIntMacro(m, POLLPRI); PyModule_AddIntMacro(m, POLLOUT); @@ -2548,17 +2510,20 @@ PyInit_select(void) #endif /* HAVE_POLL */ #ifdef HAVE_SYS_DEVPOLL_H - if (PyType_Ready(&devpoll_Type) < 0) + PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec); + if (devpoll_Type == NULL) return NULL; + _selectstate(m)->devpoll_Type = (PyTypeObject *)devpoll_Type; + Py_INCREF(devpoll_Type); #endif #ifdef HAVE_EPOLL - Py_TYPE(&pyEpoll_Type) = &PyType_Type; - if (PyType_Ready(&pyEpoll_Type) < 0) + PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec); + if (pyEpoll_Type == NULL) return NULL; - - Py_INCREF(&pyEpoll_Type); - PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type); + _selectstate(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type; + Py_INCREF(pyEpoll_Type); + PyModule_AddObject(m, "epoll", (PyObject *)_selectstate(m)->pyEpoll_Type); PyModule_AddIntMacro(m, EPOLLIN); PyModule_AddIntMacro(m, EPOLLOUT); @@ -2600,19 +2565,19 @@ PyInit_select(void) #endif /* HAVE_EPOLL */ #ifdef HAVE_KQUEUE - kqueue_event_Type.tp_new = PyType_GenericNew; - Py_TYPE(&kqueue_event_Type) = &PyType_Type; - if(PyType_Ready(&kqueue_event_Type) < 0) + PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec); + if (kqueue_event_Type == NULL) return NULL; + _selectstate(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type; + Py_INCREF(_selectstate(m)->kqueue_event_Type); + PyModule_AddObject(m, "kevent", kqueue_event_Type); - Py_INCREF(&kqueue_event_Type); - PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type); - - Py_TYPE(&kqueue_queue_Type) = &PyType_Type; - if(PyType_Ready(&kqueue_queue_Type) < 0) + PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec); + if (kqueue_queue_Type == NULL) return NULL; - Py_INCREF(&kqueue_queue_Type); - PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type); + _selectstate(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type; + Py_INCREF(_selectstate(m)->kqueue_queue_Type); + PyModule_AddObject(m, "kqueue", kqueue_queue_Type); /* event filters */ PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); |