Author: mattip <[email protected]>
Branch: numpy-fixes
Changeset: r77301:3a04c1efa907
Date: 2015-05-12 23:15 +0300
http://bitbucket.org/pypy/pypy/changeset/3a04c1efa907/

Log:    test, fix array bound overflow caused by not recalculating
        backstrides

diff --git a/pypy/module/micronumpy/ndarray.py 
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -864,8 +864,12 @@
                     raise OperationError(space.w_ValueError, space.wrap(
                         "new type not compatible with array."))
                 # Adapt the smallest dim to the new itemsize
-                minstride = strides[0]
-                mini = 0
+                if self.get_order() == 'F':
+                    minstride = strides[0]
+                    mini = 0
+                else:
+                    minstride = strides[-1]
+                    mini = len(strides) - 1
                 for i in range(len(strides)):
                     if strides[i] < minstride:
                         minstride = strides[i]
@@ -874,7 +878,8 @@
                     raise OperationError(space.w_ValueError, space.wrap(
                         "new type not compatible with array."))
                 new_shape[mini] = new_shape[mini] * old_itemsize / new_itemsize
-                strides[mini] = strides[mini] * new_itemsize / old_itemsize    
+                strides[mini] = strides[mini] * new_itemsize / old_itemsize
+                backstrides[mini] = strides[mini] * new_shape[mini]
         if dtype.is_object() != impl.dtype.is_object():
             raise oefmt(space.w_ValueError, 'expect trouble in ndarray.view,'
                 ' one of target dtype or dtype is object dtype')
diff --git a/pypy/module/micronumpy/test/test_iterators.py 
b/pypy/module/micronumpy/test/test_iterators.py
--- a/pypy/module/micronumpy/test/test_iterators.py
+++ b/pypy/module/micronumpy/test/test_iterators.py
@@ -66,6 +66,29 @@
         assert s.offset == 1
         assert s._indices == [1,0]
 
+    def test_one_in_shape(self):
+        strides = [16, 4, 8]
+        shape   = [3,  4, 1]
+        backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
+        assert backstrides == [32, 12, 0]
+        i = ArrayIter(MockArray(shape, strides), support.product(shape), shape,
+                      strides, backstrides)
+        assert not i.contiguous
+        s = i.reset()
+        for j in range(3):
+            s = i.next(s)
+        assert s.offset == 12
+        assert not i.done(s)
+        assert s._indices == [0, 3, 0]
+        while not i.done(s):
+            old_indices = s._indices[:]
+            old_offset = s.offset
+            s = i.next(s)
+        assert s.offset == 0
+        assert s._indices == [0, 0, 0]
+        assert old_indices == [2, 3, 0]
+        assert old_offset == 44
+
     def test_iterator_goto(self):
         shape = [3, 5]
         strides = [1, 3]
diff --git a/pypy/module/micronumpy/test/test_ndarray.py 
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -1818,7 +1818,7 @@
         y = x.view(dtype='int16')
 
     def test_view_of_slice(self):
-        from numpy import empty
+        from numpy import empty, dtype
         x = empty([6], 'uint32')
         x.fill(0xdeadbeef)
         s = x[::3]
@@ -1834,6 +1834,12 @@
         v = s.view(y.__class__)
         assert v.strides == (4, 24)
 
+        a = empty([3, 2, 1], dtype='float64')
+        b = a.view(dtype('uint32'))
+        assert b.strides == (16, 8, 4)
+        assert b.shape == (3, 2, 2)
+        b.fill(0xdeadbeef)
+
     def test_tolist_scalar(self):
         from numpy import dtype
         int32 = dtype('int32').type
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to