[pygobject] Cleanup overzealous new and init implementations



commit 2f2069c9efcd8f312ce9ffa572df371fbc08822d
Author: Simon Feltman <sfeltman src gnome org>
Date:   Thu Aug 15 19:23:18 2013 -0700

    Cleanup overzealous new and init implementations
    
    Remove PyGObject initializer code attempting to set properties on
    GObjects that have already been created. There were a number of
    overridden __new__ and __init__ methods that stripped away
    arguments before calling the base class to work around attempted
    property sets and argument count errors (fixing the symptom not
    the problem).
    Use Gtk.ListStore/TreeStore.new with __new__ override instead
    of __init__ with set_column_types.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705810

 gi/_gobject/gobjectmodule.c |   37 +++++++++++++++----------------------
 gi/_gobject/pygobject.c     |   16 ++++++++++++++--
 gi/overrides/GObject.py     |    3 ---
 gi/overrides/Gdk.py         |   15 ---------------
 gi/overrides/Gtk.py         |   11 ++++-------
 gi/overrides/Pango.py       |    5 -----
 gi/pygi-boxed.c             |    6 ------
 7 files changed, 33 insertions(+), 60 deletions(-)
---
diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c
index ac37904..e982107 100644
--- a/gi/_gobject/gobjectmodule.c
+++ b/gi/_gobject/gobjectmodule.c
@@ -980,28 +980,21 @@ pygobject_constructv(PyGObject  *self,
                      guint       n_parameters,
                      GParameter *parameters)
 {
-    if (self->obj == NULL) {
-        GObject *obj;
-        pygobject_init_wrapper_set((PyObject *) self);
-        obj = g_object_newv(pyg_type_from_object((PyObject *) self),
-                            n_parameters, parameters);
-
-        if (g_object_is_floating (obj))
-            self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING;
-        pygobject_sink (obj);
+    GObject *obj;
+
+    g_assert (self->obj == NULL);
+    pygobject_init_wrapper_set((PyObject *) self);
+    obj = g_object_newv(pyg_type_from_object((PyObject *) self),
+                        n_parameters, parameters);
+
+    if (g_object_is_floating (obj))
+        self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING;
+    pygobject_sink (obj);
+
+    pygobject_init_wrapper_set(NULL);
+    self->obj = obj;
+    pygobject_register_wrapper((PyObject *) self);
 
-        pygobject_init_wrapper_set(NULL);
-        if (self->obj == NULL) {
-            self->obj = obj;
-            pygobject_register_wrapper((PyObject *) self);
-        }
-    } else {
-        int i;
-        for (i = 0; i < n_parameters; ++i)
-            g_object_set_property(self->obj,
-                                 parameters[i].name,
-                                 &parameters[i].value);
-    }
     return 0;
 }
 
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index f78b7f5..129f29a 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -1265,7 +1265,19 @@ pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
     GParameter *params = NULL;
     GObjectClass *class;
 
-    if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
+    /* Only do GObject creation and property setting if the GObject hasn't
+     * already been created. The case where self->obj already exists can occur
+     * when C constructors are called directly (Gtk.Button.new_with_label)
+     * and we are simply wrapping the result with a PyGObject.
+     * In these cases we want to ignore any keyword arguments passed along
+     * to __init__ and simply return.
+     *
+     * See: https://bugzilla.gnome.org/show_bug.cgi?id=705810
+     */
+    if (self->obj != NULL)
+        return 0;
+
+    if (!PyArg_ParseTuple(args, ":GObject.__init__", NULL))
        return -1;
 
     object_type = pyg_type_from_object((PyObject *)self);
@@ -1289,7 +1301,7 @@ pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
 
     if (pygobject_constructv(self, n_params, params))
        PyErr_SetString(PyExc_RuntimeError, "could not create object");
-          
+
  cleanup:
     for (i = 0; i < n_params; i++) {
        g_free((gchar *) params[i].name);
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index 83f1481..2187ce5 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -205,9 +205,6 @@ __all__ += ['features', 'list_properties', 'new',
 
 
 class Value(GObjectModule.Value):
-    def __new__(cls, *args, **kwargs):
-        return GObjectModule.Value.__new__(cls)
-
     def __init__(self, value_type=None, py_value=None):
         GObjectModule.Value.__init__(self)
         if value_type is not None:
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index 14edc70..381e797 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -38,9 +38,6 @@ class Color(Gdk.Color):
         self.green = green
         self.blue = blue
 
-    def __new__(cls, *args, **kwargs):
-        return Gdk.Color.__new__(cls)
-
     def __eq__(self, other):
         return self.equal(other)
 
@@ -81,9 +78,6 @@ if Gdk._version == '3.0':
             self.blue = blue
             self.alpha = alpha
 
-        def __new__(cls, *args, **kwargs):
-            return Gdk.RGBA.__new__(cls)
-
         def __eq__(self, other):
             return self.equal(other)
 
@@ -124,9 +118,6 @@ if Gdk._version == '2.0':
             self.width = width
             self.height = height
 
-        def __new__(cls, *args, **kwargs):
-            return Gdk.Rectangle.__new__(cls)
-
         def __repr__(self):
             return '<Gdk.Rectangle(x=%d, y=%d, width=%d, height=%d)>' % (self.x, self.y, self.height, 
self.width)
 
@@ -202,9 +193,6 @@ class Event(Gdk.Event):
     if Gdk._version == '2.0':
         _UNION_MEMBERS[Gdk.EventType.NO_EXPOSE] = 'no_expose'
 
-    def __new__(cls, *args, **kwargs):
-        return Gdk.Event.__new__(cls)
-
     def __getattr__(self, name):
         real_event = getattr(self, '_UNION_MEMBERS').get(self.type)
         if real_event:
@@ -316,9 +304,6 @@ class Cursor(Gdk.Cursor):
 
         return _constructor(*args, **kwds)
 
-    def __init__(self, *args, **kwargs):
-        Gdk.Cursor.__init__(self)
-
 Cursor = override(Cursor)
 __all__.append('Cursor')
 
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 58251de..96802fb 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -909,9 +909,8 @@ __all__.append('TreeModelSort')
 
 
 class ListStore(Gtk.ListStore, TreeModel, TreeSortable):
-    def __init__(self, *column_types):
-        Gtk.ListStore.__init__(self)
-        self.set_column_types(column_types)
+    def __new__(self, *column_types):
+        return Gtk.ListStore.new(column_types)
 
     def _do_insert(self, position, row):
         if row is not None:
@@ -1158,10 +1157,8 @@ __all__.append('TreePath')
 
 
 class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
-
-    def __init__(self, *column_types):
-        Gtk.TreeStore.__init__(self)
-        self.set_column_types(column_types)
+    def __new__(self, *column_types):
+        return Gtk.TreeStore.new(column_types)
 
     def _do_insert(self, parent, position, row):
         if row is not None:
diff --git a/gi/overrides/Pango.py b/gi/overrides/Pango.py
index 15d5edc..74602c4 100644
--- a/gi/overrides/Pango.py
+++ b/gi/overrides/Pango.py
@@ -52,11 +52,6 @@ class Layout(Pango.Layout):
     def __new__(cls, context):
         return Pango.Layout.new(context)
 
-    def __init__(self, context, **kwds):
-        # simply discard 'context', since it was set by
-        # __new__ and it is not a PangoLayout property
-        super(Layout, self).__init__(**kwds)
-
     def set_markup(self, text, length=-1):
         super(Layout, self).set_markup(text, length)
 
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index 5bf2c19..d352e23 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -75,17 +75,11 @@ _boxed_new (PyTypeObject *type,
             PyObject     *args,
             PyObject     *kwargs)
 {
-    static char *kwlist[] = { NULL };
-
     GIBaseInfo *info;
     gsize size = 0;
     gpointer boxed;
     PyGIBoxed *self = NULL;
 
-    if (!PyArg_ParseTupleAndKeywords (args, kwargs, "", kwlist)) {
-        return NULL;
-    }
-
     info = _pygi_object_get_gi_info ( (PyObject *) type, &PyGIBaseInfo_Type);
     if (info == NULL) {
         if (PyErr_ExceptionMatches (PyExc_AttributeError)) {


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