[pypy-commit] pypy dtypes-compatability: add and modify tests for numpy compatibility, fix shape failures

mattip noreply at buildbot.pypy.org
Wed Jun 10 22:06:15 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: dtypes-compatability
Changeset: r78016:1bb47ca4e3f7
Date: 2015-06-10 20:21 +0300
http://bitbucket.org/pypy/pypy/changeset/1bb47ca4e3f7/

Log:	add and modify tests for numpy compatibility, fix shape failures

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
@@ -58,7 +58,7 @@
 
     @enforceargs(byteorder=SomeChar())
     def __init__(self, itemtype, w_box_type, byteorder=NPY.NATIVE, names=[],
-                 fields={}, elsize=None, shape=[], subdtype=None):
+                 fields={}, elsize=-1, shape=[], subdtype=None):
         self.itemtype = itemtype
         self.w_box_type = w_box_type
         if itemtype.get_element_size() == 1 or isinstance(itemtype, types.ObjectType):
@@ -66,7 +66,7 @@
         self.byteorder = byteorder
         self.names = names
         self.fields = fields
-        if elsize is None:
+        if elsize < 0:
             elsize = itemtype.get_element_size()
         self.elsize = elsize
         self.alignment = itemtype.alignment
@@ -277,8 +277,8 @@
         self.names = names
 
     def descr_del_names(self, space):
-        raise OperationError(space.w_AttributeError, space.wrap(
-            "Cannot delete dtype names attribute"))
+        raise oefmt(space.w_AttributeError, 
+            "Cannot delete dtype names attribute")
 
     def eq(self, space, w_other):
         w_other = space.call_function(space.gettypefor(W_Dtype), w_other)
@@ -429,6 +429,7 @@
 
         version = space.wrap(3)
         endian = self.byteorder
+        flags = 0
         if endian == NPY.NATIVE:
             endian = NPY.NATBYTE
         subdescr = self.descr_get_subdtype(space)
@@ -436,14 +437,14 @@
         values = self.descr_get_fields(space)
         if self.is_flexible():
             w_size = space.wrap(self.elsize)
-            alignment = space.wrap(self.alignment)
+            w_alignment = space.wrap(self.alignment)
         else:
             w_size = space.wrap(-1)
-            alignment = space.wrap(-1)
-        flags = space.wrap(0)
+            w_alignment = space.wrap(-1)
+        w_flags = space.wrap(flags)
 
         data = space.newtuple([version, space.wrap(endian), subdescr,
-                               names, values, w_size, alignment, flags])
+                               names, values, w_size, w_alignment, w_flags])
         return space.newtuple([w_class, builder_args, data])
 
     def descr_setstate(self, space, w_data):
@@ -564,8 +565,7 @@
 
 
 def dtype_from_dict(space, w_dict):
-    raise OperationError(space.w_NotImplementedError, space.wrap(
-        "dtype from dict"))
+    raise oefmt(space.w_NotImplementedError, "dtype from dict")
 
 
 def dtype_from_spec(space, w_spec):
@@ -612,22 +612,37 @@
 def descr__new__(space, w_subtype, w_dtype, align=False, w_copy=None, w_shape=None):
     # align and w_copy are necessary for pickling
     cache = get_dtype_cache(space)
-
     if w_shape is not None and (space.isinstance_w(w_shape, space.w_int) or
                                 space.len_w(w_shape) > 0):
         subdtype = descr__new__(space, w_subtype, w_dtype, align, w_copy)
         assert isinstance(subdtype, W_Dtype)
         size = 1
         if space.isinstance_w(w_shape, space.w_int):
+            dim = space.int_w(w_shape)
+            if dim == 1:
+                return subdtype
             w_shape = space.newtuple([w_shape])
         shape = []
         for w_dim in space.fixedview(w_shape):
-            dim = space.int_w(w_dim)
+            try:
+                dim = space.int_w(w_dim)
+            except OperationError as e:
+                if e.match(space, space.w_OverflowError):
+                    raise oefmt(space.w_ValueError, "invalid shape in fixed-type tuple.")
+                else:
+                    raise
+            if dim > 2 ** 32 -1:
+                raise oefmt(space.w_ValueError, "invalid shape in fixed-type tuple: "
+                      "dimension does not fit into a C int.")
+            elif dim < 0:
+                raise oefmt(space.w_ValueError, "invalid shape in fixed-type tuple: "
+                      "dimension smaller than zero.")
             shape.append(dim)
             size *= dim
-        if size == 1:
-            return subdtype
         size *= subdtype.elsize
+        if size >= 2 ** 31:
+            raise oefmt(space.w_ValueError, "invalid shape in fixed-type tuple: "
+                  "dtype size in bytes must fit into a C int.")
         return W_Dtype(types.VoidType(space),
                        space.gettypefor(boxes.W_VoidBox),
                        shape=shape, subdtype=subdtype, elsize=size)
@@ -673,6 +688,10 @@
             return dtype
         if w_dtype is dtype.w_box_type:
             return dtype
+        if space.isinstance_w(w_dtype, space.w_type) and \
+           space.is_true(space.issubtype(w_dtype, dtype.w_box_type)):
+            return cache.w_objectdtype
+            #return W_Dtype(types.VoidType(space), w_box_type=dtype.w_box_type)
     if space.isinstance_w(w_dtype, space.w_type):
         return cache.w_objectdtype
     raise oefmt(space.w_TypeError, "data type not understood")
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
@@ -92,6 +92,7 @@
         assert d == np.dtype('i8')
         assert d.shape == ()
         d = np.dtype((np.int64, 1,))
+        assert d.shape == ()
         assert d == np.dtype('i8')
         assert d.shape == ()
         d = np.dtype((np.int64, 4))
@@ -111,6 +112,7 @@
         assert "int8" == dtype("int8")
         raises(TypeError, lambda: dtype("int8") == 3)
         assert dtype(bool) == bool
+        assert dtype('f8') != dtype(('f8', (1,)))
 
     def test_dtype_cmp(self):
         from numpy import dtype
@@ -342,10 +344,10 @@
         raises(TypeError, type, "Foo", (dtype,), {})
 
     def test_can_subclass(self):
-        import numpy
-        class xyz(numpy.void):
+        import numpy as np
+        class xyz(np.void):
             pass
-        assert True
+        assert np.dtype(xyz).name == 'xyz'
 
     def test_index(self):
         import numpy as np
@@ -413,7 +415,7 @@
         assert loads(dumps(a.dtype)) == a.dtype
         assert np.dtype('bool').__reduce__() == (dtype, ('b1', 0, 1), (3, '|', None, None, None, -1, -1, 0))
         assert np.dtype('|V16').__reduce__() == (dtype, ('V16', 0, 1), (3, '|', None, None, None, 16, 1, 0))
-        assert np.dtype(('<f8', 2)).__reduce__() == (dtype, ('V16', 0, 1), (3, '|', (dtype('float64'), (2,)), None, None, 16, 1, 0))
+        assert np.dtype(('<f8', 2)).__reduce__() == (dtype, ('V16', 0, 1), (3, '|', (dtype('float64'), (2,)), None, None, 16, 8, 0))
 
     def test_newbyteorder(self):
         import numpy as np
@@ -1286,7 +1288,7 @@
                      ('x', 'y', 'z', 'value'),
                      {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0),
                       'z': (dtype('int32'), 8), 'value': (dtype('float64'), 12),
-                      }, 20, 1, 0))
+                      }, 20, 1, 16))
 
         new_d = loads(dumps(d))
 
@@ -1305,6 +1307,22 @@
 
         assert new_d.itemsize == d.itemsize == 76
 
+    def test_shape_invalid(self):
+        import numpy as np
+        # Check that the shape is valid.
+        max_int = 2 ** (8 * 4 - 1)
+        max_intp = 2 ** (8 * np.dtype('intp').itemsize - 1) - 1
+        # Too large values (the datatype is part of this)
+        raises(ValueError, np.dtype, [('a', 'f4', max_int // 4 + 1)])
+        raises(ValueError, np.dtype, [('a', 'f4', max_int + 1)])
+        raises(ValueError, np.dtype, [('a', 'f4', (max_int, 2))])
+        # Takes a different code path (fails earlier:
+        raises(ValueError, np.dtype, [('a', 'f4', max_intp + 1)])
+        # Negative values
+        raises(ValueError, np.dtype, [('a', 'f4', -1)])
+        raises(ValueError, np.dtype, [('a', 'f4', (-1, -1))])
+
+
 class AppTestNotDirect(BaseNumpyAppTest):
     def setup_class(cls):
         BaseNumpyAppTest.setup_class.im_func(cls)


More information about the pypy-commit mailing list