[pygobject/gsoc2009: 160/160] Use gtype.pytype rather than custom functions to register wrapper types



commit d1cfbe08afdd052b544568a880f7dfbe5052a7c8
Author: Simon van der Linden <svdlinden src gnome org>
Date:   Fri Aug 14 16:41:42 2009 +0200

    Use gtype.pytype rather than custom functions to register wrapper types

 gi/gimodule.c               |   28 ++++++++++++++
 gi/module.py                |    9 +++-
 gi/pygi-info.c              |   88 -------------------------------------------
 gi/types.py                 |    8 +---
 gobject/gobjectmodule.c     |    4 --
 gobject/pygboxed.c          |   11 +----
 gobject/pygboxed.h          |    3 -
 gobject/pyginterface.c      |   11 +----
 gobject/pyginterface.h      |    2 -
 gobject/pygobject-private.h |    5 +-
 gobject/pygobject.c         |   11 +----
 gobject/pygobject.h         |   11 -----
 gobject/pygtype.c           |   88 ++++++++++++++++++++++++++++++++++++------
 13 files changed, 120 insertions(+), 159 deletions(-)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 5bbb561..2557ea0 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -100,7 +100,35 @@ out:
     return info;
 }
 
+static PyObject *
+_wrap_pyg_set_object_has_new_constructor (PyObject *self,
+                                          PyObject *args,
+                                          PyObject *kwargs)
+{
+    static char *kwlist[] = { "g_type", NULL };
+    PyObject *py_g_type;
+    GType g_type;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                "O!:set_object_has_new_constructor",
+                kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
+        return NULL;
+    }
+
+    g_type = pyg_type_from_object(py_g_type);
+    if (!g_type_is_a(g_type, G_TYPE_OBJECT)) {
+        PyErr_SetString(PyExc_TypeError, "must be a subtype of GObject");
+        return NULL;
+    }
+
+    pyg_set_object_has_new_constructor(g_type);
+
+    Py_RETURN_NONE;
+}
+
+
 static PyMethodDef _pygi_functions[] = {
+    { "set_object_has_new_constructor", (PyCFunction)_wrap_pyg_set_object_has_new_constructor, METH_VARARGS | METH_KEYWORDS },
     { NULL, NULL, 0 }
 };
 
diff --git a/gi/module.py b/gi/module.py
index 2983d18..969c876 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -96,9 +96,11 @@ class DynamicModule(object):
             g_type = info.get_g_type()
 
             # Check if there is already a Python wrapper.
-            if g_type != gobject.TYPE_NONE and g_type.pytype is not None:
-                self.__dict__[name] = g_type.pytype
-                return gtype.pytype
+            if g_type != gobject.TYPE_NONE:
+                type_ = g_type.pytype
+                if type_ is not None:
+                    self.__dict__[name] = type_
+                    return type_
 
             # Create a wrapper.
             if isinstance(info, ObjectInfo):
@@ -124,6 +126,7 @@ class DynamicModule(object):
             }
             value = metaclass(name, bases, dict_)
 
+            # Register the new Python wrapper.
             if g_type != gobject.TYPE_NONE:
                 g_type.pytype = value
 
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index d3fc32f..1cf2e1a 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -1100,41 +1100,9 @@ _wrap_g_struct_info_get_methods (PyGIBaseInfo *self)
     return infos;
 }
 
-static PyObject *
-_wrap_g_struct_info_register_type (PyGIBaseInfo *self,
-                                   PyObject     *args,
-                                   PyObject     *kwargs)
-{
-    static char *kwlist[] = { "type", NULL };
-    PyTypeObject *type;
-    GType g_type;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                "O!:StructInfo.register_type",
-                kwlist, &PyType_Type, &type)) {
-        return NULL;
-    }
-
-    if (!PyType_IsSubtype(type, &PyGBoxed_Type)) {
-        PyErr_SetString(PyExc_TypeError, "argument 1: Must be a subtype of gobject.GBoxed");
-        return NULL;
-    }
-
-    g_type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)self->info);
-    if (!g_type_is_a(g_type, G_TYPE_BOXED)) {
-        PyErr_Format(PyExc_TypeError, "unable to register type; %s is not a boxed type", g_type_name(g_type));
-        return NULL;
-    }
-
-    pyg_register_boxed_type(g_type, type);
-
-    Py_RETURN_NONE;
-}
-
 static PyMethodDef _PyGIStructInfo_methods[] = {
     { "get_fields", (PyCFunction)_wrap_g_struct_info_get_fields, METH_NOARGS },
     { "get_methods", (PyCFunction)_wrap_g_struct_info_get_methods, METH_NOARGS },
-    { "register_type", (PyCFunction)_wrap_g_struct_info_register_type, METH_VARARGS | METH_KEYWORDS },
     { NULL, NULL, 0 }
 };
 
@@ -1314,40 +1282,11 @@ _wrap_g_object_info_get_interfaces (PyGIBaseInfo *self)
     return infos;
 }
 
-static PyObject *
-_wrap_g_object_info_register_type (PyGIBaseInfo *self,
-                                   PyObject     *args,
-                                   PyObject     *kwargs)
-{
-    static char *kwlist[] = { "type", NULL };
-    PyTypeObject *type;
-    GType g_type;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                "O!:ObjectInfo.register_type",
-                kwlist, &PyType_Type, &type)) {
-        return NULL;
-    }
-
-    if (!PyType_IsSubtype(type, &PyGObject_Type)) {
-        PyErr_SetString(PyExc_TypeError, "argument 1: Must be a subtype of gobject.GObject");
-        return NULL;
-    }
-
-    g_type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)self->info);
-
-    pyg_register_object_type(g_type, type);
-    pyg_set_object_has_new_constructor(g_type);
-
-    Py_RETURN_NONE;
-}
-
 static PyMethodDef _PyGIObjectInfo_methods[] = {
     { "get_parent", (PyCFunction)_wrap_g_object_info_get_parent, METH_NOARGS },
     { "get_methods", (PyCFunction)_wrap_g_object_info_get_methods, METH_NOARGS },
     { "get_fields", (PyCFunction)_wrap_g_object_info_get_fields, METH_NOARGS },
     { "get_interfaces", (PyCFunction)_wrap_g_object_info_get_interfaces, METH_NOARGS },
-    { "register_type", (PyCFunction)_wrap_g_object_info_register_type, METH_VARARGS | METH_KEYWORDS },
     { NULL, NULL, 0 }
 };
 
@@ -1391,35 +1330,8 @@ _wrap_g_interface_info_get_methods (PyGIBaseInfo *self)
     return infos;
 }
 
-static PyObject *
-_wrap_g_interface_info_register_type (PyGIBaseInfo *self,
-                                      PyObject     *args,
-                                      PyObject     *kwargs)
-{
-    static char *kwlist[] = { "type", NULL };
-    PyTypeObject *type;
-    GType g_type;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                "O!:InterfaceInfo.register_type",
-                kwlist, &PyType_Type, &type)) {
-        return NULL;
-    }
-
-    if (!PyType_IsSubtype(type, &PyGInterface_Type)) {
-        PyErr_SetString(PyExc_TypeError, "argument 1: Must be a subtype of gobject.GInterface");
-        return NULL;
-    }
-
-    g_type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)self->info);
-    pyg_register_interface_type(g_type, type);
-
-    Py_RETURN_NONE;
-}
-
 static PyMethodDef _PyGIInterfaceInfo_methods[] = {
     { "get_methods", (PyCFunction)_wrap_g_interface_info_get_methods, METH_NOARGS },
-    { "register_type", (PyCFunction)_wrap_g_interface_info_register_type, METH_VARARGS | METH_KEYWORDS },
     { NULL, NULL, 0 }
 };
 
diff --git a/gi/types.py b/gi/types.py
index 5319550..91bd269 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -25,7 +25,7 @@ from __future__ import absolute_import
 import gobject
 from new import instancemethod
 
-from ._gi import InterfaceInfo, ObjectInfo, StructInfo
+from ._gi import InterfaceInfo, ObjectInfo, StructInfo, set_object_has_new_constructor
 
 
 def Function(info):
@@ -93,8 +93,7 @@ class GObjectMeta(gobject.GObjectMeta, MetaClassHelper):
 
         if (isinstance(cls.__info__, ObjectInfo)):
             cls._setup_fields()
-
-        cls.__info__.register_type(cls)
+            set_object_has_new_constructor(cls.__info__.get_g_type())
 
 
 class StructMeta(type, MetaClassHelper):
@@ -109,6 +108,3 @@ class StructMeta(type, MetaClassHelper):
         cls._setup_fields()
         cls._setup_methods()
 
-        if cls.__gtype__.is_a(gobject.GBoxed):
-            cls.__info__.register_type(cls)
-
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 293f011..7c77d3e 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -2576,13 +2576,9 @@ struct _PyGObject_Functions pygobject_api_functions = {
   &PyGTypeWrapper_Type,
 
   &PyGObject_Type,
-  pyg_register_object_type,
   pygobject_new_from_type,
 
   &PyGInterface_Type,
-  pyg_register_interface_type,
-
-  pyg_register_boxed_type
 };
 
 /* for addon libraries ... */
diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c
index 15cb368..7fe05d4 100644
--- a/gobject/pygboxed.c
+++ b/gobject/pygboxed.c
@@ -93,14 +93,6 @@ static PyMethodDef pygboxed_methods[] = {
 };
 
 
-void
-pyg_register_boxed_type (GType         g_type,
-                         PyTypeObject *type)
-{
-    Py_INCREF((PyObject *)type);
-    g_type_set_qdata(g_type, pygboxed_type_key, type);
-}
-
 /**
  * pyg_register_boxed:
  * @dict: the module dictionary to store the wrapper class.
@@ -136,7 +128,8 @@ pyg_register_boxed(PyObject *dict, const gchar *class_name,
 			 o=pyg_type_wrapper_new(boxed_type));
     Py_DECREF(o);
 
-    pyg_register_boxed_type (boxed_type, type);
+    Py_INCREF((PyObject *)type);
+    g_type_set_qdata(boxed_type, pygboxed_type_key, type);
 
     PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
 
diff --git a/gobject/pygboxed.h b/gobject/pygboxed.h
index f719967..8433b9d 100644
--- a/gobject/pygboxed.h
+++ b/gobject/pygboxed.h
@@ -22,9 +22,6 @@
 #ifndef __PYGOBJECT_BOXED_H__ 
 #define __PYGOBJECT_BOXED_H__
 
-void pyg_register_boxed_type (GType         g_type,
-                              PyTypeObject *type);
-
 void pygobject_boxed_register_types(PyObject *d);
 
 #endif /* __PYGOBJECT_BOXED_H__ */
diff --git a/gobject/pyginterface.c b/gobject/pyginterface.c
index bf4131f..a857f41 100644
--- a/gobject/pyginterface.c
+++ b/gobject/pyginterface.c
@@ -53,14 +53,6 @@ pyg_interface_free(PyObject *op)
     PyObject_FREE(op);
 }
 
-void
-pyg_register_interface_type (GType         g_type,
-							 PyTypeObject *type)
-{
-	Py_INCREF((PyObject *)type);
-    g_type_set_qdata(g_type, pyginterface_type_key, type);
-}
-
 /**
  * pyg_register_interface:
  * @dict: a module dictionary.
@@ -92,7 +84,8 @@ pyg_register_interface(PyObject *dict, const gchar *class_name,
         Py_DECREF(o);
     }
 
-	pyg_register_interface_type(gtype, type);
+	Py_INCREF((PyObject *)type);
+    g_type_set_qdata(gtype, pyginterface_type_key, type);
 
     PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
 
diff --git a/gobject/pyginterface.h b/gobject/pyginterface.h
index 20eb382..0f390c2 100644
--- a/gobject/pyginterface.h
+++ b/gobject/pyginterface.h
@@ -28,8 +28,6 @@ extern GQuark pyginterface_info_key;
 
 extern PyTypeObject PyGInterface_Type;
 
-void pyg_register_interface_type (GType         g_type,
-                                  PyTypeObject *type);
 void pyg_register_interface(PyObject *dict,
 			    const gchar *class_name,
 			    GType gtype,
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index eaf224f..a106ca8 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -157,8 +157,6 @@ void          pygobject_register_sinkfunc(GType type,
 					  void (* sinkfunc)(GObject *object));
 int           pyg_type_register          (PyTypeObject *class,
 					  const gchar *type_name);
-void          pyg_register_object_type   (GType         g_type,
-                                          PyTypeObject *type);
 
 /* from pygboxed.c */
 extern PyTypeObject PyGBoxed_Type;
@@ -228,5 +226,8 @@ pyg_object_peek_inst_data(GObject *obj)
             g_object_get_qdata(obj, pygobject_instance_data_key));
 }
 
+/* pyginterface */
+extern PyTypeObject PyGInterface_Type;
+
 
 #endif
diff --git a/gobject/pygobject.c b/gobject/pygobject.c
index c772fca..187456d 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -648,14 +648,6 @@ pyg_type_get_bases(GType gtype)
     return bases;
 }
 
-void
-pyg_register_object_type (GType         g_type,
-                          PyTypeObject *type)
-{
-    Py_INCREF((PyObject *)type);
-    g_type_set_qdata(g_type, pygobject_class_key, type);
-}
-
 /**
  * pygobject_new_with_interfaces
  * @gtype: the GType of the GObject subclass.
@@ -756,7 +748,8 @@ pygobject_new_with_interfaces(GType gtype)
     }
 
     /* stash a pointer to the python class with the GType */
-    pyg_register_object_type(gtype, type);
+    Py_INCREF((PyObject *)type);
+    g_type_set_qdata(gtype, pygobject_class_key, type);
 
     pyglib_gil_state_release(state);
 
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index 1b15d9c..fa963a2 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -202,18 +202,11 @@ struct _PyGObject_Functions {
     PyTypeObject *type_wrapper_type;
 
     PyTypeObject *object_type;
-    void      (*register_object_type) (GType         g_type,
-                                       PyTypeObject *type);
     PyObject *(*object_new_from_type) (PyTypeObject *type,
                                        GObject *obj,
                                        gboolean sink);
 
     PyTypeObject *interface_type;
-    void      (*register_interface_type) (GType         g_type,
-                                          PyTypeObject *type);
-
-    void      (*register_boxed_type) (GType         g_type,
-                                      PyTypeObject *type);
 };
 
 #ifndef _INSIDE_PYGOBJECT_
@@ -283,13 +276,9 @@ struct _PyGObject_Functions *_PyGObject_API;
 #define PyGTypeWrapper_Type        (*_PyGObject_API->type_wrapper_type)
 
 #define PyGObject_Type             (*_PyGObject_API->object_type)
-#define pyg_register_object_type   (_PyGObject_API->register_object_type)
 #define pygobject_new_from_type    (_PyGObject_API->object_new_from_type)
 
 #define PyGInterface_Type          (*_PyGObject_API->interface_type)
-#define pyg_register_interface_type (_PyGObject_API->register_interface_type)
-
-#define pyg_register_boxed_type    (_PyGObject_API->register_boxed_type)
 
 #define pyg_block_threads()   G_STMT_START {   \
     if (_PyGObject_API->block_threads != NULL) \
diff --git a/gobject/pygtype.c b/gobject/pygtype.c
index 601ea83..6daafce 100644
--- a/gobject/pygtype.c
+++ b/gobject/pygtype.c
@@ -70,14 +70,47 @@ pyg_type_wrapper_dealloc(PyGTypeWrapper *self)
     PyObject_DEL(self);
 }
 
+static GQuark
+_pyg_type_key (GType type) {
+    GQuark key;
+
+    if (g_type_is_a(type, G_TYPE_INTERFACE)) {
+        key = pyginterface_type_key;
+    } else if (g_type_is_a(type, G_TYPE_ENUM)) {
+        key = pygenum_class_key;
+    } else if (g_type_is_a(type, G_TYPE_FLAGS)) {
+        key = pygflags_class_key;
+    } else if (g_type_is_a(type, G_TYPE_POINTER)) {
+        key = pygpointer_class_key;
+    } else if (g_type_is_a(type, G_TYPE_BOXED)) {
+        key = pygboxed_type_key;
+    } else if (g_type_is_a(type, G_TYPE_OBJECT)) {
+        key = pygobject_class_key;
+    } else {
+        PyErr_Format(PyExc_TypeError,
+                "type '%s' do not accept Python wrappers",
+                g_type_name(type));
+        key = 0;
+    }
+
+    return key;
+}
+
 static PyObject *
 _wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure)
 {
+    GQuark key;
     PyObject *py_type;
-    
-    py_type = g_type_get_qdata(self->type, pygobject_class_key);
-    if (!py_type)
-      py_type = Py_None;
+
+    key = _pyg_type_key(self->type);
+    if (key == 0) {
+        return NULL;
+    }
+
+    py_type = g_type_get_qdata(self->type, key);
+    if (py_type == NULL) {
+        Py_RETURN_NONE;
+    }
 
     Py_INCREF(py_type);
     return py_type;
@@ -86,20 +119,49 @@ _wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure)
 static int
 _wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure)
 {
+    GQuark key;
+    PyTypeObject *base_type;
     PyObject *py_type;
     
-    py_type = g_type_get_qdata(self->type, pygobject_class_key);
-    Py_CLEAR(py_type);
-    if (value == Py_None)
-	g_type_set_qdata(self->type, pygobject_class_key, NULL);
-    else if (PyType_Check(value)) {
-	Py_INCREF(value);
-	g_type_set_qdata(self->type, pygobject_class_key, value);
+    key = _pyg_type_key(self->type);
+    if (key == 0) {
+        return -1;
+    }
+
+    if (g_type_is_a(self->type, G_TYPE_INTERFACE)) {
+        base_type = &PyGInterface_Type;
+    } else if (g_type_is_a(self->type, G_TYPE_ENUM)) {
+        base_type = &PyGEnum_Type;
+    } else if (g_type_is_a(self->type, G_TYPE_FLAGS)) {
+        base_type = &PyGFlags_Type;
+    } else if (g_type_is_a(self->type, G_TYPE_POINTER)) {
+        base_type = &PyGPointer_Type;
+    } else if (g_type_is_a(self->type, G_TYPE_BOXED)) {
+        base_type = &PyGBoxed_Type;
+    } else if (g_type_is_a(self->type, G_TYPE_OBJECT)) {
+        base_type = &PyGObject_Type;
     } else {
-	PyErr_SetString(PyExc_TypeError, "Value must be None or a type object");
-	return -1;
+        base_type = NULL;
+        g_assert_not_reached();
+    }
+
+    if (!PyType_Check(value)) {
+        PyErr_Format(PyExc_TypeError, "must be %s or None, not %s",
+                base_type->tp_name, Py_TYPE(value)->tp_name);
+        return -1;
     }
 
+    Py_INCREF(value);
+
+    py_type = g_type_get_qdata(self->type, key);
+    Py_CLEAR(py_type);
+
+    if (value == Py_None) {
+        Py_CLEAR(value);
+    }
+
+    g_type_set_qdata(self->type, key, value);
+
     return 0;
 }
 



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