From 42b2a610567ec6d33176bcd44fd0c3dc415809ab Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sat, 22 Feb 2020 22:27:58 +0800 Subject: [PATCH 1/6] Port audioop extension module to multiphase initialization(PEP 489) --- Modules/audioop.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/Modules/audioop.c b/Modules/audioop.c index 7726c88b1a9d49..f5a44a1c871062 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1909,6 +1909,7 @@ audioop_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(state->AudioopError); return 0; } + static int audioop_clear(PyObject *m) { _audioopstate *state = _audioopstate(m); @@ -1916,18 +1917,42 @@ audioop_clear(PyObject *m) { Py_CLEAR(state->AudioopError); return 0; } + static void audioop_free(void *m) { audioop_clear((PyObject *)m); } +static int +audioop_exec(PyObject* m) +{ + _audioopstate *state = _audioopstate(m); + + state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL); + if (state->AudioopError == NULL) { + return -1; + } + + Py_INCREF(state->AudioopError); + if (PyModule_AddObject(m, "error", state->AudioopError) < 0) { + Py_DECREF(state->AudioopError); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot audioop_slots[] = { + {Py_mod_exec, audioop_exec} +}; + static struct PyModuleDef audioopmodule = { PyModuleDef_HEAD_INIT, "audioop", NULL, sizeof(_audioopstate), audioop_methods, - NULL, + audioop_slots, audioop_traverse, audioop_clear, audioop_free @@ -1936,14 +1961,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); } From 981bac98647a71583b2aadbb33ac6c51351b16d0 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2020 14:34:02 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core and Builtins/2020-02-22-14-33-59.bpo-1635741.BTJ0cX.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-02-22-14-33-59.bpo-1635741.BTJ0cX.rst 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 00000000000000..e1ba44afc57ca3 --- /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 From b776cb15040b364de6103a34a1324a1fd8c1399b Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Wed, 26 Feb 2020 01:04:05 +0800 Subject: [PATCH 3/6] port _audioopstate() macro to inline function --- Modules/audioop.c | 76 +++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/Modules/audioop.c b/Modules/audioop.c index f5a44a1c871062..62d5f48dc9ed12 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 *m) +{ + void *state = PyModule_GetState(m); + 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,18 +1923,22 @@ static PyMethodDef audioop_methods[] = { }; static int -audioop_traverse(PyObject *m, visitproc visit, void *arg) { - _audioopstate *state = _audioopstate(m); - if (state != NULL) +audioop_traverse(PyObject *m, visitproc visit, void *arg) +{ + audioop_state *state = (audioop_state *)PyModule_GetState(m); + if (state) { Py_VISIT(state->AudioopError); + } return 0; } static int -audioop_clear(PyObject *m) { - _audioopstate *state = _audioopstate(m); - if (state != NULL) +audioop_clear(PyObject *m) +{ + audioop_state *state = (audioop_state *)PyModule_GetState(m); + if (state) { Py_CLEAR(state->AudioopError); + } return 0; } @@ -1926,7 +1950,7 @@ audioop_free(void *m) { static int audioop_exec(PyObject* m) { - _audioopstate *state = _audioopstate(m); + audioop_state *state = get_audioop_state(m); state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL); if (state->AudioopError == NULL) { @@ -1950,7 +1974,7 @@ static struct PyModuleDef audioopmodule = { PyModuleDef_HEAD_INIT, "audioop", NULL, - sizeof(_audioopstate), + sizeof(audioop_state), audioop_methods, audioop_slots, audioop_traverse, From 1a1b56ec0a8e28431482279031cc885e3464cc88 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sat, 29 Feb 2020 20:13:15 -0600 Subject: [PATCH 4/6] Update Modules/audioop.c Co-Authored-By: Victor Stinner --- Modules/audioop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/audioop.c b/Modules/audioop.c index 62d5f48dc9ed12..48f5a33a5aa39b 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1967,7 +1967,8 @@ audioop_exec(PyObject* m) } static PyModuleDef_Slot audioop_slots[] = { - {Py_mod_exec, audioop_exec} + {Py_mod_exec, audioop_exec}, + {0, NULL} }; static struct PyModuleDef audioopmodule = { From cfa67a7b9385f7cffcfd54f63c92f30f928c7ccf Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sun, 1 Mar 2020 16:06:52 +0800 Subject: [PATCH 5/6] using the var name module to replace m --- Modules/audioop.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/audioop.c b/Modules/audioop.c index 48f5a33a5aa39b..e113d9a069b261 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1923,9 +1923,9 @@ static PyMethodDef audioop_methods[] = { }; static int -audioop_traverse(PyObject *m, visitproc visit, void *arg) +audioop_traverse(PyObject *module, visitproc visit, void *arg) { - audioop_state *state = (audioop_state *)PyModule_GetState(m); + audioop_state *state = (audioop_state *)PyModule_GetState(module); if (state) { Py_VISIT(state->AudioopError); } @@ -1933,9 +1933,9 @@ audioop_traverse(PyObject *m, visitproc visit, void *arg) } static int -audioop_clear(PyObject *m) +audioop_clear(PyObject *module) { - audioop_state *state = (audioop_state *)PyModule_GetState(m); + audioop_state *state = (audioop_state *)PyModule_GetState(module); if (state) { Py_CLEAR(state->AudioopError); } @@ -1943,14 +1943,14 @@ audioop_clear(PyObject *m) } static void -audioop_free(void *m) { - audioop_clear((PyObject *)m); +audioop_free(void *module) { + audioop_clear((PyObject *)module); } static int -audioop_exec(PyObject* m) +audioop_exec(PyObject* module) { - audioop_state *state = get_audioop_state(m); + audioop_state *state = get_audioop_state(module); state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL); if (state->AudioopError == NULL) { @@ -1958,7 +1958,7 @@ audioop_exec(PyObject* m) } Py_INCREF(state->AudioopError); - if (PyModule_AddObject(m, "error", state->AudioopError) < 0) { + if (PyModule_AddObject(module, "error", state->AudioopError) < 0) { Py_DECREF(state->AudioopError); return -1; } From 5364b74fe08bc59063a148639484cc7c67419d99 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sun, 1 Mar 2020 16:12:08 +0800 Subject: [PATCH 6/6] using the var name module to replace m in get_audioop_state() --- Modules/audioop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/audioop.c b/Modules/audioop.c index e113d9a069b261..467bd6362a6634 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -378,9 +378,9 @@ typedef struct { } audioop_state; static inline audioop_state * -get_audioop_state(PyObject *m) +get_audioop_state(PyObject *module) { - void *state = PyModule_GetState(m); + void *state = PyModule_GetState(module); assert(state != NULL); return (audioop_state *)state; }