[pypy-svn] r71559 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test

electronicru at codespeak.net electronicru at codespeak.net
Sun Feb 28 17:54:23 CET 2010


Author: electronicru
Date: Sun Feb 28 17:54:21 2010
New Revision: 71559

Modified:
   pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
Log:
Added tests for many errors; mdarray's slice setitem() is debugged and tested now.


Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py	Sun Feb 28 17:54:21 2010
@@ -1,7 +1,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.interpreter.gateway import interp2app
-from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.baseobjspace import W_Root, UnpackValueError
 from pypy.objspace.std.sliceobject import W_SliceObject
 from pypy.rlib.debug import make_sure_not_resized
 
@@ -16,6 +16,7 @@
 from pypy.module.micronumpy.dtype import unwrap_int, coerce_int
 from pypy.module.micronumpy.dtype import unwrap_float, coerce_float
 from pypy.module.micronumpy.dtype import create_factory
+#import pdb; pdb.set_trace()
 
 def compute_pos(space, indexes, dim):
     current = 1
@@ -34,60 +35,108 @@
 
 def compute_slices(space, slices, dims):
     slices = space.fixedview(slices)
-    if len(slices) > len(dims):
-        raise OperationError(space.w_IndexError,
-                             space.wrap('too many indices'))
-    strides = []
-    i = 1
-    for dim in dims:
-        strides.append(i)
-        i *= dim
+    strides = make_sure_not_resized([0]*len(dims))
+    stride = 1
+    for i in range(len(dims)-1, -1, -1):
+        strides[i] = stride
+        stride *= dims[i]
     shape = dims[:]
-    strides.reverse()
     newshape = []
     extract = [0]
-    slicelen = i #saved
+    slicelen = stride #saved
+    unoptimized = True
     for i in range(len(slices)):
+        factor = slicelen / strides[i-1] if i>0 else 1
         w_index = slices[i]
         if isinstance(w_index, W_SliceObject):
-            newextract = []
             l = shape[i]
             stride = strides[i]
             start, stop, step, slen = w_index.indices4(space, l)
             if slen == 0:
                 extract = []
+                newshape.append(0)
                 continue #as in numpy
             newshape.append(slen)
+            # I suspect that fiendish difficulty while will understand this code.
+            # Please, understand before to edit.
             if step == 1:
-                for i in range(len(extract)):
-                    extract[i] += start*stride
+                start *= stride
+                if unoptimized:
+                    for j in range(len(extract)):
+                        extract[j] += start
+                    unoptimized = False
+                else:
+                    newextract = make_sure_not_resized([0]*len(extract)*factor)
+                    prestride = strides[i-1]
+                    for j in range(len(extract)):
+                        jf = j*factor
+                        st = extract[j]
+                        for k in range(factor):
+                            newextract[jf+k] = st + start
+                            st += prestride
+                    extract = newextract
                 slicelen = stride*slen
             else:
-                for i in range(len(extract)):
-                    st = extract[i]
-                    for j in range(slicelength):
-                        newextract.append(st+start*stride)
-                        start += step
+                if unoptimized:
+                    newextract = make_sure_not_resized([0]*len(extract)*slen)
+                    for j in range(len(extract)):
+                        js = j*slen
+                        st = extract[j]
+                        index = start
+                        for k in range(slen):
+                            newextract[js + k] = st + index*stride
+                            index += step
+                else:
+                    newextract = make_sure_not_resized([0]*len(extract)*factor*slen)
+                    prestride = strides[i-1]
+                    for j in range(len(extract)):
+                        st = extract[j]
+                        jfs = j*factor*slen
+                        for f in range(factor):
+                            fs = f*slen
+                            index = start
+                            for k in range(slen):
+                                newextract[jfs+fs+k] = st + index*stride
+                                index +=step
+                            st += prestride
+                    unoptimized = True
                 extract = newextract
                 slicelen = stride
         elif space.is_w(w_index, space.w_Ellipsis):
             newshape.append(shape[i])
+            unoptimized = False
         else: #Must be integer
             try:
                 index = space.int_w(w_index)
             except TypeError, e:
                 raise OperationError(space.w_IndexError,
                                      space.wrap('Wrong index'))
+            if not (-shape[i] <= index < shape[i]):
+                raise OperationError(space.w_IndexError,
+                                     space.wrap('index out of range'))
+            if index < 0:
+                index += shape[i]
             stride = strides[i]
             start = index*stride
-            for i in range(len(extract)):
-                extract[i] += start
+            if unoptimized:
+                for j in range(len(extract)):
+                    extract[j] += start
+            else:
+                newextract = make_sure_not_resized([0]*len(extract)*factor)
+                prestride = strides[i-1]
+                for j in range(len(extract)):
+                    jf = j*factor
+                    st = extract[j]
+                    for k in range(factor):
+                        newextract[jf+k] = st + start
+                        st += prestride
+                extract = newextract
             #No adding for shape
             slicelen = stride
 
-        newshape.extend(shape[i+1:]) #add rest of shape
-        #all slices are absolutely eqi-length
-        return newshape, extract, slicelen
+    newshape.extend(shape[i+1:]) #add rest of shape
+    #all slices are absolutely eqi-length
+    return newshape, extract, slicelen
 
 
 class BaseMultiDimArray(BaseNumArray): pass
@@ -193,14 +242,14 @@
         def _internal_load(self, w_xs, shape, indexes):
             space = self.space
             length = shape[0]
-            xs = space.fixedview(w_xs, length)
             shapemismatch = OperationError(space.w_ValueError,
                                            space.wrap('shape mismatch'))
+            try:
+                xs = space.fixedview(w_xs, length)
+            except UnpackValueError:
+                raise shapemismatch
             for i in range(length):
-                try:
-                    w_x = xs[i]
-                except IndexError:
-                    raise shapemismatch
+                w_x = xs[i]
                 try:
                     space.iter(w_x)
                 except OperationError, e:
@@ -254,10 +303,19 @@
 
         def descr_setitem(self, w_index, w_value):
             space = self.space
+            validate_index(self, space, w_index)
+            try:
+                space.iter(w_index)
+            except OperationError, e:
+                if not (e.match(space, space.w_IndexError) or
+                        e.match(space, space.w_TypeError)):
+                    raise
+                w_index = space.newlist([w_index])
             try:
                 indexes = self._unpack_indexes(space, w_index)
             except OperationError, e:
-                if not e.match(space, space.w_IndexError):
+                if not (e.match(space, space.w_IndexError) or
+                        e.match(space, space.w_TypeError)):
                     #not raised by _unpack_indexes
                     raise
                 shape, regions, lslice = \
@@ -271,10 +329,10 @@
                     for start in regions:
                         self.storage[start:start+lslice]=[value]*lslice
                     return
-                arr = array_fromseq(space, w_value)
+                arr = array_fromseq(space, w_value, None)
                 ls = len(arr.shape)
-                lss = len(self.shape)
-                if not (ls <= lss and arr.shape == self.shape[lss-ls:lss]):
+                lss = len(shape)
+                if not (ls <= lss and list(arr.shape) == shape[lss-ls:lss]):
                     raise OperationError(space.w_ValueError,
                                          space.wrap('array dimensions '
                                          'are not compatible for copy'))

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py	Sun Feb 28 17:54:21 2010
@@ -143,6 +143,15 @@
             space = self.space
             i = 0
             for x in space.fixedview(w_values, self.len()):
+                try:
+                    space.iter(x)
+                except OperationError, e:
+                    if not e.match(space, space.w_TypeError):
+                        raise
+                else:
+                    raise OperationError(space.w_ValueError,
+                                           space.wrap('shape mismatch'))
+
                 self.storage[i] = coerce(space, x)
                 i += 1
 

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py	Sun Feb 28 17:54:21 2010
@@ -26,6 +26,7 @@
     def test_sdarray_operators(self):
         from numpy import array
         from operator import mul, div, add, sub
+        compare = self.compare
         d = range(1, self.length)
         #skip('overkill...')
         for data_type in (int, float):
@@ -35,7 +36,6 @@
             ar2 = array(data)
             for operator in (mul, div, add, sub):
                 for value in xrange(1, 16):
-                    compare = self.compare
                     assert compare(operator(ar2, value), [operator(x, value) for x in data])
                 assert compare(operator(ar, ar2), [operator(x, y) for (x, y) in zip(ar, ar2)])
 
@@ -145,6 +145,14 @@
                    return result
            return gen_array
            """)
+        cls.w_compare = cls.space.appexec([],
+        """():
+           def compare(a, b):
+               for x, y in zip(a, b):
+                   if x != y: return False
+                   assert type(x) == type(y)
+               return True
+           return compare""")
                                 
 
     def test_multidim(self):
@@ -172,6 +180,9 @@
         assert len(ar) == 3
         assert ar.shape == (3, 2)
 
+        raises(ValueError, array, [[2, 3, 4], [5, 6]])
+        raises(ValueError, array, [2, [3, 4]])
+
     def test_getset(self):
         from numpy import zeros
         ar = zeros((3, 3, 3), dtype=int)
@@ -189,19 +200,38 @@
         from numpy import array
         ar = array([range(i*3, i*3+3) for i in range(3)])
         assert len(ar) == 3
-        #skip("mdarray.shape currently is a list instead of a tuple as it should be")
         assert ar.shape == (3, 3)
         for i in range(3):
             for j in range(3):
                 assert ar[i, j] == i*3+j
     
-    def test_various_slices(self):
+    def test_get_set_slices(self):
         from numpy import array
         gen_array = self.gen_array
+        compare = self.compare
+        #getitem
         ar = array(gen_array((3,3)))
         s1 = ar[0]
         assert s1[1]==1
         s2 = ar[1:3]
         assert s2[0][0] == 3
+        raises(IndexError, ar.__getitem__, 'what a strange index')
+        raises(IndexError, ar.__getitem__, (2, 2, 2)) #too many
+        raises(IndexError, ar.__getitem__, 5)
+        raises(IndexError, ar.__getitem__, (0, 6))
+        #print ar[2:2].shape
+        assert 0 in ar[2:2].shape
+        assert compare(ar[-1], ar[2])
+        assert compare(ar[2:3][0], ar[2])
+        assert compare(ar[1, 0::2], [3, 5])
+        assert compare(ar[0::2, 0], [0, 6])
+        #setitem
+        ar[2] = 3
+        assert ar[2, 0] == ar[2, 1] == ar[2, 2] == 3
+        raises(ValueError, ar.__setitem__, slice(2, 3), [1])
+        ar[2] = [0, 1, 2]
+        assert compare(ar[0], ar[2])
+        assert compare(ar[..., 0], [0, 3, 0])
+
 
             



More information about the Pypy-commit mailing list