From 3938273dfd085dc75f64ce44706cf508fd971099 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sun, 27 Aug 2006 10:53:54 +0000 Subject: Bug 353039 – Failure in signal emission during do_set_property invoked from constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 14 ++++++++++++++ gobject/gobjectmodule.c | 16 +++++++++++----- tests/test_signal.py | 30 +++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d632195..6632da5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-08-27 Gustavo J. A. M. Carneiro + + * gobject/gobjectmodule.c (pygobject__g_instance_init): If + necessary, attach the GObject to the PyGObject here. + (pygobject_constructv): Cope with the fact that wrapper->obj may + have already been set due to the change above. + + * tests/test_signal.py: Add test case fixed by the changes above, + basically calling self.emit() inside do_set_property called + implicitly by the constructor due to a CONSTRUCT property. + + Fixes bug 353039: "Failure in signal emission during + do_set_property invoked from constructor". + 2006-08-26 Gustavo J. A. M. Carneiro * gobject/gobjectmodule.c (pyg_type_register): Fix type diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index dabff01..dde48b6 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -1173,8 +1173,9 @@ pygobject__g_instance_init(GTypeInstance *instance, wrapper = g_object_get_qdata(object, pygobject_wrapper_key); if (wrapper == NULL) { wrapper = pygobject_init_wrapper_get(); - if (wrapper) { - g_object_set_qdata(object, pygobject_wrapper_key, wrapper); + if (wrapper && ((PyGObject *) wrapper)->obj == NULL) { + ((PyGObject *) wrapper)->obj = object; + pygobject_register_wrapper(wrapper); } } pygobject_init_wrapper_set(NULL); @@ -3070,11 +3071,16 @@ pygobject_constructv(PyGObject *self, GParameter *parameters) { if (self->obj == NULL) { + GObject *obj; pygobject_init_wrapper_set((PyObject *) self); - self->obj = g_object_newv(pyg_type_from_object((PyObject *) self), - n_parameters, parameters); + obj = g_object_newv(pyg_type_from_object((PyObject *) self), + n_parameters, parameters); pygobject_init_wrapper_set(NULL); - pygobject_register_wrapper((PyObject *) self); + if (self->obj == NULL) { + self->obj = obj; + pygobject_sink(obj); + pygobject_register_wrapper((PyObject *) self); + } } else { int i; for (i = 0; i < n_parameters; ++i) diff --git a/tests/test_signal.py b/tests/test_signal.py index fd1e33c..bb33fb8 100644 --- a/tests/test_signal.py +++ b/tests/test_signal.py @@ -211,7 +211,35 @@ class TestClosures(unittest.TestCase): c = C(self) data = c.emit("my_signal", "\01\00\02") self.assertEqual(data, "\02\00\01") - + +class SigPropClass(gobject.GObject): + __gsignals__ = { 'my_signal': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + (gobject.TYPE_INT,)) } + + __gproperties__ = { + 'foo': (str, None, None, '', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT), + } + + signal_emission_failed = False + + def do_my_signal(self, arg): + self.arg = arg + + def do_set_property(self, pspec, value): + if pspec.name == 'foo': + self._foo = value + else: + raise AttributeError, 'unknown property %s' % pspec.name + try: + self.emit("my-signal", 1) + except TypeError: + self.signal_emission_failed = True + + +class TestSigProp(unittest.TestCase): + def testEmitInPropertySetter(self): + obj = SigPropClass() + self.failIf(obj.signal_emission_failed) if __name__ == '__main__': unittest.main() -- cgit