[pygobject] working enum/flags/pid subclasses of long



commit c03e6b482548aee99362356807c804f8834fad2b
Author: John Ehresman <jpe wingware com>
Date:   Thu Apr 15 17:11:30 2010 -0400

    working enum/flags/pid subclasses of long
    
    https://bugzilla.gnome.org/show_bug.cgi?id=615872

 glib/pygspawn.c    |    7 +++--
 gobject/pygenum.c  |   61 ++++++++++++++++++++++++------------------
 gobject/pygflags.c |   76 ++++++++++++++++++++++------------------------------
 3 files changed, 71 insertions(+), 73 deletions(-)
---
diff --git a/glib/pygspawn.c b/glib/pygspawn.c
index f849d5b..e924299 100644
--- a/glib/pygspawn.c
+++ b/glib/pygspawn.c
@@ -64,12 +64,13 @@ pyg_pid_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
 PyObject *
 pyg_pid_new(GPid pid)
 {
-	PYGLIB_PyLongObject *pygpid;
-    pygpid = PyObject_NEW(PYGLIB_PyLongObject, &PyGPid_Type);
+    PYGLIB_PyLongObject *pygpid;
 
 #if PY_VERSION_HEX >= 0x03000000
-#   warning "FIXME: figure out how to subclass long"
+    return PyObject_CallMethod((PyObject*)&PyLong_Type, "__new__", "Oi", 
+		               &PyGPid_Type, pygpid);
 #else
+    pygpid = PyObject_NEW(PyIntObject, &PyGPid_Type);
     pygpid->ob_ival = pid;
 #endif
     return (PyObject *) pygpid;
diff --git a/gobject/pygenum.c b/gobject/pygenum.c
index 71d8e11..0ad8405 100644
--- a/gobject/pygenum.c
+++ b/gobject/pygenum.c
@@ -35,6 +35,23 @@ GQuark pygenum_class_key;
 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    
+    ((PyGEnum*)item)->gtype = gtype;
+    
+    return item;
+}
+
+static PyObject *
 pyg_enum_richcompare(PyGEnum *self, PyObject *other, int op)
 {
     static char warning[256];
@@ -61,13 +78,16 @@ pyg_enum_repr(PyGEnum *self)
   const char *value;
   guint index;
   static char tmp[256];
+  long l;
 
   enum_class = g_type_class_ref(self->gtype);
   g_assert(G_IS_ENUM_CLASS(enum_class));
 
-  for (index = 0; index < enum_class->n_values; index++)
-      if (PYGLIB_PyLong_AS_LONG(self) == enum_class->values[index].value)
+  l = PYGLIB_PyLong_AS_LONG(self);
+  for (index = 0; index < enum_class->n_values; index++) 
+      if (l == enum_class->values[index].value)
           break;
+
   value = enum_class->values[index].value_name;
   if (value)
       sprintf(tmp, "<enum %s of type %s>", value, g_type_name(self->gtype));
@@ -170,22 +190,15 @@ pyg_enum_from_gtype (GType gtype, int value)
 				  "__enum_values__");
     intvalue = PYGLIB_PyLong_FromLong(value);
     retval = PyDict_GetItem(values, intvalue);
-    Py_DECREF(intvalue);
-    if (!retval) {
+    if (retval) {
+	Py_INCREF(retval);
+    }
+    else {
 	PyErr_Clear();
-	retval = ((PyTypeObject *)pyclass)->tp_alloc((PyTypeObject *)pyclass, 0);
-	g_assert(retval != NULL);
-
-#if PY_VERSION_HEX >= 0x03000000
-#   warning "FIXME: figure out how to subclass long"
-#else
-	((PYGLIB_PyLongObject*)retval)->ob_ival = value;
-#endif
-	((PyGFlags*)retval)->gtype = gtype;
-	//return _PyLong_FromLong(value);
+	retval = pyg_enum_val_new(pyclass, gtype, intvalue);
     }
+    Py_DECREF(intvalue);
 
-    Py_INCREF(retval);
     return retval;
 }
 
@@ -246,16 +259,9 @@ pyg_enum_add (PyObject *   module,
     values = PyDict_New();
     for (i = 0; i < eclass->n_values; i++) {
 	PyObject *item, *intval;
-
-	item = ((PyTypeObject *)stub)->tp_alloc((PyTypeObject *)stub, 0);
-#if PY_VERSION_HEX >= 0x03000000
-#   warning "FIXME: figure out how to subclass long"
-#else
-	((PYGLIB_PyLongObject*)item)->ob_ival = eclass->values[i].value;
-#endif
-	((PyGEnum*)item)->gtype = gtype;
-
+      
         intval = PYGLIB_PyLong_FromLong(eclass->values[i].value);
+	item = pyg_enum_val_new(stub, gtype, intval);
 	PyDict_SetItem(values, intval, item);
         Py_DECREF(intval);
 
@@ -344,13 +350,16 @@ pygobject_enum_register_types(PyObject *d)
     pygenum_class_key        = g_quark_from_static_string("PyGEnum::class");
 
     PyGEnum_Type.tp_base = &PYGLIB_PyLong_Type;
+#if PY_VERSION_HEX < 0x03000000
+    PyGEnum_Type.tp_new = pyg_enum_new;
+#else
+    PyGEnum_Type.tp_new = PyLong_Type.tp_new;
+#endif
     PyGEnum_Type.tp_repr = (reprfunc)pyg_enum_repr;
     PyGEnum_Type.tp_str = (reprfunc)pyg_enum_repr;
     PyGEnum_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
     PyGEnum_Type.tp_richcompare = (richcmpfunc)pyg_enum_richcompare;
     PyGEnum_Type.tp_methods = pyg_enum_methods;
     PyGEnum_Type.tp_getset = pyg_enum_getsets;
-    PyGEnum_Type.tp_new = pyg_enum_new;
     PYGOBJECT_REGISTER_GTYPE(d, PyGEnum_Type, "GEnum", G_TYPE_ENUM);
-
 }
diff --git a/gobject/pygflags.c b/gobject/pygflags.c
index c14e42f..cf3ca10 100644
--- a/gobject/pygflags.c
+++ b/gobject/pygflags.c
@@ -36,6 +36,23 @@ GQuark pygflags_class_key;
 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;
+    
+    return item;
+}
+
+static PyObject *
 pyg_flags_richcompare(PyGFlags *self, PyObject *other, int op)
 {
     static char warning[256];
@@ -189,23 +206,16 @@ pyg_flags_from_gtype (GType gtype, int value)
 				  "__flags_values__");
     pyint = PYGLIB_PyLong_FromLong(value);
     retval = PyDict_GetItem(values, pyint);
-    Py_DECREF(pyint);
-
     if (!retval) {
 	PyErr_Clear();
 
-	retval = ((PyTypeObject *)pyclass)->tp_alloc((PyTypeObject *)pyclass, 0);
+	retval = pyg_flags_val_new(pyclass, gtype, pyint);
 	g_assert(retval != NULL);
-
-#if PY_VERSION_HEX >= 0x03000000
-#   warning "FIXME: figure out how to subclass long"
-#else
-	((PYGLIB_PyLongObject*)retval)->ob_ival = value;
-#endif
-	((PyGFlags*)retval)->gtype = gtype;
     } else {
 	Py_INCREF(retval);
     }
+    Py_DECREF(pyint);
+    
     return retval;
 }
 
@@ -264,16 +274,9 @@ pyg_flags_add (PyObject *   module,
     values = PyDict_New();
     for (i = 0; i < eclass->n_values; i++) {
       PyObject *item, *intval;
-
-      item = ((PyTypeObject *)stub)->tp_alloc((PyTypeObject *)stub, 0);
-#if PY_VERSION_HEX >= 0x03000000
-#   warning "FIXME: figure out how to subclass long"
-#else
-      ((PYGLIB_PyLongObject*)item)->ob_ival = eclass->values[i].value;
-#endif
-      ((PyGFlags*)item)->gtype = gtype;
-
+      
       intval = PYGLIB_PyLong_FromLong(eclass->values[i].value);
+      item = pyg_flags_val_new(stub, gtype, intval);
       PyDict_SetItem(values, intval, item);
       Py_DECREF(intval);
 
@@ -281,11 +284,11 @@ pyg_flags_add (PyObject *   module,
 	  char *prefix;
 
 	  prefix = g_strdup(pyg_constant_strip_prefix(eclass->values[i].value_name, strip_prefix));
+	  Py_INCREF(item);
 	  PyModule_AddObject(module, prefix, item);
 	  g_free(prefix);
-
-	  Py_INCREF(item);
       }
+      Py_DECREF(item);
     }
 
     PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict,
@@ -439,7 +442,9 @@ static PyNumberMethods pyg_flags_as_number = {
 	(binaryfunc)pyg_flags_warn,		/* nb_multiply */
 	(binaryfunc)pyg_flags_warn,		/* nb_divide */
 	(binaryfunc)pyg_flags_warn,		/* nb_remainder */
-	(binaryfunc)pyg_flags_warn,		/* nb_divmod */
+#if PY_VERSION_HEX < 0x03000000
+        (binaryfunc)pyg_flags_warn,		/* nb_divmod */
+#endif
 	(ternaryfunc)pyg_flags_warn,		/* nb_power */
 	0,					/* nb_negative */
 	0,					/* nb_positive */
@@ -451,27 +456,6 @@ static PyNumberMethods pyg_flags_as_number = {
 	(binaryfunc)pyg_flags_and,		/* nb_and */
 	(binaryfunc)pyg_flags_xor,		/* nb_xor */
 	(binaryfunc)pyg_flags_or,		/* nb_or */
-	0,					/* nb_coerce */
-	0,					/* nb_int */
-	0,					/* nb_long */
-	0,					/* nb_float */
-	0,					/* nb_oct */
-	0,		 			/* nb_hex */
-	0,					/* nb_inplace_add */
-	0,					/* nb_inplace_subtract */
-	0,					/* nb_inplace_multiply */
-	0,					/* nb_inplace_divide */
-	0,					/* nb_inplace_remainder */
-	0,					/* nb_inplace_power */
-	0,					/* nb_inplace_lshift */
-	0,					/* nb_inplace_rshift */
-	0,					/* nb_inplace_and */
-	0,					/* nb_inplace_xor */
-	0,					/* nb_inplace_or */
-	0,					/* nb_floor_divide */
-	0,					/* nb_true_divide */
-	0,					/* nb_inplace_floor_divide */
-	0,					/* nb_inplace_true_divide */
 };
 
 void
@@ -480,12 +464,16 @@ pygobject_flags_register_types(PyObject *d)
     pygflags_class_key = g_quark_from_static_string("PyGFlags::class");
 
     PyGFlags_Type.tp_base = &PYGLIB_PyLong_Type;
+#if PY_VERSION_HEX < 0x03000000
+    PyGFlags_Type.tp_new = pyg_flags_new;
+#else
+    PyGFlags_Type.tp_new = PyLong_Type.tp_new;
+#endif
     PyGFlags_Type.tp_repr = (reprfunc)pyg_flags_repr;
     PyGFlags_Type.tp_as_number = &pyg_flags_as_number;
     PyGFlags_Type.tp_str = (reprfunc)pyg_flags_repr;
     PyGFlags_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
     PyGFlags_Type.tp_richcompare = (richcmpfunc)pyg_flags_richcompare;
     PyGFlags_Type.tp_getset = pyg_flags_getsets;
-    PyGFlags_Type.tp_new = pyg_flags_new;
     PYGOBJECT_REGISTER_GTYPE(d, PyGFlags_Type, "GFlags", G_TYPE_FLAGS);
 }



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