[pypy-commit] pypy object-dtype2: more tests, mimic numpy 1.9 ufunc behaviour

mattip noreply at buildbot.pypy.org
Thu Apr 9 15:58:43 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: object-dtype2
Changeset: r76764:dfa0d26cc06b
Date: 2015-04-09 16:03 +0300
http://bitbucket.org/pypy/pypy/changeset/dfa0d26cc06b/

Log:	more tests, mimic numpy 1.9 ufunc behaviour

diff --git a/pypy/module/micronumpy/test/test_object_arrays.py b/pypy/module/micronumpy/test/test_object_arrays.py
--- a/pypy/module/micronumpy/test/test_object_arrays.py
+++ b/pypy/module/micronumpy/test/test_object_arrays.py
@@ -66,6 +66,20 @@
         b = np.maximum.reduce(a)
         assert b is not None
 
+    def test_complex_op(self):
+        import numpy as np
+        a = np.array(['abc', 'def'], dtype=object) 
+        b = np.array([1, 2, 3], dtype=object) 
+        c = np.array([complex(1, 1), complex(1, -1)], dtype=object)
+        for arg in (a,b,c):
+            assert (arg == np.real(arg)).all()
+            assert (0 == np.imag(arg)).all()
+        raises(AttributeError, np.conj, a)
+        res = np.conj(b)
+        assert (res == b).all()
+        res = np.conj(c)
+        assert res[0] == c[1] and res[1] == c[0]
+
     def test_keep_object_alive(self):
         # only translated does it really test the gc
         import numpy as np
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
@@ -414,6 +414,9 @@
                         u(* [array] * u.nin)
                     except AttributeError:
                         pass
+                    except NotImplementedError:
+                        print s
+                        uncallable.add(s)
                     except TypeError:
                         assert s not in uncallable
                         uncallable.add(s)
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
@@ -1734,9 +1734,6 @@
             return v1
         return v2
 
-    def arctan2(self, v1, v2):
-        raise oefmt(self.space.w_AttributeError, 'arctan2')
-
     @simple_unary_op
     def bool(self,v):
         return self._bool(v)
@@ -1800,22 +1797,39 @@
         else:
             return zero
 
+    @simple_unary_op
+    def real(self, v):
+        return v
 
+    @simple_unary_op
+    def imag(self, v):
+        return 0
+
+    @simple_unary_op
+    def square(self, v):
+        return self.space.mul(v, v)
+
+def add_attributeerr_op(cls, op):
+    def func(self, *args):
+        raise oefmt(self.space.w_AttributeError, 
+            "%s", op)
+    func.__name__ = 'object_' + op
+    setattr(cls, op, func)
+        
 def add_unsupported_op(cls, op):
     def func(self, *args):
         raise oefmt(self.space.w_TypeError, 
             "ufunc '%s' not supported for input types", op)
     func.__name__ = 'object_' + op
     setattr(cls, op, func)
-        
 
-def add_unary_op(cls, op):
+def add_unary_op(cls, op, method):
     @simple_unary_op
     def func(self, w_v):
-        w_impl = self.space.lookup(w_v, op)
+        w_impl = getattr(w_v, method, None)
         if w_impl is None:
             raise oefmt(self.space.w_AttributeError, 'unknown op "%s" on object' % op)
-        return self.space.get_and_call_function(w_impl, w_v)
+        return w_impl(self.space)
     func.__name__ = 'object_' + op
     setattr(cls, op, func)
 
@@ -1841,10 +1855,15 @@
     setattr(cls, op, func)
 
 for op in ('copysign', 'isfinite', 'isinf', 'isnan', 'logaddexp', 'logaddexp2',
-           'signbit',):
+           'signbit'):
     add_unsupported_op(ObjectType, op)
-for op in ('conj', 'real', 'imag', 'rint'):
-    add_unary_op(ObjectType, op)
+for op in ('arctan2', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan',
+           'arctanh', 'ceil', 'floor', 'cos', 'sin', 'tan', 'cosh', 'sinh',
+           'tanh', 'radians', 'degrees', 'exp','exp2', 'expm1', 'fabs',
+           'log', 'log10', 'log1p', 'log2', 'sqrt', 'trunc'):
+    add_attributeerr_op(ObjectType, op)
+for op, method in (('conj', 'descr_conjugate'), ('rint', 'descr_rint')):
+    add_unary_op(ObjectType, op, method)
 for op in ('abs', 'neg', 'pos', 'invert'):
     add_space_unary_op(ObjectType, op)
 for op in ('add', 'floordiv', 'div', 'mod', 'mul', 'sub', 'lshift', 'rshift'):
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
@@ -497,10 +497,13 @@
                     out.set_scalar_value(arr)
                 else:
                     out.fill(space, arr)
-            elif calc_dtype.is_object():
-                out = arr.get_scalar_value()
+            elif isinstance(arr, res_dtype.itemtype.BoxType):
+                if res_dtype.is_object():
+                    out = arr.get_scalar_value()
+                else:
+                    out = arr
             else:
-                out = arr
+                out = space.wrap(arr)
             return out
         if isinstance(w_lhs, boxes.W_GenericBox):
             w_lhs = W_NDimArray.from_scalar(space, w_lhs)
@@ -1042,6 +1045,8 @@
 @jit.unroll_safe
 def find_unaryop_result_dtype(space, dt, promote_to_float=False,
         promote_bools=False, promote_to_largest=False):
+    if dt.is_object():
+        return dt
     if promote_to_largest:
         if dt.kind == NPY.GENBOOLLTR or dt.kind == NPY.SIGNEDLTR:
             if dt.elsize * 8 < LONG_BIT:
@@ -1128,6 +1133,9 @@
         def impl(res_dtype, value):
             res = get_op(res_dtype)(value)
             if bool_result:
+                if res_dtype.is_object() and isinstance(res, W_Root):
+                    space = res_dtype.itemtype.space
+                    res = space.bool_w(res)
                 return dtype_cache.w_booldtype.box(res)
             return res
     elif nin == 2:


More information about the pypy-commit mailing list