Author: Ilya Osadchiy <[email protected]>
Branch: numpy-impicit-convert
Changeset: r45425:6ee97b808423
Date: 2011-07-08 21:13 +0300
http://bitbucket.org/pypy/pypy/changeset/6ee97b808423/
Log: Simplifying and moving issequence to objspace
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -925,6 +925,9 @@
return self.w_True
return self.w_False
+ def issequence_w(self, w_obj):
+ return (self.findattr(w_obj, self.wrap("__getitem__")) is not None)
+
def isinstance_w(self, w_obj, w_type):
return self.is_true(self.isinstance(w_obj, w_type))
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
@@ -7,7 +7,6 @@
from pypy.tool.sourcetools import func_with_new_name
import math
-
def dummy1(v):
assert isinstance(v, float)
return v
@@ -82,23 +81,15 @@
def _binop_impl(function):
signature = Signature()
def impl(self, space, w_other):
+ w_other = convert_to_array(space, w_other)
new_sig = self.signature.transition(signature)
- if isinstance(w_other, BaseArray):
- res = Call2(
- function,
- self,
- w_other,
- new_sig.transition(w_other.signature)
- )
- w_other.invalidates.append(res)
- else:
- w_other = access_as_array(space, w_other)
- res = Call2(
- function,
- self,
- w_other,
- new_sig.transition(w_other.signature)
- )
+ res = Call2(
+ function,
+ self,
+ w_other,
+ new_sig.transition(w_other.signature)
+ )
+ w_other.invalidates.append(res)
self.invalidates.append(res)
return space.wrap(res)
return func_with_new_name(impl, "binop_%s_impl" % function.__name__)
@@ -143,14 +134,15 @@
s += concrete.getitem(i)
return space.wrap(s / size)
-def access_as_array (space, w_obj):
- try:
+def convert_to_array (space, w_obj):
+ if isinstance(w_obj, BaseArray):
+ return w_obj
+ elif space.issequence_w(w_obj):
+ # Convert to array.
+ return new_numarray(space, w_obj)
+ else:
# If it's a scalar
return FloatWrapper(space.float_w(w_obj))
- except OperationError:
- # Convert to array.
- # Could we somehow use COW in some cases?
- return new_numarray(space, w_obj)
class FloatWrapper(BaseArray):
"""
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,26 +1,17 @@
import math
from pypy.interpreter.gateway import unwrap_spec
-from pypy.module.micronumpy.interp_numarray import BaseArray, Call1, Call2,
Signature, access_as_array
+from pypy.module.micronumpy.interp_numarray import BaseArray, Call1, Call2,
Signature, convert_to_array
from pypy.rlib import rfloat
from pypy.tool.sourcetools import func_with_new_name
-def _issequence(space, w_obj):
- # Copied from cpyext's PySequence_Check
- """Return True if the object provides sequence protocol, and False
otherwise.
- This function always succeeds."""
- return (space.findattr(w_obj, space.wrap("__getitem__")) is not None)
-
def ufunc(func):
signature = Signature()
def impl(space, w_obj):
- if isinstance(w_obj, BaseArray):
- w_res = Call1(func, w_obj, w_obj.signature.transition(signature))
- w_obj.invalidates.append(w_res)
- return w_res
- elif _issequence(space, w_obj):
- w_obj_arr = access_as_array(space, w_obj)
+ if space.issequence_w(w_obj):
+ w_obj_arr = convert_to_array(space, w_obj)
w_res = Call1(func, w_obj_arr,
w_obj_arr.signature.transition(signature))
+ w_obj_arr.invalidates.append(w_res)
return w_res
else:
return space.wrap(func(space.float_w(w_obj)))
@@ -29,31 +20,13 @@
def ufunc2(func):
signature = Signature()
def impl(space, w_lhs, w_rhs):
- lhs_is_array = isinstance(w_lhs, BaseArray)
- rhs_is_array = isinstance(w_rhs, BaseArray)
- if lhs_is_array and rhs_is_array:
- # This is the (most likely) fall-through case in conversion checks
- # Not sure if making it a special case makes it much faster
- new_sig =
w_lhs.signature.transition(signature).transition(w_rhs.signature)
- w_res = Call2(func, w_lhs, w_rhs, new_sig)
- w_lhs.invalidates.append(w_res)
- w_rhs.invalidates.append(w_res)
- return w_res
- elif _issequence(space, w_lhs) or _issequence(space, w_rhs):
- if lhs_is_array:
- w_lhs_arr = w_lhs
- else:
- w_lhs_arr = access_as_array(space, w_lhs)
- if rhs_is_array:
- w_rhs_arr = w_rhs
- else:
- w_rhs_arr = access_as_array(space, w_rhs)
+ if space.issequence_w(w_lhs) or space.issequence_w(w_rhs):
+ w_lhs_arr = convert_to_array(space, w_lhs)
+ w_rhs_arr = convert_to_array(space, w_rhs)
new_sig =
w_lhs_arr.signature.transition(signature).transition(w_rhs_arr.signature)
w_res = Call2(func, w_lhs_arr, w_rhs_arr, new_sig)
- if lhs_is_array:
- w_lhs_arr.invalidates.append(w_res)
- if rhs_is_array:
- w_rhs_arr.invalidates.append(w_res)
+ w_lhs_arr.invalidates.append(w_res)
+ w_rhs_arr.invalidates.append(w_res)
return w_res
else:
return space.wrap(func(space.float_w(w_lhs), space.float_w(w_rhs)))
diff --git a/pypy/module/micronumpy/test/test_base.py
b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -1,12 +1,10 @@
from pypy.conftest import gettestobjspace
from pypy.module.micronumpy.interp_numarray import SingleDimArray, FloatWrapper
-
class BaseNumpyAppTest(object):
def setup_class(cls):
cls.space = gettestobjspace(usemodules=('micronumpy',))
-
class TestSignature(object):
def test_binop_signature(self, space):
ar = SingleDimArray(10)
@@ -26,4 +24,4 @@
v3 = ar.descr_add(space, v1)
v4 = ar.descr_add(space, v2)
- assert v3.signature is v4.signature
\ No newline at end of file
+ assert v3.signature is v4.signature
diff --git a/pypy/module/micronumpy/test/test_zjit.py
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -6,7 +6,16 @@
from pypy.module.micronumpy.compile import numpy_compile
class FakeSpace(object):
- pass
+ def issequence_w(self, w_obj):
+ # XXX: get_concrete() fails in some tests
+ # when using `return hasattr(w_obj, "__getitem__")`
+ return True
+
+ def wrap(self, w_obj):
+ return w_obj
+
+ def float_w(self, w_obj):
+ return float(w_obj)
class TestNumpyJIt(LLJitMixin):
def setup_class(cls):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit