[pypy-commit] pypy default: extend matrix test to expose indexing error since reshape() call subtype __array_finalize__, fix.
mattip
noreply at buildbot.pypy.org
Sat Feb 7 20:51:54 CET 2015
Author: mattip <matti.picus at gmail.com>
Branch:
Changeset: r75757:07ae676d67c6
Date: 2015-02-06 08:30 +0200
http://bitbucket.org/pypy/pypy/changeset/07ae676d67c6/
Log: extend matrix test to expose indexing error since reshape() call
subtype __array_finalize__, fix.
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
@@ -81,7 +81,10 @@
return w_object.descr_copy(space, w_order)
elif not copy and (subok or type(w_object) is W_NDimArray):
return w_object
- # we have a ndarray, but need to copy or change dtype or create W_NDimArray
+ if subok:
+ raise oefmt(space.w_NotImplementedError,
+ "array(..., subok=True) only partially implemented")
+ # we have a ndarray, but need to copy or change dtype
if dtype is None:
dtype = w_object.get_dtype()
if dtype != w_object.get_dtype():
@@ -89,13 +92,12 @@
copy = True
if copy:
shape = w_object.get_shape()
- _elems_w = w_object.reshape(space, space.wrap(-1))
elems_w = [None] * w_object.get_size()
- for i in range(len(elems_w)):
- elems_w[i] = _elems_w.descr_getitem(space, space.wrap(i))
- elif subok:
- raise oefmt(space.w_NotImplementedError,
- "array(...copy=False, subok=True) not implemented yet")
+ elsize = w_object.get_dtype().elsize
+ # TODO - use w_object.implementation without copying to a list
+ # unfortunately that causes a union error in translation
+ for i in range(w_object.get_size()):
+ elems_w[i] = w_object.implementation.getitem(i * elsize)
else:
sz = support.product(w_object.get_shape()) * dtype.elsize
return W_NDimArray.from_shape_and_storage(space,
@@ -113,7 +115,7 @@
dtype = descriptor.variable_dtype(space, dtype.char + '1')
w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
- if len(elems_w) == 1:
+ if support.product(shape) < 2:
w_arr.set_scalar_value(dtype.coerce(space, elems_w[0]))
else:
loop.assign(space, w_arr, elems_w)
diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py
--- a/pypy/module/micronumpy/test/test_subtype.py
+++ b/pypy/module/micronumpy/test/test_subtype.py
@@ -272,40 +272,103 @@
import numpy as N
# numpy's matrix class caused an infinite loop
class matrix(N.ndarray):
- getcnt = 0
def __new__(subtype, data, dtype=None, copy=True):
+ print('matrix __new__')
+ if isinstance(data, matrix):
+ dtype2 = data.dtype
+ if (dtype is None):
+ dtype = dtype2
+ if (dtype2 == dtype) and (not copy):
+ return data
+ return data.astype(dtype)
+
+ if isinstance(data, N.ndarray):
+ if dtype is None:
+ intype = data.dtype
+ else:
+ intype = N.dtype(dtype)
+ new = data.view(subtype)
+ if intype != data.dtype:
+ return new.astype(intype)
+ if copy: return new.copy()
+ else: return new
+
+ if isinstance(data, str):
+ data = _convert_from_string(data)
+
+ # now convert data to an array
arr = N.array(data, dtype=dtype, copy=copy)
+ ndim = arr.ndim
shape = arr.shape
+ if (ndim > 2):
+ raise ValueError("matrix must be 2-dimensional")
+ elif ndim == 0:
+ shape = (1, 1)
+ elif ndim == 1:
+ shape = (1, shape[0])
+
+ order = False
+ if (ndim == 2) and arr.flags.fortran:
+ order = True
+
+ if not (order or arr.flags.contiguous):
+ arr = arr.copy()
ret = N.ndarray.__new__(subtype, shape, arr.dtype,
buffer=arr,
- order=True)
+ order=order)
return ret
+ def __array_finalize__(self, obj):
+ print('matrix __array_finalize__')
+ self._getitem = False
+ if (isinstance(obj, matrix) and obj._getitem): return
+ ndim = self.ndim
+ if (ndim == 2):
+ return
+ if (ndim > 2):
+ newshape = tuple([x for x in self.shape if x > 1])
+ ndim = len(newshape)
+ if ndim == 2:
+ self.shape = newshape
+ return
+ elif (ndim > 2):
+ raise ValueError("shape too large to be a matrix.")
+ else:
+ newshape = self.shape
+ if ndim == 0:
+ self.shape = (1, 1)
+ elif ndim == 1:
+ self.shape = (1, newshape[0])
+ return
+
def __getitem__(self, index):
- matrix.getcnt += 1
- if matrix.getcnt > 10:
- # XXX strides.find_shape_and_elems is sensitive
- # to shape modification
- xxx
- out = N.ndarray.__getitem__(self, index)
+ print('matrix __getitem__')
+ self._getitem = True
+
+ try:
+ out = N.ndarray.__getitem__(self, index)
+ finally:
+ self._getitem = False
if not isinstance(out, N.ndarray):
return out
+
+ if out.ndim == 0:
+ return out[()]
+ if out.ndim == 1:
+ sh = out.shape[0]
# Determine when we should have a column array
- old_shape = out.shape
- if out.ndim < 2:
- sh = out.shape[0]
try:
n = len(index)
except:
n = 0
- if n > 1:
+ if n > 1 and isscalar(index[1]):
out.shape = (sh, 1)
else:
out.shape = (1, sh)
- #print 'out, shape was',old_shape,'now',out.shape,'out',out
return out
+
a = matrix([[1., 2.], [3., 4.]])
b = N.array([a])
assert (b == a).all()
@@ -318,6 +381,17 @@
assert len(b.shape) == 2
assert (b == a).all()
+ b = N.array(a, copy=True, dtype=int)
+ assert len(b.shape) == 2
+ assert (b == a).all()
+
+ c = matrix(a, copy=False)
+ assert c.base is not None
+ c[0, 0] = 100
+ assert a[0, 0] == 100
+ b = N.array(c, copy=True)
+ assert (b == a).all()
+
def test_setstate_no_version(self):
# Some subclasses of ndarray, like MaskedArray, do not use
# version in __setstare__
More information about the pypy-commit
mailing list