On Thu, Dec 29, 2016 at 12:18 PM, Hans-Peter Jansen <h...@urpla.net> wrote: >> >>> import weakref, ctypes >> >>> T = ctypes.c_ubyte * 3 >> >>> t = T() >> >>> bytes(t) == b"\0" * 3 >> >> True >> >> >>> bytes(weakref.proxy(t)) == b"\0" * 3 >> >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> AttributeError: 'c_ubyte_Array_3' object has no attribute '__bytes__' >> >> That looks like a leaky abstraction. While I found a workaround >> >> >>> bytes(weakref.proxy(t)[:]) == b"\0" * 3 >> >> True > > I found a couple of other rough corners already, when working with the ctypes > module. Obviously, this module is lacking some love.
That's not the fault of ctypes. There's no requirement for objects that implement the buffer protocol to also implement __bytes__. You'd have the same problem if you tried to proxy a memoryview. However, using a proxy seems particularly worthless for ctypes. Type checking is integral to the design of ctypes, and a weakproxy won't work: >>> a = (ctypes.c_ubyte * 3)() >>> ctypes.addressof(a) 139959173036992 >>> ctypes.pointer(a) <__main__.LP_c_ubyte_Array_3 object at 0x7f4ac8caba60> >>> ctypes.string_at(a, 3) b'\x00\x00\x00' >>> p = weakref.proxy(a) >>> type(p) <class 'weakproxy'> >>> ctypes.addressof(p) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: invalid type >>> ctypes.pointer(p) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: _type_ must have storage info >>> ctypes.string_at(p, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/ctypes/__init__.py", line 491, in string_at return _string_at(ptr, size) ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type -- https://mail.python.org/mailman/listinfo/python-list