Issue 10803: ctypes: better support of bytearray objects (original) (raw)
Python 3.2b2 does not properly support accessing bytearrays from ctypes, which makes dealing with large buffers somewhat unpleasant.
A very first fix - a simple patch for the z_set() function - is given here.
build/Python-3.2b2 $ quilt diff Index: b/Modules/_ctypes/cfield.c
--- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1363,6 +1363,10 @@ *(char **)ptr = PyBytes_AsString(value); Py_INCREF(value); return value;
- } else if (PyByteArray_Check(value)) {
*(char **)ptr = PyByteArray_AsString(value);Py_INCREF(value);
} else if (PyLong_Check(value)) {return value;
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value);
Here are things which support bytes instances only:
- Constructor and setter of the "value" attribute of NUL terminated char buffer.
p = create_string_buffer(b"Hello") p.value b'Hello' p.raw b'Hello\x00' p.value = b'Bye' p.value b'Bye' p.raw b'Bye\x00o\x00' create_string_buffer(bytearray(b"Hello")) Traceback (most recent call last): File "", line 1, in File "/home/serhiy/py/cpython-3.4/Lib/ctypes/init.py", line 63, in create_string_buffer raise TypeError(init) TypeError: bytearray(b'Hello') p.value = bytearray(b'Hi') Traceback (most recent call last): File "", line 1, in TypeError: bytes expected instead of bytearray instance
But setter of the "raw" attribute accepts arbitrary bytes-like objects.
p.raw = bytearray(b'Hi') p.raw b'Hie\x00o\x00'
The patch adds support of bytearray here. It would be not so easy to add support for arbitrary bytes-like objects, and due to NUL-terminating it can be confused. I even not sure that support of bytearray is needed here.
Constructor of NUL terminated wchar buffer (create_unicode_buffer). Actually this doesn't work. Bytes argument is accepted, but then rejected in internal setting function. This is a bug, bytes should be removed here.
c_wchar_p.from_param() accepts bytes argument, but then reject it in internal function. This is a bug, bytes should be removed here.
c_void_p.from_param() accepts bytes and bytearray arguments, but then reject bytearray in internal function. This is a bug, either bytearray should be rejected here, or support of bytearray should be added in internal function (very easy, the patch does this). Adding support of arbitrary bytes-like objects is more complicated.
c_char_p.from_param() accepts bytes argument. Adding support for bytearray or arbitrary bytes-like objects has same complexity as in c_void_p.from_param().
Bytes arguments of call_function(), call_cdeclfunction() and CopyComPointer() are implicitly converted to pointers. It is easy to add support of bytearray, and more complicated for arbitrary bytes-like objects.