[pypy-commit] pypy default: (mattip) merge nupypy-axis-arg-check, fix for checking axis attribute
fijal
noreply at buildbot.pypy.org
Thu Jun 21 12:41:31 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r55745:36a491810048
Date: 2012-06-21 12:40 +0200
http://bitbucket.org/pypy/pypy/changeset/36a491810048/
Log: (mattip) merge nupypy-axis-arg-check, fix for checking axis
attribute
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
@@ -15,6 +15,7 @@
from pypy.rlib.rstring import StringBuilder
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.tool.sourcetools import func_with_new_name
+from pypy.module.micronumpy.interp_support import unwrap_axis_arg
count_driver = jit.JitDriver(
@@ -156,10 +157,6 @@
def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False):
def impl(self, space, w_axis=None, w_out=None):
- if space.is_w(w_axis, space.w_None):
- axis = -1
- else:
- axis = space.int_w(w_axis)
if space.is_w(w_out, space.w_None) or not w_out:
out = None
elif not isinstance(w_out, BaseArray):
@@ -168,7 +165,7 @@
else:
out = w_out
return getattr(interp_ufuncs.get(space), ufunc_name).reduce(space,
- self, True, promote_to_largest, axis,
+ self, True, promote_to_largest, w_axis,
False, out)
return func_with_new_name(impl, "reduce_%s_impl" % ufunc_name)
@@ -570,11 +567,10 @@
def descr_mean(self, space, w_axis=None, w_out=None):
if space.is_w(w_axis, space.w_None):
- w_axis = space.wrap(-1)
w_denom = space.wrap(support.product(self.shape))
else:
- dim = space.int_w(w_axis)
- w_denom = space.wrap(self.shape[dim])
+ axis = unwrap_axis_arg(space, len(self.shape), w_axis)
+ w_denom = space.wrap(self.shape[axis])
return space.div(self.descr_sum_promote(space, w_axis, w_out), w_denom)
def descr_var(self, space, w_axis=None):
@@ -1310,12 +1306,24 @@
raise OperationError(space.w_NotImplementedError, space.wrap("unsupported"))
if space.is_w(w_axis, space.w_None):
return space.wrap(support.product(arr.shape))
+ shapelen = len(arr.shape)
if space.isinstance_w(w_axis, space.w_int):
- return space.wrap(arr.shape[space.int_w(w_axis)])
+ axis = space.int_w(w_axis)
+ if axis < -shapelen or axis>= shapelen:
+ raise operationerrfmt(space.w_ValueError,
+ "axis entry %d is out of bounds [%d, %d)", axis,
+ -shapelen, shapelen)
+ return space.wrap(arr.shape[axis])
+ # numpy as of June 2012 does not implement this
s = 1
elems = space.fixedview(w_axis)
for w_elem in elems:
- s *= arr.shape[space.int_w(w_elem)]
+ axis = space.int_w(w_elem)
+ if axis < -shapelen or axis>= shapelen:
+ raise operationerrfmt(space.w_ValueError,
+ "axis entry %d is out of bounds [%d, %d)", axis,
+ -shapelen, shapelen)
+ s *= arr.shape[axis]
return space.wrap(s)
def dot(space, w_obj, w_obj2):
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -4,6 +4,7 @@
from pypy.module.micronumpy import interp_dtype
from pypy.objspace.std.strutil import strip_spaces
from pypy.rlib import jit
+from pypy.rlib.rarithmetic import maxint
FLOAT_SIZE = rffi.sizeof(lltype.Float)
@@ -103,3 +104,16 @@
return _fromstring_bin(space, s, count, length, dtype)
else:
return _fromstring_text(space, s, count, sep, length, dtype)
+
+def unwrap_axis_arg(space, shapelen, w_axis):
+ if space.is_w(w_axis, space.w_None) or not w_axis:
+ axis = maxint
+ else:
+ axis = space.int_w(w_axis)
+ if axis < -shapelen or axis>= shapelen:
+ raise operationerrfmt(space.w_ValueError,
+ "axis entry %d is out of bounds [%d, %d)", axis,
+ -shapelen, shapelen)
+ if axis < 0:
+ axis += shapelen
+ return axis
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
@@ -2,11 +2,11 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped
from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
-from pypy.module.micronumpy import interp_boxes, interp_dtype, support, loop
+from pypy.module.micronumpy import interp_boxes, interp_dtype, loop
from pypy.rlib import jit
from pypy.rlib.rarithmetic import LONG_BIT
from pypy.tool.sourcetools import func_with_new_name
-
+from pypy.module.micronumpy.interp_support import unwrap_axis_arg
class W_Ufunc(Wrappable):
_attrs_ = ["name", "promote_to_float", "promote_bools", "identity"]
@@ -121,11 +121,7 @@
"""
from pypy.module.micronumpy.interp_numarray import BaseArray
if w_axis is None:
- axis = 0
- elif space.is_w(w_axis, space.w_None):
- axis = -1
- else:
- axis = space.int_w(w_axis)
+ w_axis = space.wrap(0)
if space.is_w(w_out, space.w_None):
out = None
elif not isinstance(w_out, BaseArray):
@@ -133,9 +129,9 @@
'output must be an array'))
else:
out = w_out
- return self.reduce(space, w_obj, False, False, axis, keepdims, out)
+ return self.reduce(space, w_obj, False, False, w_axis, keepdims, out)
- def reduce(self, space, w_obj, multidim, promote_to_largest, axis,
+ def reduce(self, space, w_obj, multidim, promote_to_largest, w_axis,
keepdims=False, out=None):
from pypy.module.micronumpy.interp_numarray import convert_to_array, \
Scalar, ReduceArray, W_NDimArray
@@ -144,11 +140,11 @@
"supported for binary functions"))
assert isinstance(self, W_Ufunc2)
obj = convert_to_array(space, w_obj)
- if axis >= len(obj.shape):
- raise OperationError(space.w_ValueError, space.wrap("axis(=%d) out of bounds" % axis))
if isinstance(obj, Scalar):
raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
"on a scalar"))
+ axis = unwrap_axis_arg(space, len(obj.shape), w_axis)
+ assert axis>=0
size = obj.size
if self.comparison_func:
dtype = interp_dtype.get_dtype_cache(space).w_booldtype
@@ -163,7 +159,7 @@
if self.identity is None and size == 0:
raise operationerrfmt(space.w_ValueError, "zero-size array to "
"%s.reduce without identity", self.name)
- if shapelen > 1 and axis >= 0:
+ if shapelen > 1 and axis < shapelen:
if keepdims:
shape = obj.shape[:axis] + [1] + obj.shape[axis + 1:]
else:
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
@@ -1086,6 +1086,9 @@
assert (b == array(range(35, 70), dtype=float).reshape(5, 7)).all()
assert (a.mean(2) == array(range(0, 15), dtype=float).reshape(3, 5) * 7 + 3).all()
assert (arange(10).reshape(5, 2).mean(axis=1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all()
+ assert (a.mean(axis=-1) == a.mean(axis=2)).all()
+ raises(ValueError, a.mean, -4)
+ raises(ValueError, a.mean, 3)
def test_sum(self):
from _numpypy import array
@@ -1096,7 +1099,8 @@
a = array([True] * 5, bool)
assert a.sum() == 5
- raises(TypeError, 'a.sum(2, 3)')
+ raises(TypeError, 'a.sum(axis=0, out=3)')
+ raises(ValueError, 'a.sum(axis=2)')
d = array(0.)
b = a.sum(out=d)
assert b == d
@@ -1112,6 +1116,10 @@
assert (a.sum(0) == [30, 35, 40]).all()
assert (a.sum(axis=0) == [30, 35, 40]).all()
assert (a.sum(1) == [3, 12, 21, 30, 39]).all()
+ assert (a.sum(-1) == a.sum(-1)).all()
+ assert (a.sum(-2) == a.sum(-2)).all()
+ raises(ValueError, a.sum, -3)
+ raises(ValueError, a.sum, 2)
assert (a.max(0) == [12, 13, 14]).all()
assert (a.max(1) == [2, 5, 8, 11, 14]).all()
assert ((a + a).max() == 28)
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -573,6 +573,7 @@
a = arange(12).reshape(3, 4)
assert (add.reduce(a, 0) == [12, 15, 18, 21]).all()
assert (add.reduce(a, 1) == [6.0, 22.0, 38.0]).all()
+ raises(ValueError, add.reduce, a, 2)
def test_reduce_keepdims(self):
from _numpypy import add, arange
@@ -636,6 +637,8 @@
assert count_reduce_items(a) == 24
assert count_reduce_items(a, 1) == 3
assert count_reduce_items(a, (1, 2)) == 3 * 4
+ raises(ValueError, count_reduce_items, a, -4)
+ raises(ValueError, count_reduce_items, a, (0, 2, -4))
def test_true_divide(self):
from _numpypy import arange, array, true_divide
More information about the pypy-commit
mailing list