[Python-Dev] ctypes, memory mapped files and context manager

Hans-Peter Jansen hpj at urpla.net
Thu Jan 5 09:09:48 EST 2017


Hi Nick,

On Donnerstag, 5. Januar 2017 12:37:20 Nick Coghlan wrote:
> I don't know ctypes well enough myself to comment on the idea of
> offering fully deterministic cleanup, but the closest you could get to
> that without requiring a change to ctypes is to have the context
> manager introduce a layer of indirection:
> 
>     class _T_data(ctypes.Structure):
>         _fields = [("foo", ctypes.c_uint32)]
> 
>     class T:
>         def __init__(self, buffer):
>             self.data = _T_data.from_buffer(buffer)
>         def close(self):
>             self.data = None
> 
>     @contextmanager
>     def map_struct(m, n):
>         m.resize(n * mmap.PAGESIZE)
>         mapped = T(m)
>         try:
>             yield mapped
>         finally:
>             mapped.close()
> 
> Client code would then need to consistently access the struct through
> the data attribute:
> 
>     with map_struct(m, 1) as a:
>         a.data.foo = 1
>     with map_struct(m, 2) as b:
>         b.data.foo = 2

Thank you very much. Nice idea, indeed. 

Here's a slightly more complex example incorporating your idea:
https://gist.github.com/frispete/97c27e24a0aae1bcaf1375e2e463d239#file-ctypes_mmap_ctx2-py

I'm not sure, if I like the resulting code more than the dreaded dels.
Real code based on this approach tends to be much more complex, and 
suffers appropriately.

Anyway, your solution is working fine, and provides a choice.
Much appreciated, Nick.

@ctypes developers: with an unmap operation available, we wouldn't need 
to go through these hoops, and ctypes powers would become even more 
accessible for such cool use cases ;)...

For now, I'm about to resign from using a context manager at all, since 
it uglifies the code in one way or another without buying much..

Cheers,
Pete


More information about the Python-Dev mailing list