1. Stefano Rivera
  2. pygame-pypy


marcus  committed 5388d03

Changed size arguments to use Py_ssize_t only, where possible.
Fixed BufferProxy.write() argument handling and offset conversion.

  • Participants
  • Parent commits 87d293d
  • Branches pgreloaded

Comments (0)

Files changed (7)

File doc/MODULE_FAQ.txt

View file
 C Module FAQ
 The C API contains numerous macros and functions that ease the
 developer's life. In order to have a similar behaviour without
 implementing the same things again and again, the most important ones will be
 or floating point value from a PyObject. Those however require other
 modules to import the base module.
+.. note::
+   **Never** do an ``#include <Python.h>`` in your code directly. We are
+   using ``PY_SSIZE_T_CLEAN`` along with a set of compatibility
+   macros. To have correct includes, use ``#include "pgcompat.h``
+   instead.
+Buffer Sizes and Offset Access
+Since Python 2.5, the **Py_ssize_t** type is available, which can (and
+should) be used for numerical sizing arguments. Python 2.4 does not know
+this type however and also cannot handle the ``n`` argument in
+To come around this issue, do something like the following in the code: ::
+  Py_ssize_t offset;
+  Py_ssize_t length;
+  char *buf;
+  #ifdef IS_PYTHON_24
+    if (!PyArg_ParseTuple (args, "s#i", &buf, &length, &offset))
+        return NULL;
+  #else
+    if (!PyArg_ParseTuple (args, "s#n", &buf, &length, &offset))
+        return NULL;
+  #endif
 Text Handling
 For text guaranteed to be UTF-8 or ASCII, use the related Text_***() macros

File src/base/bufferproxy.c

View file
-#include <Python.h>
-#include <structmember.h> /* Somehow offsetof's not recognized in this file */
 #include "internals.h"
 #include "pgbase.h"
 #include "base_doc.h"
+#include <structmember.h> /* Somehow offsetof's not recognized in this file */
 static PyObject* _bufferproxy_new (PyTypeObject *type, PyObject *args,
     PyObject *kwds);
 static void _bufferproxy_dealloc (PyBufferProxy *self);
     Py_ssize_t length;
     char *buf;
+#ifdef IS_PYTHON_24
     if (!PyArg_ParseTuple (args, "s#i", &buf, &length, &offset))
         return NULL;
+    if (!PyArg_ParseTuple (args, "s#n", &buf, &length, &offset))
+        return NULL;
     if (offset + length > buffer->length)

File src/base/streamwrapper.c

View file
-#include <Python.h>
 #include "internals.h"
 #include "pgbase.h"

File src/math/mathmod.h

View file
-#include <Python.h>
+#include "pgcompat.h"
 #ifdef IS_WIN32
 #include <float.h>

File src/pgcompat.h

View file
 #include <Python.h>
 /* Python 2.4 compatibility */
 #if PY_VERSION_HEX < 0x02050000
+#ifndef IS_PYTHON_24
+#   define IS_PYTHON_24
 typedef int Py_ssize_t;

File src/pymacros.h

View file
  * Useful python macros.
-#include <Python.h>
+#include "pgcompat.h"
 #define ADD_OBJ_OR_FAIL(mod,name,type,mark)                       \
     Py_INCREF(&type);                                             \

File test/base_bufferproxy_test.py

View file
             del buf
         video.quit ()
-    def todo_test_pygame2_base_BufferProxy_write(self):
+    def test_pygame2_base_BufferProxy_write(self):
         # __doc__ (as of 2010-01-13) for pygame2.base.BufferProxy.write:
         # the length of the passed *buffer* exceeds the length of the
         # BufferProxy (reduced by *offset*), an IndexError will
         # be raised.
-        self.fail ()
+        video.init ()
+        for bpp in (32, 16, 8):
+            surface = video.Surface (10, 10, bpp)
+            buf = surface.pixels
+            for y in range (surface.height):
+                for x in range (surface.width):
+                    buf.write ('\xff', x + y * surface.pitch)
+            del buf
+            # getat = surface.get_at
+            # color = Color (255, 255, 255, 255)
+            # for x in range (surface.width):
+            #     for y in range (surface.height):
+            #         self.failUnlessEqual (getat (x, y), color,
+            #             "%s != %s at (%d, %d)" % (getat (x, y), color, x, y))
+        video.quit ()
 if __name__ == '__main__':
     unittest.main ()