[Python-checkins] bpo-1635741: Port audioop extension module to multiphase initialization (PEP 489) (GH-18608)

Hai Shi webhook-mailer at python.org
Wed Mar 11 12:49:16 EDT 2020


https://github.com/python/cpython/commit/41fbf865a35d4fb64f047f98dc24690cb0c170fd
commit: 41fbf865a35d4fb64f047f98dc24690cb0c170fd
branch: master
author: Hai Shi <shihai1992 at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-03-11T17:49:11+01:00
summary:

bpo-1635741: Port audioop extension module to multiphase initialization (PEP 489) (GH-18608)

Co-authored-by: Victor Stinner <vstinner at python.org>

files:
A Misc/NEWS.d/next/Core and Builtins/2020-02-22-14-33-59.bpo-1635741.BTJ0cX.rst
M Modules/audioop.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-22-14-33-59.bpo-1635741.BTJ0cX.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-22-14-33-59.bpo-1635741.BTJ0cX.rst
new file mode 100644
index 0000000000000..e1ba44afc57ca
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-22-14-33-59.bpo-1635741.BTJ0cX.rst	
@@ -0,0 +1 @@
+Port audioop extension module to multiphase initialization (:pep:`489`).
\ No newline at end of file
diff --git a/Modules/audioop.c b/Modules/audioop.c
index 7726c88b1a9d4..467bd6362a663 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -375,15 +375,22 @@ static PyModuleDef audioopmodule;
 
 typedef struct {
     PyObject *AudioopError;
-} _audioopstate;
+} audioop_state;
 
-#define _audioopstate(o) ((_audioopstate *)PyModule_GetState(o))
+static inline audioop_state *
+get_audioop_state(PyObject *module)
+{
+    void *state = PyModule_GetState(module);
+    assert(state != NULL);
+    return (audioop_state *)state;
+}
 
 static int
 audioop_check_size(PyObject *module, int size)
 {
     if (size < 1 || size > 4) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Size should be 1, 2, 3 or 4");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Size should be 1, 2, 3 or 4");
         return 0;
     }
     else
@@ -396,7 +403,8 @@ audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
     if (!audioop_check_size(module, size))
         return 0;
     if (len % size != 0) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "not a whole number of frames");
         return 0;
     }
     return 1;
@@ -428,7 +436,8 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
     if (!audioop_check_parameters(module, fragment->len, width))
         return NULL;
     if (index < 0 || index >= fragment->len/width) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Index out of range");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Index out of range");
         return NULL;
     }
     val = GETRAWSAMPLE(width, fragment->buf, index*width);
@@ -619,7 +628,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
     double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
 
     if (fragment->len & 1 || reference->len & 1) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Strings should be even-sized");
         return NULL;
     }
     cp1 = (const int16_t *)fragment->buf;
@@ -628,7 +638,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
     len2 = reference->len >> 1;
 
     if (len1 < len2) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "First sample should be longer");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "First sample should be longer");
         return NULL;
     }
     sum_ri_2 = _sum2(cp2, cp2, len2);
@@ -686,11 +697,13 @@ audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
     double sum_ri_2, sum_aij_ri, result;
 
     if (fragment->len & 1 || reference->len & 1) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Strings should be even-sized");
         return NULL;
     }
     if (fragment->len != reference->len) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Samples should be same size");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Samples should be same size");
         return NULL;
     }
     cp1 = (const int16_t *)fragment->buf;
@@ -730,14 +743,16 @@ audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
     double result, best_result;
 
     if (fragment->len & 1) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Strings should be even-sized");
         return NULL;
     }
     cp1 = (const int16_t *)fragment->buf;
     len1 = fragment->len >> 1;
 
     if (length < 0 || len1 < length) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Input sample should be longer");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Input sample should be longer");
         return NULL;
     }
 
@@ -969,7 +984,8 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
     if (!audioop_check_parameters(module, len, width))
         return NULL;
     if (((len / width) & 1) != 0) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "not a whole number of frames");
         return NULL;
     }
 
@@ -1064,7 +1080,8 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
     if (!audioop_check_parameters(module, fragment1->len, width))
         return NULL;
     if (fragment1->len != fragment2->len) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "Lengths should be the same");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "Lengths should be the same");
         return NULL;
     }
 
@@ -1310,7 +1327,8 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
     if (!audioop_check_size(module, width))
         return NULL;
     if (nchannels < 1) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "# of channels should be >= 1");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "# of channels should be >= 1");
         return NULL;
     }
     if (width > INT_MAX / nchannels) {
@@ -1323,17 +1341,19 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
     }
     bytes_per_frame = width * nchannels;
     if (weightA < 1 || weightB < 0) {
-        PyErr_SetString(_audioopstate(module)->AudioopError,
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
             "weightA should be >= 1, weightB should be >= 0");
         return NULL;
     }
     assert(fragment->len >= 0);
     if (fragment->len % bytes_per_frame != 0) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "not a whole number of frames");
         return NULL;
     }
     if (inrate <= 0 || outrate <= 0) {
-        PyErr_SetString(_audioopstate(module)->AudioopError, "sampling rate not > 0");
+        PyErr_SetString(get_audioop_state(module)->AudioopError,
+                        "sampling rate not > 0");
         return NULL;
     }
     /* divide inrate and outrate by their greatest common divisor */
@@ -1374,7 +1394,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
                         &d, &PyTuple_Type, &samps))
             goto exit;
         if (PyTuple_Size(samps) != nchannels) {
-            PyErr_SetString(_audioopstate(module)->AudioopError,
+            PyErr_SetString(get_audioop_state(module)->AudioopError,
                             "illegal state argument");
             goto exit;
         }
@@ -1903,31 +1923,61 @@ static PyMethodDef audioop_methods[] = {
 };
 
 static int
-audioop_traverse(PyObject *m, visitproc visit, void *arg) {
-    _audioopstate *state = _audioopstate(m);
-    if (state != NULL)
+audioop_traverse(PyObject *module, visitproc visit, void *arg)
+{
+    audioop_state *state = (audioop_state *)PyModule_GetState(module);
+    if (state) {
         Py_VISIT(state->AudioopError);
+    }
     return 0;
 }
+
 static int
-audioop_clear(PyObject *m) {
-    _audioopstate *state = _audioopstate(m);
-    if (state != NULL)
+audioop_clear(PyObject *module)
+{
+    audioop_state *state = (audioop_state *)PyModule_GetState(module);
+    if (state) {
         Py_CLEAR(state->AudioopError);
+    }
     return 0;
 }
+
 static void
-audioop_free(void *m) {
-    audioop_clear((PyObject *)m);
+audioop_free(void *module) {
+    audioop_clear((PyObject *)module);
 }
 
+static int
+audioop_exec(PyObject* module)
+{
+    audioop_state *state = get_audioop_state(module);
+
+    state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
+    if (state->AudioopError == NULL) {
+        return -1;
+    }
+
+    Py_INCREF(state->AudioopError);
+    if (PyModule_AddObject(module, "error", state->AudioopError) < 0) {
+        Py_DECREF(state->AudioopError);
+        return -1;
+    }
+
+    return 0;
+}
+
+static PyModuleDef_Slot audioop_slots[] = {
+    {Py_mod_exec, audioop_exec},
+    {0, NULL}
+};
+
 static struct PyModuleDef audioopmodule = {
     PyModuleDef_HEAD_INIT,
     "audioop",
     NULL,
-    sizeof(_audioopstate),
+    sizeof(audioop_state),
     audioop_methods,
-    NULL,
+    audioop_slots,
     audioop_traverse,
     audioop_clear,
     audioop_free
@@ -1936,14 +1986,5 @@ static struct PyModuleDef audioopmodule = {
 PyMODINIT_FUNC
 PyInit_audioop(void)
 {
-    PyObject *m = PyModule_Create(&audioopmodule);
-    if (m == NULL)
-        return NULL;
-    PyObject *AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
-    if (AudioopError == NULL)
-        return NULL;
-    Py_INCREF(AudioopError);
-    PyModule_AddObject(m, "error", AudioopError);
-    _audioopstate(m)->AudioopError = AudioopError;
-    return m;
+    return PyModuleDef_Init(&audioopmodule);
 }



More information about the Python-checkins mailing list