Commits

Lenard Lindstrom committed 49bc0a3

add PyBUF constants, PyBUFFER_SIZEOF check, and fix duplicate class name

Comments (0)

Files changed (2)

 } BufferObject;
 
 static int
+Module_AddSsize_tConstant(PyObject *module, const char *name, Py_ssize_t value)
+{
+    PyObject *py_value = PyLong_FromSsize_t(value);
+
+    if (!py_value) {
+        return -1;
+    }
+    if (PyModule_AddObject(module, name, py_value)) {
+        Py_DECREF(py_value);
+        return -1;
+    }
+    return 0;
+}
+
+static int
 check_view(BufferObject *op, const char *name)
 {
     if (!op->view_p) {
         DECREF_MOD(module);
         MODINIT_ERROR;
     }
-    obj = PyLong_FromSsize_t((Py_ssize_t)sizeof (Py_buffer));
-    if (!obj) {
-        DECREF_MOD(module);
-        MODINIT_ERROR;
-    }
-    if (PyModule_AddObject(module, "Py_buffer_SIZEOF", obj)) {
-        Py_DECREF(&obj);
+    if (Module_AddSsize_tConstant(module,
+                                  "PyBUFFER_SIZEOF",
+                                  sizeof (Py_buffer)) ||
+        PyModule_AddIntMacro(module, PyBUF_SIMPLE) ||
+        PyModule_AddIntMacro(module, PyBUF_WRITABLE) ||
+        PyModule_AddIntMacro(module, PyBUF_STRIDES) ||
+        PyModule_AddIntMacro(module, PyBUF_ND) ||
+        PyModule_AddIntMacro(module, PyBUF_C_CONTIGUOUS) ||
+        PyModule_AddIntMacro(module, PyBUF_F_CONTIGUOUS) ||
+        PyModule_AddIntMacro(module, PyBUF_ANY_CONTIGUOUS) ||
+        PyModule_AddIntMacro(module, PyBUF_INDIRECT) ||
+        PyModule_AddIntMacro(module, PyBUF_FORMAT) ||
+        PyModule_AddIntMacro(module, PyBUF_STRIDED) ||
+        PyModule_AddIntMacro(module, PyBUF_STRIDED_RO) ||
+        PyModule_AddIntMacro(module, PyBUF_RECORDS) ||
+        PyModule_AddIntMacro(module, PyBUF_RECORDS_RO) ||
+        PyModule_AddIntMacro(module, PyBUF_FULL) ||
+        PyModule_AddIntMacro(module, PyBUF_FULL_RO) ||
+        PyModule_AddIntMacro(module, PyBUF_CONTIG) ||
+        PyModule_AddIntMacro(module, PyBUF_CONTIG_RO)) {
         DECREF_MOD(module);
         MODINIT_ERROR;
     }

newbuffer_test.py

 import unittest
 
-from newbuffer import Py_buffer, BufferMixin, Py_buffer_SIZEOF
+from newbuffer import (Py_buffer, BufferMixin, PyBUFFER_SIZEOF,
+                       PyBUF_SIMPLE, PyBUF_WRITABLE, PyBUF_STRIDES,
+                       PyBUF_ND, PyBUF_C_CONTIGUOUS, PyBUF_F_CONTIGUOUS,
+                       PyBUF_ANY_CONTIGUOUS, PyBUF_INDIRECT, PyBUF_FORMAT,
+                       PyBUF_STRIDED, PyBUF_STRIDED_RO, PyBUF_RECORDS,
+                       PyBUF_RECORDS_RO, PyBUF_FULL, PyBUF_FULL_RO,
+                       PyBUF_CONTIG, PyBUF_CONTIG_RO)
 from ctypes import *
 
 class Py_bufferTest(unittest.TestCase):
             """Weakref enabled object"""
             pass
 
-        self.assertTrue(Py_buffer_SIZEOF > 0)
-        allocation = create_string_buffer(Py_buffer_SIZEOF)
+        self.assertTrue(PyBUFFER_SIZEOF > 0)
+        allocation = create_string_buffer(PyBUFFER_SIZEOF)
         b = Py_buffer(addressof(allocation))
         self.assertTrue(b)
         b.obj = None
 
     def test_property_del(self):
         """Verify Py_buffer properties can not be deleted"""
-        allocation = create_string_buffer(Py_buffer_SIZEOF)
+        allocation = create_string_buffer(PyBUFFER_SIZEOF)
         b = Py_buffer(addressof(allocation))
         self.assertRaises(AttributeError, delattr, b, 'obj')
         b.obj = []
         self.assertTrue(b.is_view_alive)
         self.assertTrue(b.is_view_obj_self)
 
-class BufferMixinReleaseBufferTest(unittest.TestCase):
+class BufferMixinTest(unittest.TestCase):
     """BufferMixin._release_buffer verification"""
     class B(BufferMixin):
         width = 3
         self.assertEqual(m.strides, (b.height * b.itemsize, b.itemsize))
         self.assertFalse(m.readonly)
 
+class ModuleConstantsTest(unittest.TestCase):
+    """Verify module constants"""
+    def test_PyBUF_x(self):
+        """the PyBUF_<flag> PyObject_GetBuffer flags"""
+        self.assertEqual(PyBUF_SIMPLE, 0)
+        self.assertEqual(PyBUF_WRITABLE, 0x0001)
+        self.assertEqual(PyBUF_STRIDES, 0x0010 | PyBUF_ND)
+        self.assertEqual(PyBUF_ND, 0x0008)
+        self.assertEqual(PyBUF_C_CONTIGUOUS, 0x0020 | PyBUF_STRIDES)
+        self.assertEqual(PyBUF_F_CONTIGUOUS, 0x0040 | PyBUF_STRIDES)
+        self.assertEqual(PyBUF_ANY_CONTIGUOUS, 0x0080 | PyBUF_STRIDES)
+        self.assertEqual(PyBUF_INDIRECT, 0x0100 | PyBUF_STRIDES)
+        self.assertEqual(PyBUF_FORMAT, 0x0004)
+        self.assertEqual(PyBUF_STRIDED, PyBUF_STRIDED_RO | PyBUF_WRITABLE)
+        self.assertEqual(PyBUF_STRIDED_RO, PyBUF_STRIDES)
+        self.assertEqual(PyBUF_RECORDS, PyBUF_RECORDS_RO | PyBUF_WRITABLE)
+        self.assertEqual(PyBUF_RECORDS_RO, PyBUF_STRIDES | PyBUF_FORMAT)
+        self.assertEqual(PyBUF_FULL, PyBUF_FULL_RO | PyBUF_WRITABLE)
+        self.assertEqual(PyBUF_FULL_RO, PyBUF_INDIRECT | PyBUF_FORMAT)
+        self.assertEqual(PyBUF_CONTIG, PyBUF_CONTIG_RO | PyBUF_WRITABLE)
+        self.assertEqual(PyBUF_CONTIG_RO, PyBUF_ND)
+
+    def test_PyBUFFER_SIZEOF(self):
+        """Sanity check on Py_buffer size contant"""
+        class Py_buffer_def(Structure):
+            """Documented Py_buffer fields"""
+            _fields_ = [('obj', py_object),
+                        ('buf', c_void_p),
+                        ('len', c_ssize_t),
+                        ('readonly', c_int),
+                        ('format', c_char_p),
+                        ('ndim', c_int),
+                        ('shape', POINTER(c_ssize_t)),
+                        ('strides', POINTER(c_ssize_t)),
+                        ('suboffsets', POINTER(c_ssize_t)),
+                        ('itemsize', c_ssize_t),
+                        ('internal', c_void_p)]
+        sz = sizeof(Py_buffer_def)
+        self.assertTrue(2 * sz > PyBUFFER_SIZEOF >= sz)
+
+
 if __name__ == '__main__':
     unittest.main()