Author: Matti Picus <[email protected]>
Branch: pypy-pyarray
Changeset: r67030:b95fcd12507d
Date: 2013-09-20 13:04 +0300
http://bitbucket.org/pypy/pypy/changeset/b95fcd12507d/
Log: start to implement __array_prepare__ and test failures
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
@@ -86,7 +86,7 @@
return W_NDimArray(scalar.Scalar(dtype, w_val))
-def convert_to_array(space, w_obj):
+def convert_to_array(space, w_obj, use_prepare=False):
#XXX: This whole routine should very likely simply be array()
from pypy.module.micronumpy.interp_numarray import array
from pypy.module.micronumpy import interp_ufuncs
@@ -101,7 +101,7 @@
if isinstance(w_result, W_NDimArray):
return w_result
else:
- raise OperationError(space.w_ValueError,
+ raise OperationError(space.w_ValueError,
space.wrap("object __array__ method not producing an
array"))
elif issequence_w(space, w_obj):
# Convert to array.
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
@@ -437,7 +437,7 @@
# stub implementation of __array__()
return self
- def descr___array_prepare__(self, space, w_array):
+ def descr___array_prepare__(self, space, w_array, w_context):
# stub implementation of __array_prepare__()
if isinstance(w_array, W_NDimArray):
return w_array
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
@@ -319,6 +319,22 @@
else:
self.done_func = None
+ def call_prepare(self, space, w_out, w_obj, w_result):
+ if isinstance(w_out, W_NDimArray):
+ w_array = space.lookup(w_out, "__array_prepare__")
+ w_caller = w_out
+ else:
+ w_array = space.lookup(w_obj, "__array_prepare__")
+ w_caller = w_obj
+ if w_array:
+ w_result = space.get_and_call_function(w_array, w_caller,
w_result, None)
+ if not isinstance(w_result, W_NDimArray):
+ raise OperationError(space.w_ValueError,
+ space.wrap("object __array_prepare__ method not"
+ " producing an array"))
+ return w_result
+
+
@jit.unroll_safe
def call(self, space, args_w):
if len(args_w) > 2:
@@ -351,11 +367,11 @@
"ufunc '%s' not supported for the input types" % self.name))
if space.is_none(w_out):
out = None
- elif not isinstance(w_out, W_NDimArray):
- raise OperationError(space.w_TypeError, space.wrap(
- 'output must be an array'))
+ #elif not isinstance(w_out, W_NDimArray):
+ # raise OperationError(space.w_TypeError, space.wrap(
+ # 'output must be an array'))
else:
- out = w_out
+ out = convert_to_array(space, w_out)
calc_dtype = out.get_dtype()
if self.comparison_func:
res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
@@ -371,14 +387,13 @@
out.set_scalar_value(arr)
else:
out.fill(arr)
- else:
- out = arr
- return out
+ return self.call_prepare(space, out, w_lhs, arr)
new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs)
new_shape = shape_agreement(space, new_shape, out,
broadcast_down=False)
- return loop.call2(space, new_shape, self.func, calc_dtype,
+ w_result = loop.call2(space, new_shape, self.func, calc_dtype,
res_dtype, w_lhs, w_rhs, out)
-
+ # XXX handle array_priority
+ return self.call_prepare(space, out, w_lhs, w_result)
W_Ufunc.typedef = TypeDef("ufunc",
__module__ = "numpypy",
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
@@ -267,8 +267,24 @@
def __array_prepare__(self, arr, context):
self.called_prepare = True
return array(arr).view(type=with_prepare)
- a = array(1).view(type=with_prepare)
- x = add(a, a)
+ class with_prepare_fail(ndarray):
+ called_prepare = False
+ def __array_prepare__(self, arr, context):
+ self.called_prepare = True
+ return array(arr[0]).view(type=with_prepare)
+ a = array(1)
+ b = array(1).view(type=with_prepare)
+ x = add(a, a, out=b)
assert x == 2
assert type(x) == with_prepare
- assert a.called_prepare
+ assert x.called_prepare
+ b.called_prepare = False
+ a = ones((3, 2)).view(type=with_prepare)
+ b = ones((3, 2))
+ c = ones((3, 2)).view(type=with_prepare_fail)
+ x = add(a, b, out=a)
+ assert (x == 2).all()
+ assert type(x) == with_prepare
+ assert x.called_prepare
+ raises(TypeError, add, a, b, out=c)
+
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit