[pygobject/gsoc2009: 70/160] Add pygobject_new_from_type



commit b2210015eb8fa5ee936aa623dc56bf3d86b6eff5
Author: Simon van der Linden <svdlinden src gnome org>
Date:   Sun Jul 26 16:08:45 2009 +0200

    Add pygobject_new_from_type
    
    Add a function to instanciate a wrapper from an arbitrary Python type for a
    given GObject instance.

 gobject/gobjectmodule.c     |    4 ++-
 gobject/pygobject-private.h |    1 +
 gobject/pygobject.c         |   62 +++++++++++++++++++++++++++++++-----------
 gobject/pygobject.h         |    5 +++
 4 files changed, 55 insertions(+), 17 deletions(-)
---
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index f8f772f..e9dd214 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -2506,7 +2506,9 @@ struct _PyGObject_Functions pygobject_api_functions = {
   pyglib_option_group_new,
 
   &PyGObject_Type,
-  &PyGTypeWrapper_Type
+  &PyGTypeWrapper_Type,
+
+  pygobject_new_from_type
 };
 
 /* for addon libraries ... */
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index 2a09eed..b4ac72e 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -149,6 +149,7 @@ void          pygobject_register_class   (PyObject *dict,
 void          pygobject_register_wrapper (PyObject *self);
 PyObject *    pygobject_new              (GObject *obj);
 PyObject *    pygobject_new_full         (GObject *obj, gboolean sink, gpointer g_class);
+PyObject *    pygobject_new_from_type    (GObject *obj, gboolean sink, PyTypeObject *type);
 void          pygobject_sink             (GObject *obj);
 PyTypeObject *pygobject_lookup_class     (GType gtype);
 void          pygobject_watch_closure    (PyObject *self, GClosure *closure);
diff --git a/gobject/pygobject.c b/gobject/pygobject.c
index b4274e1..17f6886 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -881,6 +881,49 @@ pygobject_lookup_class(GType gtype)
 }
 
 /**
+ * pygobject_new_from_type:
+ * @obj: a GObject instance.
+ * @sink: whether to sink any floating reference found on the GObject.
+ * @type: a non-strict subtype of PyGObject_Type.
+ *
+ * This function creates a wrapper instance from the given Python type for the
+ * GObject instance. In case of error, it returns NULL and sets an exception.
+ *
+ * Returns: a new reference to the wrapper instance for the object.
+ */
+PyObject *
+pygobject_new_from_type(GObject *obj, gboolean sink, PyTypeObject *type)
+{
+	PyGObject *self;
+
+	/* need to bump type refcount if created with
+	   pygobject_new_with_interfaces(). fixes bug #141042 */
+	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+		Py_INCREF(type);
+	}
+
+	self = PyObject_GC_New(PyGObject, type);
+	if (self == NULL) {
+		if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+			Py_DECREF(type);
+		}
+		return NULL;
+	}
+
+	self->inst_dict = NULL;
+	self->weakreflist = NULL;
+	self->private_flags.flags = 0;
+
+	self->obj = obj;
+	g_object_ref(self->obj);
+
+	pygobject_register_wrapper_full(self, sink);
+	PyObject_GC_Track((PyObject *)self);
+
+	return (PyObject *)self;
+}
+
+/**
  * pygobject_new_full:
  * @obj: a GObject instance.
  * @sink: whether to sink any floating reference found on the GObject.
@@ -896,7 +939,7 @@ pygobject_lookup_class(GType gtype)
 PyObject *
 pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
 {
-    PyGObject *self;
+	PyGObject *self;
 
     if (obj == NULL) {
 	Py_INCREF(Py_None);
@@ -920,21 +963,8 @@ pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
                 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
         }
         g_assert(tp != NULL);
-        
-        /* need to bump type refcount if created with
-           pygobject_new_with_interfaces(). fixes bug #141042 */
-        if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
-            Py_INCREF(tp);
-	self = PyObject_GC_New(PyGObject, tp);
-	if (self == NULL)
-	    return NULL;
-        self->inst_dict = NULL;
-	self->weakreflist = NULL;
-	self->private_flags.flags = 0;
-	self->obj = obj;
-	g_object_ref(obj);
-	pygobject_register_wrapper_full(self, sink);
-	PyObject_GC_Track((PyObject *)self);
+
+		self = (PyGObject *)pygobject_new_from_type(obj, sink, tp);
     }
 
     return (PyObject *)self;
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index b74e95b..8f91536 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -201,6 +201,10 @@ struct _PyGObject_Functions {
 
     PyTypeObject *object_type;
     PyTypeObject *type_wrapper_type;
+
+	PyObject *(*object_new_from_type) (GObject *obj,
+									   gboolean sink,
+									   PyTypeObject *type);
 };
 
 #ifndef _INSIDE_PYGOBJECT_
@@ -269,6 +273,7 @@ struct _PyGObject_Functions *_PyGObject_API;
 #define pyg_option_group_new       (_PyGObject_API->option_group_new)
 #define PyGObject_Type             (*_PyGObject_API->object_type)
 #define PyGTypeWrapper_Type        (*_PyGObject_API->type_wrapper_type)
+#define pygobject_new_from_type    (_PyGObject_API->object_new_from_type)
 
 #define pyg_block_threads()   G_STMT_START {   \
     if (_PyGObject_API->block_threads != NULL) \



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