[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