Commits

Lenard Lindstrom committed 42e2bde

Use capsule objects in preference to cobject objects. This allows Pygame to build an run from Python 3.2, which has to cobjects.

  • Participants
  • Parent commits 5138459

Comments (0)

Files changed (26)

 # BREAK = change breaks existing code
 # BUG    = fixed a bug that was (or could have been) crashing
 
+[SVN 2936] September 22, 2010
+    Use capsule objects in preference to cobject objects.
+    This allows Pygame to build an run from Python 3.2, which has to cobjects.
+
 [SVN 2934] September 16, 2010
     [BUG] Fix some MSVC warnings in hope of solving an error raised in font_test.py.
 

src/_arraysurfarray.c

         return 0;
     }
 
-#if defined(PyCObject_Check)
+#if PG_HAVE_COBJECT
     if (PyCObject_Check(cobj)) {
         inter = (PyArrayInterface *)PyCObject_AsVoidPtr(cobj);
     }
 #endif
-#if defined(PyCapsule_CheckExact)
+#if PG_HAVE_CAPSULE
     if (PyCapsule_IsValid(cobj, NULL)) {
         inter = (PyArrayInterface *)PyCapsule_GetPointer(cobj, NULL);
     }
     }
     if (func)
     {
-        obj = PyCObject_FromVoidPtr (func, NULL);
+        obj = PyCapsule_New (func, "quit", NULL);
         PyList_Append (quitfunctions, obj);
         Py_DECREF (obj);
     }
         quit = PyList_GET_ITEM (privatefuncs, num);
         if (PyCallable_Check (quit))
             PyObject_CallObject (quit, NULL);
-        else if (PyCObject_Check (quit))
+        else if (PyCapsule_CheckExact (quit))
         {
-            void* ptr = PyCObject_AsVoidPtr (quit);
+            void* ptr = PyCapsule_GetPointer (quit, "quit");
             (*(void(*)(void)) ptr) ();
         }
     }
     c_api[10] = PyGame_Video_AutoQuit;
     c_api[11] = PyGame_Video_AutoInit;
     c_api[12] = RGBAFromObj;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "base");
     if (apiobj == NULL) {
         Py_XDECREF (atexit_register);
         DECREF_MOD (module);

src/bufferproxy.c

 
     c_api[0] = &PyBufferProxy_Type;
     c_api[1] = PyBufferProxy_New;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "bufferproxy");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     /* export the c api */
     c_api[0] = &PyCD_Type;
     c_api[1] = PyCD_New;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "cdrom");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     c_api[2] = RGBAFromColorObj;
     c_api[3] = PyColor_NewLength;
 
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "color");
     if (apiobj == NULL) {
         Py_DECREF (_COLORDICT);
         DECREF_MOD(module);
     PyDict_SetItemString (dict, "window", tmp);
     Py_DECREF (tmp);
 
-    tmp = PyCObject_FromVoidPtr (info.info.x11.display, NULL);
+    tmp = PyCapsule_New (info.info.x11.display, "display", NULL);
     PyDict_SetItemString (dict, "display", tmp);
     Py_DECREF (tmp);
 
-    tmp = PyCObject_FromVoidPtr (info.info.x11.lock_func, NULL);
+    tmp = PyCapsule_New (info.info.x11.lock_func, "lock_func", NULL);
     PyDict_SetItemString (dict, "lock_func", tmp);
     Py_DECREF (tmp);
     
-    tmp = PyCObject_FromVoidPtr (info.info.x11.unlock_func, NULL);
+    tmp = PyCapsule_New (info.info.x11.unlock_func, "unlock_func", NULL);
     PyDict_SetItemString (dict, "unlock_func", tmp);
     Py_DECREF (tmp);
 
     */
     import_pygame_base ();
     if (PyErr_Occurred ()) {
-	MODINIT_ERROR;
+    	MODINIT_ERROR;
     }
     import_pygame_rect ();
     if (PyErr_Occurred ()) {
-	MODINIT_ERROR;
+    	MODINIT_ERROR;
     }
     import_pygame_surface ();
     if (PyErr_Occurred ()) {
-	MODINIT_ERROR;
+    	MODINIT_ERROR;
     }
 
     /* type preparation */
     /* export the c api */
     c_api[0] = &PyVidInfo_Type;
     c_api[1] = PyVidInfo_New;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "display");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     c_api[1] = PyEvent_New;
     c_api[2] = PyEvent_New2;
     c_api[3] = PyEvent_FillUserEvent;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "event");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     };
 #endif
 
-    PyFONT_C_API[0] = PyFONT_C_API[0]; /*clean an unused warning*/
-
     /* imported needed apis; Do this first so if there is an error
        the module is not loaded.
     */
     c_api[0] = &PyFont_Type;
     c_api[1] = PyFont_New;
     c_api[2] = &font_initialized;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "font");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
 
 
 
+#define PYGAMEAPI_FONT_FIRSTSLOT 0
 #define PYGAMEAPI_FONT_NUMSLOTS 3
 typedef struct {
   PyObject_HEAD
   PyObject* weakreflist;
 } PyFontObject;
 #define PyFont_AsFont(x) (((PyFontObject*)x)->font)
+
 #ifndef PYGAMEAPI_FONT_INTERNAL
 #define PyFont_Check(x) ((x)->ob_type == (PyTypeObject*)PyFONT_C_API[0])
 #define PyFont_Type (*(PyTypeObject*)PyFONT_C_API[0])
 #define PyFont_New (*(PyObject*(*)(TTF_Font*))PyFONT_C_API[1])
 /*slot 2 taken by FONT_INIT_CHECK*/
-#define import_pygame_font() { \
-	PyObject *module = PyImport_ImportModule(MODPREFIX "font"); \
-	if (module != NULL) { \
-		PyObject *dict = PyModule_GetDict(module); \
-		PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY); \
-		if(PyCObject_Check(c_api)) {\
-			void** localptr = (void**)PyCObject_AsVoidPtr(c_api); \
-			memcpy(PyFONT_C_API, localptr, sizeof(void*)*PYGAMEAPI_FONT_NUMSLOTS); \
-} Py_DECREF(module); } }
+
+#define import_pygame_font() \
+    _IMPORT_PYGAME_MODULE(font, FONT, PyFONT_C_API)
+
+static void* PyFONT_C_API[PYGAMEAPI_FONT_NUMSLOTS] = {NULL};
 #endif
 
-
-
-
-static void* PyFONT_C_API[PYGAMEAPI_FONT_NUMSLOTS] = {NULL};
     c_api[0] = &PyFreeTypeFont_Type;
     c_api[1] = &PyFreeTypeFont_New;
 
-    apiobj = PyCObject_FromVoidPtr(c_api, NULL);
+    apiobj = encapsulate_api(c_api, "freetype");
     if (apiobj == NULL) 
     {
         Py_DECREF (pygame_register_quit);
 /**********************************************************
  * Module declaration
  **********************************************************/
+#define PYGAMEAPI_FREETYPE_FIRSTSLOT 0
 #define PYGAMEAPI_FREETYPE_NUMSLOTS 2
 
 #define PyFreeTypeFont_AsFont(x) (((PyFreeTypeFont *)x)->font)
 #define PyFreeTypeFont_Type (*(PyTypeObject*)PyFREETYPE_C_API[1])
 #define PyFont_New (*(PyObject*(*)(const char*, int))PyFREETYPE_C_API[1])
 
-#define import_pygame_freetype() { \
-	PyObject *module = PyImport_ImportModule(MODPREFIX "freetype"); \
-	if (module != NULL) { \
-		PyObject *dict = PyModule_GetDict(module); \
-		PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY); \
-		if(PyCObject_Check(c_api)) {\
-			void** localptr = (void**)PyCObject_AsVoidPtr(c_api); \
-			memcpy(PyFREETYPE_C_API, localptr, sizeof(void*)*PYGAMEAPI_FREETYPE_NUMSLOTS); \
-} Py_DECREF(module); } }
+#define import_pygame_freetype() \
+    _IMPORT_PYGAME_MODULE(freetype, FREETYPE, PyFREETYPE_C_API)
 
+static void *PyFREETYPE_C_API[PYGAMEAPI_FREETYPE_NUMSLOTS] = {NULL};
 #endif /* PYGAME_FREETYPE_INTERNAL */
 
-static void *PyFREETYPE_C_API[PYGAMEAPI_FREETYPE_NUMSLOTS] = {NULL};
-
 #endif /* _PYGAME_FREETYPE_H_ */
     /* export the c api */
     c_api[0] = &PyJoystick_Type;
     c_api[1] = PyJoystick_New;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "joystick");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     }
     /* export the c api */
     c_api[0] = &PyMask_Type;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "mask");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
 #include <Python.h>
 #include "bitmask.h"
 
+#define PYGAMEAPI_MASK_FIRSTSLOT 0
 #define PYGAMEAPI_MASK_NUMSLOTS 1
 #define PYGAMEAPI_LOCAL_ENTRY "_PYGAME_C_API"
 
 #define PyMask_Type     (*(PyTypeObject*)PyMASK_C_API[0])
 #define PyMask_Check(x) ((x)->ob_type == &PyMask_Type)
 
-#define import_pygame_mask() {                                                                 \
-	PyObject *module = PyImport_ImportModule(IMPPREFIX "mask");                               \
-	if (module != NULL) {                                                                  \
-		PyObject *dict  = PyModule_GetDict(module);                                    \
-		PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY);           \
-		if(PyCObject_Check(c_api)) {                                                   \
-			void** localptr = (void**) PyCObject_AsVoidPtr(c_api);                 \
-			memcpy(PyMASK_C_API, localptr, sizeof(void*)*PYGAMEAPI_MASK_NUMSLOTS); \
-		} Py_DECREF(module);                                                           \
-	}                                                                                      \
-}
-
-#endif /* !defined(PYGAMEAPI_MASK_INTERNAL) */
+#define import_pygame_mask() \
+    _IMPORT_PYGAME_MODULE(mask, MASK, PyMASK_C_API)
 
 static void* PyMASK_C_API[PYGAMEAPI_MASK_NUMSLOTS] = {NULL};
+#endif /* #ifndef PYGAMEAPI_MASK_INTERNAL */
 
     c_api[3] = PyVector_NEW;
     c_api[4] = PyVectorCompatible_Check;
     */
-    apiobj = PyCObject_FromVoidPtr(c_api, NULL);
+    apiobj = encapsulate_api(c_api, "math");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     };
 #endif
 
-    PyMIXER_C_API[0] = PyMIXER_C_API[0]; /*this cleans an unused warning*/
-
     /* imported needed apis; Do this first so if there is an error
        the module is not loaded.
     */
     c_api[4] = PyChannel_New;
     c_api[5] = autoinit;
     c_api[6] = autoquit;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "mixer");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
         }
         _dict = PyModule_GetDict (music);
         ptr = PyDict_GetItemString (_dict, "_MUSIC_POINTER");
-        current_music = (Mix_Music**)PyCObject_AsVoidPtr (ptr);
+        current_music = 
+            (Mix_Music**)PyCapsule_GetPointer (ptr, "pygame.music_mixer."
+                                                    "_MUSIC_POINTER");
         ptr = PyDict_GetItemString (_dict, "_QUEUE_POINTER");
-        queue_music = (Mix_Music**)PyCObject_AsVoidPtr (ptr);
+        queue_music = 
+            (Mix_Music**)PyCapsule_GetPointer (ptr, "pygame.music_mixer."
+                                                    "_QUEUE_POINTER");
     }
     else /*music module not compiled? cleanly ignore*/
     {
 
 
 
+#define PYGAMEAPI_MIXER_FIRSTSLOT 0
 #define PYGAMEAPI_MIXER_NUMSLOTS 7
 typedef struct {
   PyObject_HEAD
 } PyChannelObject;
 #define PySound_AsChunk(x) (((PySoundObject*)x)->chunk)
 #define PyChannel_AsInt(x) (((PyChannelObject*)x)->chan)
+
 #ifndef PYGAMEAPI_MIXER_INTERNAL
 #define PySound_Check(x) ((x)->ob_type == (PyTypeObject*)PyMIXER_C_API[0])
 #define PySound_Type (*(PyTypeObject*)PyMIXER_C_API[0])
 #define PyChannel_New (*(PyObject*(*)(int))PyMIXER_C_API[4])
 #define PyMixer_AutoInit (*(PyObject*(*)(PyObject*, PyObject*))PyMIXER_C_API[5])
 #define PyMixer_AutoQuit (*(void(*)(void))PyMIXER_C_API[6])
-#define import_pygame_mixer() { \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "mixer"); \
-	if (_module != NULL) { \
-		PyObject *_dict = PyModule_GetDict(_module); \
-		PyObject *_c_api = PyDict_GetItemString(_dict, PYGAMEAPI_LOCAL_ENTRY); \
-		if(PyCObject_Check(_c_api)) {\
-			void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-			memcpy(PyMIXER_C_API, localptr, sizeof(void*)*PYGAMEAPI_MIXER_NUMSLOTS); \
-} Py_DECREF(_module); } }
+
+#define import_pygame_mixer() \
+    _IMPORT_PYGAME_MODULE(mixer, MIXER, PyMIXER_C_API)
+
+static void* PyMIXER_C_API[PYGAMEAPI_MIXER_NUMSLOTS] = {NULL};
 #endif
 
-
-
-static void* PyMIXER_C_API[PYGAMEAPI_MIXER_NUMSLOTS] = {NULL};
     if (module == NULL) {
         MODINIT_ERROR;
     }
-    cobj = PyCObject_FromVoidPtr (&current_music, NULL);
+    cobj = PyCapsule_New (&current_music,
+                          "pygame.music_mixer._MUSIC_POINTER", NULL);
     if (cobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
         DECREF_MOD (module);
         MODINIT_ERROR;
     }
-    cobj = PyCObject_FromVoidPtr (&queue_music, NULL);
+    cobj = PyCapsule_New (&queue_music,
+                          "pygame.music_mixer._QUEUE_POINTER", NULL);
     if (cobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
 #define UNICODE_DEF_FS_CODEC Py_FileSystemDefaultEncoding
 #define UNICODE_DEF_FS_ERROR "surrogateescape"
 
-#else /* PY_VERSION_HEX >= 0x03000000 */
+#else /* #if PY_VERSION_HEX >= 0x03000000 */
 
 #define PY3 0
 
 #define UNICODE_DEF_FS_CODEC Py_FileSystemDefaultEncoding
 #define UNICODE_DEF_FS_ERROR "strict"
 
-#endif /* PY_VERSION_HEX >= 0x03000000 */
+#endif /* #if PY_VERSION_HEX >= 0x03000000 */
 
 #define PY2 (!PY3)
 
 #define RELATIVE_MODULE(m) (m)
 #endif
 
-#endif /* !defined(PGCOMPAT_H) */
+#endif /* #if !defined(PGCOMPAT_H) */
 
     c_api[0] = &PyPixelArray_Type;
     c_api[1] = PyPixelArray_New;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "pixelarray");
     if (apiobj == NULL)
     {
         DECREF_MOD (module);
 
 #include <Python.h>
 
+/* Cobjects vanish in Python 3.2; so we will code as though we use capsules */
+#if defined(Py_CAPSULE_H)
+#define PG_HAVE_CAPSULE 1
+#else
+#define PG_HAVE_CAPSULE 0
+#endif
+#if defined(Py_COBJECT_H)
+#define PG_HAVE_COBJECT 1
+#else
+#define PG_HAVE_COBJECT 0
+#endif
+#if !PG_HAVE_CAPSULE
+#define PyCapsule_New(ptr, n, dfn) PyCObject_FromVoidPtr(ptr, dfn)
+#define PyCapsule_GetPointer(obj, n) PyCObject_AsVoidPtr(obj)
+#define PyCapsule_CheckExact(obj) PyCObject_Check(obj)
+#endif
+
 // No signal()
 #if defined(__SYMBIAN32__) && defined(HAVE_SIGNAL_H)
 #undef HAVE_SIGNAL_H
 #define RGBAFromObj                                                     \
     (*(int(*)(PyObject*, Uint8*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 12])
 
-#define import_pygame_base() {                                          \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "base");        \
-	if (_module != NULL) {                                           \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_BASE_NUMSLOTS; ++i)            \
-                    PyGAME_C_API[i + PYGAMEAPI_BASE_FIRSTSLOT] = localptr[i]; \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_base() IMPORT_PYGAME_MODULE(base, BASE)
 #endif
 
 
     (*(GAME_Rect*(*)(PyObject*, GAME_Rect*))                            \
      PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 3])
 
-#define import_pygame_rect() {                                          \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "rect");        \
-	if (_module != NULL) {                                         \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_RECT_NUMSLOTS; ++i)            \
-                    PyGAME_C_API[i + PYGAMEAPI_RECT_FIRSTSLOT] = localptr[i]; \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_rect() IMPORT_PYGAME_MODULE(rect, RECT)
 #endif
 
 
 #define PyCD_New                                                        \
     (*(PyObject*(*)(int))PyGAME_C_API[PYGAMEAPI_CDROM_FIRSTSLOT + 1])
 
-#define import_pygame_cd() {                                      \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "cdrom"); \
-	if (_module != NULL) {                                     \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_CDROM_NUMSLOTS; ++i)           \
-                    PyGAME_C_API[i + PYGAMEAPI_CDROM_FIRSTSLOT] = localptr[i]; \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_cd() IMPORT_PYGAME_MODULE(cdrom, CDROM)
 #endif
 
 
 #define PyJoystick_New                                                  \
     (*(PyObject*(*)(int))PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 1])
 
-#define import_pygame_joystick() {                                      \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "joystick");    \
-	if (_module != NULL) {                                           \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_JOYSTICK_NUMSLOTS; ++i)        \
-                    PyGAME_C_API[i + PYGAMEAPI_JOYSTICK_FIRSTSLOT] =    \
-                        localptr[i];                                    \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_joystick() IMPORT_PYGAME_MODULE(joystick, JOYSTICK)
 #endif
 
 
 #define PyVidInfo_New                                   \
     (*(PyObject*(*)(SDL_VideoInfo*))                    \
      PyGAME_C_API[PYGAMEAPI_DISPLAY_FIRSTSLOT + 1])
-#define import_pygame_display() {                                   \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "display"); \
-	if (_module != NULL) {                                       \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_DISPLAY_NUMSLOTS; ++i)         \
-                    PyGAME_C_API[i + PYGAMEAPI_DISPLAY_FIRSTSLOT] =     \
-                        localptr[i];                                    \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_display() IMPORT_PYGAME_MODULE(display, DISPLAY)
 #endif
 
 
      PyGAME_C_API[PYGAMEAPI_SURFACE_FIRSTSLOT + 2])
 
 #define import_pygame_surface() do {                                   \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "surface"); \
-	if (_module != NULL) {                                       \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_SURFACE_NUMSLOTS; ++i)         \
-                    PyGAME_C_API[i + PYGAMEAPI_SURFACE_FIRSTSLOT] =     \
-                        localptr[i];                                    \
-				}                                                           \
-				Py_DECREF(_module);                                          \
-			}                                                               \
-			else                                                            \
-			{                                                               \
-				break;                                                      \
-			}                                                               \
-			_module = PyImport_ImportModule(IMPPREFIX "surflock");          \
-			if (_module != NULL) {                                           \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_SURFLOCK_NUMSLOTS; ++i)        \
-                    PyGAME_C_API[i + PYGAMEAPI_SURFLOCK_FIRSTSLOT] =    \
-                        localptr[i];                                    \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
+    IMPORT_PYGAME_MODULE(surface, SURFACE);                            \
+    if (PyErr_Occurred() != NULL) break;                               \
+    IMPORT_PYGAME_MODULE(surflock, SURFLOCK);                          \
     } while (0)
 #endif
 
 #define PyEvent_FillUserEvent                           \
     (*(int (*)(PyEventObject*, SDL_Event*))             \
      PyGAME_C_API[PYGAMEAPI_EVENT_FIRSTSLOT + 3])
-#define import_pygame_event() {                                   \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "event"); \
-	if (_module != NULL) {                                     \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_EVENT_NUMSLOTS; ++i)           \
-                    PyGAME_C_API[i + PYGAMEAPI_EVENT_FIRSTSLOT] = localptr[i]; \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_event() IMPORT_PYGAME_MODULE(event, EVENT)
 #endif
 
 
         PyGAME_C_API[PYGAMEAPI_RWOBJECT_FIRSTSLOT + 5])
 #define RWopsFromFileObject                                         \
     (*(SDL_RWops*(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_RWOBJECT_FIRSTSLOT + 6])
-#define import_pygame_rwobject() {                                   \
-	PyObject *_module = PyImport_ImportModule(IMPPREFIX "rwobject"); \
-	if (_module != NULL) {                                        \
-            PyObject *_dict = PyModule_GetDict(_module);                  \
-            PyObject *_c_api = PyDict_GetItemString(_dict,                \
-                                                   PYGAMEAPI_LOCAL_ENTRY); \
-            if(PyCObject_Check(_c_api)) {                                \
-                int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
-                for(i = 0; i < PYGAMEAPI_RWOBJECT_NUMSLOTS; ++i)        \
-                    PyGAME_C_API[i + PYGAMEAPI_RWOBJECT_FIRSTSLOT] =    \
-                        localptr[i];                                    \
-            }                                                           \
-            Py_DECREF(_module);                                          \
-        }                                                               \
-    }
+#define import_pygame_rwobject() IMPORT_PYGAME_MODULE(rwobject, RWOBJECT)
+
 /* For backward compatibility */
 #define RWopsFromPython RWopsFromObject
 #define RWopsCheckPython RWopsCheckObject
 #define PyBufferProxy_New                                               \
     (*(PyObject*(*)(PyObject*, void*, Py_ssize_t, PyObject*))           \
     PyGAME_C_API[PYGAMEAPI_BUFFERPROXY_FIRSTSLOT + 1])
-#define import_pygame_bufferproxy()                                      \
-    {                                                                    \
-	PyObject *_module = PyImport_ImportModule (IMPPREFIX "bufferproxy");\
-	if (_module != NULL)                                             \
-        {                                                                \
-            PyObject *_dict = PyModule_GetDict (_module);                \
-            PyObject *_c_api = PyDict_GetItemString                      \
-                (_dict, PYGAMEAPI_LOCAL_ENTRY);                          \
-            if (PyCObject_Check (_c_api))                                \
-            {                                                            \
-                int i;                                                   \
-                void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
-                for (i = 0; i < PYGAMEAPI_BUFFERPROXY_NUMSLOTS; ++i)     \
-                    PyGAME_C_API[i + PYGAMEAPI_BUFFERPROXY_FIRSTSLOT] =  \
-                        localptr[i];                                     \
-            }                                                            \
-            Py_DECREF (_module);                                         \
-        }                                                                \
-    }
+#define import_pygame_bufferproxy() \
+    IMPORT_PYGAME_MODULE(bufferproxy, BUFFERPROXY)
 #endif /* PYGAMEAPI_BUFFERPROXY_INTERNAL */
 
 /* PixelArray */
      PyGAME_C_API[PYGAMEAPI_PIXELARRAY_FIRSTSLOT + 0])
 #define PyPixelArray_New                                                \
     (*(PyObject*(*)) PyGAME_C_API[PYGAMEAPI_PIXELARRAY_FIRSTSLOT + 1])
-#define import_pygame_pixelarray()                                       \
-    {                                                                    \
-	PyObject *_module = PyImport_ImportModule (IMPPREFIX "pixelarray"); \
-	if (_module != NULL)                                             \
-        {                                                                \
-            PyObject *_dict = PyModule_GetDict (_module);                \
-            PyObject *_c_api = PyDict_GetItemString                      \
-                (_dict, PYGAMEAPI_LOCAL_ENTRY);                          \
-            if (PyCObject_Check (_c_api))                                \
-            {                                                            \
-                int i;                                                   \
-                void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
-                for (i = 0; i < PYGAMEAPI_PIXELARRAY_NUMSLOTS; ++i)      \
-                    PyGAME_C_API[i + PYGAMEAPI_PIXELARRAY_FIRSTSLOT] =   \
-                        localptr[i];                                     \
-            }                                                            \
-            Py_DECREF (_module);                                         \
-        }                                                                \
-    }
+#define import_pygame_pixelarray() IMPORT_PYGAME_MODULE(pixelarray, PIXELARRAY)
 #endif /* PYGAMEAPI_PIXELARRAY_INTERNAL */
 
 /* Color */
 
 #define RGBAFromColorObj                                                \
     (*(int(*)(PyObject*, Uint8*)) PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 2])
-#define import_pygame_color()                                           \
-    {                                                                   \
-	PyObject *_module = PyImport_ImportModule (IMPPREFIX "color");     \
-	if (_module != NULL)                                            \
-        {                                                               \
-            PyObject *_dict = PyModule_GetDict (_module);               \
-            PyObject *_c_api = PyDict_GetItemString                     \
-                (_dict, PYGAMEAPI_LOCAL_ENTRY);                         \
-            if (PyCObject_Check (_c_api))                               \
-            {                                                           \
-                int i;                                                  \
-                void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
-                for (i = 0; i < PYGAMEAPI_COLOR_NUMSLOTS; ++i)          \
-                    PyGAME_C_API[i + PYGAMEAPI_COLOR_FIRSTSLOT] =       \
-                        localptr[i];                                    \
-            }                                                           \
-            Py_DECREF (_module);                                        \
-        }                                                               \
-    }
+#define import_pygame_color() IMPORT_PYGAME_MODULE(color, COLOR)
 #endif /* PYGAMEAPI_COLOR_INTERNAL */
 
 
 #define PyVector2_New                                             \
     (*(PyObject*(*)) PyGAME_C_API[PYGAMEAPI_MATH_FIRSTSLOT + 1])
 */
-#define import_pygame_math()                                           \
-    {                                                                   \
-	PyObject *_module = PyImport_ImportModule (IMPPREFIX "math");     \
-	if (_module != NULL)                                            \
-        {                                                               \
-            PyObject *_dict = PyModule_GetDict (_module);               \
-            PyObject *_c_api = PyDict_GetItemString                     \
-                (_dict, PYGAMEAPI_LOCAL_ENTRY);                         \
-            if (PyCObject_Check (_c_api))                               \
-            {                                                           \
-                int i;                                                  \
-                void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
-                for (i = 0; i < PYGAMEAPI_MATH_NUMSLOTS; ++i)          \
-                    PyGAME_C_API[i + PYGAMEAPI_MATH_FIRSTSLOT] =       \
-                        localptr[i];                                    \
-            }                                                           \
-            Py_DECREF (_module);                                        \
-        }                                                               \
-    }
+#define import_pygame_math() IMPORT_PYGAME_MODULE(math, MATH)
 #endif /* PYGAMEAPI_MATH_INTERNAL */
 
+#define PG_CAPSULE_NAME(m) (IMPPREFIX m "." PYGAMEAPI_LOCAL_ENTRY)
+
+#define _IMPORT_PYGAME_MODULE(module, MODULE, api_root) {                   \
+	    PyObject *_module = PyImport_ImportModule (IMPPREFIX #module);      \
+                                                                            \
+	    if (_module != NULL) {                                              \
+	        PyObject *_c_api =                                              \
+	            PyObject_GetAttrString (_module, PYGAMEAPI_LOCAL_ENTRY);    \
+                                                                            \
+            Py_DECREF (_module);                                            \
+            if (_c_api != NULL && PyCapsule_CheckExact (_c_api)) {          \
+                void **localptr =                                           \
+                    (void**) PyCapsule_GetPointer (_c_api,                  \
+                         PG_CAPSULE_NAME(#module));                         \
+                                                                            \
+                if (localptr != NULL) {                                     \
+                    memcpy (api_root + PYGAMEAPI_##MODULE##_FIRSTSLOT,      \
+                            localptr,                                       \
+                            sizeof(void **)*PYGAMEAPI_##MODULE##_NUMSLOTS); \
+                }                                                           \
+            }                                                               \
+            Py_XDECREF(_c_api);                                             \
+        }                                                                   \
+    }
+
 #ifndef NO_PYGAME_C_API
-#define PYGAMEAPI_TOTALSLOTS                                            \
+#define IMPORT_PYGAME_MODULE(module, MODULE)                                \
+    _IMPORT_PYGAME_MODULE(module, MODULE, PyGAME_C_API)
+#define PYGAMEAPI_TOTALSLOTS                                                \
     (PYGAMEAPI_MATH_FIRSTSLOT + PYGAMEAPI_MATH_NUMSLOTS)
 static void* PyGAME_C_API[PYGAMEAPI_TOTALSLOTS] = { NULL };
 #endif
 
+#if PG_HAVE_CAPSULE
+#define encapsulate_api(ptr, module) \
+    PyCapsule_New(ptr, PG_CAPSULE_NAME(module), NULL)
+#else
+#define encapsulate_api(ptr, module) \
+    PyCObject_FromVoidPtr(ptr, NULL)
+#endif
+
 /*last platform compiler stuff*/
 #if defined(macintosh) && defined(__MWERKS__) || defined(__SYMBIAN32__)
 #define PYGAME_EXPORT __declspec(export)
     c_api[1] = PyRect_New;
     c_api[2] = PyRect_New4;
     c_api[3] = GameRect_FromObject;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "rect");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     c_api[4] = RWopsEncodeFilePath;
     c_api[5] = RWopsEncodeString;
     c_api[6] = RWopsFromFileObject;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "rwobject");
     if (apiobj == NULL) {
         DECREF_MOD (module);
 	MODINIT_ERROR;
         PyObject *_dict = PyModule_GetDict (lockmodule);
         PyObject *_c_api = PyDict_GetItemString (_dict, PYGAMEAPI_LOCAL_ENTRY);
 
-        if (PyCObject_Check (_c_api))
+        if (PyCapsule_CheckExact (_c_api))
         {
             int i;
-            void **localptr = (void *)PyCObject_AsVoidPtr (_c_api);
+            void **localptr = 
+                (void *)PyCapsule_GetPointer (_c_api,
+                                              PG_CAPSULE_NAME("surflock"));
 
             for (i = 0; i < PYGAMEAPI_SURFLOCK_NUMSLOTS; ++i)
                 PyGAME_C_API[i + PYGAMEAPI_SURFLOCK_FIRSTSLOT] = localptr[i];
     c_api[0] = &PySurface_Type;
     c_api[1] = PySurface_New;
     c_api[2] = PySurface_Blit;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "surface");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;
     c_api[5] = PySurface_LockBy;
     c_api[6] = PySurface_UnlockBy;
     c_api[7] = PySurface_LockLifetime;
-    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    apiobj = encapsulate_api (c_api, "surflock");
     if (apiobj == NULL) {
         DECREF_MOD (module);
         MODINIT_ERROR;