1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygtk- Python bindings for the GTK toolkit.
3 * Copyright (C) 1998-2003 James Henstridge
5 * pygobject.c: wrapper for the GObject type.
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.
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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
28 #include "pygobject-private.h"
29 #include "pyginterface.h"
30 #include "pygparamspec.h"
35 static void pygobject_dealloc(PyGObject *self);
36 static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
37 static int pygobject_clear(PyGObject *self);
38 static PyObject * pyg_type_get_bases(GType gtype);
39 static inline int pygobject_clear(PyGObject *self);
40 static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
41 static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
42 static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
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_class_key;
49 GQuark pygobject_class_init_key;
50 GQuark pygobject_wrapper_key;
51 GQuark pygobject_has_updated_constructor_key;
52 GQuark pygobject_instance_data_key;
55 /* -------------- class <-> wrapper manipulation --------------- */
58 pygobject_data_free(PyGObjectData *data)
60 PyGILState_STATE state = pyglib_gil_state_ensure();
61 GSList *closures, *tmp;
62 Py_DECREF(data->type);
63 tmp = closures = data->closures;
65 data->closures = NULL;
68 pyg_begin_allow_threads;
70 GClosure *closure = tmp->data;
72 /* we get next item first, because the current link gets
73 * invalidated by pygobject_unwatch_closure */
75 g_closure_invalidate(closure);
77 pyg_end_allow_threads;
79 if (data->closures != NULL)
80 g_warning("invalidated all closures, but data->closures != NULL !");
83 pyglib_gil_state_release(state);
86 static inline PyGObjectData *
87 pygobject_data_new(void)
90 data = g_new0(PyGObjectData, 1);
94 static inline PyGObjectData *
95 pygobject_get_inst_data(PyGObject *self)
97 PyGObjectData *inst_data;
99 if (G_UNLIKELY(!self->obj))
101 inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
102 if (inst_data == NULL)
104 inst_data = pygobject_data_new();
106 inst_data->type = Py_TYPE(self);
107 Py_INCREF((PyObject *) inst_data->type);
109 g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
110 inst_data, (GDestroyNotify) pygobject_data_free);
116 GHashTable *custom_type_registration = NULL;
118 PyTypeObject *PyGObject_MetaType = NULL;
124 * As Python handles reference counting for us, the "floating
125 * reference" code in GTK is not all that useful. In fact, it can
126 * cause leaks. This function should be called to remove the floating
127 * references on objects on construction.
130 pygobject_sink(GObject *obj)
132 /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink().
133 * - if the object is new and owned by someone else, its ref has been sunk and
134 * we need to keep the one from that someone and add our own "fresh ref"
135 * - if the object is not and owned by nobody, its ref is floating and we need
136 * to transform it into a regular ref.
138 if (G_IS_INITIALLY_UNOWNED(obj)) {
139 g_object_ref_sink(obj);
150 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
153 pyg_props_iter_dealloc(PyGPropsIter *self)
156 PyObject_Del((PyObject*) self);
160 pygobject_props_iter_next(PyGPropsIter *iter)
162 if (iter->index < iter->n_props)
163 return pyg_param_spec_new(iter->props[iter->index++]);
165 PyErr_SetNone(PyExc_StopIteration);
172 /* a reference to the object containing the properties */
173 PyGObject *pygobject;
178 PyGProps_dealloc(PyGProps* self)
182 PyObject_GC_UnTrack((PyObject*)self);
184 tmp = self->pygobject;
185 self->pygobject = NULL;
188 PyObject_GC_Del((PyObject*)self);
192 build_parameter_list(GObjectClass *class)
195 guint n_props = 0, i;
197 PyObject *props_list;
199 props = g_object_class_list_properties(class, &n_props);
200 props_list = PyList_New(n_props);
201 for (i = 0; i < n_props; i++) {
203 name = g_strdup(g_param_spec_get_name(props[i]));
204 /* hyphens cannot belong in identifiers */
205 g_strdelimit(name, "-", '_');
206 prop_str = PYGLIB_PyUnicode_FromString(name);
208 PyList_SetItem(props_list, i, prop_str);
219 PyGProps_getattro(PyGProps *self, PyObject *attr)
224 GValue value = { 0, };
227 attr_name = PYGLIB_PyUnicode_AsString(attr);
230 return PyObject_GenericGetAttr((PyObject *)self, attr);
233 class = g_type_class_ref(self->gtype);
235 if (!strcmp(attr_name, "__members__")) {
236 return build_parameter_list(class);
239 if (self->pygobject != NULL) {
240 ret = pygi_get_property_value (self->pygobject, attr_name);
245 pspec = g_object_class_find_property(class, attr_name);
246 g_type_class_unref(class);
249 return PyObject_GenericGetAttr((PyObject *)self, attr);
252 if (!(pspec->flags & G_PARAM_READABLE)) {
253 PyErr_Format(PyExc_TypeError,
254 "property '%s' is not readable", attr_name);
258 /* If we're doing it without an instance, return a GParamSpec */
259 if (!self->pygobject) {
260 return pyg_param_spec_new(pspec);
263 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
264 pyg_begin_allow_threads;
265 g_object_get_property(self->pygobject->obj, attr_name, &value);
266 pyg_end_allow_threads;
267 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
268 g_value_unset(&value);
274 set_property_from_pspec(GObject *obj,
279 GValue value = { 0, };
281 if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
282 PyErr_Format(PyExc_TypeError,
283 "property '%s' can only be set in constructor",
288 if (!(pspec->flags & G_PARAM_WRITABLE)) {
289 PyErr_Format(PyExc_TypeError,
290 "property '%s' is not writable", attr_name);
294 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
295 if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
296 PyErr_SetString(PyExc_TypeError,
297 "could not convert argument to correct param type");
301 pyg_begin_allow_threads;
302 g_object_set_property(obj, attr_name, &value);
303 pyg_end_allow_threads;
305 g_value_unset(&value);
310 PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps);
313 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
320 if (pvalue == NULL) {
321 PyErr_SetString(PyExc_TypeError, "properties cannot be "
326 attr_name = PYGLIB_PyUnicode_AsString(attr);
329 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
332 if (!self->pygobject) {
333 PyErr_SetString(PyExc_TypeError,
334 "cannot set GOject properties without an instance");
338 ret = pygi_set_property_value (self->pygobject, attr_name, pvalue);
342 if (PyErr_Occurred())
345 obj = self->pygobject->obj;
346 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), attr_name);
348 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
351 if (!set_property_from_pspec(obj, attr_name, pspec, pvalue))
358 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
360 if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
366 pygobject_props_get_iter(PyGProps *self)
371 iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
372 class = g_type_class_ref(self->gtype);
373 iter->props = g_object_class_list_properties(class, &iter->n_props);
375 g_type_class_unref(class);
376 return (PyObject *) iter;
380 PyGProps_length(PyGProps *self)
386 class = g_type_class_ref(self->gtype);
387 props = g_object_class_list_properties(class, &n_props);
388 g_type_class_unref(class);
391 return (Py_ssize_t)n_props;
394 static PySequenceMethods _PyGProps_as_sequence = {
395 (lenfunc) PyGProps_length,
404 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject);
407 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
411 gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
412 if (obj == NULL || obj == Py_None) {
413 gprops->pygobject = NULL;
414 gprops->gtype = pyg_type_from_object(type);
416 if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
417 PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
418 " descriptor on non-GObject instances");
422 gprops->pygobject = (PyGObject *) obj;
423 gprops->gtype = pyg_type_from_object(obj);
425 return (PyObject *) gprops;
429 * pygobject_register_class:
430 * @dict: the module dictionary. A reference to the type will be stored here.
431 * @type_name: not used ?
432 * @gtype: the GType of the GObject subclass.
433 * @type: the Python type object for this wrapper.
434 * @static_bases: a tuple of Python type objects that are the bases of
437 * This function is used to register a Python type as the wrapper for
438 * a particular GObject subclass. It will also insert a reference to
439 * the wrapper class into the module dictionary passed as a reference,
440 * which simplifies initialisation.
443 pygobject_register_class(PyObject *dict, const gchar *type_name,
444 GType gtype, PyTypeObject *type,
445 PyObject *static_bases)
448 const char *class_name, *s;
449 PyObject *runtime_bases;
450 PyObject *bases_list, *bases, *mod_name;
453 class_name = type->tp_name;
454 s = strrchr(class_name, '.');
458 runtime_bases = pyg_type_get_bases(gtype);
460 PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
461 bases_list = PySequence_List(static_bases);
462 /* we start at index 1 because we want to skip the primary
463 * base, otherwise we might get MRO conflict */
464 for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
466 PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
467 int contains = PySequence_Contains(bases_list, base);
470 else if (!contains) {
471 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
473 g_message("Adding missing base %s to type %s",
474 ((PyTypeObject *)base)->tp_name, type->tp_name);
476 PyList_Append(bases_list, base);
480 bases = PySequence_Tuple(bases_list);
481 Py_DECREF(bases_list);
482 Py_DECREF(runtime_bases);
484 bases = runtime_bases;
486 Py_TYPE(type) = PyGObject_MetaType;
487 type->tp_bases = bases;
488 if (G_LIKELY(bases)) {
489 type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
490 Py_INCREF(type->tp_base);
493 pygobject_inherit_slots(type, bases, TRUE);
495 if (PyType_Ready(type) < 0) {
496 g_warning ("couldn't make the type `%s' ready", type->tp_name);
500 /* Set type.__module__ to the name of the module,
501 * otherwise it'll default to 'gobject', see #376099
503 s = strrchr(type->tp_name, '.');
505 mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
506 PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
511 o = pyg_type_wrapper_new(gtype);
512 PyDict_SetItemString(type->tp_dict, "__gtype__", o);
515 /* stash a pointer to the python class with the GType */
517 g_type_set_qdata(gtype, pygobject_class_key, type);
520 /* set up __doc__ descriptor on type */
521 PyDict_SetItemString(type->tp_dict, "__doc__",
522 pyg_object_descr_doc_get());
524 PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
528 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
530 PyGObject *self = (PyGObject*) data;
531 PyGILState_STATE state;
533 state = pyglib_gil_state_ensure();
540 pyglib_gil_state_release(state);
543 /* Called when the inst_dict is first created; switches the
544 reference counting strategy to start using toggle ref to keep the
545 wrapper alive while the GObject lives. In contrast, while
546 inst_dict was NULL the python wrapper is allowed to die at
547 will and is recreated on demand. */
549 pygobject_switch_to_toggle_ref(PyGObject *self)
551 g_assert(self->obj->ref_count >= 1);
553 if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF)
554 return; /* already using toggle ref */
555 self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
556 /* Note that add_toggle_ref will never immediately call back into
558 Py_INCREF((PyObject *) self);
559 g_object_add_toggle_ref(self->obj, pyg_toggle_notify, self);
560 g_object_unref(self->obj);
563 /* Called when an custom gobject is initalized via g_object_new instead of
564 its constructor. The next time the wrapper is access via
565 pygobject_new_full it will sink the floating reference instead of
566 adding a new reference and causing a leak */
569 pygobject_ref_float(PyGObject *self)
571 /* should only be floated once */
572 g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
574 self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
577 /* Called by gobject_new_full, if the floating flag is set remove it, otherwise
580 pygobject_ref_sink(PyGObject *self)
582 if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
583 self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
585 Py_INCREF ( (PyObject *) self);
589 * pygobject_register_wrapper:
590 * @self: the wrapper instance
592 * In the constructor of PyGTK wrappers, this function should be
593 * called after setting the obj member. It will tie the wrapper
594 * instance to the GObject so that the same wrapper instance will
595 * always be used for this GObject instance.
598 pygobject_register_wrapper(PyObject *self)
602 g_return_if_fail(self != NULL);
603 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
605 gself = (PyGObject *)self;
607 g_assert(gself->obj->ref_count >= 1);
608 /* save wrapper pointer so we can access it later */
609 g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
610 if (gself->inst_dict)
611 pygobject_switch_to_toggle_ref(gself);
615 pyg_type_get_bases(GType gtype)
617 GType *interfaces, parent_type, interface_type;
619 PyTypeObject *py_parent_type, *py_interface_type;
623 if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
626 /* Lookup the parent type */
627 parent_type = g_type_parent(gtype);
628 py_parent_type = pygobject_lookup_class(parent_type);
629 interfaces = g_type_interfaces(gtype, &n_interfaces);
630 bases = PyTuple_New(n_interfaces + 1);
631 /* We will always put the parent at the first position in bases */
632 Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
633 PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
635 /* And traverse interfaces */
637 for (i = 0; i < n_interfaces; i++) {
638 interface_type = interfaces[i];
639 py_interface_type = pygobject_lookup_class(interface_type);
640 Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
641 PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
649 * pygobject_new_with_interfaces
650 * @gtype: the GType of the GObject subclass.
652 * Creates a new PyTypeObject from the given GType with interfaces attached in
655 * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
658 pygobject_new_with_interfaces(GType gtype)
660 PyGILState_STATE state;
664 PyTypeObject *py_parent_type;
666 PyObject *modules, *module;
667 gchar *type_name, *mod_name, *gtype_name;
669 state = pyglib_gil_state_ensure();
671 bases = pyg_type_get_bases(gtype);
672 py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
676 o = pyg_type_wrapper_new(gtype);
677 PyDict_SetItemString(dict, "__gtype__", o);
680 /* set up __doc__ descriptor on type */
681 PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
683 /* generate the pygtk module name and extract the base type name */
684 gtype_name = (gchar*)g_type_name(gtype);
685 if (g_str_has_prefix(gtype_name, "Gtk")) {
688 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
689 } else if (g_str_has_prefix(gtype_name, "Gdk")) {
690 mod_name = "gtk.gdk";
692 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
693 } else if (g_str_has_prefix(gtype_name, "Atk")) {
696 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
697 } else if (g_str_has_prefix(gtype_name, "Pango")) {
700 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
702 mod_name = "__main__";
703 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
706 type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
707 "sNN", type_name, bases, dict);
712 pyglib_gil_state_release(state);
716 /* Workaround python tp_(get|set)attr slot inheritance bug.
717 * Fixes bug #144135. */
718 if (!type->tp_getattr && py_parent_type->tp_getattr) {
719 type->tp_getattro = NULL;
720 type->tp_getattr = py_parent_type->tp_getattr;
722 if (!type->tp_setattr && py_parent_type->tp_setattr) {
723 type->tp_setattro = NULL;
724 type->tp_setattr = py_parent_type->tp_setattr;
726 /* override more python stupid hacks behind our back */
727 type->tp_dealloc = py_parent_type->tp_dealloc;
728 type->tp_alloc = py_parent_type->tp_alloc;
729 type->tp_free = py_parent_type->tp_free;
730 type->tp_traverse = py_parent_type->tp_traverse;
731 type->tp_clear = py_parent_type->tp_clear;
733 pygobject_inherit_slots(type, bases, FALSE);
735 if (PyType_Ready(type) < 0) {
736 g_warning ("couldn't make the type `%s' ready", type->tp_name);
737 pyglib_gil_state_release(state);
740 /* insert type name in module dict */
741 modules = PyImport_GetModuleDict();
742 if ((module = PyDict_GetItemString(modules, mod_name)) != NULL) {
743 if (PyObject_SetAttrString(module, gtype_name, (PyObject *)type) < 0)
747 /* stash a pointer to the python class with the GType */
749 g_type_set_qdata(gtype, pygobject_class_key, type);
751 pyglib_gil_state_release(state);
756 /* Pick appropriate value for given slot (at slot_offset inside
757 * PyTypeObject structure). It must be a pointer, e.g. a pointer to a
758 * function. We use the following heuristic:
760 * - Scan all types listed as bases of the type.
761 * - If for exactly one base type slot value is non-NULL and
762 * different from that of 'object' and 'GObject', set current type
763 * slot into that value.
764 * - Otherwise (if there is more than one such base type or none at
765 * all) don't touch it and live with Python default.
767 * The intention here is to propagate slot from custom wrappers to
768 * wrappers created at runtime when appropriate. We prefer to be on
769 * the safe side, so if there is potential collision (more than one
770 * custom slot value), we discard custom overrides altogether.
772 * When registering type with pygobject_register_class(), i.e. a type
773 * that has been manually created (likely with Codegen help),
774 * `check_for_present' should be set to TRUE. In this case, the
775 * function will never overwrite any non-NULL slots already present in
776 * the type. If `check_for_present' is FALSE, such non-NULL slots are
777 * though to be set by Python interpreter and so will be overwritten
778 * if heuristic above says so.
781 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
783 static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
784 #if PY_VERSION_HEX < 0x03000000
785 offsetof(PyTypeObject, tp_compare),
787 offsetof(PyTypeObject, tp_richcompare),
788 offsetof(PyTypeObject, tp_hash),
789 offsetof(PyTypeObject, tp_iter),
790 offsetof(PyTypeObject, tp_repr),
791 offsetof(PyTypeObject, tp_str),
792 offsetof(PyTypeObject, tp_print) };
795 /* Happens when registering gobject.GObject itself, at least. */
799 for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
800 pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
804 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
805 gboolean check_for_present)
807 #define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset))
809 void *found_slot = NULL;
810 int num_bases = PyTuple_Size(bases);
813 if (check_for_present && TYPE_SLOT(type) != NULL) {
814 /* We are requested to check if there is any custom slot value
815 * in this type already and there actually is. Don't
821 for (i = 0; i < num_bases; ++i) {
822 PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
823 void *slot = TYPE_SLOT(base_type);
827 if (slot == TYPE_SLOT(&PyGObject_Type) ||
828 slot == TYPE_SLOT(&PyBaseObject_Type))
831 if (found_slot != NULL && found_slot != slot) {
832 /* We have a conflict: more than one base use different
833 * custom slots. To be on the safe side, we bail out.
841 /* Only perform the final assignment if at least one base has a
842 * custom value. Otherwise just leave this type's slot untouched.
844 if (found_slot != NULL)
845 TYPE_SLOT(type) = found_slot;
851 * pygobject_lookup_class:
852 * @gtype: the GType of the GObject subclass.
854 * This function looks up the wrapper class used to represent
855 * instances of a GObject represented by @gtype. If no wrapper class
856 * or interface has been registered for the given GType, then a new
857 * type will be created.
859 * Returns: The wrapper class for the GObject or NULL if the
860 * GType has no registered type and a new type couldn't be created
863 pygobject_lookup_class(GType gtype)
865 PyTypeObject *py_type;
867 if (gtype == G_TYPE_INTERFACE)
868 return &PyGInterface_Type;
870 py_type = pyg_type_get_custom(g_type_name(gtype));
874 py_type = g_type_get_qdata(gtype, pygobject_class_key);
875 if (py_type == NULL) {
876 py_type = g_type_get_qdata(gtype, pyginterface_type_key);
879 py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
881 if (py_type == NULL) {
882 py_type = pygobject_new_with_interfaces(gtype);
883 g_type_set_qdata(gtype, pyginterface_type_key, py_type);
891 * pygobject_new_full:
892 * @obj: a GObject instance.
893 * @sink: whether to sink any floating reference found on the GObject. DEPRECATED.
894 * @g_class: the GObjectClass
896 * This function gets a reference to a wrapper for the given GObject
897 * instance. If a wrapper has already been created, a new reference
898 * to that wrapper will be returned. Otherwise, a wrapper instance
901 * Returns: a reference to the wrapper for the GObject.
904 pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
913 /* we already have a wrapper for this object -- return it. */
914 self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
916 pygobject_ref_sink(self);
919 PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
922 tp = inst_data->type;
925 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
927 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
929 g_assert(tp != NULL);
931 /* need to bump type refcount if created with
932 pygobject_new_with_interfaces(). fixes bug #141042 */
933 if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
935 self = PyObject_GC_New(PyGObject, tp);
938 self->inst_dict = NULL;
939 self->weakreflist = NULL;
940 self->private_flags.flags = 0;
942 /* if we are creating a wrapper around a newly created object, it can have
943 a floating ref (e.g. for methods like Gtk.Button.new()). Bug 640868 */
944 g_object_ref_sink(obj);
945 pygobject_register_wrapper((PyObject *)self);
946 PyObject_GC_Track((PyObject *)self);
949 return (PyObject *)self;
954 pygobject_new(GObject *obj)
956 return pygobject_new_full(obj, TRUE, NULL);
960 pygobject_unwatch_closure(gpointer data, GClosure *closure)
962 PyGObjectData *inst_data = data;
964 inst_data->closures = g_slist_remove (inst_data->closures, closure);
968 * pygobject_watch_closure:
969 * @self: a GObject wrapper instance
970 * @closure: a GClosure to watch
972 * Adds a closure to the list of watched closures for the wrapper.
973 * The closure must be one returned by pyg_closure_new(). When the
974 * cycle GC traverses the wrapper instance, it will enumerate the
975 * references to Python objects stored in watched closures. If the
976 * cycle GC tells the wrapper to clear itself, the watched closures
977 * will be invalidated.
980 pygobject_watch_closure(PyObject *self, GClosure *closure)
985 g_return_if_fail(self != NULL);
986 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
987 g_return_if_fail(closure != NULL);
989 gself = (PyGObject *)self;
990 data = pygobject_get_inst_data(gself);
991 g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
992 data->closures = g_slist_prepend(data->closures, closure);
993 g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
996 /* -------------- PyGObject behaviour ----------------- */
998 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
1001 pygobject_dealloc(PyGObject *self)
1003 /* Untrack must be done first. This is because followup calls such as
1004 * ClearWeakRefs could call into Python and cause new allocations to
1005 * happen, which could in turn could trigger the garbage collector,
1006 * which would then get confused as it is tracking this half-deallocated
1008 PyObject_GC_UnTrack((PyObject *)self);
1010 PyObject_ClearWeakRefs((PyObject *)self);
1011 /* this forces inst_data->type to be updated, which could prove
1012 * important if a new wrapper has to be created and it is of a
1013 * unregistered type */
1014 pygobject_get_inst_data(self);
1015 pygobject_clear(self);
1016 /* the following causes problems with subclassed types */
1017 /* Py_TYPE(self)->tp_free((PyObject *)self); */
1018 PyObject_GC_Del(self);
1022 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1026 isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1030 Py_INCREF(Py_NotImplemented);
1031 return Py_NotImplemented;
1033 isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1037 Py_INCREF(Py_NotImplemented);
1038 return Py_NotImplemented;
1041 return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1042 ((PyGObject*)other)->obj,
1047 pygobject_hash(PyGObject *self)
1049 return (long)self->obj;
1053 pygobject_repr(PyGObject *self)
1057 g_snprintf(buf, sizeof(buf),
1058 "<%s object at 0x%lx (%s at 0x%lx)>",
1059 Py_TYPE(self)->tp_name,
1061 self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
1063 return PYGLIB_PyUnicode_FromString(buf);
1068 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1072 PyGObjectData *data = pygobject_get_inst_data(self);
1074 if (self->inst_dict) ret = visit(self->inst_dict, arg);
1075 if (ret != 0) return ret;
1079 for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1080 PyGClosure *closure = tmp->data;
1082 if (closure->callback) ret = visit(closure->callback, arg);
1083 if (ret != 0) return ret;
1085 if (closure->extra_args) ret = visit(closure->extra_args, arg);
1086 if (ret != 0) return ret;
1088 if (closure->swap_data) ret = visit(closure->swap_data, arg);
1089 if (ret != 0) return ret;
1096 pygobject_clear(PyGObject *self)
1099 g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1100 if (self->inst_dict) {
1101 g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
1102 self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1104 pyg_begin_allow_threads;
1105 g_object_unref(self->obj);
1106 pyg_end_allow_threads;
1110 Py_CLEAR(self->inst_dict);
1115 pygobject_free(PyObject *op)
1117 PyObject_GC_Del(op);
1121 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1122 guint *n_params, GParameter **params)
1132 *params = g_new0(GParameter, PyDict_Size(kwargs));
1133 while (PyDict_Next(kwargs, &pos, &key, &value)) {
1135 GParameter *param = &(*params)[*n_params];
1136 const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1138 pspec = g_object_class_find_property(class, key_str);
1140 PyErr_Format(PyExc_TypeError,
1141 "gobject `%s' doesn't support property `%s'",
1142 G_OBJECT_CLASS_NAME(class), key_str);
1145 g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1146 if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) {
1147 PyErr_Format(PyExc_TypeError,
1148 "could not convert value for property `%s' from %s to %s",
1149 key_str, Py_TYPE(value)->tp_name,
1150 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1153 param->name = g_strdup(key_str);
1160 /* ---------------- PyGObject methods ----------------- */
1163 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1166 guint n_params = 0, i;
1167 GParameter *params = NULL;
1168 GObjectClass *class;
1170 if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
1173 object_type = pyg_type_from_object((PyObject *)self);
1177 if (G_TYPE_IS_ABSTRACT(object_type)) {
1178 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1179 "(non-instantiable) type `%s'", g_type_name(object_type));
1183 if ((class = g_type_class_ref (object_type)) == NULL) {
1184 PyErr_SetString(PyExc_TypeError,
1185 "could not get a reference to type class");
1189 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms))
1192 if (pygobject_constructv(self, n_params, params))
1193 PyErr_SetString(PyExc_RuntimeError, "could not create object");
1196 for (i = 0; i < n_params; i++) {
1197 g_free((gchar *) params[i].name);
1198 g_value_unset(¶ms[i].value);
1201 g_type_class_unref(class);
1203 return (self->obj) ? 0 : -1;
1206 #define CHECK_GOBJECT(self) \
1207 if (!G_IS_OBJECT(self->obj)) { \
1208 PyErr_Format(PyExc_TypeError, \
1209 "object at %p of type %s is not initialized", \
1210 self, Py_TYPE(self)->tp_name); \
1215 pygobject_get_property(PyGObject *self, PyObject *args)
1219 GValue value = { 0, };
1222 if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name))
1225 CHECK_GOBJECT(self);
1227 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1230 PyErr_Format(PyExc_TypeError,
1231 "object of type `%s' does not have property `%s'",
1232 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1235 if (!(pspec->flags & G_PARAM_READABLE)) {
1236 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1240 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1241 pyg_begin_allow_threads;
1242 g_object_get_property(self->obj, param_name, &value);
1243 pyg_end_allow_threads;
1244 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
1245 g_value_unset(&value);
1250 pygobject_get_properties(PyGObject *self, PyObject *args)
1252 GObjectClass *class;
1256 if ((len = PyTuple_Size(args)) < 1) {
1257 PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1261 tuple = PyTuple_New(len);
1262 class = G_OBJECT_GET_CLASS(self->obj);
1263 for (i = 0; i < len; i++) {
1264 PyObject *py_property = PyTuple_GetItem(args, i);
1265 gchar *property_name;
1267 GValue value = { 0 };
1270 if (!PYGLIB_PyUnicode_Check(py_property)) {
1271 PyErr_SetString(PyExc_TypeError,
1272 "Expected string argument for property.");
1276 property_name = PYGLIB_PyUnicode_AsString(py_property);
1278 pspec = g_object_class_find_property(class,
1281 PyErr_Format(PyExc_TypeError,
1282 "object of type `%s' does not have property `%s'",
1283 g_type_name(G_OBJECT_TYPE(self->obj)), property_name);
1286 if (!(pspec->flags & G_PARAM_READABLE)) {
1287 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1291 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1293 pyg_begin_allow_threads;
1294 g_object_get_property(self->obj, property_name, &value);
1295 pyg_end_allow_threads;
1297 item = pyg_value_as_pyobject(&value, TRUE);
1298 PyTuple_SetItem(tuple, i, item);
1300 g_value_unset(&value);
1307 pygobject_set_property(PyGObject *self, PyObject *args)
1313 if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name,
1317 CHECK_GOBJECT(self);
1319 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1322 PyErr_Format(PyExc_TypeError,
1323 "object of type `%s' does not have property `%s'",
1324 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1328 if (!set_property_from_pspec(self->obj, param_name, pspec, pvalue))
1336 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1338 GObjectClass *class;
1342 PyObject *result = NULL;
1344 CHECK_GOBJECT(self);
1346 class = G_OBJECT_GET_CLASS(self->obj);
1348 g_object_freeze_notify (G_OBJECT(self->obj));
1351 while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1352 gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1355 pspec = g_object_class_find_property(class, key_str);
1359 g_snprintf(buf, sizeof(buf),
1360 "object `%s' doesn't support property `%s'",
1361 g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1362 PyErr_SetString(PyExc_TypeError, buf);
1366 if (!set_property_from_pspec(G_OBJECT(self->obj), key_str, pspec, value))
1373 g_object_thaw_notify (G_OBJECT(self->obj));
1379 pygobject_freeze_notify(PyGObject *self, PyObject *args)
1381 if (!PyArg_ParseTuple(args, ":GObject.freeze_notify"))
1384 CHECK_GOBJECT(self);
1386 g_object_freeze_notify(self->obj);
1392 pygobject_notify(PyGObject *self, PyObject *args)
1394 char *property_name;
1396 if (!PyArg_ParseTuple(args, "s:GObject.notify", &property_name))
1399 CHECK_GOBJECT(self);
1401 g_object_notify(self->obj, property_name);
1407 pygobject_thaw_notify(PyGObject *self, PyObject *args)
1409 if (!PyArg_ParseTuple(args, ":GObject.thaw_notify"))
1412 CHECK_GOBJECT(self);
1414 g_object_thaw_notify(self->obj);
1420 pygobject_get_data(PyGObject *self, PyObject *args)
1426 if (!PyArg_ParseTuple(args, "s:GObject.get_data", &key))
1429 CHECK_GOBJECT(self);
1431 quark = g_quark_from_string(key);
1432 data = g_object_get_qdata(self->obj, quark);
1433 if (!data) data = Py_None;
1439 pygobject_set_data(PyGObject *self, PyObject *args)
1445 if (!PyArg_ParseTuple(args, "sO:GObject.set_data", &key, &data))
1448 CHECK_GOBJECT(self);
1450 quark = g_quark_from_string(key);
1452 g_object_set_qdata_full(self->obj, quark, data, pyg_destroy_notify);
1458 pygobject_connect(PyGObject *self, PyObject *args)
1460 PyObject *first, *callback, *extra_args;
1467 len = PyTuple_Size(args);
1469 PyErr_SetString(PyExc_TypeError,
1470 "GObject.connect requires at least 2 arguments");
1473 first = PySequence_GetSlice(args, 0, 2);
1474 if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1479 if (!PyCallable_Check(callback)) {
1480 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1484 CHECK_GOBJECT(self);
1486 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1487 &sigid, &detail, TRUE)) {
1488 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1489 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1493 extra_args = PySequence_GetSlice(args, 2, len);
1494 if (extra_args == NULL)
1497 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1498 if (closure == NULL)
1499 closure = pyg_closure_new(callback, extra_args, NULL);
1501 pygobject_watch_closure((PyObject *)self, closure);
1502 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1504 Py_DECREF(extra_args);
1505 return PyLong_FromUnsignedLong(handlerid);
1509 pygobject_connect_after(PyGObject *self, PyObject *args)
1511 PyObject *first, *callback, *extra_args;
1519 len = PyTuple_Size(args);
1521 PyErr_SetString(PyExc_TypeError,
1522 "GObject.connect_after requires at least 2 arguments");
1525 first = PySequence_GetSlice(args, 0, 2);
1526 if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1527 &name, &callback)) {
1532 if (!PyCallable_Check(callback)) {
1533 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1537 CHECK_GOBJECT(self);
1539 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1540 &sigid, &detail, TRUE)) {
1541 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1542 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1546 extra_args = PySequence_GetSlice(args, 2, len);
1547 if (extra_args == NULL)
1550 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1551 if (closure == NULL)
1552 closure = pyg_closure_new(callback, extra_args, NULL);
1554 pygobject_watch_closure((PyObject *)self, closure);
1555 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1557 Py_DECREF(extra_args);
1558 return PyLong_FromUnsignedLong(handlerid);
1562 pygobject_connect_object(PyGObject *self, PyObject *args)
1564 PyObject *first, *callback, *extra_args, *object;
1572 len = PyTuple_Size(args);
1574 PyErr_SetString(PyExc_TypeError,
1575 "GObject.connect_object requires at least 3 arguments");
1578 first = PySequence_GetSlice(args, 0, 3);
1579 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1580 &name, &callback, &object)) {
1585 if (!PyCallable_Check(callback)) {
1586 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1590 CHECK_GOBJECT(self);
1592 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1593 &sigid, &detail, TRUE)) {
1594 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1595 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1599 extra_args = PySequence_GetSlice(args, 3, len);
1600 if (extra_args == NULL)
1603 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1604 if (closure == NULL)
1605 closure = pyg_closure_new(callback, extra_args, object);
1607 pygobject_watch_closure((PyObject *)self, closure);
1608 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1610 Py_DECREF(extra_args);
1611 return PyLong_FromUnsignedLong(handlerid);
1615 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1617 PyObject *first, *callback, *extra_args, *object;
1625 len = PyTuple_Size(args);
1627 PyErr_SetString(PyExc_TypeError,
1628 "GObject.connect_object_after requires at least 3 arguments");
1631 first = PySequence_GetSlice(args, 0, 3);
1632 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1633 &name, &callback, &object)) {
1638 if (!PyCallable_Check(callback)) {
1639 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1643 CHECK_GOBJECT(self);
1645 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1646 &sigid, &detail, TRUE)) {
1647 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1648 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1652 extra_args = PySequence_GetSlice(args, 3, len);
1653 if (extra_args == NULL)
1656 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1657 if (closure == NULL)
1658 closure = pyg_closure_new(callback, extra_args, object);
1660 pygobject_watch_closure((PyObject *)self, closure);
1661 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1663 Py_DECREF(extra_args);
1664 return PyLong_FromUnsignedLong(handlerid);
1668 pygobject_disconnect(PyGObject *self, PyObject *args)
1672 if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
1675 CHECK_GOBJECT(self);
1677 g_signal_handler_disconnect(self->obj, handler_id);
1683 pygobject_handler_is_connected(PyGObject *self, PyObject *args)
1687 if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
1691 CHECK_GOBJECT(self);
1693 return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
1697 pygobject_handler_block(PyGObject *self, PyObject *args)
1701 if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
1704 CHECK_GOBJECT(self);
1706 g_signal_handler_block(self->obj, handler_id);
1712 pygobject_handler_unblock(PyGObject *self, PyObject *args)
1716 if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
1718 g_signal_handler_unblock(self->obj, handler_id);
1724 pygobject_emit(PyGObject *self, PyObject *args)
1729 PyObject *first, *py_ret;
1732 GValue *params, ret = { 0, };
1734 len = PyTuple_Size(args);
1736 PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1739 first = PySequence_GetSlice(args, 0, 1);
1740 if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1746 CHECK_GOBJECT(self);
1748 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1749 &signal_id, &detail, TRUE)) {
1750 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1751 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1755 g_signal_query(signal_id, &query);
1756 if (len != query.n_params + 1) {
1759 g_snprintf(buf, sizeof(buf),
1760 "%d parameters needed for signal %s; %ld given",
1761 query.n_params, name, (long int) (len - 1));
1762 PyErr_SetString(PyExc_TypeError, buf);
1766 params = g_new0(GValue, query.n_params + 1);
1767 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1768 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1770 for (i = 0; i < query.n_params; i++)
1771 g_value_init(¶ms[i + 1],
1772 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1773 for (i = 0; i < query.n_params; i++) {
1774 PyObject *item = PyTuple_GetItem(args, i+1);
1776 if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1778 g_snprintf(buf, sizeof(buf),
1779 "could not convert type %s to %s required for parameter %d",
1780 Py_TYPE(item)->tp_name,
1781 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1782 PyErr_SetString(PyExc_TypeError, buf);
1784 for (i = 0; i < query.n_params + 1; i++)
1785 g_value_unset(¶ms[i]);
1792 if (query.return_type != G_TYPE_NONE)
1793 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1795 g_signal_emitv(params, signal_id, detail, &ret);
1797 for (i = 0; i < query.n_params + 1; i++)
1798 g_value_unset(¶ms[i]);
1801 if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1802 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1803 g_value_unset(&ret);
1813 pygobject_stop_emission(PyGObject *self, PyObject *args)
1819 if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
1822 CHECK_GOBJECT(self);
1824 if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
1825 &signal_id, &detail, TRUE)) {
1826 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1827 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1831 g_signal_stop_emission(self->obj, signal_id, detail);
1837 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1839 GSignalInvocationHint *ihint;
1845 GValue *params, ret = { 0, };
1847 CHECK_GOBJECT(self);
1849 ihint = g_signal_get_invocation_hint(self->obj);
1851 PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1852 "information for this object.");
1856 signal_id = ihint->signal_id;
1857 name = g_signal_name(signal_id);
1859 len = PyTuple_Size(args);
1860 if (signal_id == 0) {
1861 PyErr_SetString(PyExc_TypeError, "unknown signal name");
1864 g_signal_query(signal_id, &query);
1865 if (len != query.n_params) {
1868 g_snprintf(buf, sizeof(buf),
1869 "%d parameters needed for signal %s; %ld given",
1870 query.n_params, name, (long int) len);
1871 PyErr_SetString(PyExc_TypeError, buf);
1874 params = g_new0(GValue, query.n_params + 1);
1875 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1876 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1878 for (i = 0; i < query.n_params; i++)
1879 g_value_init(¶ms[i + 1],
1880 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1881 for (i = 0; i < query.n_params; i++) {
1882 PyObject *item = PyTuple_GetItem(args, i);
1884 if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1885 g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void));
1887 else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1890 g_snprintf(buf, sizeof(buf),
1891 "could not convert type %s to %s required for parameter %d",
1892 Py_TYPE(item)->tp_name,
1893 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1894 PyErr_SetString(PyExc_TypeError, buf);
1895 for (i = 0; i < query.n_params + 1; i++)
1896 g_value_unset(¶ms[i]);
1901 if (query.return_type != G_TYPE_NONE)
1902 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1903 g_signal_chain_from_overridden(params, &ret);
1904 for (i = 0; i < query.n_params + 1; i++)
1905 g_value_unset(¶ms[i]);
1907 if (query.return_type != G_TYPE_NONE) {
1908 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1909 g_value_unset(&ret);
1919 pygobject_weak_ref(PyGObject *self, PyObject *args)
1922 PyObject *callback = NULL, *user_data = NULL;
1925 CHECK_GOBJECT(self);
1927 if ((len = PySequence_Length(args)) >= 1) {
1928 callback = PySequence_ITEM(args, 0);
1929 user_data = PySequence_GetSlice(args, 1, len);
1931 retval = pygobject_weak_ref_new(self->obj, callback, user_data);
1932 Py_XDECREF(callback);
1933 Py_XDECREF(user_data);
1939 pygobject_copy(PyGObject *self)
1941 PyErr_SetString(PyExc_TypeError,
1942 "GObject descendants' instances are non-copyable");
1947 pygobject_deepcopy(PyGObject *self, PyObject *args)
1949 PyErr_SetString(PyExc_TypeError,
1950 "GObject descendants' instances are non-copyable");
1956 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
1958 PyObject *pyfunc = NULL;
1959 GClosure *closure = NULL;
1962 CHECK_GOBJECT(self);
1964 if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
1967 if (!PyCallable_Check(pyfunc)) {
1968 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
1972 closure = gclosure_from_pyfunc(self, pyfunc);
1974 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
1975 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
1979 retval = g_signal_handlers_disconnect_matched(self->obj,
1980 G_SIGNAL_MATCH_CLOSURE,
1984 return PYGLIB_PyLong_FromLong(retval);
1988 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
1990 PyObject *pyfunc = NULL;
1991 GClosure *closure = NULL;
1994 CHECK_GOBJECT(self);
1996 if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
1999 if (!PyCallable_Check(pyfunc)) {
2000 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2004 closure = gclosure_from_pyfunc(self, pyfunc);
2006 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2007 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2011 retval = g_signal_handlers_block_matched(self->obj,
2012 G_SIGNAL_MATCH_CLOSURE,
2016 return PYGLIB_PyLong_FromLong(retval);
2020 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2022 PyObject *pyfunc = NULL;
2023 GClosure *closure = NULL;
2026 CHECK_GOBJECT(self);
2028 if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2031 if (!PyCallable_Check(pyfunc)) {
2032 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2036 closure = gclosure_from_pyfunc(self, pyfunc);
2038 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2039 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2043 retval = g_signal_handlers_unblock_matched(self->obj,
2044 G_SIGNAL_MATCH_CLOSURE,
2048 return PYGLIB_PyLong_FromLong(retval);
2051 static PyMethodDef pygobject_methods[] = {
2052 { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2053 { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2054 { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2055 { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2056 { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
2057 { "notify", (PyCFunction)pygobject_notify, METH_VARARGS },
2058 { "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS },
2059 { "get_data", (PyCFunction)pygobject_get_data, METH_VARARGS },
2060 { "set_data", (PyCFunction)pygobject_set_data, METH_VARARGS },
2061 { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2062 { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2063 { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2064 { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2065 { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2066 { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2067 { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2068 { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
2069 { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
2070 { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
2071 { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2072 { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2073 { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2074 { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
2075 { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
2076 { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2077 { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2078 { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2079 { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2085 pygobject_get_dict(PyGObject *self, void *closure)
2087 if (self->inst_dict == NULL) {
2088 self->inst_dict = PyDict_New();
2089 if (self->inst_dict == NULL)
2091 if (G_LIKELY(self->obj))
2092 pygobject_switch_to_toggle_ref(self);
2094 Py_INCREF(self->inst_dict);
2095 return self->inst_dict;
2099 pygobject_get_refcount(PyGObject *self, void *closure)
2101 return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2105 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2108 PyGObject *gself = (PyGObject *) self;
2109 PyObject *inst_dict_before = gself->inst_dict;
2110 /* call parent type's setattro */
2111 res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2112 if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2113 if (G_LIKELY(gself->obj))
2114 pygobject_switch_to_toggle_ref(gself);
2119 static PyGetSetDef pygobject_getsets[] = {
2120 { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2121 { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2125 /* ------------------------------------ */
2126 /* ****** GObject weak reference ****** */
2127 /* ------------------------------------ */
2133 PyObject *user_data;
2134 gboolean have_floating_ref;
2137 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2140 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2142 if (self->callback && visit(self->callback, arg) < 0)
2144 if (self->user_data && visit(self->user_data, arg) < 0)
2150 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2153 if (self->callback) {
2155 PyGILState_STATE state = pyglib_gil_state_ensure();
2156 retval = PyObject_Call(self->callback, self->user_data, NULL);
2158 if (retval != Py_None)
2159 PyErr_Format(PyExc_TypeError,
2160 "GObject weak notify callback returned a value"
2161 " of type %s, should return None",
2162 Py_TYPE(retval)->tp_name);
2167 Py_CLEAR(self->callback);
2168 Py_CLEAR(self->user_data);
2169 if (self->have_floating_ref) {
2170 self->have_floating_ref = FALSE;
2171 Py_DECREF((PyObject *) self);
2173 pyglib_gil_state_release(state);
2178 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2180 Py_CLEAR(self->callback);
2181 Py_CLEAR(self->user_data);
2183 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2190 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2192 PyObject_GC_UnTrack((PyObject *)self);
2193 pygobject_weak_ref_clear(self);
2194 PyObject_GC_Del(self);
2198 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2200 PyGObjectWeakRef *self;
2202 self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2203 self->callback = callback;
2204 self->user_data = user_data;
2205 Py_XINCREF(self->callback);
2206 Py_XINCREF(self->user_data);
2208 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2209 if (callback != NULL) {
2210 /* when we have a callback, we should INCREF the weakref
2211 * object to make it stay alive even if it goes out of scope */
2212 self->have_floating_ref = TRUE;
2213 Py_INCREF((PyObject *) self);
2215 return (PyObject *) self;
2219 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2222 PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2225 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2227 if (self->have_floating_ref) {
2228 self->have_floating_ref = FALSE;
2235 static PyMethodDef pygobject_weak_ref_methods[] = {
2236 { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2241 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2243 static char *argnames[] = {NULL};
2245 if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2249 return pygobject_new_full(self->obj, FALSE, NULL);
2257 pyobject_copy(gpointer boxed)
2259 PyObject *object = boxed;
2266 pyobject_free(gpointer boxed)
2268 PyObject *object = boxed;
2269 PyGILState_STATE state;
2271 state = pyglib_gil_state_ensure();
2273 pyglib_gil_state_release(state);
2277 pygobject_object_register_types(PyObject *d)
2279 PyObject *o, *descr;
2281 pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2282 pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2283 pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2284 pygobject_has_updated_constructor_key =
2285 g_quark_from_static_string("PyGObject::has-updated-constructor");
2286 pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2289 if (!PY_TYPE_OBJECT)
2290 PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2293 PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2294 PyGObject_Type.tp_richcompare = pygobject_richcompare;
2295 PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2296 PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2297 PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2298 PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2299 Py_TPFLAGS_HAVE_GC);
2300 PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2301 PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2302 PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2303 PyGObject_Type.tp_methods = pygobject_methods;
2304 PyGObject_Type.tp_getset = pygobject_getsets;
2305 PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2306 PyGObject_Type.tp_init = (initproc)pygobject_init;
2307 PyGObject_Type.tp_free = (freefunc)pygobject_free;
2308 PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2309 PyGObject_Type.tp_new = PyType_GenericNew;
2310 pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2311 &PyGObject_Type, NULL);
2312 PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2313 pyg_object_descr_doc_get());
2316 PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2317 PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2318 PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2319 PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2320 PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2321 PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2322 "Python attributes.";
2323 PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2324 PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2325 if (PyType_Ready(&PyGProps_Type) < 0)
2329 PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2330 PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2331 if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2333 descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2334 PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2335 PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2336 o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject"));
2340 PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2341 PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2342 PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2343 PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2344 if (PyType_Ready(&PyGPropsIter_Type) < 0)
2347 PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2348 PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2349 PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2350 PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2351 PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2352 PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2353 PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2354 if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2356 PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);