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