-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
PEP 574: update #883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PEP 574: update #883
Conversation
…" hook Communicated by Martin Gfeller.
Actually, it seems I may have to make the contiguity requirement a bit stronger and mandate C-contiguous buffers. The reason is that, in pure Python, there doesn't seem to be any way to read the byte contents of a Fortran-contiguous buffer in physical memory order. Consider this: >>> array = _testbuffer.ndarray(list(range(6)), format="B", shape=(3, 2), strides=(1, 3))
>>> array.tolist()
[[0, 3], [1, 4], [2, 5]]
>>> array.c_contiguous
False
>>> array.f_contiguous
True
>>> m = memoryview(array)
>>> m.tobytes()
b'\x00\x03\x01\x04\x02\x05'
>>> bytes(m)
b'\x00\x03\x01\x04\x02\x05' Or with Numpy: >>> a = np.arange(12, dtype='int8').reshape((3,4))
>>> bytes(a)
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b'
>>> bytes(a.T)
b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b'
>>> memoryview(a).tobytes()
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b'
>>> memoryview(a.T).tobytes()
b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b' ... the logical transposition affects the bytes copy, even though the underlying memory contents are identical. This is not a problem in C, which has naturally access to the memory pointed to by a It's a bit unfortunate. @skrah do you see a way of achieving this? |
Hmm, I thought |
It can handle ND input:
>> x = np.array(list(range(6)), dtype="int64").reshape(2,3)
>> m = memoryview(x)
>> m.cast('B').tolist()
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0]
|
But not Fortran-contiguous data, which is the issue here: >>> m = memoryview(x.T)
>>> m.cast('B').tobytes()
Traceback (most recent call last):
File "<ipython-input-6-80a67b12e997>", line 1, in <module>
m.cast('B').tobytes()
TypeError: memoryview: casts are restricted to C-contiguous views |
D'oh :( I don't believe there was any philosophical objection behind that omission, though - just a lack of a concrete use case to justify the extra complexity in the code. It does raise a question for the pickle 5 spec though: even if the memoryview limitation is resolved in Python 3.8, would the pickle5 backport library be able to unpickle Fortran-contiguous data on older versions? |
Unpickling will depend on the |
Hmm... Thinking about this again, I could add the required API to |
Having it work in the |
Make it a requirement that buffers are contiguous. Efficient tooling for non-contiguous buffers is not available from CPython currently, and consumers shouldn't be required to implement their own handling.
Also add a bit of trivia about an undocumented ZODB-specific
cPickle
hook.