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 diff --git a/Modules/audioop.c b/Modules/audioop.c index 7726c88b1a9d49..467bd6362a6634 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); }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: