[pypy-svn] r70294 - pypy/branch/micronumpy/pypy/module/micronumpy

dan at codespeak.net dan at codespeak.net
Mon Dec 28 09:29:22 CET 2009


Author: dan
Date: Mon Dec 28 09:29:21 2009
New Revision: 70294

Added:
   pypy/branch/micronumpy/pypy/module/micronumpy/array.py
   pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py
   pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
      - copied, changed from r70213, pypy/branch/micronumpy/pypy/module/micronumpy/numarray.py
Removed:
   pypy/branch/micronumpy/pypy/module/micronumpy/numarray.py
Modified:
   pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py
   pypy/branch/micronumpy/pypy/module/micronumpy/app_numarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
Log:
Many changes.  7/9 tests passing.  Organized source code.  Parameterized single dimensional array such that it can be applied to different types.  Added applevel visible ndarray type, like NumPy supports.  Lots of little growing pain issues abound, committing just to make my changes publicly visible.

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py	Mon Dec 28 09:29:21 2009
@@ -5,13 +5,12 @@
 
     applevel_name = 'numpy'
     appleveldefs = {
-        'array' : 'app_numarray.array',
+        #'array' : 'app_numarray.array',
         }
     
     interpleveldefs = {
-        'zeros'    : 'numarray.zeros',
+        'array'    : 'ndarray.array',
+        'zeros'    : 'ndarray.zeros',
         'minimum'  : 'ufunc.minimum',
-        'IntArray' : 'numarray.IntArray',
-        'FloatArray' : 'numarray.FloatArray',
         }
 

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/app_numarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/app_numarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/app_numarray.py	Mon Dec 28 09:29:21 2009
@@ -16,16 +16,10 @@
             result = t
     return result
 
+#FIXME: move me to interplevel
 def array(xs, dtype=None):
     import numpy
-    arrays = {
-              int: numpy.IntArray,
-              float: numpy.FloatArray,
-              #complex: ComplexNumArray,
-             }
-    #type = lowest_common_type(xs)
-    #return arrays[type](xs)
-    result = numpy.zeros(len(xs), dtype=int) #FIXME: dtype=dtype !
+    result = numpy.zeros(len(xs), dtype=dtype if dtype else lowest_common_type(xs))
     for i, x in enumerate(xs):
         result[i] = x
     return result

Added: pypy/branch/micronumpy/pypy/module/micronumpy/array.py
==============================================================================
--- (empty file)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/array.py	Mon Dec 28 09:29:21 2009
@@ -0,0 +1,49 @@
+class BaseNumArray(object):
+    pass
+
+def iterable_type(space, w_xs):
+    xs = space.fixedview(w_xs)
+    type = int
+    for i in range(len(xs)):
+        type = result_types[type, xs[i]]
+    return type
+
+def mul_operation():
+    def mul(x, y): return x * y
+    return mul
+
+def div_operation():
+    def div(x, y): return x / y
+    return div
+
+def add_operation():
+    def add(x, y): return x * y
+    return add
+
+def sub_operation():
+    def sub(x, y): return x - y
+    return sub
+
+def copy_operation():
+    def copy(x, y): return x #XXX: I sure hope GCC can optimize this
+    return copy
+
+def app_mul_operation():
+    def mul(space, x, y):
+        return space.mul(x, y)
+    return mul
+
+def app_div_operation():
+    def div(space, x, y):
+        return space.div(x, y)
+    return div
+
+def app_add_operation():
+    def add(space, x, y):
+        return space.add(x, y)
+    return add
+
+def app_sub_operation():
+    def sub(space, x, y):
+        return space.sub(x, y)
+    return sub

Added: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py
==============================================================================
--- (empty file)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py	Mon Dec 28 09:29:21 2009
@@ -0,0 +1,15 @@
+def unwrap_int(space, w_x):
+    return space.int_w(w_x)
+def coerce_int(space, w_x):
+    return unwrap_int(space, space.int(w_x))
+
+def unwrap_float(space, w_x):
+    return space.float_w(w_x)
+def coerce_float(space, w_x):
+    return unwrap_float(space, space.float(w_x))
+
+from rlib.rarithmetic import r_singlefloat as float32
+def unwrap_float32(space, w_x):
+    return float32(space.float_w(w_x))
+def coerce_float32(space, w_x):
+    return unwrap_float32(space, space.float(w_x))

Added: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
==============================================================================
--- (empty file)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py	Mon Dec 28 09:29:21 2009
@@ -0,0 +1,63 @@
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import interp2app, NoneNotWrapped
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
+from pypy.rlib.debug import make_sure_not_resized
+
+from pypy.module.micronumpy.array import BaseNumArray
+
+def compute_pos(space, indexes, dim):
+    current = 1
+    pos = 0
+    for i in range(len(indexes)):
+        index = indexes[i]
+        d = dim[i]
+        if index >= d or index <= -d - 1:
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("invalid index"))
+        if index < 0:
+            index = d + index
+        pos += index * current
+        current *= d
+    return pos
+
+class MultiDimArray(BaseNumArray):
+    def __init__(self, space, shape, dtype):
+        self.shape = shape
+        self.space = space
+        # ignore dtype for now
+        size = 1
+        for dimension in shape:
+            size *= dimension
+        self.storage = [0] * size
+        make_sure_not_resized(self.storage)
+
+    def _unpack_indexes(self, space, w_index):
+        indexes = [space.int_w(w_i) for w_i in space.fixedview(w_index)]
+        if len(indexes) != len(self.shape):
+            raise OperationError(space.w_IndexError, space.wrap(
+                'Wrong index'))
+        return indexes
+
+    def getitem(self, w_index):
+        space = self.space
+        indexes = self._unpack_indexes(space, w_index)
+        pos = compute_pos(space, indexes, self.shape)
+        return space.wrap(self.storage[pos])
+
+    def setitem(self, w_index, w_value):
+        space = self.space
+        indexes = self._unpack_indexes(space, w_index)
+        pos = compute_pos(space, indexes, self.shape)
+        self.storage[pos] = space.int_w(w_value) #FIXME: lets get this thing generalized!
+        return space.w_None #XXX: necessary?
+
+    def len(self):
+        space = self.space
+        return space.wrap(self.shape[0])
+
+def unpack_dtype(space, w_dtype):
+    if space.is_w(w_dtype, space.w_int):
+        return 'i'
+    else:
+        raise NotImplementedError

Added: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py
==============================================================================
--- (empty file)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py	Mon Dec 28 09:29:21 2009
@@ -0,0 +1,131 @@
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import interp2app, NoneNotWrapped
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
+from pypy.rlib.debug import make_sure_not_resized
+
+from pypy.module.micronumpy.sdarray import sdresult
+from pypy.module.micronumpy.sdarray import GenericArray
+
+from pypy.module.micronumpy.mdarray import MultiDimArray
+
+def unpack_shape(space, w_shape):
+    if space.is_true(space.isinstance(w_shape, space.w_int)):
+        return [space.int_w(w_shape)]
+    shape_w = space.fixedview(w_shape)
+    return [space.int_w(w_i) for w_i in shape_w]
+
+class ArrayIter(Wrappable): #FIXME: 1d only!
+    def __init__(self, space, array, i):
+        self.space = space
+        self.array = array
+        self.i = i
+
+    def descr_iter(self):
+        self.space = space
+        return space.wrap(self)
+    descr_iter.unwrap_spec = ['self']
+
+    def descr_next(self):
+        space = self.space
+        try:
+            result = self.array.array.storage[self.i]
+            self.i += 1
+            return space.wrap(result)
+        except IndexError, e:
+            raise OperationError(space.w_StopIteration, space.wrap(""))
+    descr_iter.unwrap_spec = ['self']
+
+ArrayIter.typedef = TypeDef('ArrayIter',
+                            __iter__ = interp2app(ArrayIter.descr_iter),
+                            next = interp2app(ArrayIter.descr_next))
+
+def infer_shape(space, w_values): 
+    return space.len(w_values) #TODO: handle multi-dimensional arrays...
+
+class ndarray(Wrappable):
+    def __init__(self, space, w_values, w_shape, w_dtype):
+        self.array = None
+        self.space = space
+        if w_dtype == space.w_None:
+            #TODO: infer type from w_values (better than this)
+            w_dtype = space.type(space.fixedview(w_values)[0]) #FIXME: Allocates an entire array and throws it away!
+
+        self.dtype = w_dtype
+        if w_shape == space.w_None:
+            values_shape = infer_shape(space, w_values)
+            shape_w = unpack_shape(space, values_shape)
+        else:
+            shape_w = unpack_shape(space, w_shape)
+        if len(shape_w) == 1:
+            length = shape_w[0]
+            try:
+                self.array = sdresult(space, w_dtype)(space, length)
+            except KeyError, e:
+                raise OperationError(space.w_NotImplementedError,
+                        space.wrap("Haven't implemented generic array yet!"))
+
+            if not w_values == space.w_None: #space.is_true() ?
+                self.array.load_iterable(space, w_values)
+        else:
+            self.array = MultiDimArray(space, unpack_shape(space, w_shape), int) #FIXME: multi-dimensional arrays not *really* implemented
+
+    def validate_index(self, space, w_i):
+        try:
+            index_dimensionality = space.int_w(space.len(w_i))
+            array_dimensionality = len(self.array.shape)
+            if index_dimensionality > array_dimensionality:
+                raise OperationError(space.w_IndexError,
+                        space.wrap("Index dimensionality (%d) greater than array dimensionality (%d)." % (index_dimensionality, array_dimensionality)))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError): pass
+            else: raise
+
+    def descr_mul(self, w_x):
+        space = self.space
+        if space.type(w_x) in (W_ListType, W_TupleType): #TODO: fooo
+            #xs = space.fixedview(w_x)
+            pass
+        else:
+            result_array = sdresult(space, space.type(w_x))(space, self.array.length)
+            result_array.mul_scalar(self.array, w_x)
+            result = ndarray(space, space.w_None, space.wrap(result_array.length), space.w_None) #FIXME: make ndarray.__init__ understand null args
+            result.array = result_array
+    descr_mul.unwrap_spec = ['self', W_Root]
+
+    def descr_iter(self):
+        space = self.space
+        return space.wrap(ArrayIter(space, self, 0))
+    descr_iter.unwrap_spec = ['self']
+
+    def descr_getitem(self, space, w_i):
+        self.validate_index(space, w_i)
+        return self.array.getitem(w_i)
+    descr_getitem.unwrap_spec = ['self', ObjSpace, W_Root]
+
+    def descr_setitem(self, space, w_i, w_x):
+        self.validate_index(space, w_i)
+        self.array.setitem(w_i, w_x)
+    descr_setitem.unwrap_spec = ['self', ObjSpace, W_Root, W_Root]
+
+    def descr_len(self, space):
+        return self.array.len()
+    descr_len.unwrap_spec = ['self', ObjSpace]
+
+ndarray.typedef = TypeDef(
+    'ndarray',
+    #__init__ = interp2app(descr_init), #FIXME
+    __iter__ = interp2app(ndarray.descr_iter),
+    __getitem__ = interp2app(ndarray.descr_getitem),
+    __setitem__ = interp2app(ndarray.descr_setitem),
+    __len__     = interp2app(ndarray.descr_len),
+)
+
+def array(space, w_values, w_shape=None, w_dtype=None):
+    return ndarray(space, w_values, w_shape, w_dtype)
+array.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root]
+
+def zeros(space, w_shape, w_dtype):
+    return array(space, space.w_None, w_shape, w_dtype)
+zeros.unwrap_spec = [ObjSpace, W_Root, W_Root]

Copied: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (from r70213, pypy/branch/micronumpy/pypy/module/micronumpy/numarray.py)
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/numarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py	Mon Dec 28 09:29:21 2009
@@ -3,59 +3,46 @@
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, NoneNotWrapped
 from pypy.rlib.debug import make_sure_not_resized
+from pypy.objspace.std.typeobject import W_TypeObject
 
-from pypy.rlib.objectmodel import specialize
+from pypy.module.micronumpy.array import BaseNumArray
+from pypy.module.micronumpy.array import mul_operation, div_operation, add_operation, sub_operation
+from pypy.module.micronumpy.array import copy_operation
+from pypy.module.micronumpy.dtype import unwrap_int, coerce_int
+from pypy.module.micronumpy.dtype import unwrap_float, coerce_float
+from pypy.module.micronumpy.dtype import unwrap_float32, coerce_float32, float32
 
-result_types = {
-                (int, int): int,
-                (int, float): float,
-                (float, int): float,
-                (float, float): float
-               }
-
-class BaseNumArray(Wrappable):
-    pass
-
-def iterable_type(space, w_xs):
-    xs = space.fixedview(w_xs)
-    type = int
-    for i in range(len(xs)):
-        type = result_types[type, xs[i]]
-    return type
-
-def int_unwrapper(space, w_x):
-    return space.int_w(space.int(w_x))
-
-def float_unwrapper(space, w_x):
-    return space.float_w(space.float(w_x))
-
-def create_numarray(type, unwrapper, name):
+def create_numarray(data_type, unwrap, coerce):
     class NumArray(BaseNumArray):
-        def __init__(self, space, length, dtype):
-            #ignore dtype, irrelevant to optimized numarray implementations too
+        def __init__(self, space, length):
+            self.shape = (1,)
             self.length = length
             self.space = space
-            self.storage = [type(0.0)] * length
+            self.storage = [data_type(0.0)] * length
             make_sure_not_resized(self.storage)
 
+        mul = mul_operation()
+        div = div_operation()
+        add = add_operation()
+        sub = sub_operation()
+        copy = copy_operation()
 
-        def _dup_size(self, type):
-            return self.__class__(space, result_types[self.type, type], self.length)
-
-        def create_scalar_op(unwrap, f):
-            def scalar_operation(self, w_x):
+        def create_scalar_op(f):
+            def scalar_operation(self, space, source, w_x):
                 space = self.space
-                x = unwrap(w_x)
-                result = self._dup_size(type(x))
-                for i in range(self.length):
-                    result[i] = f(self.storage[i], x)
-                return space.wrap(result)
+                x = self.coerce(space, w_x)
+                for i in range(source.length):
+                    self.storage[i] = f(source.storage[i], x)
             return scalar_operation
 
-        def create_fixedview_op(unwrap, f):
+        mul_scalar = create_scalar_op(mul)
+#        div_scalar = create_scalar_op(div)
+#        add_scalar = create_scalar_op(add)
+#        sub_scalar = create_scalar_op(sub)
+
+        def create_fixedview_op(f):
             def fixedview_operation(self, w_xs):
                 space = self.space
-
                 try:
                     xs = space.fixedview(w_xs, len(self.storage))
                 except UnpackValueError, e:
@@ -63,150 +50,68 @@
                     raise OperationError(space.w_ValueError,
                                          space.wrap("shape mismatch: objects cannot be broadcast to the same shape"))
 
-                result = self._dup_size(iterable_type(space, xs))
-
                 i = 0
                 for w_x in xs:
-                    result[i] = f(self.storage[i], unwrap(w_x))
+                    self.storage[i] = f(source.storage[i], self.coerce(w_x)) #TODO: probably shouldn't coerce
                     i += 1
                 return result
             return fixedview_operation
 
-        #def mul_iterable(self, w_xs):
-            #return self.fixedview_operation(w_xs, mul)
-        
-#        def descr_mul(self, w_x):
-#            space = self.space
-#            if space.type(w_x) in [W_Int, W_Float]: #complex, long
-#                try:
-#                    return self.mul_scalar(space.int_w(w_x))
-#                except TypeError:
-#                    return self.mul_scalar(space.float_w(w_x))
-#            else:
-#                return self.mul_iterable(w_x)
-#        descr_mul.unwrap_spec = ['self', W_Root]
+        copy_iterable = create_fixedview_op(copy)
+
+        def load_iterable(self, space, w_values): #FIXME: less than ideal
+            i = 0
+            for x in space.fixedview(w_values, self.length):
+                self.storage[i] = unwrap(space, x)
+                i += 1
 
-        def descr_getitem(self, index):
+        def getitem(self, w_index):
             space = self.space
+            index = space.int_w(w_index)
             try:
                 return space.wrap(self.storage[index])
             except IndexError:
                 raise OperationError(space.w_IndexError,
                                      space.wrap("list index out of range"))
-        descr_getitem.unwrap_spec = ['self', int]
 
-        def descr_setitem(self, index, w_value):
+        def setitem(self, w_index, w_value):
             space = self.space
+            index = space.int_w(w_index)
             try:
-                self.storage[index] = unwrapper(space, w_value)
+                self.storage[index] = coerce(space, w_value)
             except IndexError:
                 raise OperationError(space.w_IndexError,
                                      space.wrap("list index out of range"))
             return space.w_None
-        descr_setitem.unwrap_spec = ['self', int, W_Root]
 
-        def descr_len(self):
-            return self.space.wrap(len(self.storage))
-        descr_len.unwrap_spec = ['self']
-
-    def descr_init(xs): pass
-
-    NumArray.typedef = TypeDef(
-        name,
-        #__init__ = interp2app(descr_init), #FIXME
-        __getitem__ = interp2app(NumArray.descr_getitem),
-        __setitem__ = interp2app(NumArray.descr_setitem),
-        __len__     = interp2app(NumArray.descr_len),
-    )
+        def len(self):
+            space = self.space
+            return space.wrap(len(self.storage))
+
     return NumArray
 
-IntArray = create_numarray(int, int_unwrapper, 'IntArray')
+IntArray = create_numarray(int, unwrap_int, coerce_int)
 NumArray = IntArray # FIXME: compatibility for now
-FloatArray = create_numarray(float, float_unwrapper, 'FloatArray')
+DoubleArray = create_numarray(float, unwrap_float, coerce_float)
+FloatArray = create_numarray(float32, unwrap_float32, coerce_float32)
+GenericArray = None
 
-#def array(space, w_xs): 
-#    w_length = space.len(w_xs)
-#    length = space.int_w(w_length)
-#    #TODO: discover type
-#    result = NumArray(space, type, length)
-#array.unwrap_spec = [ObjSpace, W_Root]
-
-def compute_pos(space, indexes, dim):
-    current = 1
-    pos = 0
-    for i in range(len(indexes)):
-        index = indexes[i]
-        d = dim[i]
-        if index >= d or index <= -d - 1:
-            raise OperationError(space.w_IndexError,
-                                 space.wrap("invalid index"))
-        if index < 0:
-            index = d + index
-        pos += index * current
-        current *= d
-    return pos
-
-class MultiDimArray(BaseNumArray):
-    def __init__(self, space, dim, dtype):
-        self.dim = dim
+class ResultFactory(object):
+    def __init__(self, space):
         self.space = space
-        # ignore dtype for now
-        size = 1
-        for el in dim:
-            size *= el
-        self.storage = [0] * size
-        make_sure_not_resized(self.storage)
-
-    def _unpack_indexes(self, space, w_index):
-        indexes = [space.int_w(w_i) for w_i in space.fixedview(w_index)]
-        if len(indexes) != len(self.dim):
-            raise OperationError(space.w_IndexError, space.wrap(
-                'Wrong index'))
-        return indexes
-
-    def descr_getitem(self, w_index):
-        space = self.space
-        indexes = self._unpack_indexes(space, w_index)
-        pos = compute_pos(space, indexes, self.dim)
-        return space.wrap(self.storage[pos])
-    descr_getitem.unwrap_spec = ['self', W_Root]
-
-    def descr_setitem(self, w_index, value):
-        space = self.space
-        indexes = self._unpack_indexes(space, w_index)
-        pos = compute_pos(space, indexes, self.dim)
-        self.storage[pos] = value
-        return space.w_None
-    descr_setitem.unwrap_spec = ['self', W_Root, int]
-
-    def descr_len(self):
-        return self.space.wrap(self.dim[0])
-    descr_len.unwrap_spec = ['self']
-
-MultiDimArray.typedef = TypeDef(
-    'NumArray',
-    __getitem__ = interp2app(MultiDimArray.descr_getitem),
-    __setitem__ = interp2app(MultiDimArray.descr_setitem),
-    __len__     = interp2app(MultiDimArray.descr_len),
-)
-
-def unpack_dim(space, w_dim):
-    if space.is_true(space.isinstance(w_dim, space.w_int)):
-        return [space.int_w(w_dim)]
-    dim_w = space.fixedview(w_dim)
-    return [space.int_w(w_i) for w_i in dim_w]
-
-def unpack_dtype(space, w_dtype):
-    if space.is_w(w_dtype, space.w_int):
-        return 'i'
-    else:
-        raise NotImplementedError
-
-def zeros(space, w_dim, w_dtype):
-    dim = unpack_dim(space, w_dim)
-    dtype = unpack_dtype(space, w_dtype)
-    if len(dim) == 1:
-        return space.wrap(NumArray(space, dim[0], dtype))
-    else:
-        return space.wrap(MultiDimArray(space, dim, dtype))
-zeros.unwrap_spec = [ObjSpace, W_Root, W_Root]
+        from pypy.objspace.std.inttype import int_typedef
+        int_type = space.gettypeobject(int_typedef)
+        from pypy.objspace.std.floattype import float_typedef
+        float_type = space.gettypeobject(float_typedef)
+
+        self.types = {
+            int_type:   IntArray,
+            float_type: FloatArray,
+                     }
+
+result_factory = None
+def sdresult(space, t):
+    global result_factory
+    if result_factory is None:
+        result_factory = ResultFactory(space)
+    return result_factory.types[t]

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py	Mon Dec 28 09:29:21 2009
@@ -1,22 +1,21 @@
-
-from numarray import NumArray
+from pypy.module.micronumpy.ndarray import array, zeros, ndarray
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root
 from pypy.interpreter.error import OperationError
 
 def minimum(space, w_a, w_b):
-    if not isinstance(w_a, NumArray) or not isinstance(w_b, NumArray):
+    if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray):
         raise OperationError(space.w_TypeError,
-                             space.wrap("expecting NumArray object"))
-    if w_a.length != w_b.length:
+                             space.wrap("expecting ndarray object"))
+    if w_a.array.length != w_b.array.length:
         raise OperationError(space.w_ValueError,
                              space.wrap("minimum of arrays of different length"))
-    res = NumArray(space, w_a.length, 'i')
-    for i in range(len(w_a.storage)):
-        one = w_a.storage[i]
-        two = w_b.storage[i]
+    res = zeros(space, space.wrap(w_a.array.length), w_a.dtype)
+    for i in range(len(w_a.array.storage)):
+        one = w_a.array.storage[i]
+        two = w_b.array.storage[i]
         if one < two:
-            res.storage[i] = one
+            res.array.storage[i] = one
         else:
-            res.storage[i] = two
+            res.array.storage[i] = two
     return space.wrap(res)
 minimum.unwrap_spec = [ObjSpace, W_Root, W_Root]



More information about the Pypy-commit mailing list