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;
53 GQuark pygobject_ref_sunk_key;
56 /* -------------- class <-> wrapper manipulation --------------- */
59 pygobject_data_free(PyGObjectData *data)
61 PyGILState_STATE state = pyglib_gil_state_ensure();
62 GSList *closures, *tmp;
63 Py_DECREF(data->type);
64 tmp = closures = data->closures;
66 data->closures = NULL;
69 pyg_begin_allow_threads;
71 GClosure *closure = tmp->data;
73 /* we get next item first, because the current link gets
74 * invalidated by pygobject_unwatch_closure */
76 g_closure_invalidate(closure);
78 pyg_end_allow_threads;
80 if (data->closures != NULL)
81 g_warning("invalidated all closures, but data->closures != NULL !");
84 pyglib_gil_state_release(state);
87 static inline PyGObjectData *
88 pygobject_data_new(void)
91 data = g_new0(PyGObjectData, 1);
95 static inline PyGObjectData *
96 pygobject_get_inst_data(PyGObject *self)
98 PyGObjectData *inst_data;
100 if (G_UNLIKELY(!self->obj))
102 inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
103 if (inst_data == NULL)
105 inst_data = pygobject_data_new();
107 inst_data->type = Py_TYPE(self);
108 Py_INCREF((PyObject *) inst_data->type);
110 g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
111 inst_data, (GDestroyNotify) pygobject_data_free);
119 void (* sinkfunc)(GObject *object);
121 static GArray *sink_funcs = NULL;
123 GHashTable *custom_type_registration = NULL;
125 PyTypeObject *PyGObject_MetaType = NULL;
131 * As Python handles reference counting for us, the "floating
132 * reference" code in GTK is not all that useful. In fact, it can
133 * cause leaks. This function should be called to remove the floating
134 * references on objects on construction.
137 pygobject_sink(GObject *obj)
139 gboolean sunk = FALSE;
141 /* We use a gobject data key to avoid running the sink funcs more than once. */
142 if (g_object_get_qdata (obj, pygobject_ref_sunk_key))
148 for (i = 0; i < sink_funcs->len; i++) {
149 if (g_type_is_a(G_OBJECT_TYPE(obj),
150 g_array_index(sink_funcs, SinkFunc, i).type)) {
151 g_array_index(sink_funcs, SinkFunc, i).sinkfunc(obj);
159 if (!sunk && G_IS_INITIALLY_UNOWNED (obj))
160 g_object_ref_sink(obj);
162 g_object_set_qdata (obj, pygobject_ref_sunk_key, GINT_TO_POINTER (1));
166 * pygobject_register_sinkfunc:
167 * type: the GType the sink function applies to.
168 * sinkfunc: a function to remove the floating reference on an object.
170 * As Python handles reference counting for us, the "floating
171 * reference" code in GTK is not all that useful. In fact, it can
172 * cause leaks. For this reason, PyGTK removes the floating
173 * references on objects on construction.
175 * The sinkfunc should be able to remove the floating reference on
176 * instances of the given type, or any subclasses.
178 * Deprecated: Since 2.22, sinkfuncs are not needed.
181 pygobject_register_sinkfunc(GType type, void (* sinkfunc)(GObject *object))
185 g_message ("pygobject_register_sinkfunc is deprecated (%s)",
189 g_return_if_fail(G_TYPE_IS_OBJECT(type));
191 g_return_if_fail(sinkfunc != NULL);
194 sink_funcs = g_array_new(FALSE, FALSE, sizeof(SinkFunc));
197 sf.sinkfunc = sinkfunc;
198 g_array_append_val(sink_funcs, sf);
208 PYGLIB_DEFINE_TYPE("gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
211 pyg_props_iter_dealloc(PyGPropsIter *self)
214 PyObject_Del((PyObject*) self);
218 pygobject_props_iter_next(PyGPropsIter *iter)
220 if (iter->index < iter->n_props)
221 return pyg_param_spec_new(iter->props[iter->index++]);
223 PyErr_SetNone(PyExc_StopIteration);
230 /* a reference to the object containing the properties */
231 PyGObject *pygobject;
236 PyGProps_dealloc(PyGProps* self)
240 PyObject_GC_UnTrack((PyObject*)self);
242 tmp = self->pygobject;
243 self->pygobject = NULL;
246 PyObject_GC_Del((PyObject*)self);
250 build_parameter_list(GObjectClass *class)
253 guint n_props = 0, i;
255 PyObject *props_list;
257 props = g_object_class_list_properties(class, &n_props);
258 props_list = PyList_New(n_props);
259 for (i = 0; i < n_props; i++) {
261 name = g_strdup(g_param_spec_get_name(props[i]));
262 /* hyphens cannot belong in identifiers */
263 g_strdelimit(name, "-", '_');
264 prop_str = PYGLIB_PyUnicode_FromString(name);
266 PyList_SetItem(props_list, i, prop_str);
277 PyGProps_getattro(PyGProps *self, PyObject *attr)
282 GValue value = { 0, };
285 attr_name = PYGLIB_PyUnicode_AsString(attr);
288 return PyObject_GenericGetAttr((PyObject *)self, attr);
291 class = g_type_class_ref(self->gtype);
293 if (!strcmp(attr_name, "__members__")) {
294 return build_parameter_list(class);
297 if (self->pygobject != NULL) {
298 ret = pygi_get_property_value (self->pygobject, attr_name);
303 pspec = g_object_class_find_property(class, attr_name);
304 g_type_class_unref(class);
307 return PyObject_GenericGetAttr((PyObject *)self, attr);
310 if (!(pspec->flags & G_PARAM_READABLE)) {
311 PyErr_Format(PyExc_TypeError,
312 "property '%s' is not readable", attr_name);
316 /* If we're doing it without an instance, return a GParamSpec */
317 if (!self->pygobject) {
318 return pyg_param_spec_new(pspec);
321 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
322 pyg_begin_allow_threads;
323 g_object_get_property(self->pygobject->obj, attr_name, &value);
324 pyg_end_allow_threads;
325 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
326 g_value_unset(&value);
332 set_property_from_pspec(GObject *obj,
337 GValue value = { 0, };
339 if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
340 PyErr_Format(PyExc_TypeError,
341 "property '%s' can only be set in constructor",
346 if (!(pspec->flags & G_PARAM_WRITABLE)) {
347 PyErr_Format(PyExc_TypeError,
348 "property '%s' is not writable", attr_name);
352 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
353 if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
354 PyErr_SetString(PyExc_TypeError,
355 "could not convert argument to correct param type");
359 pyg_begin_allow_threads;
360 g_object_set_property(obj, attr_name, &value);
361 pyg_end_allow_threads;
363 g_value_unset(&value);
368 PYGLIB_DEFINE_TYPE("gobject.GProps", PyGProps_Type, PyGProps);
371 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
378 if (pvalue == NULL) {
379 PyErr_SetString(PyExc_TypeError, "properties cannot be "
384 attr_name = PYGLIB_PyUnicode_AsString(attr);
387 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
390 if (!self->pygobject) {
391 PyErr_SetString(PyExc_TypeError,
392 "cannot set GOject properties without an instance");
396 ret = pygi_set_property_value (self->pygobject, attr_name, pvalue);
400 if (PyErr_Occurred())
403 obj = self->pygobject->obj;
404 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), attr_name);
406 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
409 if (!set_property_from_pspec(obj, attr_name, pspec, pvalue))
416 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
418 if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
424 pygobject_props_get_iter(PyGProps *self)
429 iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
430 class = g_type_class_ref(self->gtype);
431 iter->props = g_object_class_list_properties(class, &iter->n_props);
433 g_type_class_unref(class);
434 return (PyObject *) iter;
438 PyGProps_length(PyGProps *self)
444 class = g_type_class_ref(self->gtype);
445 props = g_object_class_list_properties(class, &n_props);
446 g_type_class_unref(class);
449 return (Py_ssize_t)n_props;
452 static PySequenceMethods _PyGProps_as_sequence = {
453 (lenfunc) PyGProps_length,
462 PYGLIB_DEFINE_TYPE("gobject.GPropsDescr", PyGPropsDescr_Type, PyObject);
465 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
469 gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
470 if (obj == NULL || obj == Py_None) {
471 gprops->pygobject = NULL;
472 gprops->gtype = pyg_type_from_object(type);
474 if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
475 PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
476 " descriptor on non-GObject instances");
480 gprops->pygobject = (PyGObject *) obj;
481 gprops->gtype = pyg_type_from_object(obj);
483 return (PyObject *) gprops;
487 * pygobject_register_class:
488 * @dict: the module dictionary. A reference to the type will be stored here.
489 * @type_name: not used ?
490 * @gtype: the GType of the GObject subclass.
491 * @type: the Python type object for this wrapper.
492 * @static_bases: a tuple of Python type objects that are the bases of
495 * This function is used to register a Python type as the wrapper for
496 * a particular GObject subclass. It will also insert a reference to
497 * the wrapper class into the module dictionary passed as a reference,
498 * which simplifies initialisation.
501 pygobject_register_class(PyObject *dict, const gchar *type_name,
502 GType gtype, PyTypeObject *type,
503 PyObject *static_bases)
506 const char *class_name, *s;
507 PyObject *runtime_bases;
508 PyObject *bases_list, *bases, *mod_name;
511 class_name = type->tp_name;
512 s = strrchr(class_name, '.');
516 runtime_bases = pyg_type_get_bases(gtype);
518 PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
519 bases_list = PySequence_List(static_bases);
520 /* we start at index 1 because we want to skip the primary
521 * base, otherwise we might get MRO conflict */
522 for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
524 PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
525 int contains = PySequence_Contains(bases_list, base);
528 else if (!contains) {
529 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
531 g_message("Adding missing base %s to type %s",
532 ((PyTypeObject *)base)->tp_name, type->tp_name);
534 PyList_Append(bases_list, base);
538 bases = PySequence_Tuple(bases_list);
539 Py_DECREF(bases_list);
540 Py_DECREF(runtime_bases);
542 bases = runtime_bases;
544 Py_TYPE(type) = PyGObject_MetaType;
545 type->tp_bases = bases;
546 if (G_LIKELY(bases)) {
547 type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
548 Py_INCREF(type->tp_base);
551 pygobject_inherit_slots(type, bases, TRUE);
553 if (PyType_Ready(type) < 0) {
554 g_warning ("couldn't make the type `%s' ready", type->tp_name);
558 /* Set type.__module__ to the name of the module,
559 * otherwise it'll default to 'gobject', see #376099
561 s = strrchr(type->tp_name, '.');
563 mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
564 PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
569 o = pyg_type_wrapper_new(gtype);
570 PyDict_SetItemString(type->tp_dict, "__gtype__", o);
573 /* stash a pointer to the python class with the GType */
575 g_type_set_qdata(gtype, pygobject_class_key, type);
578 /* set up __doc__ descriptor on type */
579 PyDict_SetItemString(type->tp_dict, "__doc__",
580 pyg_object_descr_doc_get());
582 PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
586 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
588 PyGObject *self = (PyGObject*) data;
589 PyGILState_STATE state;
591 state = pyglib_gil_state_ensure();
598 pyglib_gil_state_release(state);
601 /* Called when the inst_dict is first created; switches the
602 reference counting strategy to start using toggle ref to keep the
603 wrapper alive while the GObject lives. In contrast, while
604 inst_dict was NULL the python wrapper is allowed to die at
605 will and is recreated on demand. */
607 pygobject_switch_to_toggle_ref(PyGObject *self)
609 g_assert(self->obj->ref_count >= 1);
611 if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF)
612 return; /* already using toggle ref */
613 self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
614 /* Note that add_toggle_ref will never immediately call back into
616 Py_INCREF((PyObject *) self);
617 g_object_add_toggle_ref(self->obj, pyg_toggle_notify, self);
618 g_object_unref(self->obj);
622 * pygobject_register_wrapper:
623 * @self: the wrapper instance
625 * In the constructor of PyGTK wrappers, this function should be
626 * called after setting the obj member. It will tie the wrapper
627 * instance to the GObject so that the same wrapper instance will
628 * always be used for this GObject instance.
631 pygobject_register_wrapper(PyObject *self)
635 g_return_if_fail(self != NULL);
636 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
638 gself = (PyGObject *)self;
640 pygobject_sink(gself->obj);
641 g_assert(gself->obj->ref_count >= 1);
642 /* save wrapper pointer so we can access it later */
643 g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
644 if (gself->inst_dict)
645 pygobject_switch_to_toggle_ref(gself);
649 pyg_type_get_bases(GType gtype)
651 GType *interfaces, parent_type, interface_type;
653 PyTypeObject *py_parent_type, *py_interface_type;
657 if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
660 /* Lookup the parent type */
661 parent_type = g_type_parent(gtype);
662 py_parent_type = pygobject_lookup_class(parent_type);
663 interfaces = g_type_interfaces(gtype, &n_interfaces);
664 bases = PyTuple_New(n_interfaces + 1);
665 /* We will always put the parent at the first position in bases */
666 Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
667 PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
669 /* And traverse interfaces */
671 for (i = 0; i < n_interfaces; i++) {
672 interface_type = interfaces[i];
673 py_interface_type = pygobject_lookup_class(interface_type);
674 Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
675 PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
683 * pygobject_new_with_interfaces
684 * @gtype: the GType of the GObject subclass.
686 * Creates a new PyTypeObject from the given GType with interfaces attached in
689 * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
692 pygobject_new_with_interfaces(GType gtype)
694 PyGILState_STATE state;
698 PyTypeObject *py_parent_type;
700 PyObject *modules, *module;
701 gchar *type_name, *mod_name, *gtype_name;
703 state = pyglib_gil_state_ensure();
705 bases = pyg_type_get_bases(gtype);
706 py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
710 o = pyg_type_wrapper_new(gtype);
711 PyDict_SetItemString(dict, "__gtype__", o);
714 /* set up __doc__ descriptor on type */
715 PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
717 /* generate the pygtk module name and extract the base type name */
718 gtype_name = (gchar*)g_type_name(gtype);
719 if (g_str_has_prefix(gtype_name, "Gtk")) {
722 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
723 } else if (g_str_has_prefix(gtype_name, "Gdk")) {
724 mod_name = "gtk.gdk";
726 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
727 } else if (g_str_has_prefix(gtype_name, "Atk")) {
730 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
731 } else if (g_str_has_prefix(gtype_name, "Pango")) {
734 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
736 mod_name = "__main__";
737 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
740 type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
741 "sNN", type_name, bases, dict);
746 pyglib_gil_state_release(state);
750 /* Workaround python tp_(get|set)attr slot inheritance bug.
751 * Fixes bug #144135. */
752 if (!type->tp_getattr && py_parent_type->tp_getattr) {
753 type->tp_getattro = NULL;
754 type->tp_getattr = py_parent_type->tp_getattr;
756 if (!type->tp_setattr && py_parent_type->tp_setattr) {
757 type->tp_setattro = NULL;
758 type->tp_setattr = py_parent_type->tp_setattr;
760 /* override more python stupid hacks behind our back */
761 type->tp_dealloc = py_parent_type->tp_dealloc;
762 type->tp_alloc = py_parent_type->tp_alloc;
763 type->tp_free = py_parent_type->tp_free;
764 type->tp_traverse = py_parent_type->tp_traverse;
765 type->tp_clear = py_parent_type->tp_clear;
767 pygobject_inherit_slots(type, bases, FALSE);
769 if (PyType_Ready(type) < 0) {
770 g_warning ("couldn't make the type `%s' ready", type->tp_name);
771 pyglib_gil_state_release(state);
774 /* insert type name in module dict */
775 modules = PyImport_GetModuleDict();
776 if ((module = PyDict_GetItemString(modules, mod_name)) != NULL) {
777 if (PyObject_SetAttrString(module, gtype_name, (PyObject *)type) < 0)
781 /* stash a pointer to the python class with the GType */
783 g_type_set_qdata(gtype, pygobject_class_key, type);
785 pyglib_gil_state_release(state);
790 /* Pick appropriate value for given slot (at slot_offset inside
791 * PyTypeObject structure). It must be a pointer, e.g. a pointer to a
792 * function. We use the following heuristic:
794 * - Scan all types listed as bases of the type.
795 * - If for exactly one base type slot value is non-NULL and
796 * different from that of 'object' and 'GObject', set current type
797 * slot into that value.
798 * - Otherwise (if there is more than one such base type or none at
799 * all) don't touch it and live with Python default.
801 * The intention here is to propagate slot from custom wrappers to
802 * wrappers created at runtime when appropriate. We prefer to be on
803 * the safe side, so if there is potential collision (more than one
804 * custom slot value), we discard custom overrides altogether.
806 * When registering type with pygobject_register_class(), i.e. a type
807 * that has been manually created (likely with Codegen help),
808 * `check_for_present' should be set to TRUE. In this case, the
809 * function will never overwrite any non-NULL slots already present in
810 * the type. If `check_for_present' is FALSE, such non-NULL slots are
811 * though to be set by Python interpreter and so will be overwritten
812 * if heuristic above says so.
815 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
817 static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
818 #if PY_VERSION_HEX < 0x03000000
819 offsetof(PyTypeObject, tp_compare),
821 offsetof(PyTypeObject, tp_richcompare),
822 offsetof(PyTypeObject, tp_hash),
823 offsetof(PyTypeObject, tp_iter),
824 offsetof(PyTypeObject, tp_repr),
825 offsetof(PyTypeObject, tp_str),
826 offsetof(PyTypeObject, tp_print) };
829 /* Happens when registering gobject.GObject itself, at least. */
833 for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
834 pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
838 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
839 gboolean check_for_present)
841 #define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset))
843 void *found_slot = NULL;
844 int num_bases = PyTuple_Size(bases);
847 if (check_for_present && TYPE_SLOT(type) != NULL) {
848 /* We are requested to check if there is any custom slot value
849 * in this type already and there actually is. Don't
855 for (i = 0; i < num_bases; ++i) {
856 PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
857 void *slot = TYPE_SLOT(base_type);
861 if (slot == TYPE_SLOT(&PyGObject_Type) ||
862 slot == TYPE_SLOT(&PyBaseObject_Type))
865 if (found_slot != NULL && found_slot != slot) {
866 /* We have a conflict: more than one base use different
867 * custom slots. To be on the safe side, we bail out.
875 /* Only perform the final assignment if at least one base has a
876 * custom value. Otherwise just leave this type's slot untouched.
878 if (found_slot != NULL)
879 TYPE_SLOT(type) = found_slot;
885 * pygobject_lookup_class:
886 * @gtype: the GType of the GObject subclass.
888 * This function looks up the wrapper class used to represent
889 * instances of a GObject represented by @gtype. If no wrapper class
890 * or interface has been registered for the given GType, then a new
891 * type will be created.
893 * Returns: The wrapper class for the GObject or NULL if the
894 * GType has no registered type and a new type couldn't be created
897 pygobject_lookup_class(GType gtype)
899 PyTypeObject *py_type;
901 if (gtype == G_TYPE_INTERFACE)
902 return &PyGInterface_Type;
904 py_type = pyg_type_get_custom(g_type_name(gtype));
908 py_type = g_type_get_qdata(gtype, pygobject_class_key);
909 if (py_type == NULL) {
910 py_type = g_type_get_qdata(gtype, pyginterface_type_key);
913 py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
915 if (py_type == NULL) {
916 py_type = pygobject_new_with_interfaces(gtype);
917 g_type_set_qdata(gtype, pyginterface_type_key, py_type);
925 * pygobject_new_full:
926 * @obj: a GObject instance.
927 * @sink: whether to sink any floating reference found on the GObject. DEPRECATED.
928 * @g_class: the GObjectClass
930 * This function gets a reference to a wrapper for the given GObject
931 * instance. If a wrapper has already been created, a new reference
932 * to that wrapper will be returned. Otherwise, a wrapper instance
935 * Returns: a reference to the wrapper for the GObject.
938 pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
947 /* we already have a wrapper for this object -- return it. */
948 self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
953 PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
956 tp = inst_data->type;
959 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
961 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
963 g_assert(tp != NULL);
965 /* need to bump type refcount if created with
966 pygobject_new_with_interfaces(). fixes bug #141042 */
967 if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
969 self = PyObject_GC_New(PyGObject, tp);
972 self->inst_dict = NULL;
973 self->weakreflist = NULL;
974 self->private_flags.flags = 0;
977 pygobject_register_wrapper((PyObject *)self);
978 PyObject_GC_Track((PyObject *)self);
981 return (PyObject *)self;
986 pygobject_new(GObject *obj)
988 return pygobject_new_full(obj, TRUE, NULL);
992 pygobject_new_sunk(GObject *obj)
994 g_object_set_qdata (obj, pygobject_ref_sunk_key, GINT_TO_POINTER (1));
995 return pygobject_new_full(obj, TRUE, NULL);
999 pygobject_unwatch_closure(gpointer data, GClosure *closure)
1001 PyGObjectData *inst_data = data;
1003 inst_data->closures = g_slist_remove (inst_data->closures, closure);
1007 * pygobject_watch_closure:
1008 * @self: a GObject wrapper instance
1009 * @closure: a GClosure to watch
1011 * Adds a closure to the list of watched closures for the wrapper.
1012 * The closure must be one returned by pyg_closure_new(). When the
1013 * cycle GC traverses the wrapper instance, it will enumerate the
1014 * references to Python objects stored in watched closures. If the
1015 * cycle GC tells the wrapper to clear itself, the watched closures
1016 * will be invalidated.
1019 pygobject_watch_closure(PyObject *self, GClosure *closure)
1022 PyGObjectData *data;
1024 g_return_if_fail(self != NULL);
1025 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
1026 g_return_if_fail(closure != NULL);
1028 gself = (PyGObject *)self;
1029 data = pygobject_get_inst_data(gself);
1030 g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
1031 data->closures = g_slist_prepend(data->closures, closure);
1032 g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
1035 /* -------------- PyGObject behaviour ----------------- */
1037 PYGLIB_DEFINE_TYPE("gobject.GObject", PyGObject_Type, PyGObject);
1040 pygobject_dealloc(PyGObject *self)
1042 /* Untrack must be done first. This is because followup calls such as
1043 * ClearWeakRefs could call into Python and cause new allocations to
1044 * happen, which could in turn could trigger the garbage collector,
1045 * which would then get confused as it is tracking this half-deallocated
1047 PyObject_GC_UnTrack((PyObject *)self);
1049 PyObject_ClearWeakRefs((PyObject *)self);
1050 /* this forces inst_data->type to be updated, which could prove
1051 * important if a new wrapper has to be created and it is of a
1052 * unregistered type */
1053 pygobject_get_inst_data(self);
1054 pygobject_clear(self);
1055 /* the following causes problems with subclassed types */
1056 /* Py_TYPE(self)->tp_free((PyObject *)self); */
1057 PyObject_GC_Del(self);
1061 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1065 isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1069 Py_INCREF(Py_NotImplemented);
1070 return Py_NotImplemented;
1072 isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1076 Py_INCREF(Py_NotImplemented);
1077 return Py_NotImplemented;
1080 return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1081 ((PyGObject*)other)->obj,
1086 pygobject_hash(PyGObject *self)
1088 return (long)self->obj;
1092 pygobject_repr(PyGObject *self)
1096 g_snprintf(buf, sizeof(buf),
1097 "<%s object at 0x%lx (%s at 0x%lx)>",
1098 Py_TYPE(self)->tp_name,
1100 self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
1102 return PYGLIB_PyUnicode_FromString(buf);
1107 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1111 PyGObjectData *data = pygobject_get_inst_data(self);
1113 if (self->inst_dict) ret = visit(self->inst_dict, arg);
1114 if (ret != 0) return ret;
1118 for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1119 PyGClosure *closure = tmp->data;
1121 if (closure->callback) ret = visit(closure->callback, arg);
1122 if (ret != 0) return ret;
1124 if (closure->extra_args) ret = visit(closure->extra_args, arg);
1125 if (ret != 0) return ret;
1127 if (closure->swap_data) ret = visit(closure->swap_data, arg);
1128 if (ret != 0) return ret;
1135 pygobject_clear(PyGObject *self)
1138 g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1139 if (self->inst_dict) {
1140 g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
1141 self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1143 pyg_begin_allow_threads;
1144 g_object_unref(self->obj);
1145 pyg_end_allow_threads;
1149 Py_CLEAR(self->inst_dict);
1154 pygobject_free(PyObject *op)
1156 PyObject_GC_Del(op);
1160 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1161 guint *n_params, GParameter **params)
1171 *params = g_new0(GParameter, PyDict_Size(kwargs));
1172 while (PyDict_Next(kwargs, &pos, &key, &value)) {
1174 GParameter *param = &(*params)[*n_params];
1175 const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1177 pspec = g_object_class_find_property(class, key_str);
1179 PyErr_Format(PyExc_TypeError,
1180 "gobject `%s' doesn't support property `%s'",
1181 G_OBJECT_CLASS_NAME(class), key_str);
1184 g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1185 if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) {
1186 PyErr_Format(PyExc_TypeError,
1187 "could not convert value for property `%s' from %s to %s",
1188 key_str, Py_TYPE(value)->tp_name,
1189 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1192 param->name = g_strdup(key_str);
1199 /* ---------------- PyGObject methods ----------------- */
1202 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1205 guint n_params = 0, i;
1206 GParameter *params = NULL;
1207 GObjectClass *class;
1209 if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
1212 object_type = pyg_type_from_object((PyObject *)self);
1216 if (G_TYPE_IS_ABSTRACT(object_type)) {
1217 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1218 "(non-instantiable) type `%s'", g_type_name(object_type));
1222 if ((class = g_type_class_ref (object_type)) == NULL) {
1223 PyErr_SetString(PyExc_TypeError,
1224 "could not get a reference to type class");
1228 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms))
1231 if (pygobject_constructv(self, n_params, params))
1232 PyErr_SetString(PyExc_RuntimeError, "could not create object");
1235 for (i = 0; i < n_params; i++) {
1236 g_free((gchar *) params[i].name);
1237 g_value_unset(¶ms[i].value);
1240 g_type_class_unref(class);
1242 return (self->obj) ? 0 : -1;
1246 pygobject__gobject_init__(PyGObject *self, PyObject *args, PyObject *kwargs)
1248 if (pygobject_init(self, args, kwargs) < 0)
1254 #define CHECK_GOBJECT(self) \
1255 if (!G_IS_OBJECT(self->obj)) { \
1256 PyErr_Format(PyExc_TypeError, \
1257 "object at %p of type %s is not initialized", \
1258 self, Py_TYPE(self)->tp_name); \
1263 pygobject_get_property(PyGObject *self, PyObject *args)
1267 GValue value = { 0, };
1270 if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name))
1273 CHECK_GOBJECT(self);
1275 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1278 PyErr_Format(PyExc_TypeError,
1279 "object of type `%s' does not have property `%s'",
1280 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1283 if (!(pspec->flags & G_PARAM_READABLE)) {
1284 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1288 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1289 pyg_begin_allow_threads;
1290 g_object_get_property(self->obj, param_name, &value);
1291 pyg_end_allow_threads;
1292 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
1293 g_value_unset(&value);
1298 pygobject_get_properties(PyGObject *self, PyObject *args)
1300 GObjectClass *class;
1304 if ((len = PyTuple_Size(args)) < 1) {
1305 PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1309 tuple = PyTuple_New(len);
1310 class = G_OBJECT_GET_CLASS(self->obj);
1311 for (i = 0; i < len; i++) {
1312 PyObject *py_property = PyTuple_GetItem(args, i);
1313 gchar *property_name;
1315 GValue value = { 0 };
1318 if (!PYGLIB_PyUnicode_Check(py_property)) {
1319 PyErr_SetString(PyExc_TypeError,
1320 "Expected string argument for property.");
1324 property_name = PYGLIB_PyUnicode_AsString(py_property);
1326 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1329 PyErr_Format(PyExc_TypeError,
1330 "object of type `%s' does not have property `%s'",
1331 g_type_name(G_OBJECT_TYPE(self->obj)), property_name);
1334 if (!(pspec->flags & G_PARAM_READABLE)) {
1335 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1339 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1341 pyg_begin_allow_threads;
1342 g_object_get_property(self->obj, property_name, &value);
1343 pyg_end_allow_threads;
1345 item = pyg_value_as_pyobject(&value, TRUE);
1346 PyTuple_SetItem(tuple, i, item);
1348 g_value_unset(&value);
1355 pygobject_set_property(PyGObject *self, PyObject *args)
1361 if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name,
1365 CHECK_GOBJECT(self);
1367 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1370 PyErr_Format(PyExc_TypeError,
1371 "object of type `%s' does not have property `%s'",
1372 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1376 if (!set_property_from_pspec(self->obj, param_name, pspec, pvalue))
1384 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1386 GObjectClass *class;
1390 PyObject *result = NULL;
1392 CHECK_GOBJECT(self);
1394 class = G_OBJECT_GET_CLASS(self->obj);
1396 g_object_freeze_notify (G_OBJECT(self->obj));
1399 while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1400 gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1403 pspec = g_object_class_find_property(class, key_str);
1407 g_snprintf(buf, sizeof(buf),
1408 "object `%s' doesn't support property `%s'",
1409 g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1410 PyErr_SetString(PyExc_TypeError, buf);
1414 if (!set_property_from_pspec(G_OBJECT(self->obj), key_str, pspec, value))
1421 g_object_thaw_notify (G_OBJECT(self->obj));
1427 pygobject_freeze_notify(PyGObject *self, PyObject *args)
1429 if (!PyArg_ParseTuple(args, ":GObject.freeze_notify"))
1432 CHECK_GOBJECT(self);
1434 g_object_freeze_notify(self->obj);
1440 pygobject_notify(PyGObject *self, PyObject *args)
1442 char *property_name;
1444 if (!PyArg_ParseTuple(args, "s:GObject.notify", &property_name))
1447 CHECK_GOBJECT(self);
1449 g_object_notify(self->obj, property_name);
1455 pygobject_thaw_notify(PyGObject *self, PyObject *args)
1457 if (!PyArg_ParseTuple(args, ":GObject.thaw_notify"))
1460 CHECK_GOBJECT(self);
1462 g_object_thaw_notify(self->obj);
1468 pygobject_get_data(PyGObject *self, PyObject *args)
1474 if (!PyArg_ParseTuple(args, "s:GObject.get_data", &key))
1477 CHECK_GOBJECT(self);
1479 quark = g_quark_from_string(key);
1480 data = g_object_get_qdata(self->obj, quark);
1481 if (!data) data = Py_None;
1487 pygobject_set_data(PyGObject *self, PyObject *args)
1493 if (!PyArg_ParseTuple(args, "sO:GObject.set_data", &key, &data))
1496 CHECK_GOBJECT(self);
1498 quark = g_quark_from_string(key);
1500 g_object_set_qdata_full(self->obj, quark, data, pyg_destroy_notify);
1506 pygobject_connect(PyGObject *self, PyObject *args)
1508 PyObject *first, *callback, *extra_args;
1515 len = PyTuple_Size(args);
1517 PyErr_SetString(PyExc_TypeError,
1518 "GObject.connect requires at least 2 arguments");
1521 first = PySequence_GetSlice(args, 0, 2);
1522 if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1527 if (!PyCallable_Check(callback)) {
1528 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1532 CHECK_GOBJECT(self);
1534 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1535 &sigid, &detail, TRUE)) {
1536 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1537 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1541 extra_args = PySequence_GetSlice(args, 2, len);
1542 if (extra_args == NULL)
1545 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1546 if (closure == NULL)
1547 closure = pyg_closure_new(callback, extra_args, NULL);
1549 pygobject_watch_closure((PyObject *)self, closure);
1550 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1552 Py_DECREF(extra_args);
1553 return PyLong_FromUnsignedLong(handlerid);
1557 pygobject_connect_after(PyGObject *self, PyObject *args)
1559 PyObject *first, *callback, *extra_args;
1567 len = PyTuple_Size(args);
1569 PyErr_SetString(PyExc_TypeError,
1570 "GObject.connect_after requires at least 2 arguments");
1573 first = PySequence_GetSlice(args, 0, 2);
1574 if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1575 &name, &callback)) {
1580 if (!PyCallable_Check(callback)) {
1581 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1585 CHECK_GOBJECT(self);
1587 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1588 &sigid, &detail, TRUE)) {
1589 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1590 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1594 extra_args = PySequence_GetSlice(args, 2, len);
1595 if (extra_args == NULL)
1598 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1599 if (closure == NULL)
1600 closure = pyg_closure_new(callback, extra_args, NULL);
1602 pygobject_watch_closure((PyObject *)self, closure);
1603 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1605 Py_DECREF(extra_args);
1606 return PyLong_FromUnsignedLong(handlerid);
1610 pygobject_connect_object(PyGObject *self, PyObject *args)
1612 PyObject *first, *callback, *extra_args, *object;
1620 len = PyTuple_Size(args);
1622 PyErr_SetString(PyExc_TypeError,
1623 "GObject.connect_object requires at least 3 arguments");
1626 first = PySequence_GetSlice(args, 0, 3);
1627 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1628 &name, &callback, &object)) {
1633 if (!PyCallable_Check(callback)) {
1634 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1638 CHECK_GOBJECT(self);
1640 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1641 &sigid, &detail, TRUE)) {
1642 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1643 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1647 extra_args = PySequence_GetSlice(args, 3, len);
1648 if (extra_args == NULL)
1651 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1652 if (closure == NULL)
1653 closure = pyg_closure_new(callback, extra_args, object);
1655 pygobject_watch_closure((PyObject *)self, closure);
1656 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1658 Py_DECREF(extra_args);
1659 return PyLong_FromUnsignedLong(handlerid);
1663 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1665 PyObject *first, *callback, *extra_args, *object;
1673 len = PyTuple_Size(args);
1675 PyErr_SetString(PyExc_TypeError,
1676 "GObject.connect_object_after requires at least 3 arguments");
1679 first = PySequence_GetSlice(args, 0, 3);
1680 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1681 &name, &callback, &object)) {
1686 if (!PyCallable_Check(callback)) {
1687 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1691 CHECK_GOBJECT(self);
1693 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1694 &sigid, &detail, TRUE)) {
1695 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1696 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1700 extra_args = PySequence_GetSlice(args, 3, len);
1701 if (extra_args == NULL)
1704 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1705 if (closure == NULL)
1706 closure = pyg_closure_new(callback, extra_args, object);
1708 pygobject_watch_closure((PyObject *)self, closure);
1709 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1711 Py_DECREF(extra_args);
1712 return PyLong_FromUnsignedLong(handlerid);
1716 pygobject_disconnect(PyGObject *self, PyObject *args)
1720 if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
1723 CHECK_GOBJECT(self);
1725 g_signal_handler_disconnect(self->obj, handler_id);
1731 pygobject_handler_is_connected(PyGObject *self, PyObject *args)
1735 if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
1739 CHECK_GOBJECT(self);
1741 return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
1745 pygobject_handler_block(PyGObject *self, PyObject *args)
1749 if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
1752 CHECK_GOBJECT(self);
1754 g_signal_handler_block(self->obj, handler_id);
1760 pygobject_handler_unblock(PyGObject *self, PyObject *args)
1764 if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
1766 g_signal_handler_unblock(self->obj, handler_id);
1772 pygobject_emit(PyGObject *self, PyObject *args)
1777 PyObject *first, *py_ret;
1780 GValue *params, ret = { 0, };
1782 len = PyTuple_Size(args);
1784 PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1787 first = PySequence_GetSlice(args, 0, 1);
1788 if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1794 CHECK_GOBJECT(self);
1796 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1797 &signal_id, &detail, TRUE)) {
1798 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1799 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1803 g_signal_query(signal_id, &query);
1804 if (len != query.n_params + 1) {
1807 g_snprintf(buf, sizeof(buf),
1808 "%d parameters needed for signal %s; %ld given",
1809 query.n_params, name, (long int) (len - 1));
1810 PyErr_SetString(PyExc_TypeError, buf);
1814 params = g_new0(GValue, query.n_params + 1);
1815 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1816 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1818 for (i = 0; i < query.n_params; i++)
1819 g_value_init(¶ms[i + 1],
1820 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1821 for (i = 0; i < query.n_params; i++) {
1822 PyObject *item = PyTuple_GetItem(args, i+1);
1824 if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1826 g_snprintf(buf, sizeof(buf),
1827 "could not convert type %s to %s required for parameter %d",
1828 Py_TYPE(item)->tp_name,
1829 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1830 PyErr_SetString(PyExc_TypeError, buf);
1832 for (i = 0; i < query.n_params + 1; i++)
1833 g_value_unset(¶ms[i]);
1840 if (query.return_type != G_TYPE_NONE)
1841 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1843 g_signal_emitv(params, signal_id, detail, &ret);
1845 for (i = 0; i < query.n_params + 1; i++)
1846 g_value_unset(¶ms[i]);
1849 if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1850 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1851 g_value_unset(&ret);
1861 pygobject_stop_emission(PyGObject *self, PyObject *args)
1867 if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
1870 CHECK_GOBJECT(self);
1872 if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
1873 &signal_id, &detail, TRUE)) {
1874 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1875 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1879 g_signal_stop_emission(self->obj, signal_id, detail);
1885 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1887 GSignalInvocationHint *ihint;
1893 GValue *params, ret = { 0, };
1895 CHECK_GOBJECT(self);
1897 ihint = g_signal_get_invocation_hint(self->obj);
1899 PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1900 "information for this object.");
1904 signal_id = ihint->signal_id;
1905 name = g_signal_name(signal_id);
1907 len = PyTuple_Size(args);
1908 if (signal_id == 0) {
1909 PyErr_SetString(PyExc_TypeError, "unknown signal name");
1912 g_signal_query(signal_id, &query);
1913 if (len != query.n_params) {
1916 g_snprintf(buf, sizeof(buf),
1917 "%d parameters needed for signal %s; %ld given",
1918 query.n_params, name, (long int) len);
1919 PyErr_SetString(PyExc_TypeError, buf);
1922 params = g_new0(GValue, query.n_params + 1);
1923 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1924 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1926 for (i = 0; i < query.n_params; i++)
1927 g_value_init(¶ms[i + 1],
1928 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1929 for (i = 0; i < query.n_params; i++) {
1930 PyObject *item = PyTuple_GetItem(args, i);
1932 if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1933 g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void));
1935 else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1938 g_snprintf(buf, sizeof(buf),
1939 "could not convert type %s to %s required for parameter %d",
1940 Py_TYPE(item)->tp_name,
1941 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1942 PyErr_SetString(PyExc_TypeError, buf);
1943 for (i = 0; i < query.n_params + 1; i++)
1944 g_value_unset(¶ms[i]);
1949 if (query.return_type != G_TYPE_NONE)
1950 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1951 g_signal_chain_from_overridden(params, &ret);
1952 for (i = 0; i < query.n_params + 1; i++)
1953 g_value_unset(¶ms[i]);
1955 if (query.return_type != G_TYPE_NONE) {
1956 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1957 g_value_unset(&ret);
1967 pygobject_weak_ref(PyGObject *self, PyObject *args)
1970 PyObject *callback = NULL, *user_data = NULL;
1973 CHECK_GOBJECT(self);
1975 if ((len = PySequence_Length(args)) >= 1) {
1976 callback = PySequence_ITEM(args, 0);
1977 user_data = PySequence_GetSlice(args, 1, len);
1979 retval = pygobject_weak_ref_new(self->obj, callback, user_data);
1980 Py_XDECREF(callback);
1981 Py_XDECREF(user_data);
1987 pygobject_copy(PyGObject *self)
1989 PyErr_SetString(PyExc_TypeError,
1990 "gobject.GObject descendants' instances are non-copyable");
1995 pygobject_deepcopy(PyGObject *self, PyObject *args)
1997 PyErr_SetString(PyExc_TypeError,
1998 "gobject.GObject descendants' instances are non-copyable");
2004 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
2006 PyObject *pyfunc = NULL;
2007 GClosure *closure = NULL;
2010 CHECK_GOBJECT(self);
2012 if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2015 if (!PyCallable_Check(pyfunc)) {
2016 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2020 closure = gclosure_from_pyfunc(self, pyfunc);
2022 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2023 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2027 retval = g_signal_handlers_disconnect_matched(self->obj,
2028 G_SIGNAL_MATCH_CLOSURE,
2032 return PYGLIB_PyLong_FromLong(retval);
2036 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2038 PyObject *pyfunc = NULL;
2039 GClosure *closure = NULL;
2042 CHECK_GOBJECT(self);
2044 if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2047 if (!PyCallable_Check(pyfunc)) {
2048 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2052 closure = gclosure_from_pyfunc(self, pyfunc);
2054 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2055 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2059 retval = g_signal_handlers_block_matched(self->obj,
2060 G_SIGNAL_MATCH_CLOSURE,
2064 return PYGLIB_PyLong_FromLong(retval);
2068 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2070 PyObject *pyfunc = NULL;
2071 GClosure *closure = NULL;
2074 CHECK_GOBJECT(self);
2076 if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2079 if (!PyCallable_Check(pyfunc)) {
2080 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2084 closure = gclosure_from_pyfunc(self, pyfunc);
2086 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2087 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2091 retval = g_signal_handlers_unblock_matched(self->obj,
2092 G_SIGNAL_MATCH_CLOSURE,
2096 return PYGLIB_PyLong_FromLong(retval);
2099 static PyMethodDef pygobject_methods[] = {
2100 { "__gobject_init__", (PyCFunction)pygobject__gobject_init__,
2101 METH_VARARGS|METH_KEYWORDS },
2102 { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2103 { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2104 { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2105 { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2106 { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
2107 { "notify", (PyCFunction)pygobject_notify, METH_VARARGS },
2108 { "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS },
2109 { "get_data", (PyCFunction)pygobject_get_data, METH_VARARGS },
2110 { "set_data", (PyCFunction)pygobject_set_data, METH_VARARGS },
2111 { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2112 { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2113 { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2114 { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2115 { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2116 { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2117 { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2118 { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
2119 { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
2120 { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
2121 { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2122 { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2123 { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2124 { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
2125 { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
2126 { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2127 { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2128 { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2129 { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2135 pygobject_get_dict(PyGObject *self, void *closure)
2137 if (self->inst_dict == NULL) {
2138 self->inst_dict = PyDict_New();
2139 if (self->inst_dict == NULL)
2141 if (G_LIKELY(self->obj))
2142 pygobject_switch_to_toggle_ref(self);
2144 Py_INCREF(self->inst_dict);
2145 return self->inst_dict;
2149 pygobject_get_refcount(PyGObject *self, void *closure)
2151 return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2155 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2158 PyGObject *gself = (PyGObject *) self;
2159 PyObject *inst_dict_before = gself->inst_dict;
2160 /* call parent type's setattro */
2161 res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2162 if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2163 if (G_LIKELY(gself->obj))
2164 pygobject_switch_to_toggle_ref(gself);
2169 static PyGetSetDef pygobject_getsets[] = {
2170 { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2171 { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2175 /* ------------------------------------ */
2176 /* ****** GObject weak reference ****** */
2177 /* ------------------------------------ */
2183 PyObject *user_data;
2184 gboolean have_floating_ref;
2187 PYGLIB_DEFINE_TYPE("gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2190 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2192 if (self->callback && visit(self->callback, arg) < 0)
2194 if (self->user_data && visit(self->user_data, arg) < 0)
2200 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2203 if (self->callback) {
2205 PyGILState_STATE state = pyglib_gil_state_ensure();
2206 retval = PyObject_Call(self->callback, self->user_data, NULL);
2208 if (retval != Py_None)
2209 PyErr_Format(PyExc_TypeError,
2210 "GObject weak notify callback returned a value"
2211 " of type %s, should return None",
2212 Py_TYPE(retval)->tp_name);
2217 Py_CLEAR(self->callback);
2218 Py_CLEAR(self->user_data);
2219 if (self->have_floating_ref) {
2220 self->have_floating_ref = FALSE;
2221 Py_DECREF((PyObject *) self);
2223 pyglib_gil_state_release(state);
2228 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2230 Py_CLEAR(self->callback);
2231 Py_CLEAR(self->user_data);
2233 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2240 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2242 PyObject_GC_UnTrack((PyObject *)self);
2243 pygobject_weak_ref_clear(self);
2244 PyObject_GC_Del(self);
2248 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2250 PyGObjectWeakRef *self;
2252 self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2253 self->callback = callback;
2254 self->user_data = user_data;
2255 Py_XINCREF(self->callback);
2256 Py_XINCREF(self->user_data);
2258 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2259 if (callback != NULL) {
2260 /* when we have a callback, we should INCREF the weakref
2261 * object to make it stay alive even if it goes out of scope */
2262 self->have_floating_ref = TRUE;
2263 Py_INCREF((PyObject *) self);
2265 return (PyObject *) self;
2269 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2272 PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2275 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2277 if (self->have_floating_ref) {
2278 self->have_floating_ref = FALSE;
2285 static PyMethodDef pygobject_weak_ref_methods[] = {
2286 { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2291 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2293 static char *argnames[] = {NULL};
2295 if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2299 return pygobject_new_full(self->obj, FALSE, NULL);
2307 pyobject_copy(gpointer boxed)
2309 PyObject *object = boxed;
2316 pyobject_free(gpointer boxed)
2318 PyObject *object = boxed;
2319 PyGILState_STATE state;
2321 state = pyglib_gil_state_ensure();
2323 pyglib_gil_state_release(state);
2327 pygobject_object_register_types(PyObject *d)
2329 PyObject *o, *descr;
2331 pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2332 pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2333 pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2334 pygobject_has_updated_constructor_key =
2335 g_quark_from_static_string("PyGObject::has-updated-constructor");
2336 pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2337 pygobject_ref_sunk_key = g_quark_from_static_string("PyGObject::ref-sunk");
2340 if (!PY_TYPE_OBJECT)
2341 PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2344 PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2345 PyGObject_Type.tp_richcompare = pygobject_richcompare;
2346 PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2347 PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2348 PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2349 PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2350 Py_TPFLAGS_HAVE_GC);
2351 PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2352 PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2353 PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2354 PyGObject_Type.tp_methods = pygobject_methods;
2355 PyGObject_Type.tp_getset = pygobject_getsets;
2356 PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2357 PyGObject_Type.tp_init = (initproc)pygobject_init;
2358 PyGObject_Type.tp_free = (freefunc)pygobject_free;
2359 PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2360 PyGObject_Type.tp_new = PyType_GenericNew;
2361 pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2362 &PyGObject_Type, NULL);
2363 PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2364 pyg_object_descr_doc_get());
2365 pyg_set_object_has_new_constructor(G_TYPE_OBJECT);
2368 PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2369 PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2370 PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2371 PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2372 PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2373 PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2374 "Python attributes.";
2375 PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2376 PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2377 if (PyType_Ready(&PyGProps_Type) < 0)
2381 PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2382 PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2383 if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2385 descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2386 PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2387 PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2388 o=PYGLIB_PyUnicode_FromString("gobject._gobject"));
2392 PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2393 PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2394 PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2395 PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2396 if (PyType_Ready(&PyGPropsIter_Type) < 0)
2399 PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2400 PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2401 PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2402 PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2403 PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2404 PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2405 PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2406 if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2408 PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);