Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c3b3924

Browse files
committed
Issue #4580: slicing of memoryviews when itemsize != 1 is wrong.
Also fix len() to return number of items rather than length in bytes. I'm sorry it was not possible for me to work on this without reindenting a bit some stuff around. The indentation in memoryobject.c is a mess, I'll open a separate bug for it.
1 parent 8bcddca commit c3b3924

8 files changed

Lines changed: 299 additions & 218 deletions

File tree

Include/object.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,18 @@ typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
144144
typedef struct bufferinfo {
145145
void *buf;
146146
PyObject *obj; /* owned reference */
147-
Py_ssize_t len;
148-
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
149-
pointed to by strides in simple case.*/
150-
int readonly;
151-
int ndim;
152-
char *format;
153-
Py_ssize_t *shape;
154-
Py_ssize_t *strides;
155-
Py_ssize_t *suboffsets;
156-
void *internal;
147+
Py_ssize_t len;
148+
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
149+
pointed to by strides in simple case.*/
150+
int readonly;
151+
int ndim;
152+
char *format;
153+
Py_ssize_t *shape;
154+
Py_ssize_t *strides;
155+
Py_ssize_t *suboffsets;
156+
Py_ssize_t smalltable[2]; /* static store for shape and strides of
157+
mono-dimensional buffers. */
158+
void *internal;
157159
} Py_buffer;
158160

159161
typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);

Lib/ctypes/test/test_pep3118.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ def test_native_types(self):
2525
v = memoryview(ob)
2626
try:
2727
self.failUnlessEqual(normalize(v.format), normalize(fmt))
28-
self.failUnlessEqual(len(v), sizeof(ob))
28+
if shape is not None:
29+
self.failUnlessEqual(len(v), shape[0])
30+
else:
31+
self.failUnlessEqual(len(v) * sizeof(itemtp), sizeof(ob))
2932
self.failUnlessEqual(v.itemsize, sizeof(itemtp))
3033
self.failUnlessEqual(v.shape, shape)
3134
# ctypes object always have a non-strided memory block
@@ -37,7 +40,7 @@ def test_native_types(self):
3740
n = 1
3841
for dim in v.shape:
3942
n = n * dim
40-
self.failUnlessEqual(v.itemsize * n, len(v))
43+
self.failUnlessEqual(n * v.itemsize, len(v.tobytes()))
4144
except:
4245
# so that we can see the failing type
4346
print(tp)
@@ -49,7 +52,10 @@ def test_endian_types(self):
4952
v = memoryview(ob)
5053
try:
5154
self.failUnlessEqual(v.format, fmt)
52-
self.failUnlessEqual(len(v), sizeof(ob))
55+
if shape is not None:
56+
self.failUnlessEqual(len(v), shape[0])
57+
else:
58+
self.failUnlessEqual(len(v) * sizeof(itemtp), sizeof(ob))
5359
self.failUnlessEqual(v.itemsize, sizeof(itemtp))
5460
self.failUnlessEqual(v.shape, shape)
5561
# ctypes object always have a non-strided memory block
@@ -61,7 +67,7 @@ def test_endian_types(self):
6167
n = 1
6268
for dim in v.shape:
6369
n = n * dim
64-
self.failUnlessEqual(v.itemsize * n, len(v))
70+
self.failUnlessEqual(n, len(v))
6571
except:
6672
# so that we can see the failing type
6773
print(tp)

Lib/test/test_io.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def test_close_flushes(self):
260260

261261
def test_array_writes(self):
262262
a = array.array('i', range(10))
263-
n = len(memoryview(a))
263+
n = len(a.tostring())
264264
f = io.open(support.TESTFN, "wb", 0)
265265
self.assertEqual(f.write(a), n)
266266
f.close()

0 commit comments

Comments
 (0)