Author: Matti Picus <[email protected]>
Branch: str-dtype-improvement
Changeset: r62391:aaadf6eca9d9
Date: 2013-03-17 13:45 -0700
http://bitbucket.org/pypy/pypy/changeset/aaadf6eca9d9/

Log:    implement convert_from for str arrays only

diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py 
b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -47,13 +47,10 @@
         if impl.is_scalar():
             self.fill(impl.get_scalar_value())
             return
-        if self.dtype.is_str_or_unicode():
-            raise OperationError(space.w_NotImplementedError, space.wrap(
-                "concatenate(%s) not implemented yet" % self.dtype))
         shape = shape_agreement(space, self.get_shape(), arr)
         if impl.storage == self.storage:
-            impl = impl.copy()
-        loop.setslice(shape, self, impl)
+            impl = impl.copy(space)
+        loop.setslice(space, shape, self, impl)
 
     def get_size(self):
         return self.size // self.dtype.itemtype.get_element_size()
@@ -244,12 +241,12 @@
         return SliceArray(self.start, strides,
                           backstrides, shape, self, orig_array)
 
-    def copy(self):
+    def copy(self, space):
         strides, backstrides = support.calc_strides(self.get_shape(), 
self.dtype,
                                                     self.order)
         impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides,
                              backstrides)
-        return loop.setslice(self.get_shape(), impl, self)
+        return loop.setslice(space, self.get_shape(), impl, self)
 
     def create_axis_iter(self, shape, dim, cum):
         return iter.AxisIterator(self, shape, dim, cum)
@@ -284,7 +281,7 @@
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "astype(%s) not implemented yet" % self.dtype))
         else:    
-            loop.setslice(new_arr.get_shape(), new_arr.implementation, self)
+            loop.setslice(space, new_arr.get_shape(), new_arr.implementation, 
self)
         return new_arr
 
 class ConcreteArrayNotOwning(BaseConcreteArray):
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py 
b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -47,7 +47,7 @@
     def set_scalar_value(self, w_val):
         self.value = w_val.convert_to(self.dtype)
 
-    def copy(self):
+    def copy(self, space):
         scalar = Scalar(self.dtype)
         scalar.value = self.value
         return scalar
diff --git a/pypy/module/micronumpy/interp_dtype.py 
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -71,6 +71,8 @@
     def box_complex(self, real, imag):
         return self.itemtype.box_complex(real, imag)
 
+    def convert_from(self, space, box):
+        return self.itemtype.convert_from(space, self, box)
 
     def coerce(self, space, w_item):
         return self.itemtype.coerce(space, self, w_item)
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
@@ -252,7 +252,7 @@
         return self.implementation.get_scalar_value()
 
     def descr_copy(self, space):
-        return W_NDimArray(self.implementation.copy())
+        return W_NDimArray(self.implementation.copy(space))
 
     def descr_get_real(self, space):
         return W_NDimArray(self.implementation.get_real(self))
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -65,26 +65,32 @@
         obj_iter.next()
     return out
 
-setslice_driver = jit.JitDriver(name='numpy_setslice',
+setslice_driver1 = jit.JitDriver(name='numpy_setslice1',
                                 greens = ['shapelen', 'dtype'],
-                                reds = ['target', 'source', 'target_iter',
-                                        'source_iter'])
+                                reds = 'auto')
+setslice_driver2 = jit.JitDriver(name='numpy_setslice2',
+                                greens = ['shapelen', 'dtype'],
+                                reds = 'auto')
 
-def setslice(shape, target, source):
+def setslice(space, shape, target, source):
     # note that unlike everything else, target and source here are
     # array implementations, not arrays
     target_iter = target.create_iter(shape)
     source_iter = source.create_iter(shape)
     dtype = target.dtype
     shapelen = len(shape)
-    while not target_iter.done():
-        setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype,
-                                        target=target, source=source,
-                                        target_iter=target_iter,
-                                        source_iter=source_iter)
-        target_iter.setitem(source_iter.getitem().convert_to(dtype))
-        target_iter.next()
-        source_iter.next()
+    if dtype.is_str_or_unicode():
+        while not target_iter.done():
+            setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype)
+            target_iter.setitem(dtype.convert_from(space, 
source_iter.getitem()))
+            target_iter.next()
+            source_iter.next()
+    else:
+        while not target_iter.done():
+            setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype)
+            target_iter.setitem(source_iter.getitem().convert_to(dtype))
+            target_iter.next()
+            source_iter.next()
     return target
 
 reduce_driver = jit.JitDriver(name='numpy_reduce',
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
@@ -1480,13 +1480,10 @@
         a = (a + a)[::2]
         b = concatenate((a[:3], a[-3:]))
         assert (b == [2, 6, 10, 2, 6, 10]).all()
-        try:
-            a = concatenate((array([1]), array(['abc'])))
-            assert a.dtype == 'S3'
-            a = concatenate((array([]), array(['abc'])))
-            assert a[0] == 'abc'
-        except NotImplementedError:
-            skip('cannot concatenate numeric with string')
+        a = concatenate((array([1]), array(['abc'])))
+        assert str(a.dtype) == '|S3'
+        a = concatenate((array([]), array(['abc'])))
+        assert a[0] == 'abc'
     
     def test_record_concatenate(self):
         # only an exact match can succeed
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
@@ -1627,6 +1627,7 @@
     def get_size(self):
         return self.size
 
+
 class StringType(BaseType, BaseStringType):
     T = lltype.Char
 
@@ -1642,7 +1643,7 @@
     @jit.unroll_safe
     def store(self, arr, i, offset, box):
         assert isinstance(box, interp_boxes.W_StringBox)
-        for k in range(min(self.size, box.arr.size-offset)):
+        for k in range(min(self.size - i, box.arr.size-offset)):
             arr.storage[k + i] = box.arr.storage[k + offset]
 
     def read(self, arr, i, offset, dtype=None):
@@ -1675,6 +1676,20 @@
     def to_builtin_type(self, space, box):
         return space.wrap(self.to_str(box))
 
+    def convert_from(self, space, mydtype, box):
+        if box.get_dtype(space).is_str_or_unicode():
+            arg = box.get_dtype(space).itemtype.to_str(box)
+        else:
+            w_arg = box.descr_str(space)
+            arg = space.str_w(space.str(w_arg))
+        arr = VoidBoxStorage(self.size, mydtype)
+        i = 0
+        for i in range(min(len(arg), self.size)):
+            arr.storage[i] = arg[i]
+        for j in range(i + 1, self.size):
+            arr.storage[j] = '\x00'
+        return interp_boxes.W_StringBox(arr,  0, arr.dtype)
+        
 class VoidType(BaseType, BaseStringType):
     T = lltype.Char
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to