[pypy-commit] pypy numpy-ufunc-object: first pass. 0 progress made, doesn't work, broke everything. But it's a start!

alex_gaynor noreply at buildbot.pypy.org
Tue Aug 30 06:24:00 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpy-ufunc-object
Changeset: r46912:c3db36472ab2
Date: 2011-08-30 00:23 -0400
http://bitbucket.org/pypy/pypy/changeset/c3db36472ab2/

Log:	first pass. 0 progress made, doesn't work, broke everything. But
	it's a start!

diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -8,6 +8,7 @@
     interpleveldefs = {
         'array': 'interp_numarray.SingleDimArray',
         'dtype': 'interp_dtype.W_Dtype',
+        'ufunc': 'interp_ufuncs.W_Ufunc',
 
         'zeros': 'interp_numarray.zeros',
         'empty': 'interp_numarray.zeros',
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
@@ -56,7 +56,7 @@
     def _unaryop_impl(w_ufunc):
         def impl(self, space):
             return w_ufunc(space, self)
-        return func_with_new_name(impl, "unaryop_%s_impl" % w_ufunc.__name__)
+        return func_with_new_name(impl, "unaryop_%s_impl" % w_ufunc.name)
 
     descr_pos = _unaryop_impl(interp_ufuncs.positive)
     descr_neg = _unaryop_impl(interp_ufuncs.negative)
@@ -65,7 +65,7 @@
     def _binop_impl(w_ufunc):
         def impl(self, space, w_other):
             return w_ufunc(space, self, w_other)
-        return func_with_new_name(impl, "binop_%s_impl" % w_ufunc.__name__)
+        return func_with_new_name(impl, "binop_%s_impl" % w_ufunc.name)
 
     descr_add = _binop_impl(interp_ufuncs.add)
     descr_sub = _binop_impl(interp_ufuncs.subtract)
@@ -81,7 +81,7 @@
                 w_other
             )
             return w_ufunc(space, w_other, self)
-        return func_with_new_name(impl, "binop_right_%s_impl" % w_ufunc.__name__)
+        return func_with_new_name(impl, "binop_right_%s_impl" % w_ufunc.name)
 
     descr_radd = _binop_right_impl(interp_ufuncs.add)
     descr_rsub = _binop_right_impl(interp_ufuncs.subtract)
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
@@ -1,7 +1,41 @@
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.typedef import TypeDef
 from pypy.module.micronumpy import interp_dtype, signature
 from pypy.tool.sourcetools import func_with_new_name
 
 
+class W_Ufunc(Wrappable):
+    def __init__(self, name, promote_to_float, promote_bools, identity):
+        self.name = name
+        self.promote_to_float = promote_to_float
+        self.promote_bools = promote_bools
+
+        self.identity = identity
+
+    def descr_repr(self, space):
+        return space.wrap("<ufunc '%s'>" % self.name)
+
+class W_Ufunc1(W_Ufunc):
+    def __init__(self, func, name, promote_to_float=False, promote_bools=False,
+        identity=None):
+
+        W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity)
+        self.func = func
+
+class W_Ufunc2(W_Ufunc):
+    def __init__(self, func, name, promote_to_float=False, promote_bools=False,
+        identity=None):
+
+        W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity)
+        self.func = func
+
+W_Ufunc.typedef = TypeDef("ufunc",
+    __module__ = "numpy",
+
+    __repr__ = interp2app(W_Ufunc.descr_repr),
+)
+
 def ufunc(func=None, promote_to_float=False, promote_bools=False):
     if func is None:
         return lambda func: ufunc(func, promote_to_float, promote_bools)
@@ -74,7 +108,7 @@
     assert False
 
 def find_unaryop_result_dtype(space, dt, promote_to_float=False,
-    promote_to_largest=False, promote_bools=False):
+    promote_bools=False, promote_to_largest=False):
     if promote_bools and (dt.kind == interp_dtype.BOOLLTR):
         return space.fromcache(interp_dtype.W_Int8Dtype)
     if promote_to_float:
@@ -108,17 +142,15 @@
 
 def ufunc_dtype_caller(ufunc_name, op_name, argcount, **kwargs):
     if argcount == 1:
-        @ufunc(**kwargs)
         def impl(res_dtype, value):
             return getattr(res_dtype, op_name)(value)
     elif argcount == 2:
-        @ufunc2(**kwargs)
         def impl(res_dtype, lvalue, rvalue):
             return getattr(res_dtype, op_name)(lvalue, rvalue)
     return func_with_new_name(impl, ufunc_name)
 
 for ufunc_def in [
-    ("add", "add", 2),
+    ("add", "add", 2, {"identity": 0}),
     ("subtract", "sub", 2),
     ("multiply", "mul", 2),
     ("divide", "div", 2, {"promote_bools": True}),
@@ -155,4 +187,9 @@
     except IndexError:
         extra_kwargs = {}
 
-    globals()[ufunc_name] = ufunc_dtype_caller(ufunc_name, op_name, argcount, **extra_kwargs)
+    func = ufunc_dtype_caller(ufunc_name, op_name, argcount)
+    if argcount == 1:
+        ufunc = W_Ufunc1(func, ufunc_name, **extra_kwargs)
+    elif argcount == 2:
+        ufunc = W_Ufunc2(func, ufunc_name, **extra_kwargs)
+    globals()[ufunc_name] = ufunc
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
@@ -3,6 +3,24 @@
 
 
 class AppTestUfuncs(BaseNumpyAppTest):
+    def test_ufunc_instance(self):
+        from numpy import add, ufunc
+
+        assert isinstance(add, ufunc)
+        assert repr(add) == "<ufunc 'add'>"
+        assert repr(ufunc) == "<type 'numpy.ufunc'>"
+
+    def test_ufunc_attrs(self):
+        from numpy import add, multiply, sin
+
+        assert add.identity == 0
+        assert multiply.identity == 1
+        assert sin.identity is None
+
+        assert add.nin == 2
+        assert multiply.nin == 2
+        assert sin.nin == 1
+
     def test_single_item(self):
         from numpy import negative, sign, minimum
 


More information about the pypy-commit mailing list