[pygobject/pygi-py3k: 1/5] Initial attempts at porting to Python 3.1



commit e737cc6b3002e2d4fc3c9c0c7a9f160394bd93f8
Author: David Malcolm <dmalcolm redhat com>
Date:   Thu Apr 15 14:20:08 2010 -0400

    Initial attempts at porting to Python 3.1
    
    Doesn't yet work

 gi/Makefile.am       |    2 +-
 gi/gimodule.c        |   70 +++++++++++++++++++----
 gi/module.py         |    2 +-
 gi/pygi-argument.c   |  155 +++++++++++++++++++++++++++++++++-----------------
 gi/pygi-boxed.c      |    9 +--
 gi/pygi-info.c       |   30 ++++++----
 gi/pygi-private.h    |   24 ++++++++
 gi/pygi-repository.c |    9 +--
 gi/pygi-struct.c     |    9 +--
 gi/types.py          |    2 +-
 10 files changed, 217 insertions(+), 95 deletions(-)
---
diff --git a/gi/Makefile.am b/gi/Makefile.am
index 63f90e3..308c7f8 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -20,7 +20,7 @@ pygi_PYTHON = \
 _gi_la_LDFLAGS = \
 	-module \
 	-avoid-version \
-	-export-symbols-regex init_gi
+	-export-symbols-regex "init_gi|PyInit__gi"
 _gi_la_LIBADD = \
 	$(GNOME_LIBS)
 _gi_la_SOURCES = \
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 8811539..32ab292 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -144,23 +144,18 @@ struct PyGI_API PyGI_API = {
 };
 
 
-PyMODINIT_FUNC
-init_gi(void)
+/* Shared Python 2 and Python 3 module-initialization logic */
+static PyObject *
+perform_module_init(PyObject *m)
 {
-    PyObject *m;
     PyObject *api;
 
-    m = Py_InitModule("_gi", _pygi_functions);
-    if (m == NULL) {
-        return;
-    }
-
     if (pygobject_init(-1, -1, -1) == NULL) {
-        return;
+        return NULL;
     }
 
     if (_pygobject_import() < 0) {
-        return;
+        return NULL;
     }
 
     _pygi_repository_register_types(m);
@@ -171,8 +166,61 @@ init_gi(void)
 
     api = PyCObject_FromVoidPtr((void *)&PyGI_API, NULL);
     if (api == NULL) {
-        return;
+        return NULL;
     }
     PyModule_AddObject(m, "_API", api);
+
+    return m;
+}
+
+
+
+#if PY_MAJOR_VERSION >= 3
+/* Module-initialization logic specific to Python 3 */
+struct module_state {
+    /* empty for now */
+};
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "_gi",
+    NULL,
+    sizeof(struct module_state),
+    _pygi_functions,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+extern PyObject * /*PyMODINIT_FUNC */
+PyInit__gi(void)
+{
+    PyObject *m;
+
+    m = PyModule_Create(&moduledef);
+    if (m == NULL) {
+        return NULL;
+    }
+
+    if (perform_module_init(m) == NULL) {
+        Py_DECREF(m);
+    }
+
+    return m;
+}
+#else
+/* Module-initialization logic specific to Python 2 */
+PyMODINIT_FUNC
+init_gi(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule("_gi", _pygi_functions);
+    if (m == NULL) {
+        return;
+    }
+
+    perform_module_init(m);
 }
+#endif
 
diff --git a/gi/module.py b/gi/module.py
index 61fbdfc..96d116f 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -127,7 +127,7 @@ class DynamicModule(object):
                 elif g_type.is_a(gobject.TYPE_POINTER) or g_type == gobject.TYPE_NONE:
                     bases = (Struct,)
                 else:
-                    raise TypeError, "unable to create a wrapper for %s.%s" % (info.get_namespace(), info.get_name())
+                    raise TypeError("unable to create a wrapper for %s.%s" % (info.get_namespace(), info.get_name()))
                 metaclass = StructMeta
             else:
                 raise NotImplementedError(info)
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index edbb31f..6690ea4 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -36,29 +36,29 @@ _pygi_g_type_tag_py_bounds (GITypeTag   type_tag,
 {
     switch(type_tag) {
         case GI_TYPE_TAG_INT8:
-            *lower = PyInt_FromLong(-128);
-            *upper = PyInt_FromLong(127);
+            *lower = PyLong_FromLong(-128);
+            *upper = PyLong_FromLong(127);
             break;
         case GI_TYPE_TAG_UINT8:
-            *upper = PyInt_FromLong(255);
-            *lower = PyInt_FromLong(0);
+            *upper = PyLong_FromLong(255);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_INT16:
-            *lower = PyInt_FromLong(-32768);
-            *upper = PyInt_FromLong(32767);
+            *lower = PyLong_FromLong(-32768);
+            *upper = PyLong_FromLong(32767);
             break;
         case GI_TYPE_TAG_UINT16:
-            *upper = PyInt_FromLong(65535);
-            *lower = PyInt_FromLong(0);
+            *upper = PyLong_FromLong(65535);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_INT32:
-            *lower = PyInt_FromLong(G_MININT32);
-            *upper = PyInt_FromLong(G_MAXINT32);
+            *lower = PyLong_FromLong(G_MININT32);
+            *upper = PyLong_FromLong(G_MAXINT32);
             break;
         case GI_TYPE_TAG_UINT32:
             /* Note: On 32-bit archs, this number doesn't fit in a long. */
             *upper = PyLong_FromLongLong(G_MAXUINT32);
-            *lower = PyInt_FromLong(0);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_INT64:
             /* Note: On 32-bit archs, these numbers don't fit in a long. */
@@ -67,34 +67,34 @@ _pygi_g_type_tag_py_bounds (GITypeTag   type_tag,
             break;
         case GI_TYPE_TAG_UINT64:
             *upper = PyLong_FromUnsignedLongLong(G_MAXUINT64);
-            *lower = PyInt_FromLong(0);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_SHORT:
-            *lower = PyInt_FromLong(G_MINSHORT);
-            *upper = PyInt_FromLong(G_MAXSHORT);
+            *lower = PyLong_FromLong(G_MINSHORT);
+            *upper = PyLong_FromLong(G_MAXSHORT);
             break;
         case GI_TYPE_TAG_USHORT:
-            *upper = PyInt_FromLong(G_MAXUSHORT);
-            *lower = PyInt_FromLong(0);
+            *upper = PyLong_FromLong(G_MAXUSHORT);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_INT:
-            *lower = PyInt_FromLong(G_MININT);
-            *upper = PyInt_FromLong(G_MAXINT);
+            *lower = PyLong_FromLong(G_MININT);
+            *upper = PyLong_FromLong(G_MAXINT);
             break;
         case GI_TYPE_TAG_UINT:
             /* Note: On 32-bit archs, this number doesn't fit in a long. */
             *upper = PyLong_FromLongLong(G_MAXUINT);
-            *lower = PyInt_FromLong(0);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_LONG:
         case GI_TYPE_TAG_SSIZE:
-            *lower = PyInt_FromLong(G_MINLONG);
-            *upper = PyInt_FromLong(G_MAXLONG);
+            *lower = PyLong_FromLong(G_MINLONG);
+            *upper = PyLong_FromLong(G_MAXLONG);
             break;
         case GI_TYPE_TAG_ULONG:
         case GI_TYPE_TAG_SIZE:
             *upper = PyLong_FromUnsignedLongLong(G_MAXULONG);
-            *lower = PyInt_FromLong(0);
+            *lower = PyLong_FromLong(0);
             break;
         case GI_TYPE_TAG_FLOAT:
             *upper = PyFloat_FromDouble(G_MAXFLOAT);
@@ -215,6 +215,7 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
         case GI_TYPE_TAG_DOUBLE:
         {
             PyObject *number, *lower, *upper;
+            int is_below_lower, is_above_upper;
 
             if (!PyNumber_Check(object)) {
                 PyErr_Format(PyExc_TypeError, "Must be number, not %s",
@@ -226,7 +227,7 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
             if (type_tag == GI_TYPE_TAG_FLOAT || type_tag == GI_TYPE_TAG_DOUBLE) {
                 number = PyNumber_Float(object);
             } else {
-                number = PyNumber_Int(object);
+                number = PyNumber_Long(object);
             }
 
             _pygi_g_type_tag_py_bounds(type_tag, &lower, &upper);
@@ -237,16 +238,22 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
             }
 
             /* Check bounds */
-            if (PyObject_Compare(lower, number) > 0
-                || PyObject_Compare(upper, number) < 0) {
+            is_below_lower = PyObject_RichCompareBool(lower, number, Py_GT);
+            if (is_below_lower == -1) {
+                retval = -1;
+                goto check_number_release;
+            }
+
+            is_above_upper = PyObject_RichCompareBool(upper, number, Py_LT);
+            if (is_above_upper == -1) {
+                retval = -1;
+                goto check_number_release;
+            }
+
+            if (is_below_lower || is_above_upper) {
                 PyObject *lower_str;
                 PyObject *upper_str;
 
-                if (PyErr_Occurred()) {
-                    retval = -1;
-                    goto check_number_release;
-                }
-
                 lower_str = PyObject_Str(lower);
                 upper_str = PyObject_Str(upper);
                 if (lower_str == NULL || upper_str == NULL) {
@@ -254,9 +261,15 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
                     goto check_number_error_release;
                 }
 
+#if PY_MAJOR_VERSION >= 3
+                PyErr_Format(PyExc_ValueError, "Must range from %s to %s",
+                        _PyUnicode_AsString(lower_str),
+                        _PyUnicode_AsString(upper_str));
+#else
                 PyErr_Format(PyExc_ValueError, "Must range from %s to %s",
                         PyString_AS_STRING(lower_str),
                         PyString_AS_STRING(upper_str));
+#endif
 
                 retval = 0;
 
@@ -295,6 +308,29 @@ check_number_release:
             }
             break;
         }
+
+        /*
+          For Python 2, both UTF8 and FILENAME expect a UTF-8 encoded PyStringObject
+
+          For Python 3, UTF8 expects a PyUnicodeObject, but FILENAME expects a
+          PyBytesObject that is hopefully UTF8 encoded but might not be
+         */
+#if PY_MAJOR_VERSION >= 3
+        case GI_TYPE_TAG_UTF8:
+            if (!PyUnicode_Check(object)) {
+                PyErr_Format(PyExc_TypeError, "Must be str, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
+            }
+            break;
+        case GI_TYPE_TAG_FILENAME:
+            if (!PyBytes_Check(object)) {
+                PyErr_Format(PyExc_TypeError, "Must be bytes, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
+            }
+            break;
+#else
         case GI_TYPE_TAG_UTF8:
         case GI_TYPE_TAG_FILENAME:
             if (!PyString_Check(object)) {
@@ -303,6 +339,7 @@ check_number_release:
                 retval = 0;
             }
             break;
+#endif
         case GI_TYPE_TAG_ARRAY:
         {
             gssize fixed_size;
@@ -382,11 +419,11 @@ check_number_release:
                 case GI_INFO_TYPE_FLAGS:
                     if (PyNumber_Check(object)) {
                         /* Accept 0 as a valid flag value */
-                        PyObject *number = PyNumber_Int(object);
+                        PyObject *number = PyNumber_Long(object);
                         if (number == NULL)
                             PyErr_Clear();
                         else {
-                            long value = PyInt_AsLong(number);
+                            long value = PyLong_AsLong(number);
                             if (value == 0)
                                 break;
                             else if (value == -1)
@@ -651,12 +688,12 @@ _pygi_argument_from_object (PyObject   *object,
         {
             PyObject *int_;
 
-            int_ = PyNumber_Int(object);
+            int_ = PyNumber_Long(object);
             if (int_ == NULL) {
                 break;
             }
 
-            arg.v_long = PyInt_AsLong(int_);
+            arg.v_long = PyLong_AsLong(int_);
 
             Py_DECREF(int_);
 
@@ -671,13 +708,13 @@ _pygi_argument_from_object (PyObject   *object,
             PyObject *number;
             guint64 value;
 
-            number = PyNumber_Int(object);
+            number = PyNumber_Long(object);
             if (number == NULL) {
                 break;
             }
 
-            if (PyInt_Check(number)) {
-                value = PyInt_AS_LONG(number);
+            if (PyLong_Check(number)) {
+                value = PyLong_AS_LONG(number);
             } else {
                 value = PyLong_AsUnsignedLongLong(number);
             }
@@ -693,13 +730,13 @@ _pygi_argument_from_object (PyObject   *object,
             PyObject *number;
             gint64 value;
 
-            number = PyNumber_Int(object);
+            number = PyNumber_Long(object);
             if (number == NULL) {
                 break;
             }
 
-            if (PyInt_Check(number)) {
-                value = PyInt_AS_LONG(number);
+            if (PyLong_Check(number)) {
+                value = PyLong_AS_LONG(number);
             } else {
                 value = PyLong_AsLongLong(number);
             }
@@ -777,7 +814,11 @@ _pygi_argument_from_object (PyObject   *object,
         {
             const gchar *string;
 
+#if PY_MAJOR_VERSION >= 3
+            string = _PyUnicode_AsString(object);
+#else
             string = PyString_AsString(object);
+#endif
 
             /* Don't need to check for errors, since g_strdup is NULL-proof. */
             arg.v_string = g_strdup(string);
@@ -788,7 +829,7 @@ _pygi_argument_from_object (PyObject   *object,
             GError *error = NULL;
             const gchar *string;
 
-            string = PyString_AsString(object);
+            string = PyBytes_AsString(object);
             if (string == NULL) {
                 break;
             }
@@ -946,12 +987,12 @@ array_item_error:
                 {
                     PyObject *int_;
 
-                    int_ = PyNumber_Int(object);
+                    int_ = PyNumber_Long(object);
                     if (int_ == NULL) {
                         break;
                     }
 
-                    arg.v_long = PyInt_AsLong(int_);
+                    arg.v_long = PyLong_AsLong(int_);
 
                     Py_DECREF(int_);
 
@@ -1170,27 +1211,27 @@ _pygi_argument_to_object (GArgument  *arg,
         }
         case GI_TYPE_TAG_INT8:
         {
-            object = PyInt_FromLong(arg->v_int8);
+            object = PyLong_FromLong(arg->v_int8);
             break;
         }
         case GI_TYPE_TAG_UINT8:
         {
-            object = PyInt_FromLong(arg->v_uint8);
+            object = PyLong_FromLong(arg->v_uint8);
             break;
         }
         case GI_TYPE_TAG_INT16:
         {
-            object = PyInt_FromLong(arg->v_int16);
+            object = PyLong_FromLong(arg->v_int16);
             break;
         }
         case GI_TYPE_TAG_UINT16:
         {
-            object = PyInt_FromLong(arg->v_uint16);
+            object = PyLong_FromLong(arg->v_uint16);
             break;
         }
         case GI_TYPE_TAG_INT32:
         {
-            object = PyInt_FromLong(arg->v_int32);
+            object = PyLong_FromLong(arg->v_int32);
             break;
         }
         case GI_TYPE_TAG_UINT32:
@@ -1210,17 +1251,17 @@ _pygi_argument_to_object (GArgument  *arg,
         }
         case GI_TYPE_TAG_SHORT:
         {
-            object = PyInt_FromLong(arg->v_short);
+            object = PyLong_FromLong(arg->v_short);
             break;
         }
         case GI_TYPE_TAG_USHORT:
         {
-            object = PyInt_FromLong(arg->v_ushort);
+            object = PyLong_FromLong(arg->v_ushort);
             break;
         }
         case GI_TYPE_TAG_INT:
         {
-            object = PyInt_FromLong(arg->v_int);
+            object = PyLong_FromLong(arg->v_int);
             break;
         }
         case GI_TYPE_TAG_UINT:
@@ -1230,7 +1271,7 @@ _pygi_argument_to_object (GArgument  *arg,
         }
         case GI_TYPE_TAG_LONG:
         {
-            object = PyInt_FromLong(arg->v_long);
+            object = PyLong_FromLong(arg->v_long);
             break;
         }
         case GI_TYPE_TAG_ULONG:
@@ -1240,7 +1281,7 @@ _pygi_argument_to_object (GArgument  *arg,
         }
         case GI_TYPE_TAG_SSIZE:
         {
-            object = PyInt_FromLong(arg->v_ssize);
+            object = PyLong_FromLong(arg->v_ssize);
             break;
         }
         case GI_TYPE_TAG_SIZE:
@@ -1288,7 +1329,11 @@ _pygi_argument_to_object (GArgument  *arg,
                 break;
             }
 
+#if PY_MAJOR_VERSION >= 3
+            object = PyUnicode_FromString(arg->v_string);
+#else
             object = PyString_FromString(arg->v_string);
+#endif
             break;
         case GI_TYPE_TAG_FILENAME:
         {
@@ -1308,7 +1353,11 @@ _pygi_argument_to_object (GArgument  *arg,
                 break;
             }
 
+#if PY_MAJOR_VERSION >= 3
+            object = PyBytes_FromString(string);
+#else
             object = PyString_FromString(string);
+#endif
 
             g_free(string);
 
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index b157eb8..18ac0aa 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -44,7 +44,7 @@ _boxed_dealloc (PyGIBoxed *self)
         }
     }
 
-    ((PyGObject *)self)->ob_type->tp_free((PyObject *)self);
+    Py_TYPE(((PyGObject *)self))->tp_free((PyObject *)self);
 }
 
 static PyObject *
@@ -104,8 +104,7 @@ _boxed_init (PyObject *self,
 
 
 PyTypeObject PyGIBoxed_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+    PyVarObject_HEAD_INIT(NULL, 0)
     "gi.Boxed",                                /* tp_name */
     sizeof(PyGIBoxed),                         /* tp_basicsize */
     0,                                         /* tp_itemsize */
@@ -113,7 +112,7 @@ PyTypeObject PyGIBoxed_Type = {
     (printfunc)NULL,                           /* tp_print */
     (getattrfunc)NULL,                         /* tp_getattr */
     (setattrfunc)NULL,                         /* tp_setattr */
-    (cmpfunc)NULL,                             /* tp_compare */
+    NULL,                                      /* tp_compare */
     (reprfunc)NULL,                            /* tp_repr */
     NULL,                                      /* tp_as_number */
     NULL,                                      /* tp_as_sequence */
@@ -171,7 +170,7 @@ _pygi_boxed_new (PyTypeObject *type,
 void
 _pygi_boxed_register_types (PyObject *m)
 {
-    PyGIBoxed_Type.ob_type = &PyType_Type;
+    Py_TYPE(&PyGIBoxed_Type) = &PyType_Type;
     PyGIBoxed_Type.tp_base = &PyGBoxed_Type;
     PyGIBoxed_Type.tp_new = (newfunc)_boxed_new;
     PyGIBoxed_Type.tp_init = (initproc)_boxed_init;
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 18981a2..7acedd7 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -28,8 +28,7 @@
 #define _PyGI_DEFINE_INFO_TYPE(name, cname, base) \
 static PyMethodDef _Py##cname##_methods[]; \
 PyTypeObject Py##cname##_Type = { \
-    PyObject_HEAD_INIT(NULL) \
-    0, \
+    PyVarObject_HEAD_INIT(NULL, 0)  \
     "gi." name,                               /* tp_name */ \
     sizeof(PyGIBaseInfo),                     /* tp_basicsize */ \
     0,                                        /* tp_itemsize */ \
@@ -37,7 +36,7 @@ PyTypeObject Py##cname##_Type = { \
     (printfunc)NULL,                          /* tp_print */ \
     (getattrfunc)NULL,                        /* tp_getattr */ \
     (setattrfunc)NULL,                        /* tp_setattr */ \
-    (cmpfunc)NULL,                            /* tp_compare */ \
+    NULL,                                     /* tp_compare */ \
     (reprfunc)NULL,                           /* tp_repr */ \
     NULL,                                     /* tp_as_number */ \
     NULL,                                     /* tp_as_sequence */ \
@@ -74,7 +73,7 @@ _base_info_dealloc (PyGIBaseInfo *self)
 
     g_base_info_unref(self->info);
 
-    self->ob_type->tp_free((PyObject *)self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -88,15 +87,20 @@ _base_info_traverse (PyGIBaseInfo *self,
 static PyObject *
 _base_info_repr (PyGIBaseInfo *self)
 {
-    return PyString_FromFormat("<%s object (%s) at 0x%p>",
-            self->ob_type->tp_name, g_base_info_get_name(self->info), (void *)self);
+    return
+#if PY_MAJOR_VERSION >= 3
+            PyUnicode_FromFormat
+#else
+            PyString_FromFormat
+#endif
+            ("<%s object (%s) at 0x%p>",
+            Py_TYPE(self)->tp_name, g_base_info_get_name(self->info), (void *)self);
 }
 
 static PyMethodDef _PyGIBaseInfo_methods[];
 
 PyTypeObject PyGIBaseInfo_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+    PyVarObject_HEAD_INIT(NULL, 0)
     "gi.BaseInfo",                             /* tp_name */
     sizeof(PyGIBaseInfo),                      /* tp_basicsize */
     0,                                         /* tp_itemsize */
@@ -104,7 +108,7 @@ PyTypeObject PyGIBaseInfo_Type = {
     (printfunc)NULL,                           /* tp_print */
     (getattrfunc)NULL,                         /* tp_getattr */
     (setattrfunc)NULL,                         /* tp_setattr */
-    (cmpfunc)NULL,                             /* tp_compare */
+    NULL,                                      /* tp_compare */
     (reprfunc)_base_info_repr,             /* tp_repr */
     NULL,                                      /* tp_as_number */
     NULL,                                      /* tp_as_sequence */
@@ -130,13 +134,13 @@ PyTypeObject PyGIBaseInfo_Type = {
 static PyObject *
 _wrap_g_base_info_get_name (PyGIBaseInfo *self)
 {
-    return PyString_FromString(g_base_info_get_name(self->info));
+    return PyUnicode_FromString(g_base_info_get_name(self->info));
 }
 
 static PyObject *
 _wrap_g_base_info_get_namespace (PyGIBaseInfo *self)
 {
-    return PyString_FromString(g_base_info_get_namespace(self->info));
+    return PyUnicode_FromString(g_base_info_get_namespace(self->info));
 }
 
 static PyObject *
@@ -1793,7 +1797,7 @@ _wrap_g_value_info_get_value (PyGIBaseInfo *self)
 
     value = g_value_info_get_value((GIValueInfo *)self->info);
 
-    return PyInt_FromLong(value);
+    return PyLong_FromLong(value);
 }
 
 
@@ -2087,7 +2091,7 @@ void
 _pygi_info_register_types (PyObject *m)
 {
 #define _PyGI_REGISTER_TYPE(m, type, name) \
-    type.ob_type = &PyType_Type; \
+    Py_TYPE(&type) = &PyType_Type;         \
     if (PyType_Ready(&type)) \
         return; \
     if (PyModule_AddObject(m, name, (PyObject *)&type)) \
diff --git a/gi/pygi-private.h b/gi/pygi-private.h
index 562c8ab..d41124c 100644
--- a/gi/pygi-private.h
+++ b/gi/pygi-private.h
@@ -27,6 +27,28 @@
 
 G_BEGIN_DECLS
 
+#if PY_MAJOR_VERSION >= 3
+
+#define _PyGI_ERROR_PREFIX(format, ...) G_STMT_START { \
+    PyObject *py_error_prefix; \
+    py_error_prefix = PyUnicode_FromFormat(format, ## __VA_ARGS__); \
+    if (py_error_prefix != NULL) { \
+        PyObject *py_error_type, *py_error_value, *py_error_traceback; \
+        PyErr_Fetch(&py_error_type, &py_error_value, &py_error_traceback); \
+        if (PyUnicode_Check(py_error_value)) { \
+            PyObject *new; \
+            new = PyUnicode_Concat(py_error_prefix, py_error_value); \
+            Py_DECREF(py_error_value); \
+            if (new != NULL) { \
+                py_error_value = new; \
+            } \
+        } \
+        PyErr_Restore(py_error_type, py_error_value, py_error_traceback); \
+    } \
+} G_STMT_END
+
+#else
+
 #define _PyGI_ERROR_PREFIX(format, ...) G_STMT_START { \
     PyObject *py_error_prefix; \
     py_error_prefix = PyString_FromFormat(format, ## __VA_ARGS__); \
@@ -43,6 +65,8 @@ G_BEGIN_DECLS
     } \
 } G_STMT_END
 
+#endif
+
 #if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION == 20
 /* Private stuff copied from glib-2.20.x sources */
 struct _GRealArray
diff --git a/gi/pygi-repository.c b/gi/pygi-repository.c
index f84fc7b..60e158a 100644
--- a/gi/pygi-repository.c
+++ b/gi/pygi-repository.c
@@ -28,8 +28,7 @@ PyObject *PyGIRepositoryError;
 static PyMethodDef _PyGIRepository_methods[];
 
 PyTypeObject PyGIRepository_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+    PyVarObject_HEAD_INIT(NULL, 0)
     "gi.Repository",         /* tp_name */
     sizeof(PyGIRepository),  /* tp_basicsize */
     0,                       /* tp_itemsize */
@@ -37,7 +36,7 @@ PyTypeObject PyGIRepository_Type = {
     (printfunc)NULL,         /* tp_print */
     (getattrfunc)NULL,       /* tp_getattr */
     (setattrfunc)NULL,       /* tp_setattr */
-    (cmpfunc)NULL,           /* tp_compare */
+    NULL,                    /* tp_compare */
     (reprfunc)NULL,          /* tp_repr */
     NULL,                    /* tp_as_number */
     NULL,                    /* tp_as_sequence */
@@ -207,7 +206,7 @@ _wrap_g_irepository_get_typelib_path (PyGIRepository *self,
         return NULL;
     }
 
-    return PyString_FromString(typelib_path);
+    return PyBytes_FromString(typelib_path);
 }
 
 static PyMethodDef _PyGIRepository_methods[] = {
@@ -222,7 +221,7 @@ static PyMethodDef _PyGIRepository_methods[] = {
 void
 _pygi_repository_register_types (PyObject *m)
 {
-    PyGIRepository_Type.ob_type = &PyType_Type;
+    Py_TYPE(&PyGIRepository_Type) = &PyType_Type;
     if (PyType_Ready(&PyGIRepository_Type)) {
         return;
     }
diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c
index b1e81bf..7185b00 100644
--- a/gi/pygi-struct.c
+++ b/gi/pygi-struct.c
@@ -37,7 +37,7 @@ _struct_dealloc (PyGIStruct *self)
         g_free(((PyGPointer *)self)->pointer);
     }
 
-    ((PyGPointer *)self)->ob_type->tp_free((PyObject *)self);
+    Py_TYPE((PyGPointer *)self)->tp_free((PyObject *)self);
 }
 
 static PyObject *
@@ -100,8 +100,7 @@ _struct_init (PyObject *self,
 
 
 PyTypeObject PyGIStruct_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+    PyVarObject_HEAD_INIT(NULL, 0)
     "gi.Struct",                               /* tp_name */
     sizeof(PyGIStruct),                        /* tp_basicsize */
     0,                                         /* tp_itemsize */
@@ -109,7 +108,7 @@ PyTypeObject PyGIStruct_Type = {
     (printfunc)NULL,                           /* tp_print */
     (getattrfunc)NULL,                         /* tp_getattr */
     (setattrfunc)NULL,                         /* tp_setattr */
-    (cmpfunc)NULL,                             /* tp_compare */
+    NULL,                                      /* tp_compare */
     (reprfunc)NULL,                            /* tp_repr */
     NULL,                                      /* tp_as_number */
     NULL,                                      /* tp_as_sequence */
@@ -164,7 +163,7 @@ _pygi_struct_new (PyTypeObject *type,
 void
 _pygi_struct_register_types (PyObject *m)
 {
-    PyGIStruct_Type.ob_type = &PyType_Type;
+    Py_TYPE(&PyGIStruct_Type) = &PyType_Type;
     PyGIStruct_Type.tp_base = &PyGPointer_Type;
     PyGIStruct_Type.tp_new = (newfunc)_struct_new;
     PyGIStruct_Type.tp_init = (initproc)_struct_init;
diff --git a/gi/types.py b/gi/types.py
index b7061bd..b6badd2 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -49,7 +49,7 @@ def Constructor(info):
     def constructor(cls, *args):
         cls_name = info.get_container().get_name()
         if cls.__name__ != cls_name:
-            raise TypeError, '%s constructor cannot be used to create instances of a subclass' % cls_name
+            raise TypeError('%s constructor cannot be used to create instances of a subclass' % cls_name)
         return info.invoke(cls, *args)
 
     constructor.__info__ = info



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