[Python-checkins] bpo-1635741: Port the termios to multi-phase init (PEP 489) (GH-22139)

Mohamed Koubaa webhook-mailer at python.org
Tue Sep 8 04:59:20 EDT 2020


https://github.com/python/cpython/commit/15dcdb211366e0788e831fc2a1f785e6a5ca2749
commit: 15dcdb211366e0788e831fc2a1f785e6a5ca2749
branch: master
author: Mohamed Koubaa <koubaa.m at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-09-08T10:59:15+02:00
summary:

bpo-1635741: Port the termios to multi-phase init (PEP 489) (GH-22139)

files:
A Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst
M Modules/termios.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst
new file mode 100644
index 0000000000000..1e19b34b372d8
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst	
@@ -0,0 +1,2 @@
+Port the :mod:`termios` extension module to multi-phase initialization
+(:pep:`489`).
diff --git a/Modules/termios.c b/Modules/termios.c
index 178ae4ee6e41d..cc0d5853f85e3 100644
--- a/Modules/termios.c
+++ b/Modules/termios.c
@@ -51,8 +51,6 @@ get_termios_state(PyObject *module)
     return (termiosmodulestate *)state;
 }
 
-#define modulestate_global get_termios_state(PyState_FindModule(&termiosmodule))
-
 static int fdconv(PyObject* obj, void* p)
 {
     int fd;
@@ -79,31 +77,32 @@ indexing in the cc array must be done using the symbolic constants defined\n\
 in this module.");
 
 static PyObject *
-termios_tcgetattr(PyObject *self, PyObject *args)
+termios_tcgetattr(PyObject *module, PyObject *args)
 {
     int fd;
-    struct termios mode;
-    PyObject *cc;
-    speed_t ispeed, ospeed;
-    PyObject *v;
-    int i;
-    char ch;
-
     if (!PyArg_ParseTuple(args, "O&:tcgetattr",
-                          fdconv, (void*)&fd))
+                          fdconv, (void*)&fd)) {
         return NULL;
+    }
 
-    if (tcgetattr(fd, &mode) == -1)
-        return PyErr_SetFromErrno(modulestate_global->TermiosError);
+    termiosmodulestate *state = PyModule_GetState(module);
+    struct termios mode;
+    if (tcgetattr(fd, &mode) == -1) {
+        return PyErr_SetFromErrno(state->TermiosError);
+    }
 
-    ispeed = cfgetispeed(&mode);
-    ospeed = cfgetospeed(&mode);
+    speed_t ispeed = cfgetispeed(&mode);
+    speed_t ospeed = cfgetospeed(&mode);
 
-    cc = PyList_New(NCCS);
-    if (cc == NULL)
+    PyObject *cc = PyList_New(NCCS);
+    if (cc == NULL) {
         return NULL;
+    }
+
+    PyObject *v;
+    int i;
     for (i = 0; i < NCCS; i++) {
-        ch = (char)mode.c_cc[i];
+        char ch = (char)mode.c_cc[i];
         v = PyBytes_FromStringAndSize(&ch, 1);
         if (v == NULL)
             goto err;
@@ -156,17 +155,15 @@ queued output, or termios.TCSAFLUSH to change after transmitting all\n\
 queued output and discarding all queued input. ");
 
 static PyObject *
-termios_tcsetattr(PyObject *self, PyObject *args)
+termios_tcsetattr(PyObject *module, PyObject *args)
 {
     int fd, when;
-    struct termios mode;
-    speed_t ispeed, ospeed;
-    PyObject *term, *cc, *v;
-    int i;
-
+    PyObject *term;
     if (!PyArg_ParseTuple(args, "O&iO:tcsetattr",
-                          fdconv, &fd, &when, &term))
+                          fdconv, &fd, &when, &term)) {
         return NULL;
+    }
+
     if (!PyList_Check(term) || PyList_Size(term) != 7) {
         PyErr_SetString(PyExc_TypeError,
                      "tcsetattr, arg 3: must be 7 element list");
@@ -174,18 +171,22 @@ termios_tcsetattr(PyObject *self, PyObject *args)
     }
 
     /* Get the old mode, in case there are any hidden fields... */
-    termiosmodulestate *state = modulestate_global;
-    if (tcgetattr(fd, &mode) == -1)
+    termiosmodulestate *state = PyModule_GetState(module);
+    struct termios mode;
+    if (tcgetattr(fd, &mode) == -1) {
         return PyErr_SetFromErrno(state->TermiosError);
+    }
+
     mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
     mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
     mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
     mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3));
-    ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
-    ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
-    cc = PyList_GetItem(term, 6);
-    if (PyErr_Occurred())
+    speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
+    speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
+    PyObject *cc = PyList_GetItem(term, 6);
+    if (PyErr_Occurred()) {
         return NULL;
+    }
 
     if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
         PyErr_Format(PyExc_TypeError,
@@ -194,6 +195,8 @@ termios_tcsetattr(PyObject *self, PyObject *args)
         return NULL;
     }
 
+    int i;
+    PyObject *v;
     for (i = 0; i < NCCS; i++) {
         v = PyList_GetItem(cc, i);
 
@@ -226,15 +229,18 @@ A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
 has a system dependent meaning.");
 
 static PyObject *
-termios_tcsendbreak(PyObject *self, PyObject *args)
+termios_tcsendbreak(PyObject *module, PyObject *args)
 {
     int fd, duration;
-
     if (!PyArg_ParseTuple(args, "O&i:tcsendbreak",
-                          fdconv, &fd, &duration))
+                          fdconv, &fd, &duration)) {
         return NULL;
-    if (tcsendbreak(fd, duration) == -1)
-        return PyErr_SetFromErrno(modulestate_global->TermiosError);
+    }
+
+    termiosmodulestate *state = PyModule_GetState(module);
+    if (tcsendbreak(fd, duration) == -1) {
+        return PyErr_SetFromErrno(state->TermiosError);
+    }
 
     Py_RETURN_NONE;
 }
@@ -245,15 +251,18 @@ PyDoc_STRVAR(termios_tcdrain__doc__,
 Wait until all output written to file descriptor fd has been transmitted.");
 
 static PyObject *
-termios_tcdrain(PyObject *self, PyObject *args)
+termios_tcdrain(PyObject *module, PyObject *args)
 {
     int fd;
-
     if (!PyArg_ParseTuple(args, "O&:tcdrain",
-                          fdconv, &fd))
+                          fdconv, &fd)) {
         return NULL;
-    if (tcdrain(fd) == -1)
-        return PyErr_SetFromErrno(modulestate_global->TermiosError);
+    }
+
+    termiosmodulestate *state = PyModule_GetState(module);
+    if (tcdrain(fd) == -1) {
+        return PyErr_SetFromErrno(state->TermiosError);
+    }
 
     Py_RETURN_NONE;
 }
@@ -267,15 +276,18 @@ queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
 both queues. ");
 
 static PyObject *
-termios_tcflush(PyObject *self, PyObject *args)
+termios_tcflush(PyObject *module, PyObject *args)
 {
     int fd, queue;
-
     if (!PyArg_ParseTuple(args, "O&i:tcflush",
-                          fdconv, &fd, &queue))
+                          fdconv, &fd, &queue)) {
         return NULL;
-    if (tcflush(fd, queue) == -1)
-        return PyErr_SetFromErrno(modulestate_global->TermiosError);
+    }
+
+    termiosmodulestate *state = PyModule_GetState(module);
+    if (tcflush(fd, queue) == -1) {
+        return PyErr_SetFromErrno(state->TermiosError);
+    }
 
     Py_RETURN_NONE;
 }
@@ -289,15 +301,18 @@ termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
 or termios.TCION to restart input.");
 
 static PyObject *
-termios_tcflow(PyObject *self, PyObject *args)
+termios_tcflow(PyObject *module, PyObject *args)
 {
     int fd, action;
-
     if (!PyArg_ParseTuple(args, "O&i:tcflow",
-                          fdconv, &fd, &action))
+                          fdconv, &fd, &action)) {
         return NULL;
-    if (tcflow(fd, action) == -1)
-        return PyErr_SetFromErrno(modulestate_global->TermiosError);
+    }
+
+    termiosmodulestate *state = PyModule_GetState(module);
+    if (tcflow(fd, action) == -1) {
+        return PyErr_SetFromErrno(state->TermiosError);
+    }
 
     Py_RETURN_NONE;
 }
@@ -997,44 +1012,49 @@ static void termiosmodule_free(void *m) {
     termiosmodule_clear((PyObject *)m);
 }
 
-static struct PyModuleDef termiosmodule = {
-    PyModuleDef_HEAD_INIT,
-    "termios",
-    termios__doc__,
-    sizeof(termiosmodulestate),
-    termios_methods,
-    NULL,
-    termiosmodule_traverse,
-    termiosmodule_clear,
-    termiosmodule_free,
-};
-
-PyMODINIT_FUNC
-PyInit_termios(void)
+static int 
+termios_exec(PyObject *mod)
 {
-    PyObject *m;
     struct constant *constant = termios_constants;
-
-    if ((m = PyState_FindModule(&termiosmodule)) != NULL) {
-        Py_INCREF(m);
-        return m;
-    }
-
-    if ((m = PyModule_Create(&termiosmodule)) == NULL) {
-        return NULL;
-    }
-
-    termiosmodulestate *state = get_termios_state(m);
+    termiosmodulestate *state = get_termios_state(mod);
     state->TermiosError = PyErr_NewException("termios.error", NULL, NULL);
     if (state->TermiosError == NULL) {
-        return NULL;
+        return -1;
     }
     Py_INCREF(state->TermiosError);
-    PyModule_AddObject(m, "error", state->TermiosError);
+    if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) {
+        Py_DECREF(state->TermiosError);
+        return -1;
+    }
 
     while (constant->name != NULL) {
-        PyModule_AddIntConstant(m, constant->name, constant->value);
+        if (PyModule_AddIntConstant(
+            mod, constant->name, constant->value) < 0) {
+            return -1;
+        }
         ++constant;
     }
-    return m;
+    return 0;
+}
+
+static PyModuleDef_Slot termios_slots[] = {
+    {Py_mod_exec, termios_exec},
+    {0, NULL}
+};
+
+static struct PyModuleDef termiosmodule = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "termios",
+    .m_doc = termios__doc__,
+    .m_size = sizeof(termiosmodulestate),
+    .m_methods = termios_methods,
+    .m_slots = termios_slots,
+    .m_traverse = termiosmodule_traverse,
+    .m_clear = termiosmodule_clear,
+    .m_free = termiosmodule_free,
+};
+
+PyMODINIT_FUNC PyInit_termios(void)
+{
+    return PyModuleDef_Init(&termiosmodule);
 }



More information about the Python-checkins mailing list