python3-pyaudio fails with: PY_SSIZE_T_CLEAN macro must be defined for '#' formats
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
python-pyaudio (Debian) |
Fix Released
|
Unknown
|
|||
python-pyaudio (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Jammy |
New
|
Undecided
|
Unassigned | ||
Kinetic |
New
|
Undecided
|
Unassigned | ||
Lunar |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
I recently upgraded my system from 21.10 to 22.04 and a previous working python program stopped working.
It uses the python3-pyaudio package, and its initialisation fails like this:
SystemError: PY_SSIZE_T_CLEAN macro must be defined for '#' formats
A bit of searching came up with this stack overflow answer: https:/
> Unfortunately, a breaking change was introduced in Python 3.10 (see bpo-40943 and PEP-0353), and thus PyAudio needs updated.
>
> I've submitted a fix upstream, but as the project has not been updated since 2017, I'm not quite sure how quick it will get reviewed.
>
> In the meantime, you are free to build my fork from source and use that :)
The fix looks quite simple: https:/
So might be something that you could carry as a fix.
Changed in python-pyaudio (Debian): | |
status: | Unknown → New |
Changed in python-pyaudio (Debian): | |
status: | New → Fix Released |
It seems this patch did not completely fix the problem. I was using nrsc5-gui from https:/ /github. com/cmnybo/ nrsc5-gui, and with the proposed fix, I encountered a segfault on a call to pyaudio. Stream. write() . This segfault appears to be related to incorrect initialization of memory due to the wrong type of argument being passed in to PyArg_ParseTuple() in _portaudiomodule.c:
2037 /****** ******* ******* ******* ******* ******* ******* ******* ****** ******* ******* ******* ******* ******* ******* ******* *****/ stream( PyObject *self, PyObject *args) { throw_exception = 0; ParseTuple( args, "O!s#i|i", StreamType, throw_exception )) { (PyExc_ ValueError, "Invalid number of frames"); streamObject) ) { //<--- segfault here (PyExc_ IOError, "(i,s)" , paBadStreamPtr, "Stream closed"));
2038 * Stream Read/Write
2039 *******
2040
2041 static PyObject *pa_write_
2042 const char *data;
2043 int total_size; //<--- wrong type, should be Py_ssize_t, not int
2044 int total_frames;
2045 int err;
2046 int should_
2047
2048 PyObject *stream_arg;
2049 _pyAudio_Stream *streamObject;
2050
2051 // clang-format off
2052 if (!PyArg_
2053 &_pyAudio_
2054 &stream_arg, //<--- incorrectly initialized
2055 &data,
2056 &total_size, //<--- total_size passed here
2057 &total_frames,
2058 &should_
2059 return NULL;
2060 }
2061 // clang-format on
2062
2063 if (total_frames < 0) {
2064 PyErr_SetString
2065 return NULL;
2066 }
2067
2068 streamObject = (_pyAudio_Stream *)stream_arg;
2069
2070 if (!_is_open(
2071 PyErr_SetObject
2072 Py_BuildValue(
2073 return NULL;
2074 }
After changing the type of the "total_size" variable from int to Py_ssize_t, the segfault no longer occurred, and the audio stream played normally.
A modified patch that fixes the segfault is attached.