[pypy-commit] pypy numpy-data-buffer: fix off-by-ones, fix NumpyViewBuffer.calc_index, test float dtype a bit.

timo_jbo noreply at buildbot.pypy.org
Mon Oct 3 07:51:50 CEST 2011


Author: Timo Paulssen <timonator at perpetuum-immobile.de>
Branch: numpy-data-buffer
Changeset: r47781:02416eeae241
Date: 2011-10-03 07:51 +0200
http://bitbucket.org/pypy/pypy/changeset/02416eeae241/

Log:	fix off-by-ones, fix NumpyViewBuffer.calc_index, test float dtype a
	bit.

diff --git a/pypy/module/_numpy/interp_buffer.py b/pypy/module/_numpy/interp_buffer.py
--- a/pypy/module/_numpy/interp_buffer.py
+++ b/pypy/module/_numpy/interp_buffer.py
@@ -13,7 +13,7 @@
 
     def getitem(self, index):
         index = self.calc_index(index)
-        if index > self.getlength() - 1:
+        if index > self.getlength():
             raise IndexError("Index out of bounds (0<=index<%d)" % self.getlength())
         storage = self.array.get_concrete().get_root_storage()
         char_data = rffi.cast(CHAR_TP, storage)
@@ -21,15 +21,14 @@
 
     def setitem(self, index, value):
         index = self.calc_index(index)
-        if index > self.getlength() - 1:
+        if index > self.getlength():
             raise IndexError("Index out of bounds (0<=index<%d)" % self.getlength())
         storage = self.array.get_concrete().get_root_storage()
         char_ptr = rffi.cast(CHAR_TP, storage)
         char_ptr[index] = value
 
     def setslice(self, index, newstring):
-        offset_index = self.calc_index(index)
-        if offset_index + len(newstring) > self.getlength():
+        if index + len(newstring) > self.getlength():
             raise IndexError("End of slice to set out of bounds (0<=index<%d)" % self.getlength())
         for idx in range(0, len(newstring)):
             self.setitem(index + idx, newstring[idx])
@@ -39,5 +38,12 @@
 
 class NumpyViewBuffer(NumpyBuffer):
     def calc_index(self, index):
-        return self.array.calc_index(index) * self.array.find_dtype().num_bytes
+        box_size = self.array.find_dtype().num_bytes
+        # index is a byte-index, calculate the box-index from it
+        box_index = index / box_size
+        # and we need the byte-inside-box index, too.
+        in_box_index = index % box_size
+        # now we use calc_index to get the correct box_index
+        offset_index = self.array.calc_index(box_index)
+        return offset_index * box_size + in_box_index
 
diff --git a/pypy/module/_numpy/test/test_buffer.py b/pypy/module/_numpy/test/test_buffer.py
--- a/pypy/module/_numpy/test/test_buffer.py
+++ b/pypy/module/_numpy/test/test_buffer.py
@@ -4,6 +4,7 @@
     def test_access(self):
         from _numpy import array
         from _numpy import dtype
+        from struct import pack
         ar = array(range(5), dtype=dtype("int8"))
         buf = ar.data
 
@@ -14,9 +15,16 @@
 
         assert len(buf) == 5
 
+        br = array(range(5,10), dtype=float)
+        buf = br.data
+        assert len(buf) == 5 * (64 / 8)
+
+        assert buf[:8] == pack("d", 5)
+
     def test_mutable(self):
         from _numpy import array
         from _numpy import dtype
+        from struct import pack
         ar = array(range(5), dtype=dtype("int8"))
         buf = ar.data
         assert buf[0] == '\0'
@@ -24,9 +32,19 @@
         ar[0] = 5
         assert buf[0] == "\5"
 
+        br = array(range(5,10), dtype=float)
+        buf = br.data
+        assert len(buf) == 5 * (64 / 8)
+
+        assert buf[:8] == pack("d", 5)
+
+        br[0] = 100
+        assert buf[:8] == pack("d", 100)
+
     def test_slice_view(self):
         from _numpy import array
         from _numpy import dtype
+        from struct import pack
         ar = array(range(5), dtype=dtype("int8"))
 
         view = ar[1:-1]
@@ -43,6 +61,13 @@
 
         assert len(view) == len(ar) - 2 == 3
 
+        br = array(range(5,10), dtype=float)
+        buf = br.data
+        viewbuf = br[1:-1].data
+
+        assert len(viewbuf) == len(buf) - 2 * (64 / 8)
+        assert viewbuf[:8] == buf[8:16] == pack("d", 6)
+
     def test_buffer_set(self):
         from _numpy import array
         from _numpy import dtype


More information about the pypy-commit mailing list