-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
memoryview.__len__ should raise an exception for 0d buffers #83791
Comments
Right now, the behavior is: >>> import numpy as np
>>> arr_0d = np.array(42)
>>> mem_0d = memoryview(arr_0d)
>>> len(mem_0d)
1
>>> mem_0d[0]
TypeError: invalid indexing of 0-dim memory It seems bizarre to have this object pretend to be a sequence when you ask for its length, yet not behave like one when you actually try to use this length. I'd suggest cpython should behave like numpy here, and fail: >>> len(arr_0d)
TypeError: len() of unsized object Perhaps --- Wasn't sure how to classify this, feel free to reclassify |
The change looks reasonable, but unfortunately this is a long-standing It is also present in 2.7 (the previous implementation) and documented https://docs.python.org/3/library/stdtypes.html#memoryview I think I documented it because it looked strange back then, too. |
Thanks for pointing out the docs reference, I updated the patch to reword that section. There's a sentence right before the one you draw attention to which to me reads as another argument to change this:
On Python 2.7, this gives >>> len(view_0d)
1
>>> len(view_0d.tolist())
NotImplementedError: tolist() only supports one-dimensional objects On Python 3.8 before my patch, this gives: >>> len(view_0d)
1
>>> len(view_0d.tolist())
TypeError: object of type 'int' has no len() On Python 3.8, with my patch, this gives: >>> len(view_0d)
TypeError: 0-dim memory has no length
>>> len(view_0d.tolist())
TypeError: object of type 'int' has no len() As I read it, only with my patch is this sentence satisfied by the implementation. |
But iterating it raises different type of exception, wish obscure message. >>> import ctypes
>>> mem_0d = memoryview(ctypes.c_uint8(42))
>>> list(mem_0d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NotImplementedError: memoryview: unsupported format <B Should not '<B' and be equivalent to '>B' and just 'B'? Would not adding support of formats with specified endianess make 0-dimensional memoryview objects iterable? |
memoryview can store anything, but only access and display You can construct all sorts of formats that memoryview cannot >>> x = array(1, "c")
>>> x
array(b'1', dtype='|S1')
>>> y = memoryview(x)
>>>
>>> list(y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NotImplementedError: memoryview: unsupported format 1s I don't think that the message is obscure, since all these |
It is surprising the endianess of byte matters. |
list() has to *interpret* the endianness to display it. The endianness I suggest to look at XND, which is a memoryview on steroids and |
Changes the behaviour of `len` on a zero-dimensional `memoryview` to raise `TypeError`. Previously, `len` would return `1`.
Closed by #18463 |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: