Commit 8567f2c2 authored by Stefan Behnel's avatar Stefan Behnel

merge 0.22.x branch into master

parents b8f99d46 e8c8482f
...@@ -511,7 +511,7 @@ cdef class memoryview(object): ...@@ -511,7 +511,7 @@ cdef class memoryview(object):
property shape: property shape:
@cname('__pyx_memoryview_get_shape') @cname('__pyx_memoryview_get_shape')
def __get__(self): def __get__(self):
return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) return tuple([length for length in self.view.shape[:self.view.ndim]])
property strides: property strides:
@cname('__pyx_memoryview_get_strides') @cname('__pyx_memoryview_get_strides')
...@@ -520,15 +520,15 @@ cdef class memoryview(object): ...@@ -520,15 +520,15 @@ cdef class memoryview(object):
# Note: we always ask for strides, so if this is not set it's a bug # Note: we always ask for strides, so if this is not set it's a bug
raise ValueError("Buffer view does not expose strides") raise ValueError("Buffer view does not expose strides")
return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) return tuple([stride for stride in self.view.strides[:self.view.ndim]])
property suboffsets: property suboffsets:
@cname('__pyx_memoryview_get_suboffsets') @cname('__pyx_memoryview_get_suboffsets')
def __get__(self): def __get__(self):
if self.view.suboffsets == NULL: if self.view.suboffsets == NULL:
return [-1] * self.view.ndim return (-1,) * self.view.ndim
return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]])
property ndim: property ndim:
@cname('__pyx_memoryview_get_ndim') @cname('__pyx_memoryview_get_ndim')
...@@ -551,7 +551,7 @@ cdef class memoryview(object): ...@@ -551,7 +551,7 @@ cdef class memoryview(object):
if self._size is None: if self._size is None:
result = 1 result = 1
for length in self.shape: for length in self.view.shape[:self.view.ndim]:
result *= length result *= length
self._size = result self._size = result
...@@ -654,9 +654,8 @@ cdef tuple _unellipsify(object index, int ndim): ...@@ -654,9 +654,8 @@ cdef tuple _unellipsify(object index, int ndim):
return have_slices or nslices, tuple(result) return have_slices or nslices, tuple(result)
cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
cdef int i for suboffset in suboffsets[:ndim]:
for i in range(ndim): if suboffset >= 0:
if suboffsets[i] >= 0:
raise ValueError("Indirect dimensions not supported") raise ValueError("Indirect dimensions not supported")
# #
...@@ -987,9 +986,11 @@ cdef memoryview_fromslice({{memviewslice_name}} memviewslice, ...@@ -987,9 +986,11 @@ cdef memoryview_fromslice({{memviewslice_name}} memviewslice,
result.view.shape = <Py_ssize_t *> result.from_slice.shape result.view.shape = <Py_ssize_t *> result.from_slice.shape
result.view.strides = <Py_ssize_t *> result.from_slice.strides result.view.strides = <Py_ssize_t *> result.from_slice.strides
# only set suboffsets if actually used, otherwise set to NULL to improve compatibility
result.view.suboffsets = NULL result.view.suboffsets = NULL
for i in range(ndim): for suboffset in result.from_slice.suboffsets[:ndim]:
if result.from_slice.suboffsets[i] >= 0: if suboffset >= 0:
result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
break break
...@@ -1028,10 +1029,7 @@ cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst): ...@@ -1028,10 +1029,7 @@ cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst):
for dim in range(memview.view.ndim): for dim in range(memview.view.ndim):
dst.shape[dim] = shape[dim] dst.shape[dim] = shape[dim]
dst.strides[dim] = strides[dim] dst.strides[dim] = strides[dim]
if suboffsets == NULL: dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1
dst.suboffsets[dim] = -1
else:
dst.suboffsets[dim] = suboffsets[dim]
@cname('__pyx_memoryview_copy_object') @cname('__pyx_memoryview_copy_object')
cdef memoryview_copy(memoryview memview): cdef memoryview_copy(memoryview memview):
...@@ -1295,21 +1293,21 @@ cdef int memoryview_copy_contents({{memviewslice_name}} src, ...@@ -1295,21 +1293,21 @@ cdef int memoryview_copy_contents({{memviewslice_name}} src,
return 0 return 0
@cname('__pyx_memoryview_broadcast_leading') @cname('__pyx_memoryview_broadcast_leading')
cdef void broadcast_leading({{memviewslice_name}} *slice, cdef void broadcast_leading({{memviewslice_name}} *mslice,
int ndim, int ndim,
int ndim_other) nogil: int ndim_other) nogil:
cdef int i cdef int i
cdef int offset = ndim_other - ndim cdef int offset = ndim_other - ndim
for i in range(ndim - 1, -1, -1): for i in range(ndim - 1, -1, -1):
slice.shape[i + offset] = slice.shape[i] mslice.shape[i + offset] = mslice.shape[i]
slice.strides[i + offset] = slice.strides[i] mslice.strides[i + offset] = mslice.strides[i]
slice.suboffsets[i + offset] = slice.suboffsets[i] mslice.suboffsets[i + offset] = mslice.suboffsets[i]
for i in range(offset): for i in range(offset):
slice.shape[i] = 1 mslice.shape[i] = 1
slice.strides[i] = slice.strides[0] mslice.strides[i] = mslice.strides[0]
slice.suboffsets[i] = -1 mslice.suboffsets[i] = -1
# #
### Take care of refcounting the objects in slices. Do this seperately from any copying, ### Take care of refcounting the objects in slices. Do this seperately from any copying,
......
...@@ -1012,3 +1012,13 @@ def test_assignment_in_conditional_expression(bint left): ...@@ -1012,3 +1012,13 @@ def test_assignment_in_conditional_expression(bint left):
c = a if left else b c = a if left else b
for i in range(c.shape[0]): for i in range(c.shape[0]):
print c[i] print c[i]
def test_cpython_offbyone_issue_23349():
"""
>>> print(test_cpython_offbyone_issue_23349())
testing
"""
cdef unsigned char[:] v = bytearray(b"testing")
# the following returns 'estingt' without the workaround
return bytearray(v).decode('ascii')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment