[pygobject] add compat functions for the deprecated PyCObject api



commit e1981da105b574e273ae6500fc6d25caf6af6aae
Author: John (J5) Palmieri <johnp redhat com>
Date:   Tue Sep 28 15:31:03 2010 -0400

    add compat functions for the deprecated PyCObject api
    
    * Moved to using the PyCapsule API for python >= 3
    * PyCObject is removed from Python 3.2
    * It has also been deprecated in 2.7 but since we use the API in header files
      which are consumed by static binding modules, appling this for python 2.7
      causes crashes unless the modules are recompiled, breaking ABI.  It is safe
      to rely on for 2.7 because it will never be removed and there is talk of
      undeprecating it upstream.
    * There is no issues with static bindings under python 3 because they are not
      supported yet and most likely never will be.
    * Even if PyCObject is brought back in 3.2, PyCapsule is a much safer API
      which adds a poorman's type check when unboxing.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=630844

 gi/gimodule.c               |    2 +-
 gi/pygi.h                   |    5 ++++-
 glib/glibmodule.c           |    2 +-
 glib/pyglib-python-compat.h |   28 ++++++++++++++++++++++++++++
 glib/pyglib.c               |    6 +++---
 glib/pygoptioncontext.c     |    2 +-
 gobject/gobjectmodule.c     |    2 +-
 gobject/pygobject.h         |    6 ++++++
 gobject/pygtype.c           |   10 +++++-----
 9 files changed, 50 insertions(+), 13 deletions(-)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 89caf4e..f7624ae 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -328,7 +328,7 @@ PYGLIB_MODULE_START(_gi, "_gi")
     _pygi_boxed_register_types (module);
     _pygi_argument_init();
 
-    api = PyCObject_FromVoidPtr ( (void *) &CAPI, NULL);
+    api = PYGLIB_CPointer_WrapPointer ( (void *) &CAPI, "gi._API");
     if (api == NULL) {
         return;
     }
diff --git a/gi/pygi.h b/gi/pygi.h
index c5a0f26..1d3d686 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -83,8 +83,11 @@ _pygi_import (void)
     if (PyGI_API != NULL) {
         return 1;
     }
-
+#if PY_VERSION_HEX >= 0x03000000
+    PyGI_API = (struct PyGI_API*) PyCapsule_Import("gi._API", FALSE);
+#else
     PyGI_API = (struct PyGI_API*) PyCObject_Import("gi", "_API");
+#endif
     if (PyGI_API == NULL) {
         return -1;
     }
diff --git a/glib/glibmodule.c b/glib/glibmodule.c
index 4a58bc2..29a4713 100644
--- a/glib/glibmodule.c
+++ b/glib/glibmodule.c
@@ -797,7 +797,7 @@ pyglib_register_api(PyObject *d)
 
     /* for addon libraries ... */
     PyDict_SetItemString(d, "_PyGLib_API",
-			 o=PyCObject_FromVoidPtr(&pyglib_api,NULL));
+			 o=PYGLIB_CPointer_WrapPointer(&pyglib_api,"glib._PyGLib_API"));
     Py_DECREF(o);
     
     pyglib_init_internal(o);
diff --git a/glib/pyglib-python-compat.h b/glib/pyglib-python-compat.h
index bb7bcad..5d7516e 100644
--- a/glib/pyglib-python-compat.h
+++ b/glib/pyglib-python-compat.h
@@ -41,6 +41,34 @@ typedef int Py_ssize_t;
 typedef inquiry lenfunc;
 #endif
 
+/* PyCObject superceded by PyCapsule on Python >= 2.7
+ * However since this effects header files used by
+ * static bindings we are only applying the change to
+ * Python 3.x where we don't support the static bindings.
+ * 3.2 removed PyCObject so we don't have any choice here.
+ *
+ * There is talk upstream of undeprecating PyCObject
+ * (at least where the 2.x branch is concerned)
+ * and there is no danger of it being remove from 2.7.
+ **/
+#if PY_VERSION_HEX >= 0x03000000
+# define PYGLIB_CPointer_Check PyCapsule_CheckExact
+# define PYGLIB_CPointer_WrapPointer(ptr, typename) \
+    PyCapsule_New(ptr, typename, NULL)
+# define PYGLIB_CPointer_GetPointer(obj, typename) \
+    PyCapsule_GetPointer(obj, typename)
+# define PYGLIB_CPointer_Import(module, symbol) \
+    PyCapsule_Import(##module##.##symbol##, FALSE)
+#else
+# define PYGLIB_CPointer_Check PyCObject_Check
+# define PYGLIB_CPointer_WrapPointer(ptr, typename) \
+    PyCObject_FromVoidPtr(ptr, NULL)
+# define PYGLIB_CPointer_GetPointer(obj, typename) \
+  PyCObject_AsVoidPtr(obj)
+# define PYGLIB_CPointer_Import(module, symbol) \
+    PyCObject_Import(module, symbol)
+#endif
+
 #if PY_VERSION_HEX < 0x03000000
 
 #define PYGLIB_INIT_FUNCTION(modname, fullpkgname, functions) \
diff --git a/glib/pyglib.c b/glib/pyglib.c
index 07db579..c85a628 100644
--- a/glib/pyglib.c
+++ b/glib/pyglib.c
@@ -71,8 +71,8 @@ pyglib_init(void)
     }
     
     cobject = PyObject_GetAttrString(glib, "_PyGLib_API");
-    if (cobject && PyCObject_Check(cobject))
-	_PyGLib_API = (struct _PyGLib_Functions *) PyCObject_AsVoidPtr(cobject);
+    if (cobject && PYGLIB_CPointer_Check(cobject))
+	_PyGLib_API = (struct _PyGLib_Functions *) PYGLIB_CPointer_GetPointer(cobject, "glib._PyGLib_API");
     else {
 	PyErr_SetString(PyExc_ImportError,
 			"could not import glib (could not find _PyGLib_API object)");
@@ -88,7 +88,7 @@ pyglib_init(void)
 void
 pyglib_init_internal(PyObject *api)
 {
-    _PyGLib_API = (struct _PyGLib_Functions *) PyCObject_AsVoidPtr(api);
+    _PyGLib_API = (struct _PyGLib_Functions *) PYGLIB_CPointer_GetPointer(api, "glib._PyGLib_API");
 }
 
 gboolean
diff --git a/glib/pygoptioncontext.c b/glib/pygoptioncontext.c
index 1d67ac5..93d9b24 100644
--- a/glib/pygoptioncontext.c
+++ b/glib/pygoptioncontext.c
@@ -288,7 +288,7 @@ pyg_option_context_richcompare(PyObject *self, PyObject *other, int op)
 static PyObject *
 pyg_option_get_context(PyGOptionContext *self)
 {
-    return PyCObject_FromVoidPtr(self->context, NULL);
+    return PYGLIB_CPointer_WrapPointer(self->context, "goption.context");
 }
 
 static PyMethodDef pyg_option_context_methods[] = {
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 4e9c07d..f830251 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -2511,7 +2511,7 @@ pygobject_register_api(PyObject *d)
 {
     PyObject *api;
 
-    api = PyCObject_FromVoidPtr(&pygobject_api_functions,NULL);
+    api = PYGLIB_CPointer_WrapPointer(&pygobject_api_functions, "gobject._PyGObject_API");
     PyDict_SetItemString(d, "_PyGObject_API", api);
     Py_DECREF(api);
 }
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index e75c890..afbc665 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -352,8 +352,14 @@ pygobject_init(int req_major, int req_minor, int req_micro)
     }
 
     cobject = PyObject_GetAttrString(gobject, "_PyGObject_API");
+#if PY_VERSION_HEX >= 0x03000000
+    if (cobject && PyCapsule_CheckExact(cobject))
+        _PyGObject_API = (struct _PyGObject_Functions *) PyCapsule_GetPointer(cobject, "gobject._PyGObject_API");
+
+#else
     if (cobject && PyCObject_Check(cobject))
         _PyGObject_API = (struct _PyGObject_Functions *) PyCObject_AsVoidPtr(cobject);
+#endif
     else {
         PyErr_SetString(PyExc_ImportError,
                         "could not import gobject (could not find _PyGObject_API object)");
diff --git a/gobject/pygtype.c b/gobject/pygtype.c
index c875aa2..32f8640 100644
--- a/gobject/pygtype.c
+++ b/gobject/pygtype.c
@@ -864,8 +864,8 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
 	else if (PyObject_TypeCheck(obj, &PyGPointer_Type) &&
 		   G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype))
 	    g_value_set_pointer(value, pyg_pointer_get(obj, gpointer));
-	else if (PyCObject_Check(obj))
-	    g_value_set_pointer(value, PyCObject_AsVoidPtr(obj));
+	else if (PYGLIB_CPointer_Check(obj))
+	    g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL));
 	else
 	    return -1;
 	break;
@@ -910,15 +910,15 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
         }
 	else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
 	    return bm->tovalue(value, obj);
-	else if (PyCObject_Check(obj))
-	    g_value_set_boxed(value, PyCObject_AsVoidPtr(obj));
+	else if (PYGLIB_CPointer_Check(obj))
+	    g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL));
 	else
 	    return -1;
 	break;
     }
     case G_TYPE_PARAM:
 	if (PyGParamSpec_Check(obj))
-	    g_value_set_param(value, PyCObject_AsVoidPtr(obj));
+	    g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
 	else
 	    return -1;
 	break;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]