Lenard Lindstrom avatar Lenard Lindstrom committed e452a8d

Enhance buftools.Exporter to support negative strides

For pixelcopy_test.py unit tests.

Comments (0)

Files changed (1)

test/test_utils/buftools.py

             self._strides = (ctypes.c_ssize_t * self.ndim)(*self.strides)
         else:
             raise ValueError("Mismatch in length of strides and shape")
-        buflen =  max(self.shape[i] * self.strides[i] for i in range(self.ndim))
+        buflen =  max(d * abs(s) for d, s in zip(self.shape, self.strides))
         self.buflen = buflen
         self._buf = (ctypes.c_ubyte * buflen)()
-        self.buf = ctypes.addressof(self._buf)
+        offset = sum((d - 1) * abs(s)
+                     for d, s in zip(self.shape, self.strides) if s < 0)
+        self.buf = ctypes.addressof(self._buf) + offset
 
     def buffer_info(self):
         return (addressof(self.buffer), self.shape[0])
         self.assertRaises(BufferError, Importer, a, PyBUF_ANY_CONTIGUOUS)
         self.assertRaises(BufferError, Importer, a, PyBUF_CONTIG)
 
+    def test_negative_strides(self):
+        self.check_args(3, (3, 5, 4), 'B', (20, 4, -1), 60, 60, 1, 3)
+        self.check_args(3, (3, 5, 3), 'B', (20, 4, -1), 45, 60, 1, 2)
+        self.check_args(3, (3, 5, 4), 'B', (20, -4, 1), 60, 60, 1, 16)
+        self.check_args(3, (3, 5, 4), 'B', (-20, -4, -1), 60, 60, 1, 59)
+        self.check_args(3, (3, 5, 3), 'B', (-20, -4, -1), 45, 60, 1, 58)
+
     def test_attributes(self):
         a = Exporter((13, 5, 11, 3), '=h', (440, 88, 8, 2))
         self.assertEqual(a.ndim, 4)
         self.assertEqual(a.strides, (440, 88, 8, 2))
 
     def check_args(self, call_flags,
-                   shape, format, strides, length, bufsize, itemsize):
+                   shape, format, strides, length, bufsize, itemsize,
+                   offset=0):
         format_arg = format if call_flags & 1 else None
         strides_arg = strides if call_flags & 2 else None
         a = Exporter(shape, format_arg, strides_arg)
         self.assertEqual(a.buflen, bufsize)
+        self.assertEqual(a.buf, ctypes.addressof(a._buf) + offset)
         m = Importer(a, PyBUF_RECORDS_RO)
         self.assertEqual(m.buf, a.buf)
         self.assertEqual(m.len, length)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.