Anonymous avatar Anonymous committed 5388d03

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

Comments (0)

Files changed (7)

doc/MODULE_FAQ.txt

 ============
 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
+``PyArg_ParseTuple``.
+
+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

src/base/bufferproxy.c

 */
 #define PYGAME_BUFFERPROXY_INTERNAL
 
-#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;
+#else
+    if (!PyArg_ParseTuple (args, "s#n", &buf, &length, &offset))
+        return NULL;
+#endif
 
     if (offset + length > buffer->length)
     {

src/base/streamwrapper.c

 */
 #define PYGAME_STREAMWRAPPER_INTERNAL
 
-#include <Python.h>
 #include "internals.h"
 #include "pgbase.h"
 

src/math/mathmod.h

 #ifndef _PYGAME_MATHMOD_H_
 #define _PYGAME_MATHMOD_H_
 
-#include <Python.h>
+#include "pgcompat.h"
 
 #ifdef IS_WIN32
 #include <float.h>
 #ifndef _PYGAME_PYTHONCOMPAT_H_
 #define _PYGAME_PYTHONCOMPAT_H_
 
+#define PY_SSIZE_T_CLEAN
+
 #include <Python.h>
 
 /* Python 2.4 compatibility */
 #if PY_VERSION_HEX < 0x02050000
+
+#ifndef IS_PYTHON_24
+#   define IS_PYTHON_24
+#endif
+
 typedef int Py_ssize_t;
 #define PY_SSIZE_T_MAX INT_MAX
 #define PY_SSIZE_T_MIN INT_MIN
  * Useful python macros.
  */
 
-#include <Python.h>
+#include "pgcompat.h"
 
 #define ADD_OBJ_OR_FAIL(mod,name,type,mark)                       \
     Py_INCREF(&type);                                             \

test/base_bufferproxy_test.py

             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 ()
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.