Make a memoryview read-only in Python pre-3.8

768 Views Asked by At

Python 3.8 added the memoryview.toreadonly() method. But is there a way to make a read-only memoryview in previous version of python -- specifically Python 3.5 and 3.3?

For a little bit more background, I use memoryviews to share parts of large binary blobs between objects. Sometimes the blob is an in-memory byte object, but sometimes it is also a read/write mmapped file. And I would like to avoid modifications by mistake of the underlying file through the memoryviews.

1

There are 1 best solutions below

0
blhsing On

You can create a read-only wrapper/proxy class for memoryview to deny setter and deleter calls. For getter calls, make sure to wrap the sliced view in another instance of the read-only proxy class if a slice is requested:

class ReadonlyMemoryView:
    def __init__(self, obj):
        self.view = memoryview(obj)

    def __getitem__(self, index):
        value = self.view[index]
        if isinstance(index, slice):
            return self.__class__(value)
        return value

    def __setitem__(self, index, value):
        raise TypeError('cannot modify read-only memory')

    def __delitem__(self, index):
        raise TypeError('cannot modify read-only memory')

    def __getattr__(self, name):
        return getattr(self.view, name)

so that:

m = ReadonlyMemoryView(bytearray(range(10)))
print(m[3:7][1:3].tolist())
m[3] = 1

outputs:

[4, 5]

and produces:

Traceback (most recent call last):
  File "prog.py", line 22, in <module>
  File "prog.py", line 12, in __setitem__
TypeError: cannot modify read-only memory

Demo of the code running on Python 2.7: https://ideone.com/2iivHt