Imported Upstream version 3.21.0
[platform/upstream/python-gobject.git] / gi / pygobject.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * pygtk- Python bindings for the GTK toolkit.
3  * Copyright (C) 1998-2003  James Henstridge
4  *
5  *   pygobject.c: wrapper for the GObject type.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <pyglib.h>
26 #include "pygobject-private.h"
27 #include "pyginterface.h"
28 #include "pygparamspec.h"
29
30 #include "pygi.h"
31 #include "pygi-value.h"
32 #include "pygi-type.h"
33 #include "pygi-property.h"
34 #include "pygi-signal-closure.h"
35
36 static void pygobject_dealloc(PyGObject *self);
37 static int  pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
38 static int  pygobject_clear(PyGObject *self);
39 static PyObject * pyg_type_get_bases(GType gtype);
40 static inline int pygobject_clear(PyGObject *self);
41 static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
42 static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
43 static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases,
44                                     gboolean check_for_present);
45 static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
46                                     gboolean check_for_present);
47 GType PY_TYPE_OBJECT = 0;
48 GQuark pygobject_custom_key;
49 GQuark pygobject_class_key;
50 GQuark pygobject_class_init_key;
51 GQuark pygobject_wrapper_key;
52 GQuark pygobject_has_updated_constructor_key;
53 GQuark pygobject_instance_data_key;
54
55 /* Copied from glib. gobject uses hyphens in property names, but in Python
56  * we can only represent hyphens as underscores. Convert underscores to
57  * hyphens for glib compatibility. */
58 static void
59 canonicalize_key (gchar *key)
60 {
61     gchar *p;
62
63     for (p = key; *p != 0; p++)
64     {
65         gchar c = *p;
66
67         if (c != '-' &&
68             (c < '0' || c > '9') &&
69             (c < 'A' || c > 'Z') &&
70             (c < 'a' || c > 'z'))
71                 *p = '-';
72     }
73 }
74
75 /* -------------- class <-> wrapper manipulation --------------- */
76
77 void
78 pygobject_data_free(PyGObjectData *data)
79 {
80     /* This function may be called after the python interpreter has already
81      * been shut down. If this happens, we cannot do any python calls, so just
82      * free the memory. */
83     PyGILState_STATE state;
84     PyThreadState *_save = NULL;
85     gboolean state_saved = FALSE;
86
87     GSList *closures, *tmp;
88
89     if (Py_IsInitialized()) {
90         state_saved = TRUE;
91         state = pyglib_gil_state_ensure();
92         Py_DECREF(data->type);
93         /* We cannot use Py_BEGIN_ALLOW_THREADS here because this is inside
94          * a branch. */
95         Py_UNBLOCK_THREADS; /* Modifies _save */
96     }
97
98     tmp = closures = data->closures;
99 #ifndef NDEBUG
100     data->closures = NULL;
101     data->type = NULL;
102 #endif
103     while (tmp) {
104         GClosure *closure = tmp->data;
105  
106           /* we get next item first, because the current link gets
107            * invalidated by pygobject_unwatch_closure */
108         tmp = tmp->next;
109         g_closure_invalidate(closure);
110     }
111  
112     if (data->closures != NULL)
113         g_warning("invalidated all closures, but data->closures != NULL !");
114
115     g_free(data);
116
117     if (state_saved && Py_IsInitialized ()) {
118         Py_BLOCK_THREADS; /* Restores _save */
119         pyglib_gil_state_release(state);
120     }
121 }
122
123 static inline PyGObjectData *
124 pygobject_data_new(void)
125 {
126     PyGObjectData *data;
127     data = g_new0(PyGObjectData, 1);
128     return data;
129 }
130
131 static inline PyGObjectData *
132 pygobject_get_inst_data(PyGObject *self)
133 {
134     PyGObjectData *inst_data;
135
136     if (G_UNLIKELY(!self->obj))
137         return NULL;
138     inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
139     if (inst_data == NULL)
140     {
141         inst_data = pygobject_data_new();
142
143         inst_data->type = Py_TYPE(self);
144         Py_INCREF((PyObject *) inst_data->type);
145
146         g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
147                                 inst_data, (GDestroyNotify) pygobject_data_free);
148     }
149     return inst_data;
150 }
151
152
153 PyTypeObject *PyGObject_MetaType = NULL;
154
155 /**
156  * pygobject_sink:
157  * @obj: a GObject
158  * 
159  * As Python handles reference counting for us, the "floating
160  * reference" code in GTK is not all that useful.  In fact, it can
161  * cause leaks.  This function should be called to remove the floating
162  * references on objects on construction.
163  **/
164 void
165 pygobject_sink(GObject *obj)
166 {
167     /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink().
168      * - if the object is new and owned by someone else, its ref has been sunk and
169      *   we need to keep the one from that someone and add our own "fresh ref"
170      * - if the object is not and owned by nobody, its ref is floating and we need
171      *   to transform it into a regular ref.
172      */
173     if (G_IS_INITIALLY_UNOWNED(obj)) {
174         g_object_ref_sink(obj);
175     }
176 }
177
178 typedef struct {
179     PyObject_HEAD
180     GParamSpec **props;
181     guint n_props;
182     guint index;
183 } PyGPropsIter;
184
185 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
186
187 static void
188 pyg_props_iter_dealloc(PyGPropsIter *self)
189 {
190     g_free(self->props);
191     PyObject_Del((PyObject*) self);
192 }
193
194 static PyObject*
195 pygobject_props_iter_next(PyGPropsIter *iter)
196 {
197     if (iter->index < iter->n_props)
198         return pyg_param_spec_new(iter->props[iter->index++]);
199     else {
200         PyErr_SetNone(PyExc_StopIteration);
201         return NULL;
202     }
203 }
204
205 typedef struct {
206     PyObject_HEAD
207     /* a reference to the object containing the properties */
208     PyGObject *pygobject;
209     GType      gtype;
210 } PyGProps;
211
212 static void
213 PyGProps_dealloc(PyGProps* self)
214 {
215     PyGObject *tmp;
216
217     PyObject_GC_UnTrack((PyObject*)self);
218
219     tmp = self->pygobject;
220     self->pygobject = NULL;
221     Py_XDECREF(tmp);
222
223     PyObject_GC_Del((PyObject*)self);
224 }
225
226 static PyObject*
227 build_parameter_list(GObjectClass *class)
228 {
229     GParamSpec **props;
230     guint n_props = 0, i;
231     PyObject *prop_str;
232     PyObject *props_list;
233
234     props = g_object_class_list_properties(class, &n_props);
235     props_list = PyList_New(n_props);
236     for (i = 0; i < n_props; i++) {
237         char *name;
238         name = g_strdup(g_param_spec_get_name(props[i]));
239         /* hyphens cannot belong in identifiers */
240         g_strdelimit(name, "-", '_');
241         prop_str = PYGLIB_PyUnicode_FromString(name);
242         
243         PyList_SetItem(props_list, i, prop_str);
244         g_free(name);
245     }
246
247     if (props)
248         g_free(props);
249     
250     return props_list;
251 }
252
253 static PyObject*
254 PyGProps_getattro(PyGProps *self, PyObject *attr)
255 {
256     char *attr_name, *property_name;
257     GObjectClass *class;
258     GParamSpec *pspec;
259
260     attr_name = PYGLIB_PyUnicode_AsString(attr);
261     if (!attr_name) {
262         PyErr_Clear();
263         return PyObject_GenericGetAttr((PyObject *)self, attr);
264     }
265
266     class = g_type_class_ref(self->gtype);
267
268     /* g_object_class_find_property recurses through the class hierarchy,
269      * so the resulting pspec tells us the owner_type that owns the property
270      * we're dealing with. */
271     property_name = g_strdup(attr_name);
272     canonicalize_key(property_name);
273     pspec = g_object_class_find_property(class, property_name);
274     g_free(property_name);
275     g_type_class_unref(class);
276
277     if (!pspec) {
278         return PyObject_GenericGetAttr((PyObject *)self, attr);
279     }
280
281     if (!self->pygobject) {
282         /* If we're doing it without an instance, return a GParamSpec */
283         return pyg_param_spec_new(pspec);
284     }
285
286     return pygi_get_property_value (self->pygobject, pspec);
287 }
288
289 static gboolean
290 set_property_from_pspec(GObject *obj,
291                         GParamSpec *pspec,
292                         PyObject *pvalue)
293 {
294     GValue value = { 0, };
295
296     if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
297         PyErr_Format(PyExc_TypeError,
298                      "property '%s' can only be set in constructor",
299                      pspec->name);
300         return FALSE;
301     }   
302
303     if (!(pspec->flags & G_PARAM_WRITABLE)) {
304         PyErr_Format(PyExc_TypeError,
305                      "property '%s' is not writable", pspec->name);
306         return FALSE;
307     }   
308
309     g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
310     if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
311         PyObject *pvalue_str = PyObject_Str(pvalue);
312         PyErr_Format(PyExc_TypeError,
313                      "could not convert '%s' to type '%s' when setting property '%s.%s'",
314                      PYGLIB_PyUnicode_AsString(pvalue_str),
315                      g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)),
316                      G_OBJECT_TYPE_NAME(obj),
317                      pspec->name);
318         Py_DECREF(pvalue_str);
319         return FALSE;
320     }
321
322     Py_BEGIN_ALLOW_THREADS;
323     g_object_set_property(obj, pspec->name, &value);
324     g_value_unset(&value);
325     Py_END_ALLOW_THREADS;
326
327     return TRUE;
328 }
329
330 PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps);
331
332 static int
333 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
334 {
335     GParamSpec *pspec;
336     char *attr_name, *property_name;
337     GObject *obj;
338     int ret = -1;
339     
340     if (pvalue == NULL) {
341         PyErr_SetString(PyExc_TypeError, "properties cannot be "
342                         "deleted");
343         return -1;
344     }
345
346     attr_name = PYGLIB_PyUnicode_AsString(attr);
347     if (!attr_name) {
348         PyErr_Clear();
349         return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
350     }
351
352     if (!self->pygobject) {
353         PyErr_SetString(PyExc_TypeError,
354                         "cannot set GOject properties without an instance");
355         return -1;
356     }
357
358     obj = self->pygobject->obj;
359
360     property_name = g_strdup(attr_name);
361     canonicalize_key(property_name);
362
363     /* g_object_class_find_property recurses through the class hierarchy,
364      * so the resulting pspec tells us the owner_type that owns the property
365      * we're dealing with. */
366     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj),
367                                          property_name);
368     g_free(property_name);
369     if (!pspec) {
370         return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
371     }
372     if (!pyg_gtype_is_custom (pspec->owner_type)) {
373         /* This GType is not implemented in Python: see if we can set the
374          * property via gi. */
375         ret = pygi_set_property_value (self->pygobject, pspec, pvalue);
376         if (ret == 0)
377             return 0;
378         else if (ret == -1 && PyErr_Occurred())
379             return -1;
380     }
381
382     /* This GType is implemented in Python, or we failed to set it via gi:
383      * do a straightforward set. */
384     if (!set_property_from_pspec(obj, pspec, pvalue))
385         return -1;
386                                   
387     return 0;
388 }
389
390 static int
391 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
392 {
393     if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
394         return -1;
395     return 0;
396 }
397
398 static PyObject*
399 pygobject_props_get_iter(PyGProps *self)
400 {
401     PyGPropsIter *iter;
402     GObjectClass *class;
403
404     iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
405     class = g_type_class_ref(self->gtype);
406     iter->props = g_object_class_list_properties(class, &iter->n_props);
407     iter->index = 0;
408     g_type_class_unref(class);
409     return (PyObject *) iter;
410 }
411
412 static PyObject*
413 pygobject_props_dir(PyGProps *self)
414 {
415     PyObject *ret;
416     GObjectClass *class;
417
418     class = g_type_class_ref (self->gtype);
419     ret = build_parameter_list (class);
420     g_type_class_unref (class);
421
422     return ret;
423 }
424
425 static PyMethodDef pygobject_props_methods[] = {
426     { "__dir__", (PyCFunction)pygobject_props_dir, METH_NOARGS},
427     { NULL, NULL, 0}
428 };
429
430
431 static Py_ssize_t
432 PyGProps_length(PyGProps *self)
433 {
434     GObjectClass *class;
435     GParamSpec **props;
436     guint n_props;
437     
438     class = g_type_class_ref(self->gtype);
439     props = g_object_class_list_properties(class, &n_props);
440     g_type_class_unref(class);
441     g_free(props);
442
443     return (Py_ssize_t)n_props;
444 }
445
446 static PySequenceMethods _PyGProps_as_sequence = {
447     (lenfunc) PyGProps_length,
448     0,
449     0,
450     0,
451     0,
452     0,
453     0
454 };
455
456 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject);
457
458 static PyObject *
459 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
460 {
461     PyGProps *gprops;
462
463     gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
464     if (obj == NULL || obj == Py_None) {
465         gprops->pygobject = NULL;
466         gprops->gtype = pyg_type_from_object(type);
467     } else {
468         if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
469             PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
470                             " descriptor on non-GObject instances");
471             return NULL;
472         }
473         Py_INCREF(obj);
474         gprops->pygobject = (PyGObject *) obj;
475         gprops->gtype = pyg_type_from_object(obj);
476     }
477     return (PyObject *) gprops;
478 }
479
480 /**
481  * pygobject_register_class:
482  * @dict: the module dictionary.  A reference to the type will be stored here.
483  * @type_name: not used ?
484  * @gtype: the GType of the GObject subclass.
485  * @type: the Python type object for this wrapper.
486  * @static_bases: a tuple of Python type objects that are the bases of
487  * this type
488  *
489  * This function is used to register a Python type as the wrapper for
490  * a particular GObject subclass.  It will also insert a reference to
491  * the wrapper class into the module dictionary passed as a reference,
492  * which simplifies initialisation.
493  */
494 void
495 pygobject_register_class(PyObject *dict, const gchar *type_name,
496                          GType gtype, PyTypeObject *type,
497                          PyObject *static_bases)
498 {
499     PyObject *o;
500     const char *class_name, *s;
501     PyObject *runtime_bases;
502     PyObject *bases_list, *bases, *mod_name;
503     int i;
504     
505     class_name = type->tp_name;
506     s = strrchr(class_name, '.');
507     if (s != NULL)
508         class_name = s + 1;
509
510     runtime_bases = pyg_type_get_bases(gtype);
511     if (static_bases) {
512         PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
513         bases_list = PySequence_List(static_bases);
514           /* we start at index 1 because we want to skip the primary
515            * base, otherwise we might get MRO conflict */
516         for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
517         {
518             PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
519             int contains = PySequence_Contains(bases_list, base);
520             if (contains < 0)
521                 PyErr_Print();
522             else if (!contains) {
523                 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
524 #if 0
525                     g_message("Adding missing base %s to type %s",
526                               ((PyTypeObject *)base)->tp_name, type->tp_name);
527 #endif
528                     PyList_Append(bases_list, base);
529                 }
530             }
531         }
532         bases = PySequence_Tuple(bases_list);
533         Py_DECREF(bases_list);
534         Py_DECREF(runtime_bases);
535     } else
536         bases = runtime_bases;
537
538     Py_TYPE(type) = PyGObject_MetaType;
539     type->tp_bases = bases;
540     if (G_LIKELY(bases)) {
541         type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
542         Py_INCREF(type->tp_base);
543     }
544
545     pygobject_inherit_slots(type, bases, TRUE);
546
547     if (PyType_Ready(type) < 0) {
548         g_warning ("couldn't make the type `%s' ready", type->tp_name);
549         return;
550     }
551
552     /* Set type.__module__ to the name of the module,
553      * otherwise it'll default to 'gobject', see #376099
554      */
555     s = strrchr(type->tp_name, '.');
556     if (s != NULL) {
557         mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
558         PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
559         Py_DECREF(mod_name);
560     }
561     
562     if (gtype) {
563         o = pyg_type_wrapper_new(gtype);
564         PyDict_SetItemString(type->tp_dict, "__gtype__", o);
565         Py_DECREF(o);
566
567         /* stash a pointer to the python class with the GType */
568         Py_INCREF(type);
569         g_type_set_qdata(gtype, pygobject_class_key, type);
570     }
571
572     /* set up __doc__ descriptor on type */
573     PyDict_SetItemString(type->tp_dict, "__doc__",
574                          pyg_object_descr_doc_get());
575
576     PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
577 }
578
579 static void
580 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
581 {
582     PyGObject *self;
583     PyGILState_STATE state;
584
585     state = pyglib_gil_state_ensure();
586
587     /* Avoid thread safety problems by using qdata for wrapper retrieval
588      * instead of the user data argument.
589      * See: https://bugzilla.gnome.org/show_bug.cgi?id=709223
590      */
591     self = (PyGObject *)g_object_get_qdata (object, pygobject_wrapper_key);
592     if (self) {
593         if (is_last_ref)
594             Py_DECREF(self);
595         else
596             Py_INCREF(self);
597     }
598
599     pyglib_gil_state_release(state);
600 }
601
602   /* Called when the inst_dict is first created; switches the 
603      reference counting strategy to start using toggle ref to keep the
604      wrapper alive while the GObject lives.  In contrast, while
605      inst_dict was NULL the python wrapper is allowed to die at
606      will and is recreated on demand. */
607 static inline void
608 pygobject_switch_to_toggle_ref(PyGObject *self)
609 {
610     g_assert(self->obj->ref_count >= 1);
611
612     if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF)
613         return; /* already using toggle ref */
614     self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
615       /* Note that add_toggle_ref will never immediately call back into 
616          pyg_toggle_notify */
617     Py_INCREF((PyObject *) self);
618     g_object_add_toggle_ref(self->obj, pyg_toggle_notify, NULL);
619     g_object_unref(self->obj);
620 }
621
622 /* Called when an custom gobject is initalized via g_object_new instead of
623    its constructor.  The next time the wrapper is access via 
624    pygobject_new_full it will sink the floating reference instead of
625    adding a new reference and causing a leak */
626  
627 void
628 pygobject_ref_float(PyGObject *self)
629 {
630     /* should only be floated once */
631     g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
632     
633     self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
634 }
635
636 /* Called by gobject_new_full, if the floating flag is set remove it, otherwise
637    ref the pyobject */
638 void
639 pygobject_ref_sink(PyGObject *self)
640 {
641     if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
642         self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
643     else
644         Py_INCREF ( (PyObject *) self);
645 }
646
647 /**
648  * pygobject_register_wrapper:
649  * @self: the wrapper instance
650  *
651  * In the constructor of PyGTK wrappers, this function should be
652  * called after setting the obj member.  It will tie the wrapper
653  * instance to the GObject so that the same wrapper instance will
654  * always be used for this GObject instance.
655  */
656 void
657 pygobject_register_wrapper(PyObject *self)
658 {
659     PyGObject *gself;
660
661     g_return_if_fail(self != NULL);
662     g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
663
664     gself = (PyGObject *)self;
665
666     g_assert(gself->obj->ref_count >= 1);
667       /* save wrapper pointer so we can access it later */
668     g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
669     if (gself->inst_dict)
670         pygobject_switch_to_toggle_ref(gself);
671 }
672
673 static PyObject *
674 pyg_type_get_bases(GType gtype)
675 {
676     GType *interfaces, parent_type, interface_type;
677     guint n_interfaces;
678     PyTypeObject *py_parent_type, *py_interface_type;
679     PyObject *bases;
680     int i;
681     
682     if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
683         return NULL;
684
685     /* Lookup the parent type */
686     parent_type = g_type_parent(gtype);
687     py_parent_type = pygobject_lookup_class(parent_type);
688     interfaces = g_type_interfaces(gtype, &n_interfaces);
689     bases = PyTuple_New(n_interfaces + 1);
690     /* We will always put the parent at the first position in bases */
691     Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
692     PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
693
694     /* And traverse interfaces */
695     if (n_interfaces) {
696         for (i = 0; i < n_interfaces; i++) {
697             interface_type = interfaces[i];
698             py_interface_type = pygobject_lookup_class(interface_type);
699             Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
700             PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
701         }
702     }
703     g_free(interfaces);
704     return bases;
705 }
706
707 /**
708  * pygobject_new_with_interfaces
709  * @gtype: the GType of the GObject subclass.
710  *
711  * Creates a new PyTypeObject from the given GType with interfaces attached in
712  * bases.
713  *
714  * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
715  */
716 static PyTypeObject *
717 pygobject_new_with_interfaces(GType gtype)
718 {
719     PyGILState_STATE state;
720     PyObject *o;
721     PyTypeObject *type;
722     PyObject *dict;
723     PyTypeObject *py_parent_type;
724     PyObject *bases;
725
726     state = pyglib_gil_state_ensure();
727
728     bases = pyg_type_get_bases(gtype);
729     py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
730
731     dict = PyDict_New();
732     
733     o = pyg_type_wrapper_new(gtype);
734     PyDict_SetItemString(dict, "__gtype__", o);
735     Py_DECREF(o);
736
737     /* set up __doc__ descriptor on type */
738     PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
739
740     /* Something special to point out that it's not accessible through
741      * gi.repository */
742     o = PYGLIB_PyUnicode_FromString ("__gi__");
743     PyDict_SetItemString (dict, "__module__", o);
744     Py_DECREF (o);
745
746     type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
747                                                 "sNN", g_type_name (gtype), bases, dict);
748
749     if (type == NULL) {
750         PyErr_Print();
751         pyglib_gil_state_release(state);
752         return NULL;
753     }
754
755       /* Workaround python tp_(get|set)attr slot inheritance bug.
756        * Fixes bug #144135. */
757     if (!type->tp_getattr && py_parent_type->tp_getattr) {
758         type->tp_getattro = NULL;
759         type->tp_getattr = py_parent_type->tp_getattr;
760     }
761     if (!type->tp_setattr && py_parent_type->tp_setattr) {
762         type->tp_setattro = NULL;
763         type->tp_setattr = py_parent_type->tp_setattr;
764     }
765       /* override more python stupid hacks behind our back */
766     type->tp_dealloc = py_parent_type->tp_dealloc;
767     type->tp_alloc = py_parent_type->tp_alloc;
768     type->tp_free = py_parent_type->tp_free;
769     type->tp_traverse = py_parent_type->tp_traverse;
770     type->tp_clear = py_parent_type->tp_clear;
771
772     pygobject_inherit_slots(type, bases, FALSE);
773
774     if (PyType_Ready(type) < 0) {
775         g_warning ("couldn't make the type `%s' ready", type->tp_name);
776         pyglib_gil_state_release(state);
777         return NULL;
778     }
779
780     /* stash a pointer to the python class with the GType */
781     Py_INCREF(type);
782     g_type_set_qdata(gtype, pygobject_class_key, type);
783
784     pyglib_gil_state_release(state);
785
786     return type;
787 }
788
789 /* Pick appropriate value for given slot (at slot_offset inside
790  * PyTypeObject structure).  It must be a pointer, e.g. a pointer to a
791  * function.  We use the following heuristic:
792  *
793  * - Scan all types listed as bases of the type.
794  * - If for exactly one base type slot value is non-NULL and
795  *   different from that of 'object' and 'GObject', set current type
796  *   slot into that value.
797  * - Otherwise (if there is more than one such base type or none at
798  *   all) don't touch it and live with Python default.
799  *
800  * The intention here is to propagate slot from custom wrappers to
801  * wrappers created at runtime when appropriate.  We prefer to be on
802  * the safe side, so if there is potential collision (more than one
803  * custom slot value), we discard custom overrides altogether.
804  *
805  * When registering type with pygobject_register_class(), i.e. a type
806  * that has been manually created (likely with Codegen help),
807  * `check_for_present' should be set to TRUE.  In this case, the
808  * function will never overwrite any non-NULL slots already present in
809  * the type.  If `check_for_present' is FALSE, such non-NULL slots are
810  * though to be set by Python interpreter and so will be overwritten
811  * if heuristic above says so.
812  */
813 static void
814 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
815 {
816     static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
817 #if PY_VERSION_HEX < 0x03000000
818                                   offsetof(PyTypeObject, tp_compare),
819 #endif
820                                   offsetof(PyTypeObject, tp_richcompare),
821                                   offsetof(PyTypeObject, tp_hash),
822                                   offsetof(PyTypeObject, tp_iter),
823                                   offsetof(PyTypeObject, tp_repr),
824                                   offsetof(PyTypeObject, tp_str),
825                                   offsetof(PyTypeObject, tp_print) };
826     int i;
827
828     /* Happens when registering gobject.GObject itself, at least. */
829     if (!bases)
830         return;
831
832     for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
833         pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
834 }
835
836 static void
837 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
838                         gboolean check_for_present)
839 {
840 #define TYPE_SLOT(type)  (* (void **) (((char *) (type)) + slot_offset))
841
842     void *found_slot = NULL;
843     int num_bases = PyTuple_Size(bases);
844     int i;
845
846     if (check_for_present && TYPE_SLOT(type) != NULL) {
847         /* We are requested to check if there is any custom slot value
848          * in this type already and there actually is.  Don't
849          * overwrite it.
850          */
851         return;
852     }
853
854     for (i = 0; i < num_bases; ++i) {
855         PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
856         void *slot = TYPE_SLOT(base_type);
857
858         if (slot == NULL)
859             continue;
860         if (slot == TYPE_SLOT(&PyGObject_Type) ||
861             slot == TYPE_SLOT(&PyBaseObject_Type))
862             continue;
863
864         if (found_slot != NULL && found_slot != slot) {
865             /* We have a conflict: more than one base use different
866              * custom slots.  To be on the safe side, we bail out.
867              */
868             return;
869         }
870
871         found_slot = slot;
872     }
873
874     /* Only perform the final assignment if at least one base has a
875      * custom value.  Otherwise just leave this type's slot untouched.
876      */
877     if (found_slot != NULL)
878         TYPE_SLOT(type) = found_slot;
879
880 #undef TYPE_SLOT
881 }
882
883 /**
884  * pygobject_lookup_class:
885  * @gtype: the GType of the GObject subclass.
886  *
887  * This function looks up the wrapper class used to represent
888  * instances of a GObject represented by @gtype.  If no wrapper class
889  * or interface has been registered for the given GType, then a new
890  * type will be created.
891  *
892  * Returns: The wrapper class for the GObject or NULL if the
893  *          GType has no registered type and a new type couldn't be created
894  */
895 PyTypeObject *
896 pygobject_lookup_class(GType gtype)
897 {
898     PyTypeObject *py_type;
899
900     if (gtype == G_TYPE_INTERFACE)
901         return &PyGInterface_Type;
902     
903     py_type = g_type_get_qdata(gtype, pygobject_class_key);
904     if (py_type == NULL) {
905         py_type = g_type_get_qdata(gtype, pyginterface_type_key);
906
907     if (py_type == NULL)
908         py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
909
910         if (py_type == NULL) {
911             py_type = pygobject_new_with_interfaces(gtype);
912             g_type_set_qdata(gtype, pyginterface_type_key, py_type);
913         }
914     }
915     
916     return py_type;
917 }
918
919 /**
920  * pygobject_new_full:
921  * @obj: a GObject instance.
922  * @steal: whether to steal a ref from the GObject or add (sink) a new one.
923  * @g_class: the GObjectClass
924  *
925  * This function gets a reference to a wrapper for the given GObject
926  * instance.  If a wrapper has already been created, a new reference
927  * to that wrapper will be returned.  Otherwise, a wrapper instance
928  * will be created.
929  *
930  * Returns: a reference to the wrapper for the GObject.
931  */
932 PyObject *
933 pygobject_new_full(GObject *obj, gboolean steal, gpointer g_class)
934 {
935     PyGObject *self;
936
937     if (obj == NULL) {
938         Py_RETURN_NONE;
939     }
940
941     /* If the GObject already has a PyObject wrapper stashed in its qdata, re-use it.
942      */
943     self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
944     if (self != NULL) {
945         /* Note the use of "pygobject_ref_sink" here only deals with PyObject
946          * wrapper ref counts and has nothing to do with GObject.
947          */
948         pygobject_ref_sink(self);
949
950         /* If steal is true, we also want to decref the incoming GObjects which
951          * already have a Python wrapper because the wrapper is already holding a
952          * strong reference.
953          */
954         if (steal)
955             g_object_unref (obj);
956
957     } else {
958         /* create wrapper */
959         PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
960         PyTypeObject *tp;
961         if (inst_data)
962             tp = inst_data->type;
963         else {
964             if (g_class)
965                 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
966             else
967                 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
968         }
969         g_assert(tp != NULL);
970         
971         /* need to bump type refcount if created with
972            pygobject_new_with_interfaces(). fixes bug #141042 */
973         if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
974             Py_INCREF(tp);
975         self = PyObject_GC_New(PyGObject, tp);
976         if (self == NULL)
977             return NULL;
978         self->inst_dict = NULL;
979         self->weakreflist = NULL;
980         self->private_flags.flags = 0;
981         self->obj = obj;
982
983         /* If we are not stealing a ref or the object is floating,
984          * add a regular ref or sink the object. */
985         if (g_object_is_floating (obj))
986             self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING;
987         if (!steal || self->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING)
988             g_object_ref_sink (obj);
989
990         pygobject_register_wrapper((PyObject *)self);
991         PyObject_GC_Track((PyObject *)self);
992     }
993
994     return (PyObject *)self;
995 }
996
997
998 PyObject *
999 pygobject_new(GObject *obj)
1000 {
1001     return pygobject_new_full(obj,
1002                               /*steal=*/FALSE,
1003                               NULL);
1004 }
1005
1006 static void
1007 pygobject_unwatch_closure(gpointer data, GClosure *closure)
1008 {
1009     PyGObjectData *inst_data = data;
1010
1011     inst_data->closures = g_slist_remove (inst_data->closures, closure);
1012 }
1013
1014 /**
1015  * pygobject_watch_closure:
1016  * @self: a GObject wrapper instance
1017  * @closure: a GClosure to watch
1018  *
1019  * Adds a closure to the list of watched closures for the wrapper.
1020  * The closure must be one returned by pyg_closure_new().  When the
1021  * cycle GC traverses the wrapper instance, it will enumerate the
1022  * references to Python objects stored in watched closures.  If the
1023  * cycle GC tells the wrapper to clear itself, the watched closures
1024  * will be invalidated.
1025  */
1026 void
1027 pygobject_watch_closure(PyObject *self, GClosure *closure)
1028 {
1029     PyGObject *gself;
1030     PyGObjectData *data;
1031
1032     g_return_if_fail(self != NULL);
1033     g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
1034     g_return_if_fail(closure != NULL);
1035
1036     gself = (PyGObject *)self;
1037     data = pygobject_get_inst_data(gself);
1038     g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
1039     data->closures = g_slist_prepend(data->closures, closure);
1040     g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
1041 }
1042
1043
1044 /* -------------- PyGObject behaviour ----------------- */
1045
1046 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
1047
1048 static void
1049 pygobject_dealloc(PyGObject *self)
1050 {
1051     /* Untrack must be done first. This is because followup calls such as
1052      * ClearWeakRefs could call into Python and cause new allocations to
1053      * happen, which could in turn could trigger the garbage collector,
1054      * which would then get confused as it is tracking this half-deallocated
1055      * object. */
1056     PyObject_GC_UnTrack((PyObject *)self);
1057
1058     PyObject_ClearWeakRefs((PyObject *)self);
1059       /* this forces inst_data->type to be updated, which could prove
1060        * important if a new wrapper has to be created and it is of a
1061        * unregistered type */
1062     pygobject_get_inst_data(self);
1063     pygobject_clear(self);
1064     /* the following causes problems with subclassed types */
1065     /* Py_TYPE(self)->tp_free((PyObject *)self); */
1066     PyObject_GC_Del(self);
1067 }
1068
1069 static PyObject*
1070 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1071 {
1072     int isinst;
1073
1074     isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1075     if (isinst == -1)
1076         return NULL;
1077     if (!isinst) {
1078         Py_INCREF(Py_NotImplemented);
1079         return Py_NotImplemented;
1080     }
1081     isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1082     if (isinst == -1)
1083         return NULL;
1084     if (!isinst) {
1085         Py_INCREF(Py_NotImplemented);
1086         return Py_NotImplemented;
1087     }
1088
1089     return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1090                                            ((PyGObject*)other)->obj,
1091                                            op);
1092 }
1093
1094 static long
1095 pygobject_hash(PyGObject *self)
1096 {
1097     return (long)self->obj;
1098 }
1099
1100 static PyObject *
1101 pygobject_repr(PyGObject *self)
1102 {
1103     PyObject *module, *repr;
1104     gchar *module_str, *namespace;
1105
1106     module = PyObject_GetAttrString ((PyObject *)self, "__module__");
1107     if (module == NULL)
1108         return NULL;
1109
1110     if (!PYGLIB_PyUnicode_Check (module)) {
1111         Py_DECREF (module);
1112         return NULL;
1113     }
1114
1115     module_str = PYGLIB_PyUnicode_AsString (module);
1116     namespace = g_strrstr (module_str, ".");
1117     if (namespace == NULL) {
1118         namespace = module_str;
1119     } else {
1120         namespace += 1;
1121     }
1122
1123     repr = PYGLIB_PyUnicode_FromFormat ("<%s.%s object at %p (%s at %p)>",
1124                                         namespace, Py_TYPE (self)->tp_name, self,
1125                                         self->obj ? G_OBJECT_TYPE_NAME (self->obj) : "uninitialized",
1126                                         self->obj);
1127     Py_DECREF (module);
1128     return repr;
1129 }
1130
1131
1132 static int
1133 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1134 {
1135     int ret = 0;
1136     GSList *tmp;
1137     PyGObjectData *data = pygobject_get_inst_data(self);
1138
1139     if (self->inst_dict) ret = visit(self->inst_dict, arg);
1140     if (ret != 0) return ret;
1141
1142     if (data) {
1143
1144         for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1145             PyGClosure *closure = tmp->data;
1146
1147             if (closure->callback) ret = visit(closure->callback, arg);
1148             if (ret != 0) return ret;
1149
1150             if (closure->extra_args) ret = visit(closure->extra_args, arg);
1151             if (ret != 0) return ret;
1152
1153             if (closure->swap_data) ret = visit(closure->swap_data, arg);
1154             if (ret != 0) return ret;
1155         }
1156     }
1157     return ret;
1158 }
1159
1160 static inline int
1161 pygobject_clear(PyGObject *self)
1162 {
1163     if (self->obj) {
1164         g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1165         if (self->inst_dict) {
1166             g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, NULL);
1167             self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1168         } else {
1169             Py_BEGIN_ALLOW_THREADS;
1170             g_object_unref(self->obj);
1171             Py_END_ALLOW_THREADS;
1172         }
1173         self->obj = NULL;
1174     }
1175     Py_CLEAR(self->inst_dict);
1176     return 0;
1177 }
1178
1179 static void
1180 pygobject_free(PyObject *op)
1181 {
1182     PyObject_GC_Del(op);
1183 }
1184
1185 gboolean
1186 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1187                                        guint *n_params, GParameter **params)
1188 {
1189     *n_params = 0;
1190     *params = NULL;
1191
1192     if (kwargs) {
1193         Py_ssize_t pos = 0;
1194         PyObject *key;
1195         PyObject *value;
1196
1197         *params = g_new0(GParameter, PyDict_Size(kwargs));
1198         while (PyDict_Next(kwargs, &pos, &key, &value)) {
1199             GParamSpec *pspec;
1200             GParameter *param = &(*params)[*n_params];
1201             const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1202
1203             pspec = g_object_class_find_property(class, key_str);
1204             if (!pspec) {
1205                 PyErr_Format(PyExc_TypeError,
1206                              "gobject `%s' doesn't support property `%s'",
1207                              G_OBJECT_CLASS_NAME(class), key_str);
1208                 return FALSE;
1209             }
1210             g_value_init(&param->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1211             if (pyg_param_gvalue_from_pyobject(&param->value, value, pspec) < 0) {
1212                 PyErr_Format(PyExc_TypeError,
1213                              "could not convert value for property `%s' from %s to %s",
1214                              key_str, Py_TYPE(value)->tp_name,
1215                              g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1216                 return FALSE;
1217             }
1218             param->name = g_strdup(key_str);
1219             ++(*n_params);
1220         }
1221     }
1222     return TRUE;
1223 }
1224
1225 /* ---------------- PyGObject methods ----------------- */
1226
1227 static int
1228 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1229 {
1230     GType object_type;
1231     guint n_params = 0, i;
1232     GParameter *params = NULL;
1233     GObjectClass *class;
1234
1235     /* Only do GObject creation and property setting if the GObject hasn't
1236      * already been created. The case where self->obj already exists can occur
1237      * when C constructors are called directly (Gtk.Button.new_with_label)
1238      * and we are simply wrapping the result with a PyGObject.
1239      * In these cases we want to ignore any keyword arguments passed along
1240      * to __init__ and simply return.
1241      *
1242      * See: https://bugzilla.gnome.org/show_bug.cgi?id=705810
1243      */
1244     if (self->obj != NULL)
1245         return 0;
1246
1247     if (!PyArg_ParseTuple(args, ":GObject.__init__", NULL))
1248         return -1;
1249
1250     object_type = pyg_type_from_object((PyObject *)self);
1251     if (!object_type)
1252         return -1;
1253
1254     if (G_TYPE_IS_ABSTRACT(object_type)) {
1255         PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1256                      "(non-instantiable) type `%s'", g_type_name(object_type));
1257         return -1;
1258     }
1259
1260     if ((class = g_type_class_ref (object_type)) == NULL) {
1261         PyErr_SetString(PyExc_TypeError,
1262                         "could not get a reference to type class");
1263         return -1;
1264     }
1265
1266     if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, &params))
1267         goto cleanup;
1268
1269     if (pygobject_constructv(self, n_params, params))
1270         PyErr_SetString(PyExc_RuntimeError, "could not create object");
1271
1272  cleanup:
1273     for (i = 0; i < n_params; i++) {
1274         g_free((gchar *) params[i].name);
1275         g_value_unset(&params[i].value);
1276     }
1277     g_free(params);
1278     g_type_class_unref(class);
1279     
1280     return (self->obj) ? 0 : -1;
1281 }
1282
1283 #define CHECK_GOBJECT(self) \
1284     if (!G_IS_OBJECT(self->obj)) {                                           \
1285         PyErr_Format(PyExc_TypeError,                                        \
1286                      "object at %p of type %s is not initialized",           \
1287                      self, Py_TYPE(self)->tp_name);                          \
1288         return NULL;                                                         \
1289     }
1290
1291 static PyObject *
1292 pygobject_get_property (PyGObject *self, PyObject *args)
1293 {
1294     gchar *param_name;
1295
1296     if (!PyArg_ParseTuple (args, "s:GObject.get_property", &param_name)) {
1297         return NULL;
1298     }
1299
1300     CHECK_GOBJECT(self);
1301
1302     return pygi_get_property_value_by_name (self, param_name);
1303 }
1304
1305 static PyObject *
1306 pygobject_get_properties(PyGObject *self, PyObject *args)
1307 {
1308     int len, i;
1309     PyObject *tuple;
1310
1311     if ((len = PyTuple_Size(args)) < 1) {
1312         PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1313         return NULL;
1314     }
1315
1316     tuple = PyTuple_New(len);
1317     for (i = 0; i < len; i++) {
1318         PyObject *py_property = PyTuple_GetItem(args, i);
1319         gchar *property_name;
1320         PyObject *item;
1321
1322         if (!PYGLIB_PyUnicode_Check(py_property)) {
1323             PyErr_SetString(PyExc_TypeError,
1324                             "Expected string argument for property.");
1325             goto fail;
1326         }
1327
1328         property_name = PYGLIB_PyUnicode_AsString(py_property);
1329         item = pygi_get_property_value_by_name (self, property_name);
1330         PyTuple_SetItem (tuple, i, item);
1331     }
1332
1333     return tuple;
1334
1335 fail:
1336     Py_DECREF (tuple);
1337     return NULL;
1338 }
1339
1340 static PyObject *
1341 pygobject_set_property(PyGObject *self, PyObject *args)
1342 {
1343     gchar *param_name;
1344     GParamSpec *pspec;
1345     PyObject *pvalue;
1346     int ret = -1;
1347
1348     if (!PyArg_ParseTuple(args, "sO:GObject.set_property", &param_name,
1349                           &pvalue))
1350         return NULL;
1351     
1352     CHECK_GOBJECT(self);
1353     
1354     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1355                                          param_name);
1356     if (!pspec) {
1357         PyErr_Format(PyExc_TypeError,
1358                      "object of type `%s' does not have property `%s'",
1359                      g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1360         return NULL;
1361     }
1362     
1363     ret = pygi_set_property_value (self, pspec, pvalue);
1364     if (ret == 0)
1365         goto done;
1366     else if (PyErr_Occurred())
1367         return  NULL;
1368
1369     if (!set_property_from_pspec(self->obj, pspec, pvalue))
1370         return NULL;
1371
1372 done:
1373
1374     Py_INCREF(Py_None);
1375     return Py_None;
1376 }
1377
1378 static PyObject *
1379 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1380 {    
1381     GObjectClass    *class;
1382     Py_ssize_t      pos;
1383     PyObject        *value;
1384     PyObject        *key;
1385     PyObject        *result = NULL;
1386
1387     CHECK_GOBJECT(self);
1388
1389     class = G_OBJECT_GET_CLASS(self->obj);
1390     
1391     g_object_freeze_notify (G_OBJECT(self->obj));
1392     pos = 0;
1393
1394     while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1395         gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1396         GParamSpec *pspec;
1397         int ret = -1;
1398
1399         pspec = g_object_class_find_property(class, key_str);
1400         if (!pspec) {
1401             gchar buf[512];
1402
1403             g_snprintf(buf, sizeof(buf),
1404                        "object `%s' doesn't support property `%s'",
1405                        g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1406             PyErr_SetString(PyExc_TypeError, buf);
1407             goto exit;
1408         }
1409
1410         ret = pygi_set_property_value (self, pspec, value);
1411         if (ret != 0) {
1412             /* Non-zero return code means that either an error occured ...*/
1413             if (PyErr_Occurred())
1414                 goto exit;
1415
1416             /* ... or the property couldn't be found , so let's try the default
1417              * call. */
1418             if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value))
1419                 goto exit;
1420         }
1421     }
1422
1423     result = Py_None;
1424
1425  exit:
1426     g_object_thaw_notify (G_OBJECT(self->obj));
1427     Py_XINCREF(result);
1428     return result;
1429 }
1430
1431 /* custom closure for gobject bindings */
1432 static void
1433 pygbinding_closure_invalidate(gpointer data, GClosure *closure)
1434 {
1435     PyGClosure *pc = (PyGClosure *)closure;
1436     PyGILState_STATE state;
1437
1438     state = pyglib_gil_state_ensure();
1439     Py_XDECREF(pc->callback);
1440     Py_XDECREF(pc->extra_args);
1441     pyglib_gil_state_release(state);
1442
1443     pc->callback = NULL;
1444     pc->extra_args = NULL;
1445 }
1446
1447 static void
1448 pygbinding_marshal (GClosure     *closure,
1449                     GValue       *return_value,
1450                     guint         n_param_values,
1451                     const GValue *param_values,
1452                     gpointer      invocation_hint,
1453                     gpointer      marshal_data)
1454 {
1455     PyGILState_STATE state;
1456     PyGClosure *pc = (PyGClosure *)closure;
1457     PyObject *params, *ret;
1458     GValue *out_value;
1459
1460     state = pyglib_gil_state_ensure();
1461
1462     /* construct Python tuple for the parameter values */
1463     params = PyTuple_New(2);
1464     PyTuple_SetItem (params, 0, pyg_value_as_pyobject(&param_values[0], FALSE));
1465     PyTuple_SetItem (params, 1, pyg_value_as_pyobject(&param_values[1], FALSE));
1466
1467     /* params passed to function may have extra arguments */
1468     if (pc->extra_args) {
1469         PyObject *tuple = params;
1470         params = PySequence_Concat(tuple, pc->extra_args);
1471         Py_DECREF(tuple);
1472     }
1473     ret = PyObject_CallObject(pc->callback, params);
1474     if (!ret) {
1475         PyErr_Print ();
1476         goto out;
1477     } else if (ret == Py_None) {
1478         g_value_set_boolean (return_value, FALSE);
1479         goto out;
1480     }
1481
1482     out_value = g_value_get_boxed (&param_values[2]);
1483     if (pyg_value_from_pyobject (out_value, ret) != 0) {
1484         PyErr_SetString (PyExc_ValueError, "can't convert value");
1485         PyErr_Print ();
1486         g_value_set_boolean (return_value, FALSE);
1487     } else {
1488         g_value_set_boolean (return_value, TRUE);
1489     }
1490
1491     Py_DECREF(ret);
1492
1493 out:
1494     Py_DECREF(params);
1495     pyglib_gil_state_release(state);
1496 }
1497
1498 static GClosure *
1499 pygbinding_closure_new (PyObject *callback, PyObject *extra_args)
1500 {
1501     GClosure *closure;
1502
1503     g_return_val_if_fail(callback != NULL, NULL);
1504     closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
1505     g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate);
1506     g_closure_set_marshal(closure, pygbinding_marshal);
1507     Py_INCREF(callback);
1508     ((PyGClosure *)closure)->callback = callback;
1509     if (extra_args && extra_args != Py_None) {
1510         Py_INCREF(extra_args);
1511         if (!PyTuple_Check(extra_args)) {
1512             PyObject *tmp = PyTuple_New(1);
1513             PyTuple_SetItem(tmp, 0, extra_args);
1514             extra_args = tmp;
1515         }
1516         ((PyGClosure *)closure)->extra_args = extra_args;
1517     }
1518     return closure;
1519 }
1520
1521 static PyObject *
1522 pygobject_bind_property(PyGObject *self, PyObject *args)
1523 {
1524         gchar *source_name, *target_name;
1525         gchar *source_canon, *target_canon;
1526         PyObject *target, *source_repr, *target_repr;
1527         PyObject *transform_to, *transform_from, *user_data = NULL;
1528         GBinding *binding;
1529         GBindingFlags flags = G_BINDING_DEFAULT;
1530         GClosure *to_closure = NULL, *from_closure = NULL;
1531
1532         transform_from = NULL;
1533         transform_to = NULL;
1534
1535         if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property",
1536                               &source_name, &target, &target_name, &flags,
1537                               &transform_to, &transform_from, &user_data))
1538                 return NULL;
1539
1540         CHECK_GOBJECT(self);
1541         if (!PyObject_TypeCheck(target, &PyGObject_Type)) {
1542                 PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject");
1543                 return NULL;
1544         }
1545
1546         if (transform_to && transform_to != Py_None) {
1547                 if (!PyCallable_Check (transform_to)) {
1548                         PyErr_SetString (PyExc_TypeError,
1549                                          "transform_to must be callable or None");
1550                         return NULL;
1551                 }
1552                 to_closure = pygbinding_closure_new (transform_to, user_data);
1553         }
1554
1555         if (transform_from && transform_from != Py_None) {
1556                 if (!PyCallable_Check (transform_from)) {
1557                         PyErr_SetString (PyExc_TypeError,
1558                                          "transform_from must be callable or None");
1559                         return NULL;
1560                 }
1561                 from_closure = pygbinding_closure_new (transform_from, user_data);
1562         }
1563
1564         /* Canonicalize underscores to hyphens. Note the results must be freed. */
1565         source_canon = g_strdelimit(g_strdup(source_name), "_", '-');
1566         target_canon = g_strdelimit(g_strdup(target_name), "_", '-');
1567
1568         binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon,
1569                                                         pygobject_get(target), target_canon,
1570                                                         flags, to_closure, from_closure);
1571         g_free(source_canon);
1572         g_free(target_canon);
1573         source_canon = target_canon = NULL;
1574
1575         if (binding == NULL) {
1576                 source_repr = PyObject_Repr((PyObject*)self);
1577                 target_repr = PyObject_Repr(target);
1578                 PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s",
1579                              PYGLIB_PyUnicode_AsString(source_repr), source_name,
1580                              PYGLIB_PyUnicode_AsString(target_repr), target_name);
1581                 Py_DECREF(source_repr);
1582                 Py_DECREF(target_repr);
1583                 return NULL;
1584         }
1585
1586         return pygobject_new (G_OBJECT (binding));
1587 }
1588
1589 static PyObject *
1590 connect_helper(PyGObject *self, gchar *name, PyObject *callback, PyObject *extra_args, PyObject *object, gboolean after)
1591 {
1592     guint sigid;
1593     GQuark detail = 0;
1594     GClosure *closure = NULL;
1595     gulong handlerid;
1596     GSignalQuery query_info;
1597
1598     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1599                              &sigid, &detail, TRUE)) {
1600         PyObject *repr = PyObject_Repr((PyObject*)self);
1601         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1602                      PYGLIB_PyUnicode_AsString(repr),
1603                      name);
1604         Py_DECREF(repr);
1605         return NULL;
1606     }
1607
1608     if (object && !PyObject_TypeCheck (object, &PyGObject_Type)) {
1609         if (PyErr_WarnEx (PyGIDeprecationWarning,
1610                           "Using non GObject arguments for connect_object() is deprecated, use: "
1611                           "connect_data(signal, callback, data, connect_flags=GObject.ConnectFlags.SWAPPED)",
1612                           1)) {
1613             return NULL;
1614         }
1615     }
1616
1617     g_signal_query (sigid, &query_info);
1618     if (!pyg_gtype_is_custom (query_info.itype)) {
1619         /* The signal is implemented by a non-Python class, probably
1620          * something in the gi repository. */
1621         closure = pygi_signal_closure_new (self, query_info.itype,
1622                                            query_info.signal_name, callback,
1623                                            extra_args, object);
1624     }
1625
1626     if (!closure) {
1627         /* The signal is either implemented at the Python level, or it comes
1628          * from a foreign class that we don't have introspection data for. */
1629         closure = pyg_closure_new (callback, extra_args, object);
1630     }
1631
1632     pygobject_watch_closure((PyObject *)self, closure);
1633     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1634                                                closure, after);
1635     return PyLong_FromUnsignedLong(handlerid);
1636 }
1637
1638 static PyObject *
1639 pygobject_connect(PyGObject *self, PyObject *args)
1640 {
1641     PyObject *first, *callback, *extra_args, *ret;
1642     gchar *name;
1643     guint len;
1644
1645     len = PyTuple_Size(args);
1646     if (len < 2) {
1647         PyErr_SetString(PyExc_TypeError,
1648                         "GObject.connect requires at least 2 arguments");
1649         return NULL;
1650     }
1651     first = PySequence_GetSlice(args, 0, 2);
1652     if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1653         Py_DECREF(first);
1654         return NULL;
1655     }
1656     Py_DECREF(first);
1657     if (!PyCallable_Check(callback)) {
1658         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1659         return NULL;
1660     }
1661     
1662     CHECK_GOBJECT(self);
1663     
1664     extra_args = PySequence_GetSlice(args, 2, len);
1665     if (extra_args == NULL)
1666         return NULL;
1667
1668     ret = connect_helper(self, name, callback, extra_args, NULL, FALSE);
1669     Py_DECREF(extra_args);
1670     return ret;
1671 }
1672
1673 static PyObject *
1674 pygobject_connect_after(PyGObject *self, PyObject *args)
1675 {
1676     PyObject *first, *callback, *extra_args, *ret;
1677     gchar *name;
1678     Py_ssize_t len;
1679
1680     len = PyTuple_Size(args);
1681     if (len < 2) {
1682         PyErr_SetString(PyExc_TypeError,
1683                         "GObject.connect_after requires at least 2 arguments");
1684         return NULL;
1685     }
1686     first = PySequence_GetSlice(args, 0, 2);
1687     if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1688                           &name, &callback)) {
1689         Py_DECREF(first);
1690         return NULL;
1691     }
1692     Py_DECREF(first);
1693     if (!PyCallable_Check(callback)) {
1694         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1695         return NULL;
1696     }
1697     
1698     CHECK_GOBJECT(self);
1699     
1700     extra_args = PySequence_GetSlice(args, 2, len);
1701     if (extra_args == NULL)
1702         return NULL;
1703
1704     ret = connect_helper(self, name, callback, extra_args, NULL, TRUE);
1705     Py_DECREF(extra_args);
1706     return ret;
1707 }
1708
1709 static PyObject *
1710 pygobject_connect_object(PyGObject *self, PyObject *args)
1711 {
1712     PyObject *first, *callback, *extra_args, *object, *ret;
1713     gchar *name;
1714     Py_ssize_t len;
1715
1716     len = PyTuple_Size(args);
1717     if (len < 3) {
1718         PyErr_SetString(PyExc_TypeError,
1719                 "GObject.connect_object requires at least 3 arguments");
1720         return NULL;
1721     }
1722     first = PySequence_GetSlice(args, 0, 3);
1723     if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1724                           &name, &callback, &object)) {
1725         Py_DECREF(first);
1726         return NULL;
1727     }
1728     Py_DECREF(first);
1729     if (!PyCallable_Check(callback)) {
1730         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1731         return NULL;
1732     }
1733     
1734     CHECK_GOBJECT(self);
1735     
1736     extra_args = PySequence_GetSlice(args, 3, len);
1737     if (extra_args == NULL)
1738         return NULL;
1739
1740     ret = connect_helper(self, name, callback, extra_args, object, FALSE);
1741     Py_DECREF(extra_args);
1742     return ret;
1743 }
1744
1745 static PyObject *
1746 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1747 {
1748     PyObject *first, *callback, *extra_args, *object, *ret;
1749     gchar *name;
1750     Py_ssize_t len;
1751
1752     len = PyTuple_Size(args);
1753     if (len < 3) {
1754         PyErr_SetString(PyExc_TypeError,
1755                 "GObject.connect_object_after requires at least 3 arguments");
1756         return NULL;
1757     }
1758     first = PySequence_GetSlice(args, 0, 3);
1759     if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1760                           &name, &callback, &object)) {
1761         Py_DECREF(first);
1762         return NULL;
1763     }
1764     Py_DECREF(first);
1765     if (!PyCallable_Check(callback)) {
1766         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1767         return NULL;
1768     }
1769     
1770     CHECK_GOBJECT(self);
1771     
1772     extra_args = PySequence_GetSlice(args, 3, len);
1773     if (extra_args == NULL)
1774         return NULL;
1775
1776     ret = connect_helper(self, name, callback, extra_args, object, TRUE);
1777     Py_DECREF(extra_args);
1778     return ret;
1779 }
1780
1781 static PyObject *
1782 pygobject_emit(PyGObject *self, PyObject *args)
1783 {
1784     guint signal_id, i, j;
1785     Py_ssize_t len;
1786     GQuark detail;
1787     PyObject *first, *py_ret, *repr = NULL;
1788     gchar *name;
1789     GSignalQuery query;
1790     GValue *params, ret = { 0, };
1791     
1792     len = PyTuple_Size(args);
1793     if (len < 1) {
1794         PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1795         return NULL;
1796     }
1797     first = PySequence_GetSlice(args, 0, 1);
1798     if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1799         Py_DECREF(first);
1800         return NULL;
1801     }
1802     Py_DECREF(first);
1803     
1804     CHECK_GOBJECT(self);
1805     
1806     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1807                              &signal_id, &detail, TRUE)) {
1808         repr = PyObject_Repr((PyObject*)self);
1809         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1810                      PYGLIB_PyUnicode_AsString(repr),
1811                      name);
1812         Py_DECREF(repr);
1813         return NULL;
1814     }
1815     g_signal_query(signal_id, &query);
1816     if (len != query.n_params + 1) {
1817         gchar buf[128];
1818
1819         g_snprintf(buf, sizeof(buf),
1820                    "%d parameters needed for signal %s; %ld given",
1821                    query.n_params, name, (long int) (len - 1));
1822         PyErr_SetString(PyExc_TypeError, buf);
1823         return NULL;
1824     }
1825
1826     params = g_new0(GValue, query.n_params + 1);
1827     g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1828     g_value_set_object(&params[0], G_OBJECT(self->obj));
1829
1830     for (i = 0; i < query.n_params; i++)
1831         g_value_init(&params[i + 1],
1832                      query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1833     for (i = 0; i < query.n_params; i++) {
1834         PyObject *item = PyTuple_GetItem(args, i+1);
1835
1836         if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1837             gchar buf[128];
1838             g_snprintf(buf, sizeof(buf),
1839                        "could not convert type %s to %s required for parameter %d",
1840                        Py_TYPE(item)->tp_name,
1841                        G_VALUE_TYPE_NAME(&params[i+1]), i);
1842             PyErr_SetString(PyExc_TypeError, buf);
1843
1844             for (j = 0; j <= i; j++)
1845                 g_value_unset(&params[j]);
1846
1847             g_free(params);
1848             return NULL;
1849         }
1850     }    
1851
1852     if (query.return_type != G_TYPE_NONE)
1853         g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1854     
1855     g_signal_emitv(params, signal_id, detail, &ret);
1856
1857     for (i = 0; i < query.n_params + 1; i++)
1858         g_value_unset(&params[i]);
1859     
1860     g_free(params);
1861     if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1862         py_ret = pyg_value_as_pyobject(&ret, TRUE);
1863         g_value_unset(&ret);
1864     } else {
1865         Py_INCREF(Py_None);
1866         py_ret = Py_None;
1867     }
1868
1869     return py_ret;
1870 }
1871
1872 static PyObject *
1873 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1874 {
1875     GSignalInvocationHint *ihint;
1876     guint signal_id, i;
1877     Py_ssize_t len;
1878     PyObject *py_ret;
1879     const gchar *name;
1880     GSignalQuery query;
1881     GValue *params, ret = { 0, };
1882     
1883     CHECK_GOBJECT(self);
1884     
1885     ihint = g_signal_get_invocation_hint(self->obj);
1886     if (!ihint) {
1887         PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1888                         "information for this object.");
1889         return NULL;
1890     }
1891
1892     signal_id = ihint->signal_id;
1893     name = g_signal_name(signal_id);
1894
1895     len = PyTuple_Size(args);
1896     if (signal_id == 0) {
1897         PyErr_SetString(PyExc_TypeError, "unknown signal name");
1898         return NULL;
1899     }
1900     g_signal_query(signal_id, &query);
1901     if (len != query.n_params) {
1902         gchar buf[128];
1903
1904         g_snprintf(buf, sizeof(buf),
1905                    "%d parameters needed for signal %s; %ld given",
1906                    query.n_params, name, (long int) len);
1907         PyErr_SetString(PyExc_TypeError, buf);
1908         return NULL;
1909     }
1910     params = g_new0(GValue, query.n_params + 1);
1911     g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1912     g_value_set_object(&params[0], G_OBJECT(self->obj));
1913
1914     for (i = 0; i < query.n_params; i++)
1915         g_value_init(&params[i + 1],
1916                      query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1917     for (i = 0; i < query.n_params; i++) {
1918         PyObject *item = PyTuple_GetItem(args, i);
1919
1920         if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1921             g_value_set_static_boxed(&params[i+1], pyg_boxed_get(item, void));
1922         }
1923         else if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1924             gchar buf[128];
1925
1926             g_snprintf(buf, sizeof(buf),
1927                        "could not convert type %s to %s required for parameter %d",
1928                        Py_TYPE(item)->tp_name,
1929                        g_type_name(G_VALUE_TYPE(&params[i+1])), i);
1930             PyErr_SetString(PyExc_TypeError, buf);
1931             for (i = 0; i < query.n_params + 1; i++)
1932                 g_value_unset(&params[i]);
1933             g_free(params);
1934             return NULL;
1935         }
1936     }
1937     if (query.return_type != G_TYPE_NONE)
1938         g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1939     g_signal_chain_from_overridden(params, &ret);
1940     for (i = 0; i < query.n_params + 1; i++)
1941         g_value_unset(&params[i]);
1942     g_free(params);
1943     if (query.return_type != G_TYPE_NONE) {
1944         py_ret = pyg_value_as_pyobject(&ret, TRUE);
1945         g_value_unset(&ret);
1946     } else {
1947         Py_INCREF(Py_None);
1948         py_ret = Py_None;
1949     }
1950     return py_ret;
1951 }
1952
1953
1954 static PyObject *
1955 pygobject_weak_ref(PyGObject *self, PyObject *args)
1956 {
1957     int len;
1958     PyObject *callback = NULL, *user_data = NULL;
1959     PyObject *retval;
1960
1961     CHECK_GOBJECT(self);
1962
1963     if ((len = PySequence_Length(args)) >= 1) {
1964         callback = PySequence_ITEM(args, 0);
1965         user_data = PySequence_GetSlice(args, 1, len);
1966     }
1967     retval = pygobject_weak_ref_new(self->obj, callback, user_data);
1968     Py_XDECREF(callback);
1969     Py_XDECREF(user_data);
1970     return retval;
1971 }
1972
1973
1974 static PyObject *
1975 pygobject_copy(PyGObject *self)
1976 {
1977     PyErr_SetString(PyExc_TypeError,
1978                     "GObject descendants' instances are non-copyable");
1979     return NULL;
1980 }
1981
1982 static PyObject *
1983 pygobject_deepcopy(PyGObject *self, PyObject *args)
1984 {
1985     PyErr_SetString(PyExc_TypeError,
1986                     "GObject descendants' instances are non-copyable");
1987     return NULL;
1988 }
1989
1990
1991 static PyObject *
1992 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
1993 {
1994     PyObject *pyfunc = NULL, *repr = NULL;
1995     GClosure *closure = NULL;
1996     guint retval;
1997     
1998     CHECK_GOBJECT(self);
1999
2000     if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2001         return NULL;
2002
2003     if (!PyCallable_Check(pyfunc)) {
2004         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2005         return NULL;
2006     }
2007
2008     closure = gclosure_from_pyfunc(self, pyfunc);
2009     if (!closure) {
2010         repr = PyObject_Repr((PyObject*)pyfunc);
2011         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2012                      PYGLIB_PyUnicode_AsString(repr));
2013         Py_DECREF(repr);
2014         return NULL;
2015     }
2016     
2017     retval = g_signal_handlers_disconnect_matched(self->obj,
2018                                                   G_SIGNAL_MATCH_CLOSURE,
2019                                                   0, 0,
2020                                                   closure,
2021                                                   NULL, NULL);
2022     return PYGLIB_PyLong_FromLong(retval);
2023 }
2024
2025 static PyObject *
2026 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2027 {
2028     PyObject *pyfunc = NULL, *repr = NULL;
2029     GClosure *closure = NULL;
2030     guint retval;
2031     
2032     CHECK_GOBJECT(self);
2033
2034     if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2035         return NULL;
2036
2037     if (!PyCallable_Check(pyfunc)) {
2038         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2039         return NULL;
2040     }
2041
2042     closure = gclosure_from_pyfunc(self, pyfunc);
2043     if (!closure) {
2044         repr = PyObject_Repr((PyObject*)pyfunc);
2045         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2046                      PYGLIB_PyUnicode_AsString(repr));
2047         Py_DECREF(repr);
2048         return NULL;
2049     }
2050     
2051     retval = g_signal_handlers_block_matched(self->obj,
2052                                              G_SIGNAL_MATCH_CLOSURE,
2053                                              0, 0,
2054                                              closure,
2055                                              NULL, NULL);
2056     return PYGLIB_PyLong_FromLong(retval);
2057 }
2058
2059 static PyObject *
2060 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2061 {
2062     PyObject *pyfunc = NULL, *repr = NULL;
2063     GClosure *closure = NULL;
2064     guint retval;
2065     
2066     CHECK_GOBJECT(self);
2067
2068     if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2069         return NULL;
2070
2071     if (!PyCallable_Check(pyfunc)) {
2072         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2073         return NULL;
2074     }
2075
2076     closure = gclosure_from_pyfunc(self, pyfunc);
2077     if (!closure) {
2078         repr = PyObject_Repr((PyObject*)pyfunc);
2079         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2080                      PYGLIB_PyUnicode_AsString(repr));
2081         Py_DECREF(repr);
2082         return NULL;
2083     }
2084     
2085     retval = g_signal_handlers_unblock_matched(self->obj,
2086                                                G_SIGNAL_MATCH_CLOSURE,
2087                                                0, 0,
2088                                                closure,
2089                                                NULL, NULL);
2090     return PYGLIB_PyLong_FromLong(retval);
2091 }
2092
2093
2094 static PyMethodDef pygobject_methods[] = {
2095     { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2096     { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2097     { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2098     { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2099     { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS },
2100     { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2101     { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2102     { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2103     { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2104     { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2105     { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2106     { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2107     { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2108     { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2109     { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2110     { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2111     { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2112     { NULL, NULL, 0 }
2113 };
2114
2115
2116 static PyObject *
2117 pygobject_get_dict(PyGObject *self, void *closure)
2118 {
2119     if (self->inst_dict == NULL) {
2120         self->inst_dict = PyDict_New();
2121         if (self->inst_dict == NULL)
2122             return NULL;
2123         if (G_LIKELY(self->obj))
2124             pygobject_switch_to_toggle_ref(self);
2125     }
2126     Py_INCREF(self->inst_dict);
2127     return self->inst_dict;
2128 }
2129
2130 static PyObject *
2131 pygobject_get_refcount(PyGObject *self, void *closure)
2132 {
2133     if (self->obj == NULL) {
2134         PyErr_Format(PyExc_TypeError, "GObject instance is not yet created");
2135         return NULL;
2136     }
2137     return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2138 }
2139
2140 static PyObject *
2141 pygobject_get_pointer(PyGObject *self, void *closure)
2142 {
2143     return PYGLIB_CPointer_WrapPointer (self->obj, NULL);
2144 }
2145
2146 static int
2147 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2148 {
2149     int res;
2150     PyGObject *gself = (PyGObject *) self;
2151     PyObject *inst_dict_before = gself->inst_dict;
2152       /* call parent type's setattro */
2153     res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2154     if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2155         if (G_LIKELY(gself->obj))
2156             pygobject_switch_to_toggle_ref(gself);
2157     }
2158     return res;
2159 }
2160
2161 static PyGetSetDef pygobject_getsets[] = {
2162     { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2163     { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2164     { "__gpointer__", (getter)pygobject_get_pointer, (setter)0, },
2165     { NULL, 0, 0 }
2166 };
2167
2168 /* ------------------------------------ */
2169 /* ****** GObject weak reference ****** */
2170 /* ------------------------------------ */
2171
2172 typedef struct {
2173     PyObject_HEAD
2174     GObject *obj;
2175     PyObject *callback;
2176     PyObject *user_data;
2177     gboolean have_floating_ref;
2178 } PyGObjectWeakRef;
2179
2180 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2181
2182 static int
2183 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2184 {
2185     if (self->callback && visit(self->callback, arg) < 0)
2186         return -1;
2187     if (self->user_data && visit(self->user_data, arg) < 0)
2188         return -1;
2189     return 0;
2190 }
2191
2192 static void
2193 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2194 {
2195     self->obj = NULL;
2196     if (self->callback) {
2197         PyObject *retval;
2198         PyGILState_STATE state = pyglib_gil_state_ensure();
2199         retval = PyObject_Call(self->callback, self->user_data, NULL);
2200         if (retval) {
2201             if (retval != Py_None)
2202                 PyErr_Format(PyExc_TypeError,
2203                              "GObject weak notify callback returned a value"
2204                              " of type %s, should return None",
2205                              Py_TYPE(retval)->tp_name);
2206             Py_DECREF(retval);
2207             PyErr_Print();
2208         } else
2209             PyErr_Print();
2210         Py_CLEAR(self->callback);
2211         Py_CLEAR(self->user_data);
2212         if (self->have_floating_ref) {
2213             self->have_floating_ref = FALSE;
2214             Py_DECREF((PyObject *) self);
2215         }
2216         pyglib_gil_state_release(state);
2217     }
2218 }
2219
2220 static inline int
2221 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2222 {
2223     Py_CLEAR(self->callback);
2224     Py_CLEAR(self->user_data);
2225     if (self->obj) {
2226         g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2227         self->obj = NULL;
2228     }
2229     return 0;
2230 }
2231
2232 static void
2233 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2234 {
2235     PyObject_GC_UnTrack((PyObject *)self);
2236     pygobject_weak_ref_clear(self);
2237     PyObject_GC_Del(self);
2238 }
2239
2240 static PyObject *
2241 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2242 {
2243     PyGObjectWeakRef *self;
2244
2245     self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2246     self->callback = callback;
2247     self->user_data = user_data;
2248     Py_XINCREF(self->callback);
2249     Py_XINCREF(self->user_data);
2250     self->obj = obj;
2251     g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2252     if (callback != NULL) {
2253           /* when we have a callback, we should INCREF the weakref
2254            * object to make it stay alive even if it goes out of scope */
2255         self->have_floating_ref = TRUE;
2256         Py_INCREF((PyObject *) self);
2257     }
2258     return (PyObject *) self;
2259 }
2260
2261 static PyObject *
2262 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2263 {
2264     if (!self->obj) {
2265         PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2266         return NULL;
2267     }
2268     g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2269     self->obj = NULL;
2270     if (self->have_floating_ref) {
2271         self->have_floating_ref = FALSE;
2272         Py_DECREF(self);
2273     }
2274     Py_INCREF(Py_None);
2275     return Py_None;
2276 }
2277
2278 static PyMethodDef pygobject_weak_ref_methods[] = {
2279     { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2280     { NULL, NULL, 0}
2281 };
2282
2283 static PyObject *
2284 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2285 {
2286     static char *argnames[] = {NULL};
2287
2288     if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2289         return NULL;
2290
2291     if (self->obj)
2292         return pygobject_new(self->obj);
2293     else {
2294         Py_INCREF(Py_None);
2295         return Py_None;
2296     }
2297 }
2298
2299 static gpointer
2300 pyobject_copy(gpointer boxed)
2301 {
2302     PyObject *object = boxed;
2303     PyGILState_STATE state;
2304
2305     state = pyglib_gil_state_ensure();
2306     Py_INCREF(object);
2307     pyglib_gil_state_release(state);
2308     return object;
2309 }
2310
2311 static void
2312 pyobject_free(gpointer boxed)
2313 {
2314     PyObject *object = boxed;
2315     PyGILState_STATE state;
2316
2317     state = pyglib_gil_state_ensure();
2318     Py_DECREF(object);
2319     pyglib_gil_state_release(state);
2320 }
2321
2322 void
2323 pygobject_object_register_types(PyObject *d)
2324 {
2325     PyObject *o, *descr;
2326
2327     pygobject_custom_key = g_quark_from_static_string("PyGObject::custom");
2328     pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2329     pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2330     pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2331     pygobject_has_updated_constructor_key =
2332         g_quark_from_static_string("PyGObject::has-updated-constructor");
2333     pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2334
2335     /* GObject */
2336     if (!PY_TYPE_OBJECT)
2337         PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2338                                                       pyobject_copy,
2339                                                       pyobject_free);
2340     PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2341     PyGObject_Type.tp_richcompare = pygobject_richcompare;
2342     PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2343     PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2344     PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2345     PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2346                                Py_TPFLAGS_HAVE_GC);
2347     PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2348     PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2349     PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2350     PyGObject_Type.tp_methods = pygobject_methods;
2351     PyGObject_Type.tp_getset = pygobject_getsets;
2352     PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2353     PyGObject_Type.tp_init = (initproc)pygobject_init;
2354     PyGObject_Type.tp_free = (freefunc)pygobject_free;
2355     PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2356     PyGObject_Type.tp_new = PyType_GenericNew;
2357     pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2358                              &PyGObject_Type, NULL);
2359     PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2360                          pyg_object_descr_doc_get());
2361
2362     /* GProps */
2363     PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2364     PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2365     PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2366     PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2367     PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2368     PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2369         "Python attributes.";
2370     PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2371     PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2372     PyGProps_Type.tp_methods = pygobject_props_methods;
2373     if (PyType_Ready(&PyGProps_Type) < 0)
2374         return;
2375
2376     /* GPropsDescr */
2377     PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2378     PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2379     if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2380         return;
2381     descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2382     PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2383     PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2384                         o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject"));
2385     Py_DECREF(o);
2386
2387     /* GPropsIter */
2388     PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2389     PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2390     PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2391     PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2392     if (PyType_Ready(&PyGPropsIter_Type) < 0)
2393         return;
2394
2395     PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2396     PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2397     PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2398     PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2399     PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2400     PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2401     PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2402     if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2403         return;
2404     PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
2405 }