[pypy-commit] pypy default: merge numpy-unify-methods which checks that there exists an implementation or an exception for all single-arg ufuncs on all base numpypy dtypes, and implements the missing ones
mattip
noreply at buildbot.pypy.org
Mon Feb 25 23:12:20 CET 2013
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r61800:f5a6f7eb7622
Date: 2013-02-25 23:20 +0200
http://bitbucket.org/pypy/pypy/changeset/f5a6f7eb7622/
Log: merge numpy-unify-methods which checks that there exists an
implementation or an exception for all single-arg ufuncs on all base
numpypy dtypes, and implements the missing ones
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -39,6 +39,7 @@
.. branch: task-decorator
.. branch: fix-e4fa0b2
.. branch: win32-fixes
+.. branch: numpy-unify-methods
.. branch: fix-version-tool
.. branch: popen2-removal
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
@@ -258,6 +258,9 @@
if w_obj.get_dtype().is_flexible_type():
raise OperationError(space.w_TypeError,
space.wrap('Not implemented for this type'))
+ if self.int_only and not w_obj.get_dtype().is_int_type():
+ raise OperationError(space.w_TypeError, space.wrap(
+ "ufunc %s not supported for the input type" % self.name))
calc_dtype = find_unaryop_result_dtype(space,
w_obj.get_dtype(),
promote_to_float=self.promote_to_float,
@@ -337,6 +340,9 @@
promote_bools=self.promote_bools,
allow_complex=self.allow_complex,
)
+ if self.int_only and not calc_dtype.is_int_type():
+ raise OperationError(space.w_TypeError, space.wrap(
+ "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):
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
@@ -82,6 +82,52 @@
for i in range(3):
assert min_c_b[i] == min(b[i], c)
+ def test_scalar(self):
+ # tests that by calling all available ufuncs on scalars, none will
+ # raise uncaught interp-level exceptions, (and crash the test)
+ # and those that are uncallable can be accounted for.
+ # test on the four base-class dtypes: int, bool, float, complex
+ # We need this test since they have no common base class.
+ import numpypy as np
+ def find_uncallable_ufuncs(v):
+ uncallable = []
+ for s in dir(np):
+ u = getattr(np, s)
+ if isinstance(u, np.ufunc) and u.nin < 2:
+ try:
+ u(a)
+ except TypeError:
+ #assert e.message.startswith('ufunc')
+ uncallable.append(s)
+ elif isinstance(u, np.ufunc) and u.nin ==2:
+ try:
+ u(a, a)
+ except TypeError:
+ #assert e.message.startswith('ufunc')
+ uncallable.append(s)
+ return uncallable
+ a = np.array(0,'int64')
+ uncallable = find_uncallable_ufuncs(a)
+ assert len(uncallable) == 0
+ a = np.array(True,'bool')
+ uncallable = find_uncallable_ufuncs(a)
+ assert len(uncallable) == 0 or uncallable == ['sign'] # numpy 1.7.0
+ a = np.array(1.0,'float')
+ uncallable = find_uncallable_ufuncs(a)
+ assert len(uncallable) == 2 and set(uncallable) == set(['bitwise_not', 'invert'])
+ a = np.array(1.0,'complex')
+ uncallable = find_uncallable_ufuncs(a)
+ assert len(uncallable) == 13
+ assert set(uncallable) == \
+ set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor',
+ 'rad2deg', 'invert', 'isneginf', 'isposinf', 'radians', 'signbit',
+ 'trunc'])
+
+ def test_int_only(self):
+ from numpypy import bitwise_and, array
+ a = array(1.0)
+ raises(TypeError, bitwise_and, a, a)
+
def test_negative(self):
from numpypy import array, negative
@@ -249,13 +295,16 @@
assert (a == ref).all()
def test_signbit(self):
- from numpypy import signbit
+ from numpypy import signbit, add
assert (signbit([0, 0.0, 1, 1.0, float('inf')]) ==
[False, False, False, False, False]).all()
assert (signbit([-0, -0.0, -1, -1.0, float('-inf')]) ==
[False, True, True, True, True]).all()
+ a = add.identity
+ assert signbit(a) == False
+
skip('sign of nan is non-determinant')
assert (signbit([float('nan'), float('-nan'), -float('nan')]) ==
[False, True, True]).all()
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -7,6 +7,7 @@
from pypy.objspace.std.floatobject import float2string
from pypy.objspace.std.complexobject import str_format
from rpython.rlib import rfloat, clibffi, rcomplex
+from rpython.rlib.rarithmetic import maxint
from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
raw_storage_getitem)
from rpython.rlib.objectmodel import specialize
@@ -375,6 +376,20 @@
def invert(self, v):
return ~v
+ @raw_unary_op
+ def isfinite(self, v):
+ return True
+
+ @raw_unary_op
+ def signbit(self, v):
+ return False
+
+ @simple_unary_op
+ def reciprocal(self, v):
+ if v:
+ return 1
+ return 0
+
NonNativeBool = Bool
class Integer(Primitive):
@@ -479,6 +494,17 @@
def invert(self, v):
return ~v
+ @simple_unary_op
+ def reciprocal(self, v):
+ if v == 0:
+ # XXX good place to warn
+ return -maxint
+ return 1 / v
+
+ @raw_unary_op
+ def signbit(self, v):
+ return v < 0
+
class NonNativeInteger(NonNativePrimitive, Integer):
_mixin_ = True
More information about the pypy-commit
mailing list