ctypes, memory mapped files and context manager

eryk sun eryksun at gmail.com
Thu Dec 29 16:27:56 EST 2016


On Thu, Dec 29, 2016 at 12:18 PM, Hans-Peter Jansen <hpj at 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


More information about the Python-list mailing list