[pygobject] Fix dynamic creation of enum and flag gi types for Python 3.3



commit 3e3525e93d852cde0f63e835b774a9b004773c69
Author: Simon Feltman <s feltman gmail com>
Date:   Sun Aug 19 02:30:39 2012 -0700

    Fix dynamic creation of enum and flag gi types for Python 3.3
    
    Importing Gtk was crashing on instantiation of dynamic Enum and Flag
    subclasses due to what looks to be an unsupported technique.  Change
    tp_new() method for classes dynamically derived from PyGEnum_Type and
    PyGFlags_Type to call PyLong_Type.tp_new() instead of attempting to call
    __new__() as a python method. This technique seems to work with all
    versions of python so the previous python version checking also became
    unnecessary.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=682323

 gi/_gobject/pygenum.c  |   29 ++++++++++++++++-------------
 gi/_gobject/pygflags.c |   21 +++++++++------------
 2 files changed, 25 insertions(+), 25 deletions(-)
---
diff --git a/gi/_gobject/pygenum.c b/gi/_gobject/pygenum.c
index 4732891..9c3c455 100644
--- a/gi/_gobject/pygenum.c
+++ b/gi/_gobject/pygenum.c
@@ -27,7 +27,6 @@
 
 #include <pyglib.h>
 #include "pygobject-private.h"
-
 #include "pygi.h"
 
 #include "pygenum.h"
@@ -38,18 +37,15 @@ PYGLIB_DEFINE_TYPE("gobject.GEnum", PyGEnum_Type, PyGEnum);
 
 static PyObject *
 pyg_enum_val_new(PyObject* subclass, GType gtype, PyObject *intval)
-{     
-    PyObject *item;
-    
-#if PY_VERSION_HEX >= 0x03000000
-    item = PyObject_CallMethod((PyObject*)&PyLong_Type, "__new__", "OO",
-                               subclass, intval);
-#else
-    item = ((PyTypeObject *)subclass)->tp_alloc((PyTypeObject *)subclass, 0);
-    ((PyIntObject*)item)->ob_ival = PyInt_AS_LONG(intval);
-#endif    
+{
+    PyObject *args, *item;
+    args = Py_BuildValue("(O)", intval);
+    item =  (&PYGLIB_PyLong_Type)->tp_new((PyTypeObject*)subclass, args, NULL);
+    Py_DECREF(args);
+    if (!item)
+	return NULL;
     ((PyGEnum*)item)->gtype = gtype;
-    
+
     return item;
 }
 
@@ -204,6 +200,10 @@ pyg_enum_from_gtype (GType gtype, int value)
     return retval;
 }
 
+/*
+ * pyg_enum_add
+ * Dynamically create a class derived from PyGEnum based on the given GType.
+ */
 PyObject *
 pyg_enum_add (PyObject *   module,
 	      const char * typename,
@@ -224,6 +224,9 @@ pyg_enum_add (PyObject *   module,
 
     state = pyglib_gil_state_ensure();
 
+    /* Create a new type derived from GEnum. This is the same as:
+     * >>> stub = type(typename, (GEnum,), {})
+     */
     instance_dict = PyDict_New();
     stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O",
                                  typename, (PyObject *)&PyGEnum_Type,
@@ -356,7 +359,7 @@ pygobject_enum_register_types(PyObject *d)
     PyGEnum_Type.tp_new = pyg_enum_new;
 #else
     PyGEnum_Type.tp_new = PyLong_Type.tp_new;
-    PyGEnum_Type.tp_hash = PyLong_Type.tp_hash;    
+    PyGEnum_Type.tp_hash = PyLong_Type.tp_hash;
 #endif
     PyGEnum_Type.tp_repr = (reprfunc)pyg_enum_repr;
     PyGEnum_Type.tp_str = (reprfunc)pyg_enum_repr;
diff --git a/gi/_gobject/pygflags.c b/gi/_gobject/pygflags.c
index 8c00f15..bad32c6 100644
--- a/gi/_gobject/pygflags.c
+++ b/gi/_gobject/pygflags.c
@@ -37,18 +37,15 @@ PYGLIB_DEFINE_TYPE("gobject.GFlags", PyGFlags_Type, PyGFlags);
 
 static PyObject *
 pyg_flags_val_new(PyObject* subclass, GType gtype, PyObject *intval)
-{     
-    PyObject *item;
-    
-#if PY_VERSION_HEX >= 0x03000000
-    item = PyObject_CallMethod((PyObject*)&PyLong_Type, "__new__", "OO",
-                               subclass, intval);
-#else
-    item = ((PyTypeObject *)subclass)->tp_alloc((PyTypeObject *)subclass, 0);
-    ((PyIntObject*)item)->ob_ival = PyInt_AS_LONG(intval);
-#endif    
-    ((PyGFlags*)item)->gtype = gtype;
-    
+{
+    PyObject *args, *item;
+    args = Py_BuildValue("(O)", intval);
+    item =  (&PYGLIB_PyLong_Type)->tp_new((PyTypeObject*)subclass, args, NULL);
+    Py_DECREF(args);
+    if (!item)
+	return NULL;
+    ((PyGEnum*)item)->gtype = gtype;
+
     return item;
 }
 



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