Index: codegen/codegen.py
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/codegen/codegen.py,v
retrieving revision 1.94
diff -u -p -d -r1.94 codegen.py
--- codegen/codegen.py	20 Jun 2005 22:57:41 -0000	1.94
+++ codegen/codegen.py	6 Jul 2005 15:12:22 -0000
@@ -742,7 +742,8 @@ class GObjectWrapper(Wrapper):
         print >> out, "static int"
         print >> out, '_wrap_%s(PyGObject *self, PyObject *args,'\
               ' PyObject *kwargs)\n{' % constructor.c_name
-        print >> out, "    GType obj_type = pyg_type_from_object((PyObject *) self);"
+        if constructor.params:
+            print >> out, "    GType obj_type = pyg_type_from_object((PyObject *) self);"
 
         def py_str_list_to_c(arg):
             if arg:
@@ -788,7 +789,7 @@ class GObjectWrapper(Wrapper):
             print >> out, "    if (!pyg_parse_constructor_args(obj_type, arg_names, prop_names,"
             print >> out, "                                    params, &nparams, parsed_args))"
             print >> out, "        return -1;"
-            print >> out, "    self->obj = g_object_newv(obj_type, nparams, params);"
+            print >> out, "    pygobject_constructv(self, nparams, params);\n"
             print >> out, "    for (i = 0; i < nparams; ++i)"
             print >> out, "        g_value_unset(&params[i].value);"
         else:
@@ -802,7 +803,7 @@ class GObjectWrapper(Wrapper):
             print >> out, '    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ":%s.__init__", kwlist))' % classname
             print >> out, "        return -1;"
             print >> out
-            print >> out, "    self->obj = g_object_newv(obj_type, 0, NULL);"
+            print >> out, "    pygobject_constructv(self, 0, NULL);\n"
 
         print >> out, \
               '    if (!self->obj) {\n' \
@@ -814,7 +815,6 @@ class GObjectWrapper(Wrapper):
             print >> out, "    g_object_ref(self->obj);\n"
 
         print >> out, \
-              '    pygobject_register_wrapper((PyObject *)self);\n' \
               '    return 0;\n' \
               '}\n\n' % { 'typename': classname }
         return "_wrap_%s" % constructor.c_name
@@ -1074,7 +1074,7 @@ def write_extension_init(overrides, pref
     fp.write(overrides.get_init() + '\n')
     fp.resetline()
 
-def write_registers(parser, fp):
+def write_registers(parser, fp, have_new_construtors):
     for boxed in parser.boxes:
         fp.write('    pyg_register_boxed(d, "' + boxed.name +
                  '", ' + boxed.typecode + ', &Py' + boxed.c_name + '_Type);\n')
@@ -1115,12 +1115,14 @@ def write_registers(parser, fp):
             fp.write('    pygobject_register_class(d, "' + obj.c_name +
                      '", ' + obj.typecode + ', &Py' + obj.c_name +
                      '_Type, NULL);\n')
+        if have_new_construtors:
+            fp.write('    pyg_set_object_has_new_constructor(%s);\n' % obj.typecode)
         if obj.class_init_func is not None:
             fp.write('    pyg_register_class_init(%s, %s);\n' %
                      (obj.typecode, obj.class_init_func))
     fp.write('}\n')
 
-def write_source(parser, overrides, prefix, fp=FileOutput(sys.stdout)):
+def write_source(parser, overrides, prefix, have_new_construtors, fp=FileOutput(sys.stdout)):
     write_headers(overrides.get_headers(), fp)
     write_imports(overrides, fp)
     write_type_declarations(parser, fp)
@@ -1132,7 +1134,7 @@ def write_source(parser, overrides, pref
 
     write_enums(parser, prefix, fp)
     write_extension_init(overrides, prefix, fp)
-    write_registers(parser, fp)
+    write_registers(parser, fp, have_new_construtors)
 
 def register_types(parser):
     for boxed in parser.boxes:
@@ -1157,8 +1159,9 @@ def main(argv):
     errorfilename = None
     opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:",
                         ["override=", "prefix=", "register=", "outfilename=",
-                         "load-types=", "errorfilename="])
+                         "load-types=", "errorfilename=", "new-constructors"])
     defines = {} # -Dkey[=val] options
+    new_constructors = False
     for opt, arg in opts:
         if opt in ('-o', '--override'):
             o = override.Overrides(arg)
@@ -1183,6 +1186,8 @@ def main(argv):
 		defines[nameval[0]] = nameval[1]
 	    except IndexError:
 		defines[nameval[0]] = None
+	elif opt == '--new-constructors':
+            new_constructors = True
     if len(args) < 1:
         print >> sys.stderr, usage
         return 1
@@ -1195,7 +1200,7 @@ def main(argv):
     p.startParsing()
     
     register_types(p)
-    write_source(p, o, prefix, FileOutput(sys.stdout, outfilename))
+    write_source(p, o, prefix, new_constructors, FileOutput(sys.stdout, outfilename))
 
     functions_coverage.printstats()
     methods_coverage.printstats()
Index: gobject/gobjectmodule.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/gobjectmodule.c,v
retrieving revision 1.178
diff -u -p -d -r1.178 gobjectmodule.c
--- gobject/gobjectmodule.c	5 Jul 2005 20:38:56 -0000	1.178
+++ gobject/gobjectmodule.c	6 Jul 2005 15:12:25 -0000
@@ -26,6 +26,7 @@
 
 #include "pygobject-private.h"
 #include "pythread.h"
+#include <gobject/gvaluecollector.h>
 
 static PyObject *gerror_exc = NULL;
 static gboolean use_gil_state_api = FALSE;
@@ -40,6 +41,9 @@ GQuark pygboxed_marshal_key;
 GQuark pygenum_class_key;
 GQuark pygflags_class_key;
 GQuark pygpointer_class_key;
+GQuark pygobject_has_updated_constructor_key;
+
+
 
 static void pyg_flags_add_constants(PyObject *module, GType flags_type,
 				    const gchar *strip_prefix);
@@ -1028,6 +1032,77 @@ get_type_name_for_class(PyTypeObject *cl
     return type_name;
 }
 
+
+static GStaticPrivate pygobject_contruction_wrapper = G_STATIC_PRIVATE_INIT;
+
+static inline void
+pygobject_push_wrapper(PyObject *wrapper)
+{
+    GSList *wrapper_list;
+
+    wrapper_list = (GSList *) g_static_private_get(&pygobject_contruction_wrapper);
+    wrapper_list = g_slist_prepend(wrapper_list, wrapper);
+    g_static_private_set(&pygobject_contruction_wrapper, wrapper_list, NULL);
+}
+
+static inline PyObject *
+pygobject_pop_wrapper(void)
+{
+    GSList *wrapper_list;
+    PyObject *retval;
+
+    wrapper_list = (GSList *) g_static_private_get(&pygobject_contruction_wrapper);
+    if (!wrapper_list)
+        return NULL;
+    retval = (PyObject *) wrapper_list->data;
+    wrapper_list = g_slist_delete_link(wrapper_list, wrapper_list);
+    g_static_private_set(&pygobject_contruction_wrapper, wrapper_list, NULL);
+    return retval;
+}
+
+static inline PyObject *
+pygobject_peek_wrapper(void)
+{
+    GSList *wrapper_list;
+
+    wrapper_list = (GSList *) g_static_private_get(&pygobject_contruction_wrapper);
+    if (!wrapper_list)
+        return NULL;
+    return (PyObject *) wrapper_list->data;
+}
+
+static void
+pygobject__g_instance_init(GTypeInstance   *instance,
+                           gpointer         g_class)
+{
+    GObject *object = (GObject *) instance;
+    PyObject *wrapper, *args, *kwargs;
+
+    if (!g_type_get_qdata(G_OBJECT_TYPE(object), pygobject_has_updated_constructor_key))
+        return;
+
+    wrapper = g_object_get_qdata(object, pygobject_wrapper_key); 
+    if (wrapper == NULL) {
+        wrapper = pygobject_peek_wrapper();
+        if (wrapper)
+            g_object_set_qdata(object, pygobject_wrapper_key, wrapper);
+    }
+    if (wrapper == NULL) {
+          /* this looks like a python object created through
+           * g_object_new -> we have no python wrapper, so create it
+           * now */
+          /* FIXME: force pygobject_new to not sink reference here.. */
+        wrapper = pygobject_new(object);
+        /* g_object_set_qdata(object, pygobject_wrapper_key, wrapper); */
+        args = PyTuple_New(0);
+        kwargs = PyDict_New();
+        if (wrapper->ob_type->tp_init(wrapper, args, kwargs))
+            PyErr_Print();
+        Py_DECREF(args);
+        Py_DECREF(kwargs);
+    }
+}
+
 int
 pyg_type_register(PyTypeObject *class, char *type_name)
 {
@@ -1036,6 +1111,7 @@ pyg_type_register(PyTypeObject *class, c
     gint i;
     GTypeQuery query;
     gpointer gclass;
+    gpointer has_new_constructor_api;
     GTypeInfo type_info = {
 	0,    /* class_size */
 
@@ -1048,7 +1124,7 @@ pyg_type_register(PyTypeObject *class, c
 
 	0,    /* instance_size */
 	0,    /* n_preallocs */
-	(GInstanceInitFunc) NULL
+	(GInstanceInitFunc) pygobject__g_instance_init
     };
 
 
@@ -1088,6 +1164,16 @@ pyg_type_register(PyTypeObject *class, c
     PyDict_SetItemString(class->tp_dict, "__gtype__", gtype);
     Py_DECREF(gtype);
 
+      /* propagate new constructor API compatility flag from parent to child type */
+    has_new_constructor_api = g_type_get_qdata(parent_type,
+                                               pygobject_has_updated_constructor_key);
+    if (has_new_constructor_api == NULL)
+        g_warning("Constructor wrapper for %s needs to be updated to the new API",
+                  g_type_name(parent_type));
+    else
+        g_type_set_qdata(instance_type, pygobject_has_updated_constructor_key,
+                         has_new_constructor_api);
+
     /* if no __doc__, set it to the auto doc descriptor */
     if (PyDict_GetItemString(class->tp_dict, "__doc__") == NULL) {
 	PyDict_SetItemString(class->tp_dict, "__doc__",
@@ -2455,6 +2541,91 @@ pyg_parse_constructor_args(GType        
     return TRUE;
 }
 
+int
+pygobject_constructv(PyGObject  *self,
+                     guint       n_parameters,
+                     GParameter *parameters)
+{
+    if (self->obj == NULL) {
+        pygobject_push_wrapper((PyObject *) self);
+        self->obj = g_object_newv(pyg_type_from_object((PyObject *) self),
+                                  n_parameters, parameters);
+        pygobject_pop_wrapper();
+        pygobject_register_wrapper((PyObject *) self);
+    }
+    return 0;
+}
+
+/* This function is mostly juste copy-paste from g_object_new, but
+ * calls pygobject_constructv instead of g_object_newv */
+int
+pygobject_construct(PyGObject *self, const char *first_property_name, ...)
+{
+    va_list var_args;
+    GObjectClass *class;
+    GParameter *params;
+    const gchar *name;
+    guint n_params = 0, n_alloced_params = 16;
+    GType object_type = pyg_type_from_object((PyObject *) self);
+    int retval;
+
+    if (!first_property_name)
+        return pygobject_constructv(self, 0, NULL);
+
+    va_start(var_args, first_property_name);
+    class = g_type_class_ref(object_type);
+
+    params = g_new(GParameter, n_alloced_params);
+    name = first_property_name;
+    while (name)
+    {
+        gchar *error = NULL;
+        GParamSpec *pspec = g_object_class_find_property(class, name);
+
+        if (!pspec)
+	{
+            g_warning("%s: object class `%s' has no property named `%s'", 
+                      G_STRFUNC, 
+                      g_type_name(object_type), 
+                      name);
+            break;
+	}
+        if (n_params >= n_alloced_params)
+	{
+            n_alloced_params += 16;
+            params = g_renew(GParameter, params, n_alloced_params);
+	}
+        params[n_params].name = name;
+        params[n_params].value.g_type = 0;
+        g_value_init(&params[n_params].value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+        G_VALUE_COLLECT(&params[n_params].value, var_args, 0, &error);
+        if (error)
+	{
+            g_warning("%s: %s", G_STRFUNC, error);
+            g_free(error);
+            g_value_unset(&params[n_params].value);
+            break;
+	}
+        n_params++;
+        name = va_arg(var_args, gchar*);
+    }
+
+    retval = pygobject_constructv(self, n_params, params);
+
+    while (n_params--)
+        g_value_unset(&params[n_params].value);
+    g_free(params);
+    va_end(var_args);
+    g_type_class_unref(class);
+    return retval;
+}
+
+void
+pyg_set_object_has_new_constructor(GType type)
+{
+    g_type_set_qdata(type, pygobject_has_updated_constructor_key, GINT_TO_POINTER(1));
+}
+
 /* ----------------- gobject module initialisation -------------- */
 
 struct _PyGObject_Functions pygobject_api_functions = {
@@ -2521,7 +2692,10 @@ struct _PyGObject_Functions pygobject_ap
   pyg_register_class_init,
   pyg_register_interface_info,
 
-  pyg_closure_set_exception_handler
+  pyg_closure_set_exception_handler,
+  pygobject_constructv,
+  pygobject_construct,
+  pyg_set_object_has_new_constructor
 };
 
 #define REGISTER_TYPE(d, type, name) \
@@ -2559,6 +2733,8 @@ initgobject(void)
     pyginterface_type_key    = g_quark_from_static_string("PyGInterface::type");
     pyginterface_info_key    = g_quark_from_static_string("PyGInterface::info");
     pygpointer_class_key     = g_quark_from_static_string("PyGPointer::class");
+    pygobject_has_updated_constructor_key =\
+        g_quark_from_static_string("PyGObject::has-updated-constructor");
 
     REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType");
 
@@ -2581,6 +2757,7 @@ initgobject(void)
 			     &PyGObject_Type, NULL);
     PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
 			 pyg_object_descr_doc_get());
+    pyg_set_object_has_new_constructor(G_TYPE_OBJECT);
 
     REGISTER_GTYPE(d, PyGInterface_Type, "GInterface", G_TYPE_INTERFACE);
     PyDict_SetItemString(PyGInterface_Type.tp_dict, "__doc__",
Index: gobject/pygobject-private.h
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject-private.h,v
retrieving revision 1.34
diff -u -p -d -r1.34 pygobject-private.h
--- gobject/pygobject-private.h	5 Jul 2005 17:16:40 -0000	1.34
+++ gobject/pygobject-private.h	6 Jul 2005 15:12:25 -0000
@@ -51,9 +51,17 @@ extern GQuark pygobject_class_init_key;
 extern GQuark pygobject_class_key;
 extern GQuark pygobject_wrapper_key;
 extern GQuark pygpointer_class_key;
+extern GQuark pygobject_has_updated_constructor_key;
 
-void  pyg_destroy_notify (gpointer user_data);
-gboolean pyg_error_check(GError **error);
+void     pyg_destroy_notify   (gpointer     user_data);
+gboolean pyg_error_check      (GError     **error);
+int      pygobject_constructv (PyGObject   *self,
+                               guint        n_parameters,
+                               GParameter  *parameters);
+int      pygobject_construct  (PyGObject   *self,
+                               const char  *first_property_name,
+                               ...);
+void     pyg_set_object_has_new_constructor (GType gtype);
 
 /* from pygtype.h */
 extern PyTypeObject PyGTypeWrapper_Type;
Index: gobject/pygobject.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject.c,v
retrieving revision 1.47
diff -u -p -d -r1.47 pygobject.c
--- gobject/pygobject.c	5 Jul 2005 17:16:40 -0000	1.47
+++ gobject/pygobject.c	6 Jul 2005 15:12:25 -0000
@@ -598,11 +598,7 @@ pygobject_init(PyGObject *self, PyObject
 	    n_params++;
 	}
     }
-
-    self->obj = g_object_newv(object_type, n_params, params);
-    if (self->obj)
-	pygobject_register_wrapper((PyObject *)self);
-    else
+    if (pygobject_constructv(self, n_params, params))
 	PyErr_SetString (PyExc_RuntimeError, "could not create object");
 	   
  cleanup:
Index: gobject/pygobject.h
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject.h,v
retrieving revision 1.52
diff -u -p -d -r1.52 pygobject.h
--- gobject/pygobject.h	10 Jun 2005 00:51:48 -0000	1.52
+++ gobject/pygobject.h	6 Jul 2005 15:12:25 -0000
@@ -163,6 +163,13 @@ struct _PyGObject_Functions {
     void      (*register_class_init) (GType gtype, PyGClassInitFunc class_init);
     void      (*register_interface_info) (GType gtype, const GInterfaceInfo *info);
     void      (*closure_set_exception_handler) (GClosure *closure, PyClosureExceptionHandler handler);
+    int       (*pygobject_constructv) (PyGObject  *self,
+                                       guint       n_parameters,
+                                       GParameter *parameters);
+    int       (*pygobject_construct) (PyGObject  *self,
+                                      const char *first_property_name,
+                                      ...);
+    void      (*set_object_has_new_constructor) (GType type);
 };
 
 #ifndef _INSIDE_PYGOBJECT_
@@ -217,6 +224,10 @@ struct _PyGObject_Functions *_PyGObject_
 #define pyg_enable_threads          (_PyGObject_API->enable_threads)
 #define pyg_register_class_init     (_PyGObject_API->register_class_init)
 #define pyg_register_interface_info (_PyGObject_API->register_interface_info)
+#define pygobject_construct         (_PyGObject_API->pygobject_construct)
+#define pygobject_constructv        (_PyGObject_API->pygobject_constructv)
+#define pyg_set_object_has_new_constructor (_PyGObject_API->set_object_has_new_constructor)
+
 
 #define pyg_block_threads()   G_STMT_START {   \
     if (_PyGObject_API->block_threads != NULL) \
Index: gtk/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/Makefile.am,v
retrieving revision 1.50
diff -u -p -d -r1.50 Makefile.am
--- gtk/Makefile.am	6 Jun 2005 22:21:49 -0000	1.50
+++ gtk/Makefile.am	6 Jul 2005 15:12:25 -0000
@@ -100,6 +100,7 @@ EXTRA_DIST += libglade.override
 .defs.c:
 	(cd $(srcdir) \
 	 && $(PYTHON) ../codegen/codegen.py \
+	   --new-constructors \
 	   $(PYGTK_CODEGEN_DEFINES) \
 	    --register ../pango-types.defs \
 	    --register ../atk-types.defs \
Index: gtk/gtk.override
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gtk.override,v
retrieving revision 1.336
diff -u -p -d -r1.336 gtk.override
--- gtk/gtk.override	27 Jun 2005 23:20:39 -0000	1.336
+++ gtk/gtk.override	6 Jul 2005 15:12:28 -0000
@@ -2677,10 +2677,8 @@ _wrap_gtk_dialog_new_with_buttons(PyGObj
                         "buttons tuple must contain text/response id pairs");
         return -1;
     }
-    
-    self->obj = g_object_new(pyg_type_from_object((PyObject*) self), NULL);
 
-    if (!self->obj) {
+    if (pygobject_constructv(self, 0, NULL)) {
         PyErr_SetString(PyExc_RuntimeError,
                         "could not create GtkDialog object");
         return -1;
