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);
997 /* -------------- Freeze Notify Context Manager ----------------- */
1000 * pygcontext_manager_enter
1001 * @self: Freeze or Block context instance
1003 * Method used for __enter__ on both GContextFeezeNotify and
1004 * GContextHandlerBlock. Does nothing since this is an object returned
1005 * by the freeze_notify() and handler_block() methods which do the actual
1006 * work of freezing and blocking.
1009 pygcontext_manager_enter(PyObject *self)
1018 } PyGContextFreezeNotify;
1020 PYGLIB_DEFINE_TYPE("gi._gobject.GContextFreezeNotify",
1021 PyGContextFreezeNotify_Type, PyGContextFreezeNotify);
1024 pygcontext_freeze_notify_new(GObject *gobj)
1026 PyGContextFreezeNotify *context;
1028 context = PyObject_New(PyGContextFreezeNotify, &PyGContextFreezeNotify_Type);
1029 if (context == NULL)
1033 context->obj = gobj;
1034 return (PyObject*)context;
1038 pygcontext_freeze_notify_dealloc(PyGContextFreezeNotify* self)
1040 g_object_unref(self->obj);
1042 PyObject_Del((PyObject*)self);
1046 pygcontext_freeze_notify_exit(PyGContextFreezeNotify *self, PyObject *args)
1048 g_object_thaw_notify(self->obj);
1052 static PyMethodDef pygcontext_freeze_notify_methods[] = {
1053 {"__enter__", (PyCFunction)pygcontext_manager_enter, METH_NOARGS, ""},
1054 {"__exit__", (PyCFunction)pygcontext_freeze_notify_exit, METH_VARARGS, ""},
1058 /* -------------- Handler Block Context Manager ----------------- */
1063 } PyGContextHandlerBlock;
1065 PYGLIB_DEFINE_TYPE("gi._gobject.GContextHandlerBlock",
1066 PyGContextHandlerBlock_Type, PyGContextHandlerBlock);
1069 pygcontext_handler_block_new(GObject *gobj, gulong handler_id)
1071 PyGContextHandlerBlock *context;
1073 context = PyObject_New(PyGContextHandlerBlock, &PyGContextHandlerBlock_Type);
1074 if (context == NULL)
1078 context->obj = gobj;
1079 context->handler_id = handler_id;
1080 return (PyObject*)context;
1084 pygcontext_handler_block_dealloc(PyGContextHandlerBlock* self)
1086 g_object_unref(self->obj);
1088 PyObject_Del((PyObject*)self);
1092 pygcontext_handler_block_exit(PyGContextHandlerBlock *self, PyObject *args)
1094 g_signal_handler_unblock(self->obj, self->handler_id);
1099 static PyMethodDef pygcontext_handler_block_methods[] = {
1100 {"__enter__", (PyCFunction)pygcontext_manager_enter, METH_NOARGS, ""},
1101 {"__exit__", (PyCFunction)pygcontext_handler_block_exit, METH_VARARGS, ""},
1106 /* -------------- PyGObject behaviour ----------------- */
1108 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
1111 pygobject_dealloc(PyGObject *self)
1113 /* Untrack must be done first. This is because followup calls such as
1114 * ClearWeakRefs could call into Python and cause new allocations to
1115 * happen, which could in turn could trigger the garbage collector,
1116 * which would then get confused as it is tracking this half-deallocated
1118 PyObject_GC_UnTrack((PyObject *)self);
1120 PyObject_ClearWeakRefs((PyObject *)self);
1121 /* this forces inst_data->type to be updated, which could prove
1122 * important if a new wrapper has to be created and it is of a
1123 * unregistered type */
1124 pygobject_get_inst_data(self);
1125 pygobject_clear(self);
1126 /* the following causes problems with subclassed types */
1127 /* Py_TYPE(self)->tp_free((PyObject *)self); */
1128 PyObject_GC_Del(self);
1132 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1136 isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1140 Py_INCREF(Py_NotImplemented);
1141 return Py_NotImplemented;
1143 isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1147 Py_INCREF(Py_NotImplemented);
1148 return Py_NotImplemented;
1151 return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1152 ((PyGObject*)other)->obj,
1157 pygobject_hash(PyGObject *self)
1159 return (long)self->obj;
1163 pygobject_repr(PyGObject *self)
1167 g_snprintf(buf, sizeof(buf),
1168 "<%s object at 0x%lx (%s at 0x%lx)>",
1169 Py_TYPE(self)->tp_name,
1171 self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
1173 return PYGLIB_PyUnicode_FromString(buf);
1178 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1182 PyGObjectData *data = pygobject_get_inst_data(self);
1184 if (self->inst_dict) ret = visit(self->inst_dict, arg);
1185 if (ret != 0) return ret;
1189 for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1190 PyGClosure *closure = tmp->data;
1192 if (closure->callback) ret = visit(closure->callback, arg);
1193 if (ret != 0) return ret;
1195 if (closure->extra_args) ret = visit(closure->extra_args, arg);
1196 if (ret != 0) return ret;
1198 if (closure->swap_data) ret = visit(closure->swap_data, arg);
1199 if (ret != 0) return ret;
1206 pygobject_clear(PyGObject *self)
1209 g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1210 if (self->inst_dict) {
1211 g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
1212 self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1214 pyg_begin_allow_threads;
1215 g_object_unref(self->obj);
1216 pyg_end_allow_threads;
1220 Py_CLEAR(self->inst_dict);
1225 pygobject_free(PyObject *op)
1227 PyObject_GC_Del(op);
1231 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1232 guint *n_params, GParameter **params)
1242 *params = g_new0(GParameter, PyDict_Size(kwargs));
1243 while (PyDict_Next(kwargs, &pos, &key, &value)) {
1245 GParameter *param = &(*params)[*n_params];
1246 const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1248 pspec = g_object_class_find_property(class, key_str);
1250 PyErr_Format(PyExc_TypeError,
1251 "gobject `%s' doesn't support property `%s'",
1252 G_OBJECT_CLASS_NAME(class), key_str);
1255 g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1256 if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) {
1257 PyErr_Format(PyExc_TypeError,
1258 "could not convert value for property `%s' from %s to %s",
1259 key_str, Py_TYPE(value)->tp_name,
1260 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1263 param->name = g_strdup(key_str);
1270 /* ---------------- PyGObject methods ----------------- */
1273 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1276 guint n_params = 0, i;
1277 GParameter *params = NULL;
1278 GObjectClass *class;
1280 if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
1283 object_type = pyg_type_from_object((PyObject *)self);
1287 if (G_TYPE_IS_ABSTRACT(object_type)) {
1288 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1289 "(non-instantiable) type `%s'", g_type_name(object_type));
1293 if ((class = g_type_class_ref (object_type)) == NULL) {
1294 PyErr_SetString(PyExc_TypeError,
1295 "could not get a reference to type class");
1299 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms))
1302 if (pygobject_constructv(self, n_params, params))
1303 PyErr_SetString(PyExc_RuntimeError, "could not create object");
1306 for (i = 0; i < n_params; i++) {
1307 g_free((gchar *) params[i].name);
1308 g_value_unset(¶ms[i].value);
1311 g_type_class_unref(class);
1313 return (self->obj) ? 0 : -1;
1316 #define CHECK_GOBJECT(self) \
1317 if (!G_IS_OBJECT(self->obj)) { \
1318 PyErr_Format(PyExc_TypeError, \
1319 "object at %p of type %s is not initialized", \
1320 self, Py_TYPE(self)->tp_name); \
1325 pygobject_get_property(PyGObject *self, PyObject *args)
1329 GValue value = { 0, };
1332 if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name))
1335 CHECK_GOBJECT(self);
1337 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1340 PyErr_Format(PyExc_TypeError,
1341 "object of type `%s' does not have property `%s'",
1342 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1345 if (!(pspec->flags & G_PARAM_READABLE)) {
1346 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1350 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1351 pyg_begin_allow_threads;
1352 g_object_get_property(self->obj, param_name, &value);
1353 pyg_end_allow_threads;
1354 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
1355 g_value_unset(&value);
1360 pygobject_get_properties(PyGObject *self, PyObject *args)
1362 GObjectClass *class;
1366 if ((len = PyTuple_Size(args)) < 1) {
1367 PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1371 tuple = PyTuple_New(len);
1372 class = G_OBJECT_GET_CLASS(self->obj);
1373 for (i = 0; i < len; i++) {
1374 PyObject *py_property = PyTuple_GetItem(args, i);
1375 gchar *property_name;
1377 GValue value = { 0 };
1380 if (!PYGLIB_PyUnicode_Check(py_property)) {
1381 PyErr_SetString(PyExc_TypeError,
1382 "Expected string argument for property.");
1386 property_name = PYGLIB_PyUnicode_AsString(py_property);
1388 pspec = g_object_class_find_property(class,
1391 PyErr_Format(PyExc_TypeError,
1392 "object of type `%s' does not have property `%s'",
1393 g_type_name(G_OBJECT_TYPE(self->obj)), property_name);
1396 if (!(pspec->flags & G_PARAM_READABLE)) {
1397 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1401 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1403 pyg_begin_allow_threads;
1404 g_object_get_property(self->obj, property_name, &value);
1405 pyg_end_allow_threads;
1407 item = pyg_value_as_pyobject(&value, TRUE);
1408 PyTuple_SetItem(tuple, i, item);
1410 g_value_unset(&value);
1417 pygobject_set_property(PyGObject *self, PyObject *args)
1423 if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name,
1427 CHECK_GOBJECT(self);
1429 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1432 PyErr_Format(PyExc_TypeError,
1433 "object of type `%s' does not have property `%s'",
1434 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1438 if (!set_property_from_pspec(self->obj, param_name, pspec, pvalue))
1446 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1448 GObjectClass *class;
1452 PyObject *result = NULL;
1454 CHECK_GOBJECT(self);
1456 class = G_OBJECT_GET_CLASS(self->obj);
1458 g_object_freeze_notify (G_OBJECT(self->obj));
1461 while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1462 gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1465 pspec = g_object_class_find_property(class, key_str);
1469 g_snprintf(buf, sizeof(buf),
1470 "object `%s' doesn't support property `%s'",
1471 g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1472 PyErr_SetString(PyExc_TypeError, buf);
1476 if (!set_property_from_pspec(G_OBJECT(self->obj), key_str, pspec, value))
1483 g_object_thaw_notify (G_OBJECT(self->obj));
1489 pygobject_freeze_notify(PyGObject *self, PyObject *args)
1491 if (!PyArg_ParseTuple(args, ":GObject.freeze_notify"))
1494 CHECK_GOBJECT(self);
1496 g_object_freeze_notify(self->obj);
1497 return pygcontext_freeze_notify_new(self->obj);
1501 pygobject_notify(PyGObject *self, PyObject *args)
1503 char *property_name;
1505 if (!PyArg_ParseTuple(args, "s:GObject.notify", &property_name))
1508 CHECK_GOBJECT(self);
1510 g_object_notify(self->obj, property_name);
1516 pygobject_thaw_notify(PyGObject *self, PyObject *args)
1518 if (!PyArg_ParseTuple(args, ":GObject.thaw_notify"))
1521 CHECK_GOBJECT(self);
1523 g_object_thaw_notify(self->obj);
1529 pygobject_connect(PyGObject *self, PyObject *args)
1531 PyObject *first, *callback, *extra_args;
1538 len = PyTuple_Size(args);
1540 PyErr_SetString(PyExc_TypeError,
1541 "GObject.connect requires at least 2 arguments");
1544 first = PySequence_GetSlice(args, 0, 2);
1545 if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1550 if (!PyCallable_Check(callback)) {
1551 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1555 CHECK_GOBJECT(self);
1557 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1558 &sigid, &detail, TRUE)) {
1559 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1560 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1564 extra_args = PySequence_GetSlice(args, 2, len);
1565 if (extra_args == NULL)
1568 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1569 if (closure == NULL)
1570 closure = pyg_closure_new(callback, extra_args, NULL);
1572 pygobject_watch_closure((PyObject *)self, closure);
1573 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1575 Py_DECREF(extra_args);
1576 return PyLong_FromUnsignedLong(handlerid);
1580 pygobject_connect_after(PyGObject *self, PyObject *args)
1582 PyObject *first, *callback, *extra_args;
1590 len = PyTuple_Size(args);
1592 PyErr_SetString(PyExc_TypeError,
1593 "GObject.connect_after requires at least 2 arguments");
1596 first = PySequence_GetSlice(args, 0, 2);
1597 if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1598 &name, &callback)) {
1603 if (!PyCallable_Check(callback)) {
1604 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1608 CHECK_GOBJECT(self);
1610 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1611 &sigid, &detail, TRUE)) {
1612 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1613 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1617 extra_args = PySequence_GetSlice(args, 2, len);
1618 if (extra_args == NULL)
1621 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1622 if (closure == NULL)
1623 closure = pyg_closure_new(callback, extra_args, NULL);
1625 pygobject_watch_closure((PyObject *)self, closure);
1626 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1628 Py_DECREF(extra_args);
1629 return PyLong_FromUnsignedLong(handlerid);
1633 pygobject_connect_object(PyGObject *self, PyObject *args)
1635 PyObject *first, *callback, *extra_args, *object;
1643 len = PyTuple_Size(args);
1645 PyErr_SetString(PyExc_TypeError,
1646 "GObject.connect_object requires at least 3 arguments");
1649 first = PySequence_GetSlice(args, 0, 3);
1650 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1651 &name, &callback, &object)) {
1656 if (!PyCallable_Check(callback)) {
1657 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1661 CHECK_GOBJECT(self);
1663 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1664 &sigid, &detail, TRUE)) {
1665 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1666 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1670 extra_args = PySequence_GetSlice(args, 3, len);
1671 if (extra_args == NULL)
1674 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1675 if (closure == NULL)
1676 closure = pyg_closure_new(callback, extra_args, object);
1678 pygobject_watch_closure((PyObject *)self, closure);
1679 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1681 Py_DECREF(extra_args);
1682 return PyLong_FromUnsignedLong(handlerid);
1686 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1688 PyObject *first, *callback, *extra_args, *object;
1696 len = PyTuple_Size(args);
1698 PyErr_SetString(PyExc_TypeError,
1699 "GObject.connect_object_after requires at least 3 arguments");
1702 first = PySequence_GetSlice(args, 0, 3);
1703 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1704 &name, &callback, &object)) {
1709 if (!PyCallable_Check(callback)) {
1710 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1714 CHECK_GOBJECT(self);
1716 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1717 &sigid, &detail, TRUE)) {
1718 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1719 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1723 extra_args = PySequence_GetSlice(args, 3, len);
1724 if (extra_args == NULL)
1727 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1728 if (closure == NULL)
1729 closure = pyg_closure_new(callback, extra_args, object);
1731 pygobject_watch_closure((PyObject *)self, closure);
1732 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1734 Py_DECREF(extra_args);
1735 return PyLong_FromUnsignedLong(handlerid);
1739 pygobject_disconnect(PyGObject *self, PyObject *args)
1743 if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
1746 CHECK_GOBJECT(self);
1748 g_signal_handler_disconnect(self->obj, handler_id);
1754 pygobject_handler_is_connected(PyGObject *self, PyObject *args)
1758 if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
1762 CHECK_GOBJECT(self);
1764 return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
1768 pygobject_handler_block(PyGObject *self, PyObject *args)
1772 if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
1775 CHECK_GOBJECT(self);
1777 g_signal_handler_block(self->obj, handler_id);
1778 return pygcontext_handler_block_new(self->obj, handler_id);
1782 pygobject_handler_unblock(PyGObject *self, PyObject *args)
1786 if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
1788 g_signal_handler_unblock(self->obj, handler_id);
1794 pygobject_emit(PyGObject *self, PyObject *args)
1799 PyObject *first, *py_ret;
1802 GValue *params, ret = { 0, };
1804 len = PyTuple_Size(args);
1806 PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1809 first = PySequence_GetSlice(args, 0, 1);
1810 if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1816 CHECK_GOBJECT(self);
1818 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1819 &signal_id, &detail, TRUE)) {
1820 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1821 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1825 g_signal_query(signal_id, &query);
1826 if (len != query.n_params + 1) {
1829 g_snprintf(buf, sizeof(buf),
1830 "%d parameters needed for signal %s; %ld given",
1831 query.n_params, name, (long int) (len - 1));
1832 PyErr_SetString(PyExc_TypeError, buf);
1836 params = g_new0(GValue, query.n_params + 1);
1837 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1838 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1840 for (i = 0; i < query.n_params; i++)
1841 g_value_init(¶ms[i + 1],
1842 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1843 for (i = 0; i < query.n_params; i++) {
1844 PyObject *item = PyTuple_GetItem(args, i+1);
1846 if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1848 g_snprintf(buf, sizeof(buf),
1849 "could not convert type %s to %s required for parameter %d",
1850 Py_TYPE(item)->tp_name,
1851 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1852 PyErr_SetString(PyExc_TypeError, buf);
1854 for (i = 0; i < query.n_params + 1; i++)
1855 g_value_unset(¶ms[i]);
1862 if (query.return_type != G_TYPE_NONE)
1863 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1865 g_signal_emitv(params, signal_id, detail, &ret);
1867 for (i = 0; i < query.n_params + 1; i++)
1868 g_value_unset(¶ms[i]);
1871 if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1872 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1873 g_value_unset(&ret);
1883 pygobject_stop_emission(PyGObject *self, PyObject *args)
1889 if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
1892 CHECK_GOBJECT(self);
1894 if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
1895 &signal_id, &detail, TRUE)) {
1896 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1897 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1901 g_signal_stop_emission(self->obj, signal_id, detail);
1907 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1909 GSignalInvocationHint *ihint;
1915 GValue *params, ret = { 0, };
1917 CHECK_GOBJECT(self);
1919 ihint = g_signal_get_invocation_hint(self->obj);
1921 PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1922 "information for this object.");
1926 signal_id = ihint->signal_id;
1927 name = g_signal_name(signal_id);
1929 len = PyTuple_Size(args);
1930 if (signal_id == 0) {
1931 PyErr_SetString(PyExc_TypeError, "unknown signal name");
1934 g_signal_query(signal_id, &query);
1935 if (len != query.n_params) {
1938 g_snprintf(buf, sizeof(buf),
1939 "%d parameters needed for signal %s; %ld given",
1940 query.n_params, name, (long int) len);
1941 PyErr_SetString(PyExc_TypeError, buf);
1944 params = g_new0(GValue, query.n_params + 1);
1945 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1946 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1948 for (i = 0; i < query.n_params; i++)
1949 g_value_init(¶ms[i + 1],
1950 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1951 for (i = 0; i < query.n_params; i++) {
1952 PyObject *item = PyTuple_GetItem(args, i);
1954 if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1955 g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void));
1957 else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1960 g_snprintf(buf, sizeof(buf),
1961 "could not convert type %s to %s required for parameter %d",
1962 Py_TYPE(item)->tp_name,
1963 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1964 PyErr_SetString(PyExc_TypeError, buf);
1965 for (i = 0; i < query.n_params + 1; i++)
1966 g_value_unset(¶ms[i]);
1971 if (query.return_type != G_TYPE_NONE)
1972 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1973 g_signal_chain_from_overridden(params, &ret);
1974 for (i = 0; i < query.n_params + 1; i++)
1975 g_value_unset(¶ms[i]);
1977 if (query.return_type != G_TYPE_NONE) {
1978 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1979 g_value_unset(&ret);
1989 pygobject_weak_ref(PyGObject *self, PyObject *args)
1992 PyObject *callback = NULL, *user_data = NULL;
1995 CHECK_GOBJECT(self);
1997 if ((len = PySequence_Length(args)) >= 1) {
1998 callback = PySequence_ITEM(args, 0);
1999 user_data = PySequence_GetSlice(args, 1, len);
2001 retval = pygobject_weak_ref_new(self->obj, callback, user_data);
2002 Py_XDECREF(callback);
2003 Py_XDECREF(user_data);
2009 pygobject_copy(PyGObject *self)
2011 PyErr_SetString(PyExc_TypeError,
2012 "GObject descendants' instances are non-copyable");
2017 pygobject_deepcopy(PyGObject *self, PyObject *args)
2019 PyErr_SetString(PyExc_TypeError,
2020 "GObject descendants' instances are non-copyable");
2026 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
2028 PyObject *pyfunc = NULL;
2029 GClosure *closure = NULL;
2032 CHECK_GOBJECT(self);
2034 if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2037 if (!PyCallable_Check(pyfunc)) {
2038 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2042 closure = gclosure_from_pyfunc(self, pyfunc);
2044 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2045 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2049 retval = g_signal_handlers_disconnect_matched(self->obj,
2050 G_SIGNAL_MATCH_CLOSURE,
2054 return PYGLIB_PyLong_FromLong(retval);
2058 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2060 PyObject *pyfunc = NULL;
2061 GClosure *closure = NULL;
2064 CHECK_GOBJECT(self);
2066 if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2069 if (!PyCallable_Check(pyfunc)) {
2070 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2074 closure = gclosure_from_pyfunc(self, pyfunc);
2076 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2077 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2081 retval = g_signal_handlers_block_matched(self->obj,
2082 G_SIGNAL_MATCH_CLOSURE,
2086 return PYGLIB_PyLong_FromLong(retval);
2090 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2092 PyObject *pyfunc = NULL;
2093 GClosure *closure = NULL;
2096 CHECK_GOBJECT(self);
2098 if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2101 if (!PyCallable_Check(pyfunc)) {
2102 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2106 closure = gclosure_from_pyfunc(self, pyfunc);
2108 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2109 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2113 retval = g_signal_handlers_unblock_matched(self->obj,
2114 G_SIGNAL_MATCH_CLOSURE,
2118 return PYGLIB_PyLong_FromLong(retval);
2121 static PyMethodDef pygobject_methods[] = {
2122 { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2123 { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2124 { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2125 { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2126 { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
2127 { "notify", (PyCFunction)pygobject_notify, METH_VARARGS },
2128 { "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS },
2129 { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2130 { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2131 { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2132 { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2133 { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2134 { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2135 { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2136 { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
2137 { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
2138 { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
2139 { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2140 { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2141 { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2142 { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
2143 { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
2144 { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2145 { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2146 { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2147 { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2153 pygobject_get_dict(PyGObject *self, void *closure)
2155 if (self->inst_dict == NULL) {
2156 self->inst_dict = PyDict_New();
2157 if (self->inst_dict == NULL)
2159 if (G_LIKELY(self->obj))
2160 pygobject_switch_to_toggle_ref(self);
2162 Py_INCREF(self->inst_dict);
2163 return self->inst_dict;
2167 pygobject_get_refcount(PyGObject *self, void *closure)
2169 if (self->obj == NULL) {
2170 PyErr_Format(PyExc_TypeError, "GObject instance is not yet created");
2173 return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2177 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2180 PyGObject *gself = (PyGObject *) self;
2181 PyObject *inst_dict_before = gself->inst_dict;
2182 /* call parent type's setattro */
2183 res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2184 if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2185 if (G_LIKELY(gself->obj))
2186 pygobject_switch_to_toggle_ref(gself);
2191 static PyGetSetDef pygobject_getsets[] = {
2192 { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2193 { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2197 /* ------------------------------------ */
2198 /* ****** GObject weak reference ****** */
2199 /* ------------------------------------ */
2205 PyObject *user_data;
2206 gboolean have_floating_ref;
2209 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2212 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2214 if (self->callback && visit(self->callback, arg) < 0)
2216 if (self->user_data && visit(self->user_data, arg) < 0)
2222 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2225 if (self->callback) {
2227 PyGILState_STATE state = pyglib_gil_state_ensure();
2228 retval = PyObject_Call(self->callback, self->user_data, NULL);
2230 if (retval != Py_None)
2231 PyErr_Format(PyExc_TypeError,
2232 "GObject weak notify callback returned a value"
2233 " of type %s, should return None",
2234 Py_TYPE(retval)->tp_name);
2239 Py_CLEAR(self->callback);
2240 Py_CLEAR(self->user_data);
2241 if (self->have_floating_ref) {
2242 self->have_floating_ref = FALSE;
2243 Py_DECREF((PyObject *) self);
2245 pyglib_gil_state_release(state);
2250 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2252 Py_CLEAR(self->callback);
2253 Py_CLEAR(self->user_data);
2255 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2262 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2264 PyObject_GC_UnTrack((PyObject *)self);
2265 pygobject_weak_ref_clear(self);
2266 PyObject_GC_Del(self);
2270 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2272 PyGObjectWeakRef *self;
2274 self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2275 self->callback = callback;
2276 self->user_data = user_data;
2277 Py_XINCREF(self->callback);
2278 Py_XINCREF(self->user_data);
2280 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2281 if (callback != NULL) {
2282 /* when we have a callback, we should INCREF the weakref
2283 * object to make it stay alive even if it goes out of scope */
2284 self->have_floating_ref = TRUE;
2285 Py_INCREF((PyObject *) self);
2287 return (PyObject *) self;
2291 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2294 PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2297 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2299 if (self->have_floating_ref) {
2300 self->have_floating_ref = FALSE;
2307 static PyMethodDef pygobject_weak_ref_methods[] = {
2308 { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2313 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2315 static char *argnames[] = {NULL};
2317 if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2321 return pygobject_new_full(self->obj, FALSE, NULL);
2329 pyobject_copy(gpointer boxed)
2331 PyObject *object = boxed;
2338 pyobject_free(gpointer boxed)
2340 PyObject *object = boxed;
2341 PyGILState_STATE state;
2343 state = pyglib_gil_state_ensure();
2345 pyglib_gil_state_release(state);
2349 pygobject_object_register_types(PyObject *d)
2351 PyObject *o, *descr;
2353 pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2354 pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2355 pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2356 pygobject_has_updated_constructor_key =
2357 g_quark_from_static_string("PyGObject::has-updated-constructor");
2358 pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2361 if (!PY_TYPE_OBJECT)
2362 PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2365 PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2366 PyGObject_Type.tp_richcompare = pygobject_richcompare;
2367 PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2368 PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2369 PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2370 PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2371 Py_TPFLAGS_HAVE_GC);
2372 PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2373 PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2374 PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2375 PyGObject_Type.tp_methods = pygobject_methods;
2376 PyGObject_Type.tp_getset = pygobject_getsets;
2377 PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2378 PyGObject_Type.tp_init = (initproc)pygobject_init;
2379 PyGObject_Type.tp_free = (freefunc)pygobject_free;
2380 PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2381 PyGObject_Type.tp_new = PyType_GenericNew;
2382 pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2383 &PyGObject_Type, NULL);
2384 PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2385 pyg_object_descr_doc_get());
2388 PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2389 PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2390 PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2391 PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2392 PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2393 PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2394 "Python attributes.";
2395 PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2396 PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2397 if (PyType_Ready(&PyGProps_Type) < 0)
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)
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"));
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)
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)
2428 PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
2430 PyGContextFreezeNotify_Type.tp_dealloc = (destructor)pygcontext_freeze_notify_dealloc;
2431 PyGContextFreezeNotify_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2432 PyGContextFreezeNotify_Type.tp_doc = "Context manager for freeze/thaw of GObjects";
2433 PyGContextFreezeNotify_Type.tp_methods = pygcontext_freeze_notify_methods;
2434 if (PyType_Ready(&PyGContextFreezeNotify_Type) < 0)
2437 PyGContextHandlerBlock_Type.tp_dealloc = (destructor)pygcontext_handler_block_dealloc;
2438 PyGContextHandlerBlock_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2439 PyGContextHandlerBlock_Type.tp_doc = "Context manager for handler blocking of GObjects";
2440 PyGContextHandlerBlock_Type.tp_methods = pygcontext_handler_block_methods;
2441 if (PyType_Ready(&PyGContextHandlerBlock_Type) < 0)