8000 bpo-1635741: Port audioop extension module to multiphase initializati… · python/cpython@41fbf86 · GitHub
[go: up one dir, main page]

Skip to content

Commit 41fbf86

Browse files
shihai1991vstinner
andauthored
bpo-1635741: Port audioop extension module to multiphase initialization (PEP 489) (GH-18608)
Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent a158168 commit 41fbf86

File tree

2 files changed

+80
-38
lines changed

2 files changed

+80
-38
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Port audioop extension module to multiphase initialization (:pep:`489`).

Modules/audioop.c

Lines changed: 79 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -375,15 +375,22 @@ static PyModuleDef audioopmodule;
375375

376376
typedef struct {
377377
PyObject *AudioopError;
378-
} _audioopstate;
378+
} audioop_state;
379379

380-
#define _audioopstate(o) ((_audioopstate *)PyModule_GetState(o))
380+
static inline audioop_state *
381+
get_audioop_state(PyObject *module)
382+
{
383+
void *state = PyModule_GetState(module);
384+
assert(state != NULL);
385+
return (audioop_state *)state;
386+
}
381387

382388
static int
383389
audioop_check_size(PyObject *module, int size)
384390
{
385391
if (size < 1 || size > 4) {
386-
PyErr_SetString(_audioopstate(module)->AudioopError, "Size should be 1, 2, 3 or 4");
392+
PyErr_SetString(get_audioop_state(module)->AudioopError,
393+
"Size should be 1, 2, 3 or 4");
387394
return 0;
388395
}
389396
else
@@ -396,7 +403,8 @@ audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
396403
if (!audioop_check_size(module, size))
397404
return 0;
398405
if (len % size != 0) {
399-
PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
406+
PyErr_SetString(get_audioop_state(module)->AudioopError,
407+
"not a whole number of frames");
400408
return 0;
401409
}
402410
return 1;
@@ -428,7 +436,8 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
428436
if (!audioop_check_parameters(module, fragment->len, width))
429437
return NULL;
430438
if (index < 0 || index >= fragment->len/width) {
431-
PyErr_SetString(_audioopstate(module)->AudioopError, "Index out of range");
439+
PyErr_SetString(get_audioop_state(module)->AudioopError,
440+
"Index out of range");
432441
return NULL;
433442
}
434443
val = GETRAWSAMPLE(width, fragment->buf, index*width);
@@ -619,7 +628,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
619628
double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
620629

621630
if (fragment->len & 1 || reference->len & 1) {
622-
PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
631+
PyErr_SetString(get_audioop_state(module)->AudioopError,
632+
"Strings should be even-sized");
623633
return NULL;
624634
}
625635
cp1 = (const int16_t *)fragment->buf;
@@ -628,7 +638,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
628638
len2 = reference->len >> 1;
629639

630640
if (len1 < len2) {
631-
PyErr_SetString(_audioopstate(module)->AudioopError, "First sample should be longer");
641+
PyErr_SetString(get_audioop_state(module)->AudioopError,
642+
"First sample should be longer");
632643
return NULL;
633644
}
634645
sum_ri_2 = _sum2(cp2, cp2, len2);
@@ -686,11 +697,13 @@ audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
686697
double sum_ri_2, sum_aij_ri, result;
687698

688699
if (fragment->len & 1 || reference->len & 1) {
689-
PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
700+
PyErr_SetString(get_audioop_state(module)->AudioopError,
701+
"Strings should be even-sized");
690702
return NULL;
691703
}
692704
if (fragment->len != reference->len) {
693-
PyErr_SetString(_audioopstate(module)->AudioopError, "Samples should be same size");
705+
PyErr_SetString(get_audioop_state(module)->AudioopError,
706+
"Samples should be same size");
694707
return NULL;
695708
}
696709
cp1 = (const int16_t *)fragment->buf;
@@ -730,14 +743,16 @@ audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
730743
double result, best_result;
731744

732745
if (fragment->len & 1) {
733-
PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
746+
PyErr_SetString(get_audioop_state(module)->AudioopError,
747+
"Strings should be even-sized");
734748
return NULL;
735749
}
736750
cp1 = (const int16_t *)fragment->buf;
737751
len1 = fragment->len >> 1;
738752

739753
if (length < 0 || len1 < length) {
740-
PyErr_SetString(_audioopstate(module)->AudioopError, "Input sample should be longer");
754+
PyErr_SetString(get_audioop_state(module)->AudioopError,
755+
"Input sample should be longer");
741756
return NULL;
742757
}
743758

@@ -969,7 +984,8 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
969984
if (!audioop_check_parameters(module, len, width))
970985
return NULL;
971986
if (((len / width) & 1) != 0) {
972-
PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
987+
PyErr_SetString(get_audioop_state(module)->AudioopError,
988+
"not a whole number of frames");
973989
return NULL;
974990
}
975991

@@ -1064,7 +1080,8 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
10641080
if (!audioop_check_parameters(module, fragment1->len, width))
10651081
return NULL;
10661082
if (fragment1->len != fragment2->len) {
1067-
PyErr_SetString(_audioopstate(module)->AudioopError, "Lengths should be the same");
1083+
PyErr_SetString(get_audioop_state(module)->AudioopError,
1084+
"Lengths should be the same");
10681085
return NULL;
10691086
}
10701087

@@ -1310,7 +1327,8 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
13101327
if (!audioop_check_size(module, width))
13111328
return NULL;
13121329
if (nchannels < 1) {
1313-
PyErr_SetString(_audioopstate(module)->AudioopError, "# of channels should be >= 1");
1330+
PyErr_SetString(get_audioop_state(module)->AudioopError,
1331+
"# of channels should be >= 1");
13141332
return NULL;
13151333
}
13161334
if (width > INT_MAX / nchannels) {
@@ -1323,17 +1341,19 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
13231341
}
13241342
bytes_per_frame = width * nchannels;
13251343
if (weightA < 1 || weightB < 0) {
1326-
PyErr_SetString(_audioopstate(module)->AudioopError,
1344+
PyErr_SetString(get_audioop_state(module)->AudioopError,
13271345
"weightA should be >= 1, weightB should be >= 0");
13281346
return NULL;
13291347
}
13301348
assert(fragment->len >= 0);
13311349
if (fragment->len % bytes_per_frame != 0) {
1332-
PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
1350+
PyErr_SetString(get_audioop_state(module)->AudioopError,
1351+
"not a whole number of frames");
13331352
return NULL;
13341353
}
13351354
if (inrate <= 0 || outrate <= 0) {
1336-
PyErr_SetString(_audioopstate(module)->AudioopError, "sampling rate not > 0");
1355+
PyErr_SetString(get_audioop_state(module)->AudioopError,
1356+
"sampling rate not > 0");
13371357
return NULL;
13381358
}
13391359
/* divide inrate and outrate by their greatest common divisor */
@@ -1374,7 +1394,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
13741394
&d, &PyTuple_Type, &samps))
13751395
goto exit;
13761396
if (PyTuple_Size(samps) != nchannels) {
1377-
PyErr_SetString(_audioopstate(module)->AudioopError,
1397+
PyErr_SetString(get_audioop_state(module)->AudioopError,
13781398
"illegal state argument");
13791399
goto exit;
13801400
}
@@ -1903,31 +1923,61 @@ static PyMethodDef audioop_methods[] = {
19031923
};
19041924

19051925
static int
1906-
audioop_traverse(PyObject *m, visitproc visit, void *arg) {
1907-
_audioopstate *state = _audioopstate(m);
1908-
if (state != NULL)
1926+
audioop_traverse(PyObject *module, visitproc visit, void *arg)
1927+
{
1928+
audioop_state *state = (audioop_state *)PyModule_GetState(module);
1929+
if (state) {
19091930
Py_VISIT(state->AudioopError);
1931+
}
19101932
return 0;
19111933
}
1934+
19121935
static int
1913-
audioop_clear(PyObject *m) {
1914-
_audioopstate *state = _audioopstate(m);
1915-
if (state != NULL)
1936+
audioop_clear(PyObject *module)
1937+
{
1938+
audioop_state *state = (audioop_state *)PyModule_GetState(module);
1939+
if (state) {
19161940
Py_CLEAR(state->AudioopError);
1941+
}
19171942
return 0;
19181943
}
1944+
19191945
static void
1920-
audioop_free(void *m) {
1921-
audioop_clear((PyObject *)m);
1946+
audioop_free(void *module) {
1947+
audioop_clear((PyObject *)module);
19221948
}
19231949

1950+
static int
1951+
audioop_exec(PyObject* module)
1952+
{
1953+
audioop_state *state = get_audioop_state(module);
1954+
1955+
state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1956+
if (state->AudioopError == NULL) {
1957+
return -1;
1958+
}
1959+
1960+
Py_INCREF(state->AudioopError);
1961+
if (PyModule_AddObject(module, "error", state->AudioopError) < 0) {
1962+
Py_DECREF(state->AudioopError);
1963+
return -1;
1964+
}
1965+
1966+
return 0;
1967+
}
1968+
1969+
static PyModuleDef_Slot audioop_slots[] = {
1970+
{Py_mod_exec, audioop_exec},
1971+
{0, NULL}
1972+
};
1973+
19241974
static struct PyModuleDef audioopmodule = {
1925 C8BA 1975
PyModuleDef_HEAD_INIT,
19261976
"audioop",
19271977
NULL,
1928-
sizeof(_audioopstate),
1978+
sizeof(audioop_state),
19291979
audioop_methods,
1930-
NULL,
1980+
audioop_slots,
19311981
audioop_traverse,
19321982
audioop_clear,
19331983
audioop_free
@@ -1936,14 +1986,5 @@ static struct PyModuleDef audioopmodule = {
19361986
PyMODINIT_FUNC
19371987
PyInit_audioop(void)
19381988
{
1939-
PyObject *m = PyModule_Create(&audioopmodule);
1940-
if (m == NULL)
1941-
return NULL;
1942-
PyObject *AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1943-
if (AudioopError == NULL)
1944-
return NULL;
1945-
Py_INCREF(AudioopError);
1946-
PyModule_AddObject(m, "error", AudioopError);
1947-
_audioopstate(m)->AudioopError = AudioopError;
1948-
return m;
1989+
return PyModuleDef_Init(&audioopmodule);
19491990
}

0 commit comments

Comments
 (0)
0