[pypy-commit] pypy default: Merge numpypy-issue1137
timo_jbo
noreply at buildbot.pypy.org
Sat May 5 16:12:58 CEST 2012
Author: Timo Paulssen <timonator at perpetuum-immobile.de>
Branch:
Changeset: r54898:629cfca82920
Date: 2012-05-05 16:12 +0200
http://bitbucket.org/pypy/pypy/changeset/629cfca82920/
Log: Merge numpypy-issue1137
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -6,6 +6,7 @@
import re
from pypy.interpreter.baseobjspace import InternalSpaceCache, W_Root
+from pypy.interpreter.error import OperationError
from pypy.module.micronumpy import interp_boxes
from pypy.module.micronumpy.interp_dtype import get_dtype_cache
from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray,
@@ -39,11 +40,11 @@
THREE_ARG_FUNCTIONS = ['where']
class FakeSpace(object):
- w_ValueError = None
- w_TypeError = None
- w_IndexError = None
- w_OverflowError = None
- w_NotImplementedError = None
+ w_ValueError = "ValueError"
+ w_TypeError = "TypeError"
+ w_IndexError = "IndexError"
+ w_OverflowError = "OverflowError"
+ w_NotImplementedError = "NotImplementedError"
w_None = None
w_bool = "bool"
@@ -126,8 +127,13 @@
return w_obj.intval
elif isinstance(w_obj, FloatObject):
return int(w_obj.floatval)
+ elif isinstance(w_obj, SliceObject):
+ raise OperationError(self.w_TypeError, self.wrap("slice."))
raise NotImplementedError
+ def index(self, w_obj):
+ return self.wrap(self.int_w(w_obj))
+
def str_w(self, w_obj):
if isinstance(w_obj, StringObject):
return w_obj.v
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
@@ -350,12 +350,31 @@
if shape_len == 1:
if space.isinstance_w(w_idx, space.w_int):
return True
+
+ try:
+ value = space.int_w(space.index(w_idx))
+ return True
+ except OperationError:
+ pass
+
+ try:
+ value = space.int_w(w_idx)
+ return True
+ except OperationError:
+ pass
+
if space.isinstance_w(w_idx, space.w_slice):
return False
elif (space.isinstance_w(w_idx, space.w_slice) or
space.isinstance_w(w_idx, space.w_int)):
return False
- lgt = space.len_w(w_idx)
+
+ try:
+ lgt = space.len_w(w_idx)
+ except OperationError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("index must be either an int or a sequence."))
+
if lgt > shape_len:
raise OperationError(space.w_IndexError,
space.wrap("invalid index"))
@@ -1030,8 +1049,21 @@
@jit.unroll_safe
def _index_of_single_item(self, space, w_idx):
- if space.isinstance_w(w_idx, space.w_int):
- idx = space.int_w(w_idx)
+ is_valid = False
+ try:
+ idx = space.int_w(space.index(w_idx))
+ is_valid = True
+ except OperationError:
+ pass
+
+ if not is_valid:
+ try:
+ idx = space.int_w(w_idx)
+ is_valid = True
+ except OperationError:
+ pass
+
+ if is_valid:
if idx < 0:
idx = self.shape[0] + idx
if idx < 0 or idx >= self.shape[0]:
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
@@ -10,6 +10,7 @@
import sys
class BaseNumpyAppTest(object):
+ @classmethod
def setup_class(cls):
if option.runappdirect:
if '__pypy__' not in sys.builtin_module_names:
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
@@ -8,7 +8,6 @@
from pypy.module.micronumpy.interp_numarray import W_NDimArray, shape_agreement
from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
-
class MockDtype(object):
class itemtype(object):
@staticmethod
@@ -195,6 +194,36 @@
assert _to_coords(13, 'F') == [1, 0, 2]
class AppTestNumArray(BaseNumpyAppTest):
+ def w_CustomIndexObject(self, index):
+ class CustomIndexObject(object):
+ def __init__(self, index):
+ self.index = index
+ def __index__(self):
+ return self.index
+
+ return CustomIndexObject(index)
+
+ def w_CustomIndexIntObject(self, index, value):
+ class CustomIndexIntObject(object):
+ def __init__(self, index, value):
+ self.index = index
+ self.value = value
+ def __index__(self):
+ return self.index
+ def __int__(self):
+ return self.value
+
+ return CustomIndexIntObject(index, value)
+
+ def w_CustomIntObject(self, value):
+ class CustomIntObject(object):
+ def __init__(self, value):
+ self.value = value
+ def __index__(self):
+ return self.value
+
+ return CustomIntObject(value)
+
def test_ndarray(self):
from _numpypy import ndarray, array, dtype
@@ -329,6 +358,28 @@
assert a[1, 3] == 8
assert a.T[1, 2] == 11
+ def test_getitem_obj_index(self):
+ from _numpypy import arange
+
+ a = arange(10)
+
+ assert a[self.CustomIndexObject(1)] == 1
+
+ def test_getitem_obj_prefer_index_to_int(self):
+ from _numpypy import arange
+
+ a = arange(10)
+
+
+ assert a[self.CustomIndexIntObject(0, 1)] == 0
+
+ def test_getitem_obj_int(self):
+ from _numpypy import arange
+
+ a = arange(10)
+
+ assert a[self.CustomIntObject(1)] == 1
+
def test_setitem(self):
from _numpypy import array
a = array(range(5))
@@ -348,6 +399,48 @@
for i in xrange(5):
assert a[i] == i
+ def test_setitem_obj_index(self):
+ from _numpypy import arange
+
+ a = arange(10)
+
+ a[self.CustomIndexObject(1)] = 100
+ assert a[1] == 100
+
+ def test_setitem_obj_prefer_index_to_int(self):
+ from _numpypy import arange
+
+ a = arange(10)
+
+ a[self.CustomIndexIntObject(0, 1)] = 100
+ assert a[0] == 100
+
+ def test_setitem_obj_int(self):
+ from _numpypy import arange
+
+ a = arange(10)
+
+ a[self.CustomIntObject(1)] = 100
+
+ assert a[1] == 100
+
+ def test_access_swallow_exception(self):
+ class ErrorIndex(object):
+ def __index__(self):
+ return 1 / 0
+
+ class ErrorInt(object):
+ def __int__(self):
+ return 1 / 0
+
+ # numpy will swallow errors in __int__ and __index__ and
+ # just raise IndexError.
+
+ from _numpypy import arange
+ a = arange(10)
+ raises(IndexError, "a[ErrorIndex()] == 0")
+ raises(IndexError, "a[ErrorInt()] == 0")
+
def test_setslice_array(self):
from _numpypy import array
a = array(range(5))
More information about the pypy-commit
mailing list