[pypy-commit] pypy numpy-record-dtypes: implement array.tostring and figure out we don't need it, add some actual tests

fijal noreply at buildbot.pypy.org
Tue Feb 7 11:39:17 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-record-dtypes
Changeset: r52159:ed14708a881d
Date: 2012-02-07 12:38 +0200
http://bitbucket.org/pypy/pypy/changeset/ed14708a881d/

Log:	implement array.tostring and figure out we don't need it, add some
	actual tests

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
@@ -625,6 +625,11 @@
         raise OperationError(space.w_NotImplementedError, space.wrap(
             "non-int arg not supported"))
 
+    def descr_tostring(self, space):
+        ra = ToStringArray(self)
+        loop.compute(ra)
+        return space.wrap(ra.s.build())
+
     def compute_first_step(self, sig, frame):
         pass
 
@@ -805,6 +810,18 @@
         return signature.ResultSignature(self.res_dtype, self.left.create_sig(),
                                          self.right.create_sig())
 
+class ToStringArray(Call1):
+    def __init__(self, child):
+        dtype = child.find_dtype()
+        self.itemsize = dtype.itemtype.get_element_size()
+        self.s = StringBuilder(child.size * self.itemsize)
+        Call1.__init__(self, None, 'tostring', child.shape, dtype, dtype,
+                       child)
+
+    def create_sig(self):
+        return signature.ToStringSignature(self.calc_dtype,
+                                           self.values.create_sig())
+
 def done_if_true(dtype, val):
     return dtype.itemtype.bool(val)
 
@@ -1285,6 +1302,7 @@
     std = interp2app(BaseArray.descr_std),
 
     fill = interp2app(BaseArray.descr_fill),
+    tostring = interp2app(BaseArray.descr_tostring),
 
     copy = interp2app(BaseArray.descr_copy),
     flatten = interp2app(BaseArray.descr_flatten),
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -318,6 +318,17 @@
         offset = frame.get_final_iter().offset
         arr.left.setitem(offset, self.right.eval(frame, arr.right))
 
+class ToStringSignature(Call1):
+    def __init__(self, dtype, child):
+        Call1.__init__(self, None, 'tostring', dtype, child)
+
+    def eval(self, frame, arr):
+        from pypy.module.micronumpy.interp_numarray import ToStringArray
+
+        assert isinstance(arr, ToStringArray)
+        arr.s.append(self.dtype.itemtype.pack_str(
+            self.child.eval(frame, arr.values)))
+
 class BroadcastLeft(Call2):
     def _invent_numbering(self, cache, allnumbers):
         self.left._invent_numbering(new_cache(), allnumbers)
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -1,5 +1,6 @@
 from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
-
+from pypy.module.micronumpy.interp_dtype import nonnative_byteorder_prefix
+from pypy.interpreter.gateway import interp2app
 
 class AppTestDtypes(BaseNumpyAppTest):
     def test_dtype(self):
@@ -182,6 +183,20 @@
 
 
 class AppTestTypes(BaseNumpyAppTest):
+    def setup_class(cls):
+        BaseNumpyAppTest.setup_class.im_func(cls)
+        cls.w_non_native_prefix = cls.space.wrap(nonnative_byteorder_prefix)
+        def check_non_native(w_obj, w_obj2):
+            assert w_obj.storage[0] == w_obj2.storage[1]
+            assert w_obj.storage[1] == w_obj2.storage[0]
+            if w_obj.storage[0] == '\x00':
+                assert w_obj2.storage[1] == '\x00'
+                assert w_obj2.storage[0] == '\x01'
+            else:
+                assert w_obj2.storage[1] == '\x01'
+                assert w_obj2.storage[0] == '\x00'
+        cls.w_check_non_native = cls.space.wrap(interp2app(check_non_native))
+    
     def test_abstract_types(self):
         import _numpypy as numpy
         raises(TypeError, numpy.generic, 0)
@@ -427,4 +442,11 @@
     def test_alternate_constructs(self):
         from _numpypy import dtype
         assert dtype('i8') == dtype('<i8')# XXX should be equal == dtype(long)
-        assert dtype('>i8') != dtype('i8')
+        assert dtype(self.non_native_prefix + 'i8') != dtype('i8')
+
+    def test_non_native(self):
+        from _numpypy import array
+        a = array([1, 2, 3], dtype=self.non_native_prefix + 'i2')
+        assert a[0] == 1
+        assert (a + a)[1] == 4
+        self.check_non_native(a, array([1, 2, 3], 'i2'))
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
@@ -1740,6 +1740,12 @@
         #5 bytes is larger than 3 bytes
         raises(ValueError, fromstring, "\x01\x02\x03", count=5, dtype=uint8)
 
+    def test_tostring(self):
+        from _numpypy import array
+        assert array([1, 2, 3], 'i2').tostring() == '\x01\x00\x02\x00\x03\x00'
+        assert array([1, 2, 3], 'i2')[::2].tostring() == '\x01\x00\x03\x00'
+        assert array([1, 2, 3], '<i2')[::2].tostring() == '\x01\x00\x03\x00'
+        assert array([1, 2, 3], '>i2')[::2].tostring() == '\x00\x01\x00\x03'
 
 class AppTestRanges(BaseNumpyAppTest):
     def test_arange(self):
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
@@ -1,5 +1,6 @@
 import functools
 import math
+import struct
 
 from pypy.interpreter.error import OperationError
 from pypy.module.micronumpy import interp_boxes
@@ -125,6 +126,9 @@
     def runpack_str(self, s):
         return self.box(runpack(self.format_code, s))
 
+    def pack_str(self, box):
+        return struct.pack(self.format_code, self.unbox(box))
+
     @simple_binary_op
     def add(self, v1, v2):
         return v1 + v2
@@ -217,6 +221,9 @@
     def _write(self, storage, width, i, offset, value):
         Primitive._write(self, storage, width, i, offset, byteswap(value))
 
+    def pack_str(self, box):
+        return struct.pack(self.format_code, byteswap(self.unbox(box)))
+
 class Bool(BaseType, Primitive):
     T = lltype.Bool
     BoxType = interp_boxes.W_BoolBox


More information about the pypy-commit mailing list