[pypy-commit] pypy ndarray-subtype: more w_ corrections, try to be more clever in call2 for subtype compatability with numpy
mattip
noreply at buildbot.pypy.org
Sun Jul 7 00:24:07 CEST 2013
Author: Matti Picus <matti.picus at gmail.com>
Branch: ndarray-subtype
Changeset: r65245:2c2324b57f8c
Date: 2013-07-07 01:21 +0300
http://bitbucket.org/pypy/pypy/changeset/2c2324b57f8c/
Log: more w_ corrections, try to be more clever in call2 for subtype
compatability with numpy
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
@@ -28,6 +28,7 @@
def __init__(self, implementation):
assert isinstance(implementation, BaseArrayImplementation)
+ assert isinstance(self, W_NDimArray)
self.implementation = implementation
@staticmethod
@@ -41,13 +42,13 @@
impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
backstrides)
if w_subtype:
- ret = space.allocate_instance(W_NDimArray, space.type(w_subtype))
- W_NDimArray.__init__(ret, impl)
- space.call_function(space.getattr(ret,
+ w_ret = space.allocate_instance(W_NDimArray, space.type(w_subtype))
+ W_NDimArray.__init__(w_ret, impl)
+ assert isinstance(w_ret, W_NDimArray)
+ space.call_function(space.getattr(w_ret,
space.wrap('__array_finalize__')), w_subtype)
- else:
- ret = W_NDimArray(impl)
- return ret
+ return w_ret
+ return W_NDimArray(impl)
@staticmethod
def from_shape_and_storage(space, shape, storage, dtype, order='C', owning=False, w_subtype=None):
@@ -62,11 +63,11 @@
impl = concrete.ConcreteArrayNotOwning(shape, dtype, order, strides,
backstrides, storage)
if w_subtype:
- ret = space.allocate_instance(W_NDimArray, space.type(w_subtype))
- W_NDimArray.__init__(ret, impl)
- space.call_function(space.getattr(ret,
+ w_ret = space.allocate_instance(W_NDimArray, w_subtype)
+ W_NDimArray.__init__(w_ret, impl)
+ space.call_function(space.getattr(w_ret,
space.wrap('__array_finalize__')), w_subtype)
- return ret
+ return w_ret
return W_NDimArray(impl)
@staticmethod
diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py
--- a/pypy/module/micronumpy/interp_arrayops.py
+++ b/pypy/module/micronumpy/interp_arrayops.py
@@ -148,24 +148,24 @@
def repeat(space, w_arr, repeats, w_axis):
arr = convert_to_array(space, w_arr)
if space.is_none(w_axis):
- w_arr = arr.descr_flatten(space)
- orig_size = w_arr.get_shape()[0]
- shape = [w_arr.get_shape()[0] * repeats]
- w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_subtype=w_arr)
+ arr = arr.descr_flatten(space)
+ orig_size = arr.get_shape()[0]
+ shape = [arr.get_shape()[0] * repeats]
+ w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_subtype=arr)
for i in range(repeats):
Chunks([Chunk(i, shape[0] - repeats + i, repeats,
- orig_size)]).apply(space, w_res).implementation.setslice(space, w_arr)
+ orig_size)]).apply(space, w_res).implementation.setslice(space, arr)
else:
axis = space.int_w(w_axis)
- shape = w_arr.get_shape()[:]
+ shape = arr.get_shape()[:]
chunks = [Chunk(0, i, 1, i) for i in shape]
orig_size = shape[axis]
shape[axis] *= repeats
- w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_subtype=w_arr)
+ w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_subtype=arr)
for i in range(repeats):
chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats,
orig_size)
- Chunks(chunks).apply(space, w_res).implementation.setslice(space, w_arr)
+ Chunks(chunks).apply(space, w_res).implementation.setslice(space, arr)
return w_res
def count_nonzero(space, w_obj):
diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py
--- a/pypy/module/micronumpy/interp_flatiter.py
+++ b/pypy/module/micronumpy/interp_flatiter.py
@@ -65,7 +65,7 @@
if length == 1:
return base_iter.getitem()
res = W_NDimArray.from_shape(space, [length], base.get_dtype(),
- base.get_order(), subtype=base)
+ base.get_order(), w_subtype=base)
return loop.flatiter_getitem(res, base_iter, step)
def descr_setitem(self, space, w_idx, w_value):
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -147,11 +147,11 @@
chunks = self.implementation._prepare_slice_args(space, w_index)
return chunks.apply(space, self)
shape = res_shape + self.get_shape()[len(indexes):]
- res = W_NDimArray.from_shape(space, shape, self.get_dtype(),
- self.get_order(), subtype=self)
- if not res.get_size():
- return res
- return loop.getitem_array_int(space, self, res, iter_shape, indexes,
+ w_res = W_NDimArray.from_shape(space, shape, self.get_dtype(),
+ self.get_order(), w_subtype=self)
+ if not w_res.get_size():
+ return w_res
+ return loop.getitem_array_int(space, self, w_res, iter_shape, indexes,
prefix)
def setitem_array_int(self, space, w_index, w_value):
@@ -910,6 +910,8 @@
@unwrap_spec(offset=int, order=str)
def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None,
offset=0, w_strides=None, order='C'):
+ from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray
+ from pypy.module.micronumpy.support import calc_strides
if (offset != 0 or not space.is_none(w_strides) or
not space.is_none(w_buffer)):
raise OperationError(space.w_NotImplementedError,
@@ -921,11 +923,17 @@
return W_NDimArray.new_scalar(space, dtype)
if space.is_w(w_subtype, space.gettypefor(W_NDimArray)):
return W_NDimArray.from_shape(space, shape, dtype, order)
- raise OperationError(space.w_TypeError, space.wrap(
- "__new__ is not meant to be called except with a ndarray"))
+ strides, backstrides = calc_strides(shape, dtype.base, order)
+ impl = ConcreteArray(shape, dtype.base, order, strides,
+ backstrides)
+ w_ret = space.allocate_instance(W_NDimArray, w_subtype)
+ W_NDimArray.__init__(w_ret, impl)
+ space.call_function(space.getattr(w_ret,
+ space.wrap('__array_finalize__')), w_subtype)
+ return w_ret
@unwrap_spec(addr=int)
-def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype, w_subclass=None):
+def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype, w_subtype=None):
"""
Create an array from an existing buffer, given its address as int.
PyPy-only implementation detail.
@@ -937,9 +945,12 @@
space.call_function(space.gettypefor(interp_dtype.W_Dtype),
w_dtype))
shape = _find_shape(space, w_shape, dtype)
- if w_subclass:
+ if w_subtype:
+ if not space.isinstance_w(w_subtype, space.w_type):
+ raise OperationError(space.w_ValueError, space.wrap(
+ "subtype must be a subtype of ndarray, not a class instance"))
return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype,
- 'C', False, w_subclass)
+ 'C', False, w_subtype)
else:
return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype)
@@ -1122,12 +1133,12 @@
dtype = interp_dtype.variable_dtype(space, dtype.char + '1')
if ndmin > len(shape):
shape = [1] * (ndmin - len(shape)) + shape
- arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
- arr_iter = arr.create_iter()
+ w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
+ arr_iter = w_arr.create_iter()
for w_elem in elems_w:
arr_iter.setitem(dtype.coerce(space, w_elem))
arr_iter.next()
- return arr
+ return w_arr
@unwrap_spec(order=str)
def zeros(space, w_shape, w_dtype=None, order='C'):
@@ -1137,7 +1148,7 @@
shape = _find_shape(space, w_shape, dtype)
if not shape:
return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
- return space.wrap(W_NDimArray.from_shape(space, shape, dtype=dtype, order=order))
+ return W_NDimArray.from_shape(space, shape, dtype=dtype, order=order)
@unwrap_spec(order=str)
def ones(space, w_shape, w_dtype=None, order='C'):
@@ -1147,10 +1158,10 @@
shape = _find_shape(space, w_shape, dtype)
if not shape:
return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
- arr = W_NDimArray.from_shape(space, shape, dtype=dtype, order=order)
+ w_arr = W_NDimArray.from_shape(space, shape, dtype=dtype, order=order)
one = dtype.box(1)
- arr.fill(one)
- return space.wrap(arr)
+ w_arr.fill(one)
+ return w_arr
def _reconstruct(space, w_subtype, w_shape, w_dtype):
return descr_new_array(space, w_subtype, w_shape, w_dtype)
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -182,7 +182,7 @@
if out:
dtype = out.get_dtype()
temp = W_NDimArray.from_shape(space, temp_shape, dtype,
- subtype=obj)
+ w_subtype=obj)
elif keepdims:
shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:]
else:
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -21,8 +21,33 @@
def call2(space, shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out):
# handle array_priority
+ # w_lhs and w_rhs could be of different ndarray subtypes. Numpy does:
+ # 1. if __array_priorities__ are equal and one is an ndarray and the
+ # other is a subtype, flip the order
+ # 2. elif rhs.__array_priority__ is higher, flip the order
+ # Now return the subtype of the first one
+
+ w_ndarray = space.gettypefor(W_NDimArray)
+ lhs_type = space.type(w_lhs)
+ rhs_type = space.type(w_rhs)
+ lhs_for_subtype = w_lhs
+ rhs_for_subtype = w_rhs
+ #it may be something like a FlatIter, which is not an ndarray
+ if not lhs_type.issubtype(w_ndarray):
+ lhs_type = space.type(w_lhs.base)
+ lhs_for_subtype = w_lhs.base
+ if not rhs_type.issubtype(w_ndarray):
+ rhs_type = space.gettypefor(w_rhs.base)
+ rhs_for_subtype = w_rhs.base
+ if space.is_w(lhs_type, w_ndarray) and not space.is_w(rhs_type, w_ndarray):
+ w_lhs, w_rhs = w_rhs, w_lhs
+ lhs_for_subtype = rhs_for_subtype
+
+ # TODO handle __array_priorities__ and maybe flip the order
+
if out is None:
- out = W_NDimArray.from_shape(space, shape, res_dtype, w_subtype=w_lhs)
+ out = W_NDimArray.from_shape(space, shape, res_dtype,
+ w_subtype=lhs_for_subtype)
left_iter = w_lhs.create_iter(shape)
right_iter = w_rhs.create_iter(shape)
out_iter = out.create_iter(shape)
@@ -438,12 +463,12 @@
def tostring(space, arr):
builder = StringBuilder()
iter = arr.create_iter()
- res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C')
+ w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C')
itemsize = arr.get_dtype().itemtype.get_element_size()
res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
- res_str.implementation.get_storage_as_int(space))
+ w_res_str.implementation.get_storage_as_int(space))
while not iter.done():
- res_str.implementation.setitem(0, iter.getitem())
+ w_res_str.implementation.setitem(0, iter.getitem())
for i in range(itemsize):
builder.append(res_str_casted[i])
iter.next()
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1477,7 +1477,6 @@
def __new__(subtype, shape, dtype):
self = ndarray.__new__(subtype, shape, dtype)
self.id = 'subtype'
- print 'called new'
return self
a = C([2, 2], int)
assert isinstance(a, C)
@@ -1485,11 +1484,8 @@
assert a.shape == (2, 2)
assert a.dtype is dtype(int)
assert a.id == 'subtype'
- print '1'
a = a.reshape(1, 4)
- print '2'
b = a.reshape(4, 1)
- print '3'
assert isinstance(b, C)
#make sure __new__ was not called
assert not getattr(b, 'id', None)
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
@@ -11,7 +11,7 @@
def __new__(cls, subtype):
raise ValueError('should not call __new__')
def __array_finalize__(self, obj):
-
+
self.called_finalize = True
return NoNew ''')
cls.w_SubType = cls.space.appexec([], '''():
@@ -48,13 +48,11 @@
assert obj.info is None
obj = InfoArray(shape=(3,), info='information')
assert obj.info == 'information'
- print 'a'
v = obj[1:]
assert isinstance(v, InfoArray)
assert v.base is obj
assert v.info == 'information'
arr = np.arange(10)
- print '1'
cast_arr = arr.view(InfoArray)
assert isinstance(cast_arr, InfoArray)
assert cast_arr.base is arr
@@ -70,7 +68,13 @@
assert False
def test_sub_flatiter(self):
- assert False
+ from numpypy import array
+ a = array(range(9)).reshape(3, 3).view(self.NoNew)
+ c = array(range(9)).reshape(3, 3)
+ assert isinstance(a.flat[:] + a.flat[:], self.NoNew)
+ assert isinstance(a.flat[:] + c.flat[:], self.NoNew)
+ assert isinstance(c.flat[:] + a.flat[:], self.NoNew)
+ assert not isinstance(c.flat[:] + c.flat[:], self.NoNew)
def test_sub_getitem_filter(self):
assert False
More information about the pypy-commit
mailing list