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;

#if SIZEOF_VOID_P == SIZEOF_LONG_LONG *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value);

Here are things which support bytes instances only:

  1. 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.

  1. 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.

  2. c_wchar_p.from_param() accepts bytes argument, but then reject it in internal function. This is a bug, bytes should be removed here.

  3. 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.

  4. 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().

  5. 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.