? pygtk.wpr
? test.py
Index: gobject/gobjectmodule.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/gobjectmodule.c,v
retrieving revision 1.155
diff -u -r1.155 gobjectmodule.c
--- gobject/gobjectmodule.c	12 Nov 2004 20:29:37 -0000	1.155
+++ gobject/gobjectmodule.c	13 Dec 2004 18:40:03 -0000
@@ -327,6 +327,12 @@
     return NULL;
 }
 
+enum {
+    PYGOBJECT_PROPERTY_0,
+    PYGOBJECT_PROPERTY_PYTHON_DEFINED,
+    PYGOBJECT_PROPERTY_PYOBJECT,
+};
+
 static void
 pyg_object_set_property (GObject *object, guint property_id,
 			 const GValue *value, GParamSpec *pspec)
@@ -335,6 +341,11 @@
     PyObject *py_pspec, *py_value;
     PyGILState_STATE state;
 
+    if (property_id == PYGOBJECT_PROPERTY_PYOBJECT) {
+	return;
+    }
+	
+
     state = pyg_gil_state_ensure();
 
     object_wrapper = pygobject_new(object);
@@ -392,11 +403,69 @@
     pyg_gil_state_release(state);
 }
 
+
+static GObject*
+pyg_object_constructor(GType                  type,
+		       guint                  n_construct_properties,
+		       GObjectConstructParam *construct_properties)
+{
+    GObjectClass *class = g_type_class_peek (type);
+    GObjectClass *parent_class =  g_type_class_peek_parent (class);
+    PyGObject* py_obj = NULL;
+    GObject* obj;
+    int i;
+
+    g_assert (parent_class->constructor != NULL);
+
+    for (i = 0; i < n_construct_properties; i++) {
+	GObjectConstructParam *param = &construct_properties[i];
+	if (param->pspec->param_id == PYGOBJECT_PROPERTY_PYOBJECT
+	    && param->pspec->owner_type == type) {
+	    py_obj = g_value_get_pointer(param->value);
+	    if (py_obj != NULL) 
+		Py_INCREF(py_obj);
+	    else {
+		PyObject* py_class = g_type_get_qdata(type, 
+						      g_quark_from_string("PyGObject::class"));
+		if (py_class != NULL && PyType_Check(py_class)) {
+		    PyTypeObject* as_type = (PyTypeObject*)py_class;
+		    PyObject* args = PyTuple_New(0);
+		    if (args != NULL) {
+			py_obj = (PyGObject*) (as_type)->tp_new(as_type, args, NULL);
+			g_value_set_pointer(param->value, py_obj);
+			Py_DECREF(args);
+		    }
+		}
+	    }
+
+	    break;
+	}
+    }
+
+    obj = parent_class->constructor(type, n_construct_properties, construct_properties);
+    if (obj != NULL && py_obj != NULL) {
+	py_obj->obj = obj;
+	pygobject_register_wrapper((PyObject*)py_obj);
+    }
+    Py_XDECREF(py_obj);
+
+    return obj;
+}
+
 static void
 pyg_object_class_init(GObjectClass *class, PyObject *py_class)
 {
     class->set_property = pyg_object_set_property;
     class->get_property = pyg_object_get_property;
+    class->constructor = pyg_object_constructor;
+
+    g_object_class_install_property (class,
+				     PYGOBJECT_PROPERTY_PYOBJECT,
+				     g_param_spec_pointer ("pygtk-pyobject-pointer",
+							  NULL,
+							  NULL,
+							  G_PARAM_CONSTRUCT_ONLY| G_PARAM_WRITABLE));
+
 }
 
 static gboolean
Index: gobject/pygobject.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject.c,v
retrieving revision 1.39
diff -u -r1.39 pygobject.c
--- gobject/pygobject.c	27 Nov 2004 19:12:34 -0000	1.39
+++ gobject/pygobject.c	13 Dec 2004 18:40:03 -0000
@@ -564,6 +564,8 @@
     guint n_params = 0, i;
     GParameter *params = NULL;
     GObjectClass *class;
+    GParamSpec *pspec;
+    GObject* obj;
 
     if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
 	return -1;
@@ -584,14 +586,17 @@
 	return -1;
     }
 
+    if (kwargs)
+	params = g_new0(GParameter, PyDict_Size(kwargs) + 1);
+    else
+	params = g_new0(GParameter, 1);
+
     if (kwargs) {
 	int pos = 0;
 	PyObject *key;
 	PyObject *value;
 
-	params = g_new0(GParameter, PyDict_Size(kwargs));
 	while (PyDict_Next (kwargs, &pos, &key, &value)) {
-	    GParamSpec *pspec;
 	    gchar *key_str = PyString_AsString(key);
 
 	    pspec = g_object_class_find_property (class, key_str);
@@ -614,11 +619,25 @@
 	}
     }
 
-    self->obj = g_object_newv(object_type, n_params, params);
-    if (self->obj)
-	pygobject_register_wrapper((PyObject *)self);
-    else
+    pspec = g_object_class_find_property (class, "pygtk-pyobject-pointer");
+    if (pspec != NULL) {
+	params[n_params].name = g_strdup("pygtk-pyobject-pointer");
+	g_value_init(&params[n_params].value,
+		     G_PARAM_SPEC_VALUE_TYPE(pspec));
+	g_value_set_pointer(&params[n_params].value, self);
+	n_params++;
+    }
+
+    obj = g_object_newv(object_type, n_params, params);
+    if (obj == NULL) {
 	PyErr_SetString (PyExc_RuntimeError, "could not create object");
+	goto cleanup;
+    }
+    if (self->obj == NULL) {
+	self->obj = obj;
+	pygobject_register_wrapper((PyObject *)self);
+    }
+    g_assert(self->obj == obj);
 	   
  cleanup:
     for (i = 0; i < n_params; i++) {
