[pypy-commit] pypy default: merge adaptations for numpy 1.10 into default

mattip noreply at buildbot.pypy.org
Fri Nov 20 09:22:04 EST 2015


Author: mattip <matti.picus at gmail.com>
Branch: 
Changeset: r80798:479c8ee1f395
Date: 2015-11-20 16:16 +0200
http://bitbucket.org/pypy/pypy/changeset/479c8ee1f395/

Log:	merge adaptations for numpy 1.10 into default

diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -34,6 +34,7 @@
         'nditer': 'nditer.W_NDIter',
 
         'set_docstring': 'support.descr_set_docstring',
+        'VisibleDeprecationWarning': 'support.W_VisibleDeprecationWarning',
     }
     for c in ['MAXDIMS', 'CLIP', 'WRAP', 'RAISE']:
         interpleveldefs[c] = 'space.wrap(constants.%s)' % c
@@ -42,6 +43,7 @@
         from pypy.module.micronumpy.concrete import _setup
         _setup()
 
+
 class UMathModule(MixedModule):
     appleveldefs = {}
     interpleveldefs = {
@@ -138,3 +140,9 @@
         'multiarray': MultiArrayModule,
         'umath': UMathModule,
     }
+
+    def setup_after_space_initialization(self):
+        from pypy.module.micronumpy.support import W_VisibleDeprecationWarning
+        for name, w_type in {'VisibleDeprecationWarning': W_VisibleDeprecationWarning}.items():
+            setattr(self.space, 'w_' + name, self.space.gettypefor(w_type))
+
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -44,7 +44,7 @@
         from pypy.module.micronumpy.strides import calc_strides
         if len(shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             ovfcheck(support.product_check(shape) * dtype.elsize)
         except OverflowError as e:
@@ -69,7 +69,7 @@
         isize = dtype.elsize
         if len(shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             totalsize = ovfcheck(support.product_check(shape) * isize)
         except OverflowError as e:
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -444,7 +444,7 @@
 
     @unwrap_spec(axis1=int, axis2=int)
     def descr_swapaxes(self, space, axis1, axis2):
-        return self
+        raise oefmt(space.w_ValueError, 'bad axis1 argument to swapaxes')
 
     def descr_fill(self, space, w_value):
         self.get_dtype(space).coerce(space, w_value)
@@ -573,7 +573,7 @@
         try:
             ofs, dtype = self.dtype.fields[item]
         except KeyError:
-            raise oefmt(space.w_IndexError, "invalid index")
+            raise oefmt(space.w_ValueError, "no field of name %s", item)
 
         from pypy.module.micronumpy.types import VoidType
         if isinstance(dtype.itemtype, VoidType):
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -65,6 +65,7 @@
     w_KeyError = W_TypeObject("KeyError")
     w_SystemExit = W_TypeObject("SystemExit")
     w_KeyboardInterrupt = W_TypeObject("KeyboardInterrupt")
+    w_VisibleDeprecationWarning = W_TypeObject("VisibleDeprecationWarning")
     w_None = None
 
     w_bool = W_TypeObject("bool")
@@ -402,6 +403,9 @@
         assert isinstance(w_check_class, W_TypeObject)
         return w_exc_type.name == w_check_class.name
 
+    def warn(self, w_msg, w_warn_type):
+        pass
+
 class FloatObject(W_Root):
     tp = FakeSpace.w_float
     def __init__(self, floatval):
diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -457,7 +457,7 @@
     def set_shape(self, space, orig_array, new_shape):
         if len(new_shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
@@ -601,7 +601,7 @@
     def set_shape(self, space, orig_array, new_shape):
         if len(new_shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -18,7 +18,7 @@
         raise oefmt(space.w_TypeError,
                     "argument 1 must be numpy.dtype, not %T", w_dtype)
     if w_dtype.elsize == 0:
-        raise oefmt(space.w_ValueError, "itemsize cannot be zero")
+        raise oefmt(space.w_TypeError, "Empty data-type")
     if not space.isinstance_w(w_state, space.w_str):
         raise oefmt(space.w_TypeError, "initializing object must be a string")
     if space.len_w(w_state) != w_dtype.elsize:
diff --git a/pypy/module/micronumpy/descriptor.py b/pypy/module/micronumpy/descriptor.py
--- a/pypy/module/micronumpy/descriptor.py
+++ b/pypy/module/micronumpy/descriptor.py
@@ -217,6 +217,8 @@
             endian = ignore
         if self.num == NPY.UNICODE:
             size >>= 2
+        if self.num == NPY.OBJECT:
+            return "%s%s" %(endian, basic)
         return "%s%s%s" % (endian, basic, size)
 
     def descr_get_descr(self, space, style='descr', force_dict=False):
@@ -485,7 +487,12 @@
 
     def descr_str(self, space):
         if self.fields:
-            return space.str(self.descr_get_descr(space, style='str'))
+            r = self.descr_get_descr(space, style='str')
+            name = space.str_w(space.str(self.w_box_type))
+            if name != "<type 'numpy.void'>":
+                boxname = space.str(self.w_box_type)
+                r = space.newtuple([self.w_box_type, r])
+            return space.str(r)
         elif self.subdtype is not None:
             return space.str(space.newtuple([
                 self.subdtype.descr_get_str(space),
@@ -497,8 +504,13 @@
                 return self.descr_get_name(space)
 
     def descr_repr(self, space):
+        if isinstance(self.itemtype, types.CharType):
+            return space.wrap("dtype('S1')")
         if self.fields:
             r = self.descr_get_descr(space, style='repr')
+            name = space.str_w(space.str(self.w_box_type))
+            if name != "<type 'numpy.void'>":
+                r = space.newtuple([space.wrap(self.w_box_type), r])
         elif self.subdtype is not None:
             r = space.newtuple([self.subdtype.descr_get_str(space),
                                 self.descr_get_shape(space)])
@@ -942,7 +954,7 @@
     shape_w = space.fixedview(w_shape)
     if len(shape_w) < 1:
         return None
-    elif len(shape_w) == 1 and space.isinstance_w(shape_w[0], space.w_tuple):
+    elif space.isinstance_w(shape_w[0], space.w_tuple):
         # (base_dtype, new_dtype) dtype spectification
         return None
     shape = []
@@ -997,12 +1009,16 @@
         if len(spec) > 0:
             # this is (base_dtype, new_dtype) so just make it a union by setting both
             # parts' offset to 0
-            try:
-                dtype1 = make_new_dtype(space, w_subtype, w_shape, alignment)
-            except:
-                raise
-            raise oefmt(space.w_NotImplementedError, 
-                "(base_dtype, new_dtype) dtype spectification discouraged, not implemented")
+            w_dtype1 = make_new_dtype(space, w_subtype, w_shape, alignment)
+            assert isinstance(w_dtype, W_Dtype)
+            assert isinstance(w_dtype1, W_Dtype)
+            if (w_dtype.elsize != 0 and w_dtype1.elsize != 0 and 
+                    w_dtype1.elsize != w_dtype.elsize):
+                raise oefmt(space.w_ValueError,
+                    'mismatch in size of old and new data-descriptor')
+            retval = W_Dtype(w_dtype.itemtype, w_dtype.w_box_type,
+                    names=w_dtype1.names[:], fields=w_dtype1.fields.copy())
+            return retval
     if space.is_none(w_dtype):
         return cache.w_float64dtype
     if space.isinstance_w(w_dtype, w_subtype):
@@ -1032,19 +1048,22 @@
     elif space.isinstance_w(w_dtype, space.w_tuple):
         w_dtype0 = space.getitem(w_dtype, space.wrap(0))
         w_dtype1 = space.getitem(w_dtype, space.wrap(1))
-        if space.isinstance_w(w_dtype0, space.w_type) and \
-           space.isinstance_w(w_dtype1, space.w_list):
-            #obscure api - (subclass, spec). Ignore the subclass
-            return make_new_dtype(space, w_subtype, w_dtype1, alignment, 
-                        copy=copy, w_shape=w_shape, w_metadata=w_metadata)
-        subdtype = make_new_dtype(space, w_subtype, w_dtype0, alignment, copy)
-        assert isinstance(subdtype, W_Dtype)
-        if subdtype.elsize == 0:
-            name = "%s%d" % (subdtype.kind, space.int_w(w_dtype1))
+        # create a new dtype object
+        l_side = make_new_dtype(space, w_subtype, w_dtype0, alignment, copy)
+        assert isinstance(l_side, W_Dtype)
+        if l_side.elsize == 0 and space.isinstance_w(w_dtype1, space.w_int):
+            #(flexible_dtype, itemsize)
+            name = "%s%d" % (l_side.kind, space.int_w(w_dtype1))
             retval = make_new_dtype(space, w_subtype, space.wrap(name), alignment, copy)
-        else:
-            retval = make_new_dtype(space, w_subtype, w_dtype0, alignment, copy, w_shape=w_dtype1)
-        return _set_metadata_and_copy(space, w_metadata, retval, copy)
+            return _set_metadata_and_copy(space, w_metadata, retval, copy)
+        elif (space.isinstance_w(w_dtype1, space.w_int) or
+                space.isinstance_w(w_dtype1, space.w_tuple) or 
+                space.isinstance_w(w_dtype1, space.w_list) or 
+                isinstance(w_dtype1, W_NDimArray)):
+            #(fixed_dtype, shape) or (base_dtype, new_dtype)
+            retval = make_new_dtype(space, w_subtype, l_side, alignment,
+                                    copy, w_shape=w_dtype1)
+            return _set_metadata_and_copy(space, w_metadata, retval, copy)
     elif space.isinstance_w(w_dtype, space.w_dict):
         return _set_metadata_and_copy(space, w_metadata,
                 dtype_from_dict(space, w_dtype, alignment), copy)
@@ -1122,7 +1141,7 @@
             size = int(name[1:])
         except ValueError:
             raise oefmt(space.w_TypeError, "data type not understood")
-    if char == NPY.CHARLTR:
+    if char == NPY.CHARLTR and size == 0:
         return W_Dtype(
             types.CharType(space),
             elsize=1,
@@ -1133,7 +1152,7 @@
         return new_unicode_dtype(space, size)
     elif char == NPY.VOIDLTR:
         return new_void_dtype(space, size)
-    assert False
+    raise oefmt(space.w_TypeError, 'data type "%s" not understood', name)
 
 
 def new_string_dtype(space, size):
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
@@ -75,7 +75,7 @@
         dtype = space.interp_w(descriptor.W_Dtype, space.call_function(
             space.gettypefor(descriptor.W_Dtype), w_dtype))
         if (dtype.elsize != self.get_dtype().elsize or
-                dtype.is_flexible() or self.get_dtype().is_flexible()):
+                (not dtype.is_record() and self.get_dtype().is_flexible())):
             raise OperationError(space.w_ValueError, space.wrap(
                 "new type not compatible with array."))
         self.implementation.set_dtype(space, dtype)
@@ -116,6 +116,13 @@
                 "index out of range for array"))
         size = loop.count_all_true(arr)
         if arr.ndims() == 1:
+            if self.ndims() > 1 and arr.get_shape()[0] != self.get_shape()[0]:
+                msg = ("boolean index did not match indexed array along"
+                      " dimension 0; dimension is %d but corresponding"
+                      " boolean dimension is %d" % (self.get_shape()[0],
+                      arr.get_shape()[0]))
+                #warning = space.gettypefor(support.W_VisibleDeprecationWarning)
+                space.warn(space.wrap(msg), space.w_VisibleDeprecationWarning)
             res_shape = [size] + self.get_shape()[1:]
         else:
             res_shape = [size]
@@ -278,7 +285,7 @@
     def getfield(self, space, field):
         dtype = self.get_dtype()
         if field not in dtype.fields:
-            raise oefmt(space.w_ValueError, "field named %s not found", field)
+            raise oefmt(space.w_ValueError, "no field of name %s", field)
         arr = self.implementation
         ofs, subdtype = arr.dtype.fields[field][:2]
         # ofs only changes start
@@ -489,10 +496,8 @@
         numpy.swapaxes : equivalent function
         """
         if axis1 == axis2:
-            return self
+            return self.descr_view(space)
         n = self.ndims()
-        if n <= 1:
-            return self
         if axis1 < 0:
             axis1 += n
         if axis2 < 0:
@@ -501,6 +506,8 @@
             raise oefmt(space.w_ValueError, "bad axis1 argument to swapaxes")
         if axis2 < 0 or axis2 >= n:
             raise oefmt(space.w_ValueError, "bad axis2 argument to swapaxes")
+        if n <= 1:
+            return self
         return self.implementation.swapaxes(space, self, axis1, axis2)
 
     def descr_nonzero(self, space):
@@ -899,7 +906,7 @@
                     if cur_shape[i] != 1:
                         raise OperationError(space.w_ValueError, space.wrap(
                             "cannot select an axis to squeeze out "
-                            "which has size greater than one"))
+                            "which has size not equal to one"))
                 else:
                     new_shape.append(cur_shape[i])
         else:
@@ -1374,7 +1381,7 @@
     shape = shape_converter(space, w_shape, dtype)
     if len(shape) > NPY.MAXDIMS:
         raise oefmt(space.w_ValueError,
-            "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+            "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
     if not space.is_none(w_buffer):
         if (not space.is_none(w_strides)):
             strides = [space.int_w(w_i) for w_i in
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -8,6 +8,17 @@
 from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.objspace.std.objspace import StdObjSpace
 from pypy.module.micronumpy import constants as NPY
+from pypy.module.exceptions.interp_exceptions import _new_exception, W_UserWarning
+
+W_VisibleDeprecationWarning = _new_exception('VisibleDeprecationWarning', W_UserWarning,
+    """Visible deprecation warning.
+
+    By default, python will not show deprecation warnings, so this class
+    can be used when a very visible warning is helpful, for example because
+    the usage is most likely a user bug.
+
+    """)
+
 
 def issequence_w(space, w_obj):
     from pypy.module.micronumpy.base import W_NDimArray
diff --git a/pypy/module/micronumpy/test/test_deprecations.py b/pypy/module/micronumpy/test/test_deprecations.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_deprecations.py
@@ -0,0 +1,33 @@
+import py
+import sys
+
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
+
+
+class AppTestDeprecations(BaseNumpyAppTest):
+    spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
+
+    def test_getitem(self):
+        import numpy as np
+        import warnings, sys
+        warnings.simplefilter('error', np.VisibleDeprecationWarning)
+        try:
+            arr = np.ones((5, 4, 3))
+            index = np.array([True])
+            raises(np.VisibleDeprecationWarning, arr.__getitem__, index)
+
+            index = np.array([False] * 6)
+            raises(np.VisibleDeprecationWarning, arr.__getitem__, index)
+
+            index = np.zeros((4, 4), dtype=bool)
+            if '__pypy__' in sys.builtin_module_names:
+                # boolean indexing matches the dims in index
+                # to the first index.ndims in arr, not implemented in pypy yet
+                raises(IndexError, arr.__getitem__, index)
+                raises(TypeError, arr.__getitem__, (slice(None), index))
+            else:
+                raises(np.VisibleDeprecationWarning, arr.__getitem__, index)
+                raises(np.VisibleDeprecationWarning, arr.__getitem__, (slice(None), index))
+        finally:
+            warnings.simplefilter('default', np.VisibleDeprecationWarning)
+
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -345,13 +345,22 @@
 
     def test_can_subclass(self):
         import numpy as np
+        import sys
         class xyz(np.void):
             pass
         assert np.dtype(xyz).name == 'xyz'
         # another obscure API, used in numpy record.py
-        # it seems numpy throws away the subclass type and parses the spec
         a = np.dtype((xyz, [('x', 'int32'), ('y', 'float32')]))
-        assert repr(a) == "dtype([('x', '<i4'), ('y', '<f4')])"
+        assert "[('x', '<i4'), ('y', '<f4')]" in repr(a)
+        assert 'xyz' in repr(a)
+        data = [(1, 'a'), (2, 'bbb')]
+        b = np.dtype((xyz, [('a', int), ('b', object)]))
+        if '__pypy__' in sys.builtin_module_names:
+            raises(NotImplemented, np.array, data, dtype=b)
+        else:
+            arr = np.array(data, dtype=b)
+            assert arr[0][0] == 1
+            assert arr[0][1] == 'a'
 
     def test_index(self):
         import numpy as np
@@ -486,20 +495,11 @@
         class O(object):
             pass
         for o in [object, O]:
-            if self.ptr_size == 4:
-                assert np.dtype(o).str == '|O4'
-            elif self.ptr_size == 8:
-                assert np.dtype(o).str == '|O8'
-            else:
-                assert False,'self._ptr_size unknown'
+            assert np.dtype(o).str == '|O'
         # Issue gh-2798
-        if '__pypy__' in sys.builtin_module_names:
-            a = np.array(['a'], dtype="O")
-            raises(NotImplementedError, a.astype, ("O", [("name", "O")]))
-            skip("(base_dtype, new_dtype) dtype specification discouraged")
         a = np.array(['a'], dtype="O").astype(("O", [("name", "O")]))
         assert a[0] == 'a'
-        assert a == 'a'
+        assert a != 'a'
         assert a['name'].dtype == a.dtype
 
 class AppTestTypes(BaseAppTestDtypes):
@@ -1038,13 +1038,7 @@
             assert d.name == "string64"
             assert d.num == 18
         for i in [1, 2, 3]:
-            d = dtype('c%d' % i)
-            assert d.itemsize == 1
-            assert d.kind == 'S'
-            assert d.type is str_
-            assert d.name == 'string8'
-            assert d.num == 18
-            assert d.str == '|S1'
+            raises(TypeError, dtype, 'c%d' % i)
 
     def test_unicode_dtype(self):
         from numpy import dtype, unicode_
@@ -1068,6 +1062,7 @@
         assert d.char == 'c'
         assert d.kind == 'S'
         assert d.str == '|S1'
+        assert repr(d) == "dtype('S1')"
 
 class AppTestRecordDtypes(BaseNumpyAppTest):
     spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
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
@@ -269,7 +269,7 @@
         assert (y == x.T).all()
 
         exc = raises(ValueError, ndarray, [1,2,256]*10000)
-        assert exc.value[0] == 'sequence too large; must be smaller than 32'
+        assert exc.value[0] == 'sequence too large; cannot be greater than 32'
         exc = raises(ValueError, ndarray, [1,2,256]*10)
         assert exc.value[0] == 'array is too big.'
 
@@ -838,14 +838,19 @@
 
     def test_build_scalar(self):
         from numpy import dtype
+        import sys
         try:
             from numpy.core.multiarray import scalar
         except ImportError:
             from numpy import scalar
         exc = raises(TypeError, scalar, int, 2)
         assert exc.value[0] == 'argument 1 must be numpy.dtype, not type'
-        exc = raises(ValueError, scalar, dtype('void'), 'abc')
-        assert exc.value[0] == 'itemsize cannot be zero'
+        if '__pypy__' in sys.builtin_module_names:
+            exc = raises(TypeError, scalar, dtype('void'), 'abc')
+        else:
+            a = scalar(dtype('void'), 'abc')
+            exc = raises(TypeError, str, a)
+        assert exc.value[0] == 'Empty data-type'
         exc = raises(TypeError, scalar, dtype(float), 2.5)
         assert exc.value[0] == 'initializing object must be a string'
         exc = raises(ValueError, scalar, dtype(float), 'abc')
@@ -1081,14 +1086,6 @@
             for i in range(5):
                 assert a[i] == getattr(c[i], reg_op).__call__(d[i])
 
-    def test_inplace_cast(self):
-        import numpy as np
-        a = np.zeros(5, dtype=np.float64)
-        b = np.zeros(5, dtype=np.complex64)
-        a += b
-        assert a.sum() == 0
-        assert a.dtype is np.dtype(np.float64)
-
     def test_add_list(self):
         from numpy import array, ndarray
         a = array(range(5))
@@ -1965,7 +1962,7 @@
         assert len(a) == 6
         assert (a == [0,1,2,3,4,5]).all()
         assert a.dtype is dtype(int)
-        a = concatenate((a1, a2), axis=1)
+        a = concatenate((a1, a2), axis=0)
         assert (a == [0,1,2,3,4,5]).all()
         a = concatenate((a1, a2), axis=-1)
         assert (a == [0,1,2,3,4,5]).all()
@@ -2013,7 +2010,7 @@
 
         g1 = array([0,1,2])
         g2 = array([[3,4,5]])
-        exc = raises(ValueError, concatenate, (g1, g2), axis=2)
+        exc = raises(ValueError, concatenate, (g1, g2), axis=0)
         assert str(exc.value) == \
                 "all the input arrays must have same number of dimensions"
 
@@ -2129,16 +2126,16 @@
         assert exc.value.message == "'axis' entry 5 is out of bounds [-4, 4)"
         exc = raises(ValueError, a.squeeze, 0)
         assert exc.value.message == "cannot select an axis to squeeze out " \
-                                    "which has size greater than one"
+                                    "which has size not equal to one"
         exc = raises(ValueError, a.squeeze, (1, 1))
         assert exc.value.message == "duplicate value in 'axis'"
 
     def test_swapaxes(self):
         from numpy import array
         x = array([])
-        assert x.swapaxes(0, 2) is x
+        raises(ValueError, x.swapaxes,0, 2)
         x = array([[1, 2]])
-        assert x.swapaxes(0, 0) is x
+        assert x.swapaxes(0, 0) is not x
         exc = raises(ValueError, x.swapaxes, -3, 0)
         assert exc.value.message == "bad axis1 argument to swapaxes"
         exc = raises(ValueError, x.swapaxes, 0, 3)
@@ -2169,7 +2166,7 @@
         # test virtual
         assert ((x + x).swapaxes(0,1) == array([[[ 2,  4,  6], [14, 16, 18]],
                                          [[ 8, 10, 12], [20, 22, 24]]])).all()
-        assert array(1).swapaxes(10, 12) == 1
+        raises(ValueError, array(1).swapaxes, 10, 12)
 
     def test_filter_bug(self):
         from numpy import array
@@ -2410,6 +2407,7 @@
 
     def test_data(self):
         from numpy import array
+        import sys
         a = array([1, 2, 3, 4], dtype='i4')
         assert a.data[0] == '\x01'
         assert a.data[1] == '\x00'
@@ -2418,7 +2416,8 @@
         assert a[1] == 0xff
         assert len(a.data) == 16
         assert type(a.data) is buffer
-        assert a[1:].data._pypy_raw_address() - a.data._pypy_raw_address() == a.strides[0]
+        if '__pypy__' in sys.builtin_module_names:
+            assert a[1:].data._pypy_raw_address() - a.data._pypy_raw_address() == a.strides[0]
 
     def test_explicit_dtype_conversion(self):
         from numpy import array
@@ -2505,7 +2504,7 @@
 
     def test_string_filling(self):
         import numpy
-        a = numpy.empty((10,10), dtype='c1')
+        a = numpy.empty((10,10), dtype='S1')
         a.fill(12)
         assert (a == '1').all()
 
@@ -3073,7 +3072,8 @@
         assert (b == zeros(10)).all()
 
     def test_array_interface(self):
-        from numpy import array, ones
+        from numpy import array
+        import numpy as np
         a = array(2.5)
         i = a.__array_interface__
         assert isinstance(i['data'][0], int)
@@ -3095,9 +3095,10 @@
         assert b_data + 3 * b.dtype.itemsize == c_data
 
         class Dummy(object):
-            def __init__(self, aif=None):
+            def __init__(self, aif=None, base=None):
                 if aif is not None:
                     self.__array_interface__ = aif
+                self.base = base
 
         a = array(Dummy())
         assert a.dtype == object
@@ -3125,12 +3126,22 @@
         assert b.dtype == 'uint8'
         assert b.shape == (50,)
 
-        a = ones((1,), dtype='float16')
+        a = np.ones((1,), dtype='float16')
         b = Dummy(a.__array_interface__)
         c = array(b)
         assert c.dtype == 'float16'
         assert (a == c).all()
 
+        t = np.dtype([("a", np.float64), ("b", np.float64)], align=True)
+        a = np.zeros(10, dtype=t)
+        a['a'] = range(10, 20)
+        a['b'] = range(20, 30)
+        interface = dict(a.__array_interface__)
+        array = np.array(Dummy(interface))
+        assert array.dtype.kind == 'V'
+        array.dtype = a.dtype
+        assert array[5]['b'] == 25
+
     def test_array_indexing_one_elem(self):
         from numpy import array, arange
         raises(IndexError, 'arange(3)[array([3.5])]')
@@ -3726,7 +3737,7 @@
         assert a[()]['y'] == 0
         assert a.shape == ()
         a = zeros(2, dtype=[('x', int), ('y', float)])
-        raises(IndexError, 'a[0]["xyz"]')
+        raises(ValueError, 'a[0]["xyz"]')
         assert a[0]['x'] == 0
         assert a[0]['y'] == 0
         exc = raises(ValueError, "a[0] = (1, 2, 3)")
@@ -3794,7 +3805,7 @@
         exc = raises(IndexError, "arr[3L]")
         assert exc.value.message == "too many indices for array"
         exc = raises(ValueError, "arr['xx'] = 2")
-        assert exc.value.message == "field named xx not found"
+        assert exc.value.message == "no field of name xx"
         assert arr['y'].dtype == a
         assert arr['y'].shape == ()
         assert arr['y'][()]['x'] == 0
@@ -3969,8 +3980,8 @@
             exc = raises(IndexError, "a[0][%d]" % v)
             assert exc.value.message == "invalid index (%d)" % \
                                         (v + 2 if v < 0 else v)
-        exc = raises(IndexError, "a[0]['z']")
-        assert exc.value.message == "invalid index"
+        exc = raises(ValueError, "a[0]['z']")
+        assert exc.value.message == "no field of name z"
         exc = raises(IndexError, "a[0][None]")
         assert exc.value.message == "invalid index"
 
@@ -4153,7 +4164,7 @@
         d = np.ones(3, dtype=[('a', 'i8'), ('b', 'i8')])
         e = np.ones(3, dtype=[('a', 'i8'), ('b', 'i8'), ('c', 'i8')])
         exc = raises(TypeError, abs, a)
-        assert exc.value[0] == 'Not implemented for this type'
+        assert exc.value[0].startswith("ufunc 'absolute' did not contain a loop")
         assert (a == a).all()
         assert not (a != a).any()
         assert (a == b).all()
diff --git a/pypy/module/micronumpy/test/test_scalar.py b/pypy/module/micronumpy/test/test_scalar.py
--- a/pypy/module/micronumpy/test/test_scalar.py
+++ b/pypy/module/micronumpy/test/test_scalar.py
@@ -142,7 +142,7 @@
         assert f.round() == 13.
         assert f.round(decimals=-1) == 10.
         assert f.round(decimals=1) == 13.4
-        assert b.round(decimals=5) is b
+        raises(TypeError, b.round, decimals=5)
         assert f.round(decimals=1, out=None) == 13.4
         assert b.round() == 1.0
 
@@ -404,8 +404,8 @@
         def _do_test(np_type, orig_val, exp_val):
             val = np_type(orig_val)
             assert val == orig_val
-            assert val.swapaxes(10, 20) == exp_val
-            assert type(val.swapaxes(0, 1)) is np_type
+            raises(ValueError, val.swapaxes, 10, 20)
+            raises(ValueError, val.swapaxes, 0, 1)
             raises(TypeError, val.swapaxes, 0, ())
 
         for t in int8, int16, int32, int64:
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -123,7 +123,7 @@
         res = int_func12(a)
         assert len(res) == 2
         assert isinstance(res, tuple)
-        assert (res[0] == a).all()
+        assert all([r is None for r in res[0]]) # ??? no warning or error, just a fail?
         res = sumdiff(2 * a, a)
         assert (res[0] == 3 * a).all()
         assert (res[1] == a).all()
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -450,10 +450,12 @@
 
     @specialize.argtype(1)
     def round(self, v, decimals=0):
-        if decimals != 0:
-            # numpy 1.9.0 compatible
-            return v
-        return Float64(self.space).box(self.unbox(v))
+        if decimals == 0:
+            return Float64(self.space).box(self.unbox(v))
+        # numpy 1.10 compatibility
+        raise oefmt(self.space.w_TypeError, "ufunc casting failure")
+            
+            
 
 class Integer(Primitive):
     _mixin_ = True
@@ -2412,18 +2414,20 @@
                 ofs += size
 
     def coerce(self, space, dtype, w_items):
+        if dtype.is_record():
+            # the dtype is a union of a void and a record,
+            return record_coerce(self, space, dtype, w_items)
         arr = VoidBoxStorage(dtype.elsize, dtype)
         self._coerce(space, arr, 0, dtype, w_items, dtype.shape)
         return boxes.W_VoidBox(arr, 0, dtype)
 
     @jit.unroll_safe
     def store(self, arr, i, offset, box, native):
-        assert i == 0
         assert isinstance(box, boxes.W_VoidBox)
         assert box.dtype is box.arr.dtype
         with arr as arr_storage, box.arr as box_storage:
             for k in range(box.arr.dtype.elsize):
-                arr_storage[k + offset] = box_storage[k + box.ofs]
+                arr_storage[i + k + offset] = box_storage[k + box.ofs]
 
     def readarray(self, arr, i, offset, dtype=None):
         from pypy.module.micronumpy.base import W_NDimArray
@@ -2472,17 +2476,7 @@
 class CharType(StringType):
     char = NPY.CHARLTR
 
-class RecordType(FlexibleType):
-    T = lltype.Char
-    num = NPY.VOID
-    kind = NPY.VOIDLTR
-    char = NPY.VOIDLTR
-
-    def read(self, arr, i, offset, dtype):
-        return boxes.W_VoidBox(arr, i + offset, dtype)
-
-    @jit.unroll_safe
-    def coerce(self, space, dtype, w_item):
+def record_coerce(typ, space, dtype, w_item):
         from pypy.module.micronumpy.base import W_NDimArray
         if isinstance(w_item, boxes.W_VoidBox):
             if dtype == w_item.dtype:
@@ -2520,6 +2514,19 @@
             subdtype.store(arr, 0, ofs, w_box)
         return boxes.W_VoidBox(arr, 0, dtype)
 
+class RecordType(FlexibleType):
+    T = lltype.Char
+    num = NPY.VOID
+    kind = NPY.VOIDLTR
+    char = NPY.VOIDLTR
+
+    def read(self, arr, i, offset, dtype):
+        return boxes.W_VoidBox(arr, i + offset, dtype)
+
+    @jit.unroll_safe
+    def coerce(self, space, dtype, w_item):
+        return record_coerce(self, space, dtype, w_item)
+
     def runpack_str(self, space, s, native):
         raise oefmt(space.w_NotImplementedError,
                     "fromstring not implemented for record types")


More information about the pypy-commit mailing list