[Python-checkins] bpo-1635741: Port select module to multiphase init (GH-23409)

tiran webhook-mailer at python.org
Sat Nov 21 14:29:30 EST 2020


https://github.com/python/cpython/commit/ea97ebab3578a6e0bb505da96819ac44d422a6cb
commit: ea97ebab3578a6e0bb505da96819ac44d422a6cb
branch: master
author: Christian Heimes <christian at python.org>
committer: tiran <christian at python.org>
date: 2020-11-21T20:29:26+01:00
summary:

bpo-1635741: Port select module to multiphase init (GH-23409)

files:
A Misc/NEWS.d/next/C API/2020-11-19-17-44-36.bpo-1635741.qBZc3o.rst
M Modules/clinic/selectmodule.c.h
M Modules/selectmodule.c

diff --git a/Misc/NEWS.d/next/C API/2020-11-19-17-44-36.bpo-1635741.qBZc3o.rst b/Misc/NEWS.d/next/C API/2020-11-19-17-44-36.bpo-1635741.qBZc3o.rst
new file mode 100644
index 0000000000000..e66e8d7e40626
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-11-19-17-44-36.bpo-1635741.qBZc3o.rst	
@@ -0,0 +1,2 @@
+Port :mod:`select` extension module to multiphase initialization
+(:pep:`489`).
diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h
index 00a78c48477b4..d7095dfb00ead 100644
--- a/Modules/clinic/selectmodule.c.h
+++ b/Modules/clinic/selectmodule.c.h
@@ -933,11 +933,11 @@ select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
     PyObject *return_value = NULL;
 
-    if ((type == _selectstate_global->kqueue_queue_Type) &&
+    if ((type == _selectstate_by_type(type)->kqueue_queue_Type) &&
         !_PyArg_NoPositional("kqueue", args)) {
         goto exit;
     }
-    if ((type == _selectstate_global->kqueue_queue_Type) &&
+    if ((type == _selectstate_by_type(type)->kqueue_queue_Type) &&
         !_PyArg_NoKeywords("kqueue", kwargs)) {
         goto exit;
     }
@@ -1179,4 +1179,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize
 #ifndef SELECT_KQUEUE_CONTROL_METHODDEF
     #define SELECT_KQUEUE_CONTROL_METHODDEF
 #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */
-/*[clinic end generated code: output=162f4f4efa850416 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=cd2062a787e13b35 input=a9049054013a1b77]*/
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index d02e3905f57e5..693a833caea77 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -77,16 +77,16 @@ get_select_state(PyObject *module)
     return (_selectstate *)state;
 }
 
-#define _selectstate_global get_select_state(PyState_FindModule(&selectmodule))
+#define _selectstate_by_type(type) get_select_state(PyType_GetModule(type))
 
 /*[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 *" "_selectstate_global->kqueue_queue_Type"
+class select.poll "pollObject *" "_selectstate_by_type(type)->poll_Type"
+class select.devpoll "devpollObject *" "_selectstate_by_type(type)->devpoll_Type"
+class select.epoll "pyEpoll_Object *" "_selectstate_by_type(type)->pyEpoll_Type"
+class select.kqueue "kqueue_queue_Object *" "_selectstate_by_type(type)->kqueue_queue_Type"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8072de35824aa327]*/
 
 /* list of Python objects and their file descriptor */
 typedef struct {
@@ -709,10 +709,10 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
 }
 
 static pollObject *
-newPollObject(void)
+newPollObject(PyObject *module)
 {
     pollObject *self;
-    self = PyObject_New(pollObject, _selectstate_global->poll_Type);
+    self = PyObject_New(pollObject, get_select_state(module)->poll_Type);
     if (self == NULL)
         return NULL;
     /* ufd_uptodate is a Boolean, denoting whether the
@@ -1073,7 +1073,7 @@ static PyGetSetDef devpoll_getsetlist[] = {
 };
 
 static devpollObject *
-newDevPollObject(void)
+newDevPollObject(PyObject *module)
 {
     devpollObject *self;
     int fd_devpoll, limit_result;
@@ -1103,7 +1103,7 @@ newDevPollObject(void)
         return NULL;
     }
 
-    self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
+    self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type);
     if (self == NULL) {
         close(fd_devpoll);
         PyMem_DEL(fds);
@@ -1166,7 +1166,7 @@ static PyObject *
 select_poll_impl(PyObject *module)
 /*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
 {
-    return (PyObject *)newPollObject();
+    return (PyObject *)newPollObject(module);
 }
 
 #ifdef HAVE_SYS_DEVPOLL_H
@@ -1184,7 +1184,7 @@ static PyObject *
 select_devpoll_impl(PyObject *module)
 /*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
 {
-    return (PyObject *)newDevPollObject();
+    return (PyObject *)newDevPollObject(module);
 }
 #endif
 
@@ -1238,8 +1238,6 @@ typedef struct {
     SOCKET epfd;                        /* epoll control file descriptor */
 } pyEpoll_Object;
 
-#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
-
 static PyObject *
 pyepoll_err_closed(void)
 {
@@ -1667,7 +1665,8 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
                            PyObject *exc_value, PyObject *exc_tb)
 /*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
 {
-    return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
+    _selectstate *state = _selectstate_by_type(Py_TYPE(self));
+    return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL);
 }
 
 static PyGetSetDef pyepoll_getsetlist[] = {
@@ -1741,15 +1740,13 @@ typedef struct {
     struct kevent e;
 } kqueue_event_Object;
 
-#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
+#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
 
 typedef struct {
     PyObject_HEAD
     SOCKET kqfd;                /* kqueue control fd */
 } kqueue_queue_Object;
 
-#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 *!
 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
@@ -1890,8 +1887,9 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
                          int op)
 {
     int result;
+    _selectstate *state = _selectstate_by_type(Py_TYPE(s));
 
-    if (!kqueue_event_Check(o)) {
+    if (!kqueue_event_Check(o, state)) {
         Py_RETURN_NOTIMPLEMENTED;
     }
 
@@ -2113,6 +2111,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
     struct timespec timeoutspec;
     struct timespec *ptimeoutspec;
     _PyTime_t timeout, deadline = 0;
+    _selectstate *state = _selectstate_by_type(Py_TYPE(self));
 
     if (self->kqfd < 0)
         return kqueue_queue_err_closed();
@@ -2165,9 +2164,10 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
             PyErr_NoMemory();
             goto error;
         }
+        _selectstate *state = _selectstate_by_type(Py_TYPE(self));
         for (i = 0; i < nchanges; ++i) {
             ei = PySequence_Fast_GET_ITEM(seq, i);
-            if (!kqueue_event_Check(ei)) {
+            if (!kqueue_event_Check(ei, state)) {
                 PyErr_SetString(PyExc_TypeError,
                     "changelist must be an iterable of "
                     "select.kevent objects");
@@ -2229,7 +2229,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, _selectstate_global->kqueue_event_Type);
+        ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type);
         if (ch == NULL) {
             goto error;
         }
@@ -2392,24 +2392,28 @@ On Windows, only sockets are supported; on Unix, all file descriptors.");
 static int
 _select_traverse(PyObject *module, visitproc visit, void *arg)
 {
-    Py_VISIT(get_select_state(module)->close);
-    Py_VISIT(get_select_state(module)->poll_Type);
-    Py_VISIT(get_select_state(module)->devpoll_Type);
-    Py_VISIT(get_select_state(module)->pyEpoll_Type);
-    Py_VISIT(get_select_state(module)->kqueue_event_Type);
-    Py_VISIT(get_select_state(module)->kqueue_queue_Type);
+    _selectstate *state = get_select_state(module);
+
+    Py_VISIT(state->close);
+    Py_VISIT(state->poll_Type);
+    Py_VISIT(state->devpoll_Type);
+    Py_VISIT(state->pyEpoll_Type);
+    Py_VISIT(state->kqueue_event_Type);
+    Py_VISIT(state->kqueue_queue_Type);
     return 0;
 }
 
 static int
 _select_clear(PyObject *module)
 {
-    Py_CLEAR(get_select_state(module)->close);
-    Py_CLEAR(get_select_state(module)->poll_Type);
-    Py_CLEAR(get_select_state(module)->devpoll_Type);
-    Py_CLEAR(get_select_state(module)->pyEpoll_Type);
-    Py_CLEAR(get_select_state(module)->kqueue_event_Type);
-    Py_CLEAR(get_select_state(module)->kqueue_queue_Type);
+    _selectstate *state = get_select_state(module);
+
+    Py_CLEAR(state->close);
+    Py_CLEAR(state->poll_Type);
+    Py_CLEAR(state->devpoll_Type);
+    Py_CLEAR(state->pyEpoll_Type);
+    Py_CLEAR(state->kqueue_event_Type);
+    Py_CLEAR(state->kqueue_queue_Type);
     return 0;
 }
 
@@ -2419,30 +2423,18 @@ _select_free(void *module)
     _select_clear((PyObject *)module);
 }
 
-static struct PyModuleDef selectmodule = {
-    PyModuleDef_HEAD_INIT,
-    "select",
-    module_doc,
-    sizeof(_selectstate),
-    select_methods,
-    NULL,
-    _select_traverse,
-    _select_clear,
-    _select_free,
-};
-
-PyMODINIT_FUNC
-PyInit_select(void)
+int
+_select_exec(PyObject *m)
 {
-    PyObject *m;
-    m = PyModule_Create(&selectmodule);
-    if (m == NULL)
-        return NULL;
+    _selectstate *state = get_select_state(m);
 
-    get_select_state(m)->close = PyUnicode_InternFromString("close");
-
-    Py_INCREF(PyExc_OSError);
-    PyModule_AddObject(m, "error", PyExc_OSError);
+    state->close = PyUnicode_InternFromString("close");
+    if (state->close == NULL) {
+        return -1;
+    }
+    if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
+        return -1;
+    }
 
 #ifdef PIPE_BUF
 #ifdef HAVE_BROKEN_PIPE_BUF
@@ -2462,10 +2454,11 @@ PyInit_select(void)
 #else
     {
 #endif
-        PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
-        if (poll_Type == NULL)
-            return NULL;
-        get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type;
+        state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
+            m, &poll_Type_spec, NULL);
+        if (state->poll_Type == NULL) {
+            return -1;
+        }
 
         PyModule_AddIntMacro(m, POLLIN);
         PyModule_AddIntMacro(m, POLLPRI);
@@ -2497,19 +2490,22 @@ PyInit_select(void)
 #endif /* HAVE_POLL */
 
 #ifdef HAVE_SYS_DEVPOLL_H
-    PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
-    if (devpoll_Type == NULL)
-        return NULL;
-    get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
+    state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
+        m, &devpoll_Type_spec, NULL);
+    if (state->devpoll_Type == NULL) {
+        return -1;
+    }
 #endif
 
 #ifdef HAVE_EPOLL
-    PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
-    if (pyEpoll_Type == NULL)
-        return NULL;
-    get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
-    Py_INCREF(pyEpoll_Type);
-    PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type);
+    state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
+        m, &pyEpoll_Type_spec, NULL);
+    if (state->pyEpoll_Type == NULL) {
+        return -1;
+    }
+    if (PyModule_AddType(m, state->pyEpoll_Type) < 0) {
+        return -1;
+    }
 
     PyModule_AddIntMacro(m, EPOLLIN);
     PyModule_AddIntMacro(m, EPOLLOUT);
@@ -2551,19 +2547,23 @@ PyInit_select(void)
 #endif /* HAVE_EPOLL */
 
 #ifdef HAVE_KQUEUE
-    PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
-    if (kqueue_event_Type == NULL)
-        return NULL;
-    get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
-    Py_INCREF(get_select_state(m)->kqueue_event_Type);
-    PyModule_AddObject(m, "kevent", kqueue_event_Type);
+    state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
+        m, &kqueue_event_Type_spec, NULL);
+    if (state->kqueue_event_Type == NULL) {
+        return -1;
+    }
+    if (PyModule_AddType(m, state->kqueue_event_Type) < 0) {
+        return -1;
+    }
 
-    PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
-    if (kqueue_queue_Type == NULL)
-        return NULL;
-    get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
-    Py_INCREF(get_select_state(m)->kqueue_queue_Type);
-    PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
+    state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
+        m, &kqueue_queue_Type_spec, NULL);
+    if (state->kqueue_queue_Type == NULL) {
+        return -1;
+    }
+    if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) {
+        return -1;
+    }
 
     /* event filters */
     PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
@@ -2640,5 +2640,28 @@ PyInit_select(void)
 #endif
 
 #endif /* HAVE_KQUEUE */
-    return m;
+    return 0;
+}
+
+static PyModuleDef_Slot _select_slots[] = {
+    {Py_mod_exec, _select_exec},
+    {0, NULL}
+};
+
+static struct PyModuleDef selectmodule = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "select",
+    .m_doc = module_doc,
+    .m_size = sizeof(_selectstate),
+    .m_methods = select_methods,
+    .m_slots = _select_slots,
+    .m_traverse = _select_traverse,
+    .m_clear = _select_clear,
+    .m_free = _select_free,
+};
+
+PyMODINIT_FUNC
+PyInit_select(void)
+{
+    return PyModuleDef_Init(&selectmodule);
 }



More information about the Python-checkins mailing list