[pypy-commit] pypy numpy-fixes: add failing test, support call2; in ufuncs call __array_wrap__ after __array_finalize__
mattip
noreply at buildbot.pypy.org
Fri May 8 17:19:29 CEST 2015
Author: mattip <matti.picus at gmail.com>
Branch: numpy-fixes
Changeset: r77218:c82e8c164d0b
Date: 2015-05-08 17:31 +0300
http://bitbucket.org/pypy/pypy/changeset/c82e8c164d0b/
Log: add failing test, support call2; in ufuncs call __array_wrap__ after
__array_finalize__
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
@@ -3,14 +3,16 @@
from rpython.tool.pairtype import extendabletype
from pypy.module.micronumpy import support
-def wrap_impl(space, w_cls, w_instance, impl):
+def wrap_impl(space, w_cls, w_instance, impl, postpone_finalize=False):
if w_cls is None or space.is_w(w_cls, space.gettypefor(W_NDimArray)):
w_ret = W_NDimArray(impl)
else:
w_ret = space.allocate_instance(W_NDimArray, w_cls)
W_NDimArray.__init__(w_ret, impl)
assert isinstance(w_ret, W_NDimArray)
- space.call_method(w_ret, '__array_finalize__', w_instance)
+ if not postpone_finalize:
+ # ufuncs need to call finalize after wrap
+ space.call_method(w_ret, '__array_finalize__', w_instance)
return w_ret
@@ -33,7 +35,8 @@
self.implementation = implementation
@staticmethod
- def from_shape(space, shape, dtype, order='C', w_instance=None, zero=True):
+ def from_shape(space, shape, dtype, order='C', w_instance=None,
+ zero=True, postpone_finalize=False):
from pypy.module.micronumpy import concrete, descriptor, boxes
from pypy.module.micronumpy.strides import calc_strides
strides, backstrides = calc_strides(shape, dtype.base, order)
@@ -42,7 +45,8 @@
if dtype == descriptor.get_dtype_cache(space).w_objectdtype:
impl.fill(space, boxes.W_ObjectBox(space.w_None))
if w_instance:
- return wrap_impl(space, space.type(w_instance), w_instance, impl)
+ return wrap_impl(space, space.type(w_instance), w_instance,
+ impl, postpone_finalize=postpone_finalize)
return W_NDimArray(impl)
@staticmethod
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
@@ -60,9 +60,11 @@
right_iter.track_index = False
if out is None:
- out = W_NDimArray.from_shape(space, shape, res_dtype,
- w_instance=lhs_for_subtype)
- out_iter, out_state = out.create_iter(shape)
+ w_ret = W_NDimArray.from_shape(space, shape, res_dtype,
+ w_instance=lhs_for_subtype, postpone_finalize=True)
+ else:
+ w_ret = out
+ out_iter, out_state = w_ret.create_iter(shape)
shapelen = len(shape)
while not out_iter.done(out_state):
call2_driver.jit_merge_point(shapelen=shapelen, func=func,
@@ -76,7 +78,10 @@
out_iter.setitem(out_state, func(calc_dtype, w_left, w_right).convert_to(
space, res_dtype))
out_state = out_iter.next(out_state)
- return out
+ if out is None:
+ w_ret2 = space.call_method(w_rhs, '__array_wrap__', w_ret)
+ space.call_method(w_ret2, '__array_finalize__', lhs_for_subtype)
+ return w_ret2
call1_driver = jit.JitDriver(
name='numpy_call1',
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
@@ -624,3 +624,48 @@
a = asarray(fp[5:6][:,4])
assert (a == vals).all()
+ def test__array_wrap__(self):
+ ''' Straight from the documentation of __array_wrap__
+ '''
+ import numpy as np
+
+ class MySubClass(np.ndarray):
+ output = ''
+
+ def __new__(cls, input_array, info=None):
+ obj = np.array(input_array).view(cls)
+ obj.info = info
+ return obj
+
+ def __array_finalize__(self, obj):
+ self.output += 'In __array_finalize__:'
+ self.output += ' self is %s' % repr(self)
+ self.output += ' obj is %s' % repr(obj)
+ print self.output
+ if obj is None: return
+ self.info = getattr(obj, 'info', None)
+
+ def __array_wrap__(self, out_arr, context=None):
+ self.output += 'In __array_wrap__:'
+ self.output += ' self is %s' % repr(self)
+ self.output += ' arr is %s' % repr(out_arr)
+ # then just call the parent
+ ret = np.ndarray.__array_wrap__(self, out_arr, context)
+ print 'wrap',self.output
+ return ret
+
+ obj = MySubClass(np.arange(5), info='spam')
+ assert obj.output.startswith('In __array_finalize')
+ obj.output = ''
+ arr2 = np.arange(5)+1
+ assert len(obj.output) < 1
+ ret = np.add(arr2, obj)
+ print obj.output
+ assert obj.output.startswith('In __array_wrap')
+ assert 'finalize' not in obj.output
+ assert ret.info == 'spam'
+ ret = np.negative(obj)
+ assert ret.info == 'spam'
+ ret = obj.sum()
+ assert ret.info == 'spam'
+ assert False
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -584,7 +584,6 @@
assert isinstance(w_rhs, W_NDimArray)
new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs)
new_shape = shape_agreement(space, new_shape, out, broadcast_down=False)
- # XXX call __array_wrap__ if out was not provided
return loop.call2(space, new_shape, self.func, calc_dtype,
res_dtype, w_lhs, w_rhs, out)
More information about the pypy-commit
mailing list