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, see <http://www.gnu.org/licenses/>.
26 #include "pygobject-object.h"
27 #include "pyginterface.h"
28 #include "pygparamspec.h"
31 #include "gobjectmodule.h"
33 #include "pygi-value.h"
34 #include "pygi-type.h"
35 #include "pygi-property.h"
36 #include "pygi-signal-closure.h"
38 extern PyObject *PyGIDeprecationWarning;
40 static void pygobject_dealloc(PyGObject *self);
41 static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
42 static int pygobject_clear(PyGObject *self);
43 static PyObject * pyg_type_get_bases(GType gtype);
44 static inline int pygobject_clear(PyGObject *self);
45 static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
46 static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
47 static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases,
48 gboolean check_for_present);
49 static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
50 gboolean check_for_present);
51 GType PY_TYPE_OBJECT = 0;
52 GQuark pygobject_custom_key;
53 GQuark pygobject_class_key;
54 GQuark pygobject_class_init_key;
55 GQuark pygobject_wrapper_key;
56 GQuark pygobject_has_updated_constructor_key;
57 GQuark pygobject_instance_data_key;
60 gclosure_from_pyfunc(PyGObject *object, PyObject *func)
63 PyGObjectData *inst_data;
64 inst_data = pyg_object_peek_inst_data(object->obj);
66 for (l = inst_data->closures; l; l = l->next) {
67 PyGClosure *pyclosure = l->data;
68 int res = PyObject_RichCompareBool(pyclosure->callback, func, Py_EQ);
70 PyErr_Clear(); /* Is there anything else to do? */
72 return (GClosure*)pyclosure;
79 /* Copied from glib. gobject uses hyphens in property names, but in Python
80 * we can only represent hyphens as underscores. Convert underscores to
81 * hyphens for glib compatibility. */
83 canonicalize_key (gchar *key)
87 for (p = key; *p != 0; p++)
92 (c < '0' || c > '9') &&
93 (c < 'A' || c > 'Z') &&
99 /* -------------- class <-> wrapper manipulation --------------- */
102 pygobject_data_free(PyGObjectData *data)
104 /* This function may be called after the python interpreter has already
105 * been shut down. If this happens, we cannot do any python calls, so just
106 * free the memory. */
107 PyGILState_STATE state;
108 PyThreadState *_save = NULL;
109 gboolean state_saved = FALSE;
111 GSList *closures, *tmp;
113 if (Py_IsInitialized()) {
115 state = pyglib_gil_state_ensure();
116 Py_DECREF(data->type);
117 /* We cannot use Py_BEGIN_ALLOW_THREADS here because this is inside
119 Py_UNBLOCK_THREADS; /* Modifies _save */
122 tmp = closures = data->closures;
124 data->closures = NULL;
128 GClosure *closure = tmp->data;
130 /* we get next item first, because the current link gets
131 * invalidated by pygobject_unwatch_closure */
133 g_closure_invalidate(closure);
136 if (data->closures != NULL)
137 g_warning("invalidated all closures, but data->closures != NULL !");
141 if (state_saved && Py_IsInitialized ()) {
142 Py_BLOCK_THREADS; /* Restores _save */
143 pyglib_gil_state_release(state);
147 static inline PyGObjectData *
148 pygobject_data_new(void)
151 data = g_new0(PyGObjectData, 1);
155 static inline PyGObjectData *
156 pygobject_get_inst_data(PyGObject *self)
158 PyGObjectData *inst_data;
160 if (G_UNLIKELY(!self->obj))
162 inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
163 if (inst_data == NULL)
165 inst_data = pygobject_data_new();
167 inst_data->type = Py_TYPE(self);
168 Py_INCREF((PyObject *) inst_data->type);
170 g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
171 inst_data, (GDestroyNotify) pygobject_data_free);
177 PyTypeObject *PyGObject_MetaType = NULL;
183 * As Python handles reference counting for us, the "floating
184 * reference" code in GTK is not all that useful. In fact, it can
185 * cause leaks. This function should be called to remove the floating
186 * references on objects on construction.
189 pygobject_sink(GObject *obj)
191 /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink().
192 * - if the object is new and owned by someone else, its ref has been sunk and
193 * we need to keep the one from that someone and add our own "fresh ref"
194 * - if the object is not and owned by nobody, its ref is floating and we need
195 * to transform it into a regular ref.
197 if (G_IS_INITIALLY_UNOWNED(obj)) {
198 g_object_ref_sink(obj);
209 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
212 pyg_props_iter_dealloc(PyGPropsIter *self)
215 PyObject_Del((PyObject*) self);
219 pygobject_props_iter_next(PyGPropsIter *iter)
221 if (iter->index < iter->n_props)
222 return pyg_param_spec_new(iter->props[iter->index++]);
224 PyErr_SetNone(PyExc_StopIteration);
231 /* a reference to the object containing the properties */
232 PyGObject *pygobject;
237 PyGProps_dealloc(PyGProps* self)
241 PyObject_GC_UnTrack((PyObject*)self);
243 tmp = self->pygobject;
244 self->pygobject = NULL;
247 PyObject_GC_Del((PyObject*)self);
251 build_parameter_list(GObjectClass *class)
254 guint n_props = 0, i;
256 PyObject *props_list;
258 props = g_object_class_list_properties(class, &n_props);
259 props_list = PyList_New(n_props);
260 for (i = 0; i < n_props; i++) {
262 name = g_strdup(g_param_spec_get_name(props[i]));
263 /* hyphens cannot belong in identifiers */
264 g_strdelimit(name, "-", '_');
265 prop_str = PYGLIB_PyUnicode_FromString(name);
267 PyList_SetItem(props_list, i, prop_str);
278 PyGProps_getattro(PyGProps *self, PyObject *attr)
280 char *attr_name, *property_name;
284 attr_name = PYGLIB_PyUnicode_AsString(attr);
287 return PyObject_GenericGetAttr((PyObject *)self, attr);
290 class = g_type_class_ref(self->gtype);
292 /* g_object_class_find_property recurses through the class hierarchy,
293 * so the resulting pspec tells us the owner_type that owns the property
294 * we're dealing with. */
295 property_name = g_strdup(attr_name);
296 canonicalize_key(property_name);
297 pspec = g_object_class_find_property(class, property_name);
298 g_free(property_name);
299 g_type_class_unref(class);
302 return PyObject_GenericGetAttr((PyObject *)self, attr);
305 if (!self->pygobject) {
306 /* If we're doing it without an instance, return a GParamSpec */
307 return pyg_param_spec_new(pspec);
310 return pygi_get_property_value (self->pygobject, pspec);
314 set_property_from_pspec(GObject *obj,
318 GValue value = { 0, };
320 if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
321 PyErr_Format(PyExc_TypeError,
322 "property '%s' can only be set in constructor",
327 if (!(pspec->flags & G_PARAM_WRITABLE)) {
328 PyErr_Format(PyExc_TypeError,
329 "property '%s' is not writable", pspec->name);
333 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
334 if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
335 PyObject *pvalue_str = PyObject_Str(pvalue);
336 PyErr_Format(PyExc_TypeError,
337 "could not convert '%s' to type '%s' when setting property '%s.%s'",
338 PYGLIB_PyUnicode_AsString(pvalue_str),
339 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)),
340 G_OBJECT_TYPE_NAME(obj),
342 Py_DECREF(pvalue_str);
346 Py_BEGIN_ALLOW_THREADS;
347 g_object_set_property(obj, pspec->name, &value);
348 g_value_unset(&value);
349 Py_END_ALLOW_THREADS;
354 PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps);
357 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
360 char *attr_name, *property_name;
364 if (pvalue == NULL) {
365 PyErr_SetString(PyExc_TypeError, "properties cannot be "
370 attr_name = PYGLIB_PyUnicode_AsString(attr);
373 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
376 if (!self->pygobject) {
377 PyErr_SetString(PyExc_TypeError,
378 "cannot set GOject properties without an instance");
382 obj = self->pygobject->obj;
384 property_name = g_strdup(attr_name);
385 canonicalize_key(property_name);
387 /* g_object_class_find_property recurses through the class hierarchy,
388 * so the resulting pspec tells us the owner_type that owns the property
389 * we're dealing with. */
390 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj),
392 g_free(property_name);
394 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
396 if (!pyg_gtype_is_custom (pspec->owner_type)) {
397 /* This GType is not implemented in Python: see if we can set the
398 * property via gi. */
399 ret = pygi_set_property_value (self->pygobject, pspec, pvalue);
402 else if (ret == -1 && PyErr_Occurred())
406 /* This GType is implemented in Python, or we failed to set it via gi:
407 * do a straightforward set. */
408 if (!set_property_from_pspec(obj, pspec, pvalue))
415 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
417 if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
423 pygobject_props_get_iter(PyGProps *self)
428 iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
429 class = g_type_class_ref(self->gtype);
430 iter->props = g_object_class_list_properties(class, &iter->n_props);
432 g_type_class_unref(class);
433 return (PyObject *) iter;
437 pygobject_props_dir(PyGProps *self)
442 class = g_type_class_ref (self->gtype);
443 ret = build_parameter_list (class);
444 g_type_class_unref (class);
449 static PyMethodDef pygobject_props_methods[] = {
450 { "__dir__", (PyCFunction)pygobject_props_dir, METH_NOARGS},
456 PyGProps_length(PyGProps *self)
462 class = g_type_class_ref(self->gtype);
463 props = g_object_class_list_properties(class, &n_props);
464 g_type_class_unref(class);
467 return (Py_ssize_t)n_props;
470 static PySequenceMethods _PyGProps_as_sequence = {
471 (lenfunc) PyGProps_length,
480 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject);
483 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
487 gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
488 if (obj == NULL || obj == Py_None) {
489 gprops->pygobject = NULL;
490 gprops->gtype = pyg_type_from_object(type);
492 if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
493 PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
494 " descriptor on non-GObject instances");
498 gprops->pygobject = (PyGObject *) obj;
499 gprops->gtype = pyg_type_from_object(obj);
501 return (PyObject *) gprops;
505 * pygobject_register_class:
506 * @dict: the module dictionary. A reference to the type will be stored here.
507 * @type_name: not used ?
508 * @gtype: the GType of the GObject subclass.
509 * @type: the Python type object for this wrapper.
510 * @static_bases: a tuple of Python type objects that are the bases of
513 * This function is used to register a Python type as the wrapper for
514 * a particular GObject subclass. It will also insert a reference to
515 * the wrapper class into the module dictionary passed as a reference,
516 * which simplifies initialisation.
519 pygobject_register_class(PyObject *dict, const gchar *type_name,
520 GType gtype, PyTypeObject *type,
521 PyObject *static_bases)
524 const char *class_name, *s;
525 PyObject *runtime_bases;
526 PyObject *bases_list, *bases, *mod_name;
529 class_name = type->tp_name;
530 s = strrchr(class_name, '.');
534 runtime_bases = pyg_type_get_bases(gtype);
536 PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
537 bases_list = PySequence_List(static_bases);
538 /* we start at index 1 because we want to skip the primary
539 * base, otherwise we might get MRO conflict */
540 for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
542 PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
543 int contains = PySequence_Contains(bases_list, base);
546 else if (!contains) {
547 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
549 g_message("Adding missing base %s to type %s",
550 ((PyTypeObject *)base)->tp_name, type->tp_name);
552 PyList_Append(bases_list, base);
556 bases = PySequence_Tuple(bases_list);
557 Py_DECREF(bases_list);
558 Py_DECREF(runtime_bases);
560 bases = runtime_bases;
562 Py_TYPE(type) = PyGObject_MetaType;
563 type->tp_bases = bases;
564 if (G_LIKELY(bases)) {
565 type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
566 Py_INCREF(type->tp_base);
569 pygobject_inherit_slots(type, bases, TRUE);
571 if (PyType_Ready(type) < 0) {
572 g_warning ("couldn't make the type `%s' ready", type->tp_name);
576 /* Set type.__module__ to the name of the module,
577 * otherwise it'll default to 'gobject', see #376099
579 s = strrchr(type->tp_name, '.');
581 mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
582 PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
587 o = pyg_type_wrapper_new(gtype);
588 PyDict_SetItemString(type->tp_dict, "__gtype__", o);
591 /* stash a pointer to the python class with the GType */
593 g_type_set_qdata(gtype, pygobject_class_key, type);
596 /* set up __doc__ descriptor on type */
597 PyDict_SetItemString(type->tp_dict, "__doc__",
598 pyg_object_descr_doc_get());
600 PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
604 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
607 PyGILState_STATE state;
609 state = pyglib_gil_state_ensure();
611 /* Avoid thread safety problems by using qdata for wrapper retrieval
612 * instead of the user data argument.
613 * See: https://bugzilla.gnome.org/show_bug.cgi?id=709223
615 self = (PyGObject *)g_object_get_qdata (object, pygobject_wrapper_key);
623 pyglib_gil_state_release(state);
626 /* Called when the inst_dict is first created; switches the
627 reference counting strategy to start using toggle ref to keep the
628 wrapper alive while the GObject lives. In contrast, while
629 inst_dict was NULL the python wrapper is allowed to die at
630 will and is recreated on demand. */
632 pygobject_switch_to_toggle_ref(PyGObject *self)
634 g_assert(self->obj->ref_count >= 1);
636 if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF)
637 return; /* already using toggle ref */
638 self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
639 /* Note that add_toggle_ref will never immediately call back into
641 Py_INCREF((PyObject *) self);
642 g_object_add_toggle_ref(self->obj, pyg_toggle_notify, NULL);
643 g_object_unref(self->obj);
646 /* Called when an custom gobject is initalized via g_object_new instead of
647 its constructor. The next time the wrapper is access via
648 pygobject_new_full it will sink the floating reference instead of
649 adding a new reference and causing a leak */
652 pygobject_ref_float(PyGObject *self)
654 /* should only be floated once */
655 g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
657 self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
660 /* Called by gobject_new_full, if the floating flag is set remove it, otherwise
663 pygobject_ref_sink(PyGObject *self)
665 if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
666 self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
668 Py_INCREF ( (PyObject *) self);
672 * pygobject_register_wrapper:
673 * @self: the wrapper instance
675 * In the constructor of PyGTK wrappers, this function should be
676 * called after setting the obj member. It will tie the wrapper
677 * instance to the GObject so that the same wrapper instance will
678 * always be used for this GObject instance.
681 pygobject_register_wrapper(PyObject *self)
685 g_return_if_fail(self != NULL);
686 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
688 gself = (PyGObject *)self;
690 g_assert(gself->obj->ref_count >= 1);
691 /* save wrapper pointer so we can access it later */
692 g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
693 if (gself->inst_dict)
694 pygobject_switch_to_toggle_ref(gself);
698 pyg_type_get_bases(GType gtype)
700 GType *interfaces, parent_type, interface_type;
702 PyTypeObject *py_parent_type, *py_interface_type;
706 if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
709 /* Lookup the parent type */
710 parent_type = g_type_parent(gtype);
711 py_parent_type = pygobject_lookup_class(parent_type);
712 interfaces = g_type_interfaces(gtype, &n_interfaces);
713 bases = PyTuple_New(n_interfaces + 1);
714 /* We will always put the parent at the first position in bases */
715 Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
716 PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
718 /* And traverse interfaces */
720 for (i = 0; i < n_interfaces; i++) {
721 interface_type = interfaces[i];
722 py_interface_type = pygobject_lookup_class(interface_type);
723 Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
724 PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
732 * pygobject_new_with_interfaces
733 * @gtype: the GType of the GObject subclass.
735 * Creates a new PyTypeObject from the given GType with interfaces attached in
738 * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
740 static PyTypeObject *
741 pygobject_new_with_interfaces(GType gtype)
743 PyGILState_STATE state;
747 PyTypeObject *py_parent_type;
750 state = pyglib_gil_state_ensure();
752 bases = pyg_type_get_bases(gtype);
753 py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
757 o = pyg_type_wrapper_new(gtype);
758 PyDict_SetItemString(dict, "__gtype__", o);
761 /* set up __doc__ descriptor on type */
762 PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
764 /* Something special to point out that it's not accessible through
766 o = PYGLIB_PyUnicode_FromString ("__gi__");
767 PyDict_SetItemString (dict, "__module__", o);
770 type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
771 "sNN", g_type_name (gtype), bases, dict);
775 pyglib_gil_state_release(state);
779 /* Workaround python tp_(get|set)attr slot inheritance bug.
780 * Fixes bug #144135. */
781 if (!type->tp_getattr && py_parent_type->tp_getattr) {
782 type->tp_getattro = NULL;
783 type->tp_getattr = py_parent_type->tp_getattr;
785 if (!type->tp_setattr && py_parent_type->tp_setattr) {
786 type->tp_setattro = NULL;
787 type->tp_setattr = py_parent_type->tp_setattr;
789 /* override more python stupid hacks behind our back */
790 type->tp_dealloc = py_parent_type->tp_dealloc;
791 type->tp_alloc = py_parent_type->tp_alloc;
792 type->tp_free = py_parent_type->tp_free;
793 type->tp_traverse = py_parent_type->tp_traverse;
794 type->tp_clear = py_parent_type->tp_clear;
796 pygobject_inherit_slots(type, bases, FALSE);
798 if (PyType_Ready(type) < 0) {
799 g_warning ("couldn't make the type `%s' ready", type->tp_name);
800 pyglib_gil_state_release(state);
804 /* stash a pointer to the python class with the GType */
806 g_type_set_qdata(gtype, pygobject_class_key, type);
808 pyglib_gil_state_release(state);
813 /* Pick appropriate value for given slot (at slot_offset inside
814 * PyTypeObject structure). It must be a pointer, e.g. a pointer to a
815 * function. We use the following heuristic:
817 * - Scan all types listed as bases of the type.
818 * - If for exactly one base type slot value is non-NULL and
819 * different from that of 'object' and 'GObject', set current type
820 * slot into that value.
821 * - Otherwise (if there is more than one such base type or none at
822 * all) don't touch it and live with Python default.
824 * The intention here is to propagate slot from custom wrappers to
825 * wrappers created at runtime when appropriate. We prefer to be on
826 * the safe side, so if there is potential collision (more than one
827 * custom slot value), we discard custom overrides altogether.
829 * When registering type with pygobject_register_class(), i.e. a type
830 * that has been manually created (likely with Codegen help),
831 * `check_for_present' should be set to TRUE. In this case, the
832 * function will never overwrite any non-NULL slots already present in
833 * the type. If `check_for_present' is FALSE, such non-NULL slots are
834 * though to be set by Python interpreter and so will be overwritten
835 * if heuristic above says so.
838 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
840 static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
841 #if PY_VERSION_HEX < 0x03000000
842 offsetof(PyTypeObject, tp_compare),
844 offsetof(PyTypeObject, tp_richcompare),
845 offsetof(PyTypeObject, tp_hash),
846 offsetof(PyTypeObject, tp_iter),
847 offsetof(PyTypeObject, tp_repr),
848 offsetof(PyTypeObject, tp_str),
849 offsetof(PyTypeObject, tp_print) };
852 /* Happens when registering gobject.GObject itself, at least. */
856 for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
857 pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
861 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
862 gboolean check_for_present)
864 #define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset))
866 void *found_slot = NULL;
867 int num_bases = PyTuple_Size(bases);
870 if (check_for_present && TYPE_SLOT(type) != NULL) {
871 /* We are requested to check if there is any custom slot value
872 * in this type already and there actually is. Don't
878 for (i = 0; i < num_bases; ++i) {
879 PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
880 void *slot = TYPE_SLOT(base_type);
884 if (slot == TYPE_SLOT(&PyGObject_Type) ||
885 slot == TYPE_SLOT(&PyBaseObject_Type))
888 if (found_slot != NULL && found_slot != slot) {
889 /* We have a conflict: more than one base use different
890 * custom slots. To be on the safe side, we bail out.
898 /* Only perform the final assignment if at least one base has a
899 * custom value. Otherwise just leave this type's slot untouched.
901 if (found_slot != NULL)
902 TYPE_SLOT(type) = found_slot;
908 * pygobject_lookup_class:
909 * @gtype: the GType of the GObject subclass.
911 * This function looks up the wrapper class used to represent
912 * instances of a GObject represented by @gtype. If no wrapper class
913 * or interface has been registered for the given GType, then a new
914 * type will be created.
916 * Returns: The wrapper class for the GObject or NULL if the
917 * GType has no registered type and a new type couldn't be created
920 pygobject_lookup_class(GType gtype)
922 PyTypeObject *py_type;
924 if (gtype == G_TYPE_INTERFACE)
925 return &PyGInterface_Type;
927 py_type = g_type_get_qdata(gtype, pygobject_class_key);
928 if (py_type == NULL) {
929 py_type = g_type_get_qdata(gtype, pyginterface_type_key);
932 py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
934 if (py_type == NULL) {
935 py_type = pygobject_new_with_interfaces(gtype);
936 g_type_set_qdata(gtype, pyginterface_type_key, py_type);
944 * pygobject_new_full:
945 * @obj: a GObject instance.
946 * @steal: whether to steal a ref from the GObject or add (sink) a new one.
947 * @g_class: the GObjectClass
949 * This function gets a reference to a wrapper for the given GObject
950 * instance. If a wrapper has already been created, a new reference
951 * to that wrapper will be returned. Otherwise, a wrapper instance
954 * Returns: a reference to the wrapper for the GObject.
957 pygobject_new_full(GObject *obj, gboolean steal, gpointer g_class)
965 /* If the GObject already has a PyObject wrapper stashed in its qdata, re-use it.
967 self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
969 /* Note the use of "pygobject_ref_sink" here only deals with PyObject
970 * wrapper ref counts and has nothing to do with GObject.
972 pygobject_ref_sink(self);
974 /* If steal is true, we also want to decref the incoming GObjects which
975 * already have a Python wrapper because the wrapper is already holding a
979 g_object_unref (obj);
983 PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
986 tp = inst_data->type;
989 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
991 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
993 g_assert(tp != NULL);
995 /* need to bump type refcount if created with
996 pygobject_new_with_interfaces(). fixes bug #141042 */
997 if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
999 self = PyObject_GC_New(PyGObject, tp);
1002 self->inst_dict = NULL;
1003 self->weakreflist = NULL;
1004 self->private_flags.flags = 0;
1007 /* If we are not stealing a ref or the object is floating,
1008 * add a regular ref or sink the object. */
1009 if (g_object_is_floating (obj))
1010 self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING;
1011 if (!steal || self->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING)
1012 g_object_ref_sink (obj);
1014 pygobject_register_wrapper((PyObject *)self);
1015 PyObject_GC_Track((PyObject *)self);
1018 return (PyObject *)self;
1023 pygobject_new(GObject *obj)
1025 return pygobject_new_full(obj,
1031 pygobject_unwatch_closure(gpointer data, GClosure *closure)
1033 PyGObjectData *inst_data = data;
1035 inst_data->closures = g_slist_remove (inst_data->closures, closure);
1039 * pygobject_watch_closure:
1040 * @self: a GObject wrapper instance
1041 * @closure: a GClosure to watch
1043 * Adds a closure to the list of watched closures for the wrapper.
1044 * The closure must be one returned by pyg_closure_new(). When the
1045 * cycle GC traverses the wrapper instance, it will enumerate the
1046 * references to Python objects stored in watched closures. If the
1047 * cycle GC tells the wrapper to clear itself, the watched closures
1048 * will be invalidated.
1051 pygobject_watch_closure(PyObject *self, GClosure *closure)
1054 PyGObjectData *data;
1056 g_return_if_fail(self != NULL);
1057 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
1058 g_return_if_fail(closure != NULL);
1060 gself = (PyGObject *)self;
1061 data = pygobject_get_inst_data(gself);
1062 g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
1063 data->closures = g_slist_prepend(data->closures, closure);
1064 g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
1068 /* -------------- PyGObject behaviour ----------------- */
1070 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
1073 pygobject_dealloc(PyGObject *self)
1075 /* Untrack must be done first. This is because followup calls such as
1076 * ClearWeakRefs could call into Python and cause new allocations to
1077 * happen, which could in turn could trigger the garbage collector,
1078 * which would then get confused as it is tracking this half-deallocated
1080 PyObject_GC_UnTrack((PyObject *)self);
1082 PyObject_ClearWeakRefs((PyObject *)self);
1083 /* this forces inst_data->type to be updated, which could prove
1084 * important if a new wrapper has to be created and it is of a
1085 * unregistered type */
1086 pygobject_get_inst_data(self);
1087 pygobject_clear(self);
1088 /* the following causes problems with subclassed types */
1089 /* Py_TYPE(self)->tp_free((PyObject *)self); */
1090 PyObject_GC_Del(self);
1094 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1098 isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1102 Py_INCREF(Py_NotImplemented);
1103 return Py_NotImplemented;
1105 isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1109 Py_INCREF(Py_NotImplemented);
1110 return Py_NotImplemented;
1113 return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1114 ((PyGObject*)other)->obj,
1119 pygobject_hash(PyGObject *self)
1121 return (long)self->obj;
1125 pygobject_repr(PyGObject *self)
1127 PyObject *module, *repr;
1128 gchar *module_str, *namespace;
1130 module = PyObject_GetAttrString ((PyObject *)self, "__module__");
1134 if (!PYGLIB_PyUnicode_Check (module)) {
1139 module_str = PYGLIB_PyUnicode_AsString (module);
1140 namespace = g_strrstr (module_str, ".");
1141 if (namespace == NULL) {
1142 namespace = module_str;
1147 repr = PYGLIB_PyUnicode_FromFormat ("<%s.%s object at %p (%s at %p)>",
1148 namespace, Py_TYPE (self)->tp_name, self,
1149 self->obj ? G_OBJECT_TYPE_NAME (self->obj) : "uninitialized",
1157 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1161 PyGObjectData *data = pygobject_get_inst_data(self);
1163 if (self->inst_dict) ret = visit(self->inst_dict, arg);
1164 if (ret != 0) return ret;
1168 for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1169 PyGClosure *closure = tmp->data;
1171 if (closure->callback) ret = visit(closure->callback, arg);
1172 if (ret != 0) return ret;
1174 if (closure->extra_args) ret = visit(closure->extra_args, arg);
1175 if (ret != 0) return ret;
1177 if (closure->swap_data) ret = visit(closure->swap_data, arg);
1178 if (ret != 0) return ret;
1185 pygobject_clear(PyGObject *self)
1188 g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1189 if (self->inst_dict) {
1190 g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, NULL);
1191 self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1193 Py_BEGIN_ALLOW_THREADS;
1194 g_object_unref(self->obj);
1195 Py_END_ALLOW_THREADS;
1199 Py_CLEAR(self->inst_dict);
1204 pygobject_free(PyObject *op)
1206 PyObject_GC_Del(op);
1210 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1211 guint *n_params, GParameter **params)
1221 *params = g_new0(GParameter, PyDict_Size(kwargs));
1222 while (PyDict_Next(kwargs, &pos, &key, &value)) {
1224 GParameter *param = &(*params)[*n_params];
1225 const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1227 pspec = g_object_class_find_property(class, key_str);
1229 PyErr_Format(PyExc_TypeError,
1230 "gobject `%s' doesn't support property `%s'",
1231 G_OBJECT_CLASS_NAME(class), key_str);
1234 g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1235 if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) {
1236 PyErr_Format(PyExc_TypeError,
1237 "could not convert value for property `%s' from %s to %s",
1238 key_str, Py_TYPE(value)->tp_name,
1239 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1242 param->name = g_strdup(key_str);
1249 /* ---------------- PyGObject methods ----------------- */
1252 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1255 guint n_params = 0, i;
1256 GParameter *params = NULL;
1257 GObjectClass *class;
1259 /* Only do GObject creation and property setting if the GObject hasn't
1260 * already been created. The case where self->obj already exists can occur
1261 * when C constructors are called directly (Gtk.Button.new_with_label)
1262 * and we are simply wrapping the result with a PyGObject.
1263 * In these cases we want to ignore any keyword arguments passed along
1264 * to __init__ and simply return.
1266 * See: https://bugzilla.gnome.org/show_bug.cgi?id=705810
1268 if (self->obj != NULL)
1271 if (!PyArg_ParseTuple(args, ":GObject.__init__", NULL))
1274 object_type = pyg_type_from_object((PyObject *)self);
1278 if (G_TYPE_IS_ABSTRACT(object_type)) {
1279 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1280 "(non-instantiable) type `%s'", g_type_name(object_type));
1284 if ((class = g_type_class_ref (object_type)) == NULL) {
1285 PyErr_SetString(PyExc_TypeError,
1286 "could not get a reference to type class");
1290 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms))
1293 if (pygobject_constructv(self, n_params, params))
1294 PyErr_SetString(PyExc_RuntimeError, "could not create object");
1297 for (i = 0; i < n_params; i++) {
1298 g_free((gchar *) params[i].name);
1299 g_value_unset(¶ms[i].value);
1302 g_type_class_unref(class);
1304 return (self->obj) ? 0 : -1;
1307 #define CHECK_GOBJECT(self) \
1308 if (!G_IS_OBJECT(self->obj)) { \
1309 PyErr_Format(PyExc_TypeError, \
1310 "object at %p of type %s is not initialized", \
1311 self, Py_TYPE(self)->tp_name); \
1316 pygobject_get_property (PyGObject *self, PyObject *args)
1320 if (!PyArg_ParseTuple (args, "s:GObject.get_property", ¶m_name)) {
1324 CHECK_GOBJECT(self);
1326 return pygi_get_property_value_by_name (self, param_name);
1330 pygobject_get_properties(PyGObject *self, PyObject *args)
1335 if ((len = PyTuple_Size(args)) < 1) {
1336 PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1340 tuple = PyTuple_New(len);
1341 for (i = 0; i < len; i++) {
1342 PyObject *py_property = PyTuple_GetItem(args, i);
1343 gchar *property_name;
1346 if (!PYGLIB_PyUnicode_Check(py_property)) {
1347 PyErr_SetString(PyExc_TypeError,
1348 "Expected string argument for property.");
1352 property_name = PYGLIB_PyUnicode_AsString(py_property);
1353 item = pygi_get_property_value_by_name (self, property_name);
1354 PyTuple_SetItem (tuple, i, item);
1365 pygobject_set_property(PyGObject *self, PyObject *args)
1372 if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name,
1376 CHECK_GOBJECT(self);
1378 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1381 PyErr_Format(PyExc_TypeError,
1382 "object of type `%s' does not have property `%s'",
1383 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1387 ret = pygi_set_property_value (self, pspec, pvalue);
1390 else if (PyErr_Occurred())
1393 if (!set_property_from_pspec(self->obj, pspec, pvalue))
1403 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1405 GObjectClass *class;
1409 PyObject *result = NULL;
1411 CHECK_GOBJECT(self);
1413 class = G_OBJECT_GET_CLASS(self->obj);
1415 g_object_freeze_notify (G_OBJECT(self->obj));
1418 while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1419 gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1423 pspec = g_object_class_find_property(class, key_str);
1427 g_snprintf(buf, sizeof(buf),
1428 "object `%s' doesn't support property `%s'",
1429 g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1430 PyErr_SetString(PyExc_TypeError, buf);
1434 ret = pygi_set_property_value (self, pspec, value);
1436 /* Non-zero return code means that either an error occured ...*/
1437 if (PyErr_Occurred())
1440 /* ... or the property couldn't be found , so let's try the default
1442 if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value))
1450 g_object_thaw_notify (G_OBJECT(self->obj));
1455 /* custom closure for gobject bindings */
1457 pygbinding_closure_invalidate(gpointer data, GClosure *closure)
1459 PyGClosure *pc = (PyGClosure *)closure;
1460 PyGILState_STATE state;
1462 state = pyglib_gil_state_ensure();
1463 Py_XDECREF(pc->callback);
1464 Py_XDECREF(pc->extra_args);
1465 pyglib_gil_state_release(state);
1467 pc->callback = NULL;
1468 pc->extra_args = NULL;
1472 pygbinding_marshal (GClosure *closure,
1473 GValue *return_value,
1474 guint n_param_values,
1475 const GValue *param_values,
1476 gpointer invocation_hint,
1477 gpointer marshal_data)
1479 PyGILState_STATE state;
1480 PyGClosure *pc = (PyGClosure *)closure;
1481 PyObject *params, *ret;
1484 state = pyglib_gil_state_ensure();
1486 /* construct Python tuple for the parameter values */
1487 params = PyTuple_New(2);
1488 PyTuple_SetItem (params, 0, pyg_value_as_pyobject(¶m_values[0], FALSE));
1489 PyTuple_SetItem (params, 1, pyg_value_as_pyobject(¶m_values[1], FALSE));
1491 /* params passed to function may have extra arguments */
1492 if (pc->extra_args) {
1493 PyObject *tuple = params;
1494 params = PySequence_Concat(tuple, pc->extra_args);
1497 ret = PyObject_CallObject(pc->callback, params);
1501 } else if (ret == Py_None) {
1502 g_value_set_boolean (return_value, FALSE);
1506 out_value = g_value_get_boxed (¶m_values[2]);
1507 if (pyg_value_from_pyobject (out_value, ret) != 0) {
1508 PyErr_SetString (PyExc_ValueError, "can't convert value");
1510 g_value_set_boolean (return_value, FALSE);
1512 g_value_set_boolean (return_value, TRUE);
1519 pyglib_gil_state_release(state);
1523 pygbinding_closure_new (PyObject *callback, PyObject *extra_args)
1527 g_return_val_if_fail(callback != NULL, NULL);
1528 closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
1529 g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate);
1530 g_closure_set_marshal(closure, pygbinding_marshal);
1531 Py_INCREF(callback);
1532 ((PyGClosure *)closure)->callback = callback;
1533 if (extra_args && extra_args != Py_None) {
1534 Py_INCREF(extra_args);
1535 if (!PyTuple_Check(extra_args)) {
1536 PyObject *tmp = PyTuple_New(1);
1537 PyTuple_SetItem(tmp, 0, extra_args);
1540 ((PyGClosure *)closure)->extra_args = extra_args;
1546 pygobject_bind_property(PyGObject *self, PyObject *args)
1548 gchar *source_name, *target_name;
1549 gchar *source_canon, *target_canon;
1550 PyObject *target, *source_repr, *target_repr;
1551 PyObject *transform_to, *transform_from, *user_data = NULL;
1553 GBindingFlags flags = G_BINDING_DEFAULT;
1554 GClosure *to_closure = NULL, *from_closure = NULL;
1556 transform_from = NULL;
1557 transform_to = NULL;
1559 if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property",
1560 &source_name, &target, &target_name, &flags,
1561 &transform_to, &transform_from, &user_data))
1564 CHECK_GOBJECT(self);
1565 if (!PyObject_TypeCheck(target, &PyGObject_Type)) {
1566 PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject");
1570 if (transform_to && transform_to != Py_None) {
1571 if (!PyCallable_Check (transform_to)) {
1572 PyErr_SetString (PyExc_TypeError,
1573 "transform_to must be callable or None");
1576 to_closure = pygbinding_closure_new (transform_to, user_data);
1579 if (transform_from && transform_from != Py_None) {
1580 if (!PyCallable_Check (transform_from)) {
1581 PyErr_SetString (PyExc_TypeError,
1582 "transform_from must be callable or None");
1585 from_closure = pygbinding_closure_new (transform_from, user_data);
1588 /* Canonicalize underscores to hyphens. Note the results must be freed. */
1589 source_canon = g_strdelimit(g_strdup(source_name), "_", '-');
1590 target_canon = g_strdelimit(g_strdup(target_name), "_", '-');
1592 binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon,
1593 pygobject_get(target), target_canon,
1594 flags, to_closure, from_closure);
1595 g_free(source_canon);
1596 g_free(target_canon);
1597 source_canon = target_canon = NULL;
1599 if (binding == NULL) {
1600 source_repr = PyObject_Repr((PyObject*)self);
1601 target_repr = PyObject_Repr(target);
1602 PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s",
1603 PYGLIB_PyUnicode_AsString(source_repr), source_name,
1604 PYGLIB_PyUnicode_AsString(target_repr), target_name);
1605 Py_DECREF(source_repr);
1606 Py_DECREF(target_repr);
1610 return pygobject_new (G_OBJECT (binding));
1614 connect_helper(PyGObject *self, gchar *name, PyObject *callback, PyObject *extra_args, PyObject *object, gboolean after)
1618 GClosure *closure = NULL;
1620 GSignalQuery query_info;
1622 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1623 &sigid, &detail, TRUE)) {
1624 PyObject *repr = PyObject_Repr((PyObject*)self);
1625 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1626 PYGLIB_PyUnicode_AsString(repr),
1632 if (object && !PyObject_TypeCheck (object, &PyGObject_Type)) {
1633 if (PyErr_WarnEx (PyGIDeprecationWarning,
1634 "Using non GObject arguments for connect_object() is deprecated, use: "
1635 "connect_data(signal, callback, data, connect_flags=GObject.ConnectFlags.SWAPPED)",
1641 g_signal_query (sigid, &query_info);
1642 if (!pyg_gtype_is_custom (query_info.itype)) {
1643 /* The signal is implemented by a non-Python class, probably
1644 * something in the gi repository. */
1645 closure = pygi_signal_closure_new (self, query_info.itype,
1646 query_info.signal_name, callback,
1647 extra_args, object);
1651 /* The signal is either implemented at the Python level, or it comes
1652 * from a foreign class that we don't have introspection data for. */
1653 closure = pyg_closure_new (callback, extra_args, object);
1656 pygobject_watch_closure((PyObject *)self, closure);
1657 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1659 return PyLong_FromUnsignedLong(handlerid);
1663 pygobject_connect(PyGObject *self, PyObject *args)
1665 PyObject *first, *callback, *extra_args, *ret;
1669 len = PyTuple_Size(args);
1671 PyErr_SetString(PyExc_TypeError,
1672 "GObject.connect requires at least 2 arguments");
1675 first = PySequence_GetSlice(args, 0, 2);
1676 if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1681 if (!PyCallable_Check(callback)) {
1682 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1686 CHECK_GOBJECT(self);
1688 extra_args = PySequence_GetSlice(args, 2, len);
1689 if (extra_args == NULL)
1692 ret = connect_helper(self, name, callback, extra_args, NULL, FALSE);
1693 Py_DECREF(extra_args);
1698 pygobject_connect_after(PyGObject *self, PyObject *args)
1700 PyObject *first, *callback, *extra_args, *ret;
1704 len = PyTuple_Size(args);
1706 PyErr_SetString(PyExc_TypeError,
1707 "GObject.connect_after requires at least 2 arguments");
1710 first = PySequence_GetSlice(args, 0, 2);
1711 if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1712 &name, &callback)) {
1717 if (!PyCallable_Check(callback)) {
1718 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1722 CHECK_GOBJECT(self);
1724 extra_args = PySequence_GetSlice(args, 2, len);
1725 if (extra_args == NULL)
1728 ret = connect_helper(self, name, callback, extra_args, NULL, TRUE);
1729 Py_DECREF(extra_args);
1734 pygobject_connect_object(PyGObject *self, PyObject *args)
1736 PyObject *first, *callback, *extra_args, *object, *ret;
1740 len = PyTuple_Size(args);
1742 PyErr_SetString(PyExc_TypeError,
1743 "GObject.connect_object requires at least 3 arguments");
1746 first = PySequence_GetSlice(args, 0, 3);
1747 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1748 &name, &callback, &object)) {
1753 if (!PyCallable_Check(callback)) {
1754 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1758 CHECK_GOBJECT(self);
1760 extra_args = PySequence_GetSlice(args, 3, len);
1761 if (extra_args == NULL)
1764 ret = connect_helper(self, name, callback, extra_args, object, FALSE);
1765 Py_DECREF(extra_args);
1770 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1772 PyObject *first, *callback, *extra_args, *object, *ret;
1776 len = PyTuple_Size(args);
1778 PyErr_SetString(PyExc_TypeError,
1779 "GObject.connect_object_after requires at least 3 arguments");
1782 first = PySequence_GetSlice(args, 0, 3);
1783 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1784 &name, &callback, &object)) {
1789 if (!PyCallable_Check(callback)) {
1790 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1794 CHECK_GOBJECT(self);
1796 extra_args = PySequence_GetSlice(args, 3, len);
1797 if (extra_args == NULL)
1800 ret = connect_helper(self, name, callback, extra_args, object, TRUE);
1801 Py_DECREF(extra_args);
1806 pygobject_emit(PyGObject *self, PyObject *args)
1808 guint signal_id, i, j;
1811 PyObject *first, *py_ret, *repr = NULL;
1814 GValue *params, ret = { 0, };
1816 len = PyTuple_Size(args);
1818 PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1821 first = PySequence_GetSlice(args, 0, 1);
1822 if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1828 CHECK_GOBJECT(self);
1830 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1831 &signal_id, &detail, TRUE)) {
1832 repr = PyObject_Repr((PyObject*)self);
1833 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1834 PYGLIB_PyUnicode_AsString(repr),
1839 g_signal_query(signal_id, &query);
1840 if (len != query.n_params + 1) {
1843 g_snprintf(buf, sizeof(buf),
1844 "%d parameters needed for signal %s; %ld given",
1845 query.n_params, name, (long int) (len - 1));
1846 PyErr_SetString(PyExc_TypeError, buf);
1850 params = g_new0(GValue, query.n_params + 1);
1851 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1852 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1854 for (i = 0; i < query.n_params; i++)
1855 g_value_init(¶ms[i + 1],
1856 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1857 for (i = 0; i < query.n_params; i++) {
1858 PyObject *item = PyTuple_GetItem(args, i+1);
1860 if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1862 g_snprintf(buf, sizeof(buf),
1863 "could not convert type %s to %s required for parameter %d",
1864 Py_TYPE(item)->tp_name,
1865 G_VALUE_TYPE_NAME(¶ms[i+1]), i);
1866 PyErr_SetString(PyExc_TypeError, buf);
1868 for (j = 0; j <= i; j++)
1869 g_value_unset(¶ms[j]);
1876 if (query.return_type != G_TYPE_NONE)
1877 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1879 g_signal_emitv(params, signal_id, detail, &ret);
1881 for (i = 0; i < query.n_params + 1; i++)
1882 g_value_unset(¶ms[i]);
1885 if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1886 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1887 g_value_unset(&ret);
1897 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1899 GSignalInvocationHint *ihint;
1905 GValue *params, ret = { 0, };
1907 CHECK_GOBJECT(self);
1909 ihint = g_signal_get_invocation_hint(self->obj);
1911 PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1912 "information for this object.");
1916 signal_id = ihint->signal_id;
1917 name = g_signal_name(signal_id);
1919 len = PyTuple_Size(args);
1920 if (signal_id == 0) {
1921 PyErr_SetString(PyExc_TypeError, "unknown signal name");
1924 g_signal_query(signal_id, &query);
1925 if (len != query.n_params) {
1928 g_snprintf(buf, sizeof(buf),
1929 "%d parameters needed for signal %s; %ld given",
1930 query.n_params, name, (long int) len);
1931 PyErr_SetString(PyExc_TypeError, buf);
1934 params = g_new0(GValue, query.n_params + 1);
1935 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1936 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1938 for (i = 0; i < query.n_params; i++)
1939 g_value_init(¶ms[i + 1],
1940 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1941 for (i = 0; i < query.n_params; i++) {
1942 PyObject *item = PyTuple_GetItem(args, i);
1944 if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1945 g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void));
1947 else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1950 g_snprintf(buf, sizeof(buf),
1951 "could not convert type %s to %s required for parameter %d",
1952 Py_TYPE(item)->tp_name,
1953 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
1954 PyErr_SetString(PyExc_TypeError, buf);
1955 for (i = 0; i < query.n_params + 1; i++)
1956 g_value_unset(¶ms[i]);
1961 if (query.return_type != G_TYPE_NONE)
1962 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1963 g_signal_chain_from_overridden(params, &ret);
1964 for (i = 0; i < query.n_params + 1; i++)
1965 g_value_unset(¶ms[i]);
1967 if (query.return_type != G_TYPE_NONE) {
1968 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1969 g_value_unset(&ret);
1979 pygobject_weak_ref(PyGObject *self, PyObject *args)
1982 PyObject *callback = NULL, *user_data = NULL;
1985 CHECK_GOBJECT(self);
1987 if ((len = PySequence_Length(args)) >= 1) {
1988 callback = PySequence_ITEM(args, 0);
1989 user_data = PySequence_GetSlice(args, 1, len);
1991 retval = pygobject_weak_ref_new(self->obj, callback, user_data);
1992 Py_XDECREF(callback);
1993 Py_XDECREF(user_data);
1999 pygobject_copy(PyGObject *self)
2001 PyErr_SetString(PyExc_TypeError,
2002 "GObject descendants' instances are non-copyable");
2007 pygobject_deepcopy(PyGObject *self, PyObject *args)
2009 PyErr_SetString(PyExc_TypeError,
2010 "GObject descendants' instances are non-copyable");
2016 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
2018 PyObject *pyfunc = NULL, *repr = NULL;
2019 GClosure *closure = NULL;
2022 CHECK_GOBJECT(self);
2024 if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2027 if (!PyCallable_Check(pyfunc)) {
2028 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2032 closure = gclosure_from_pyfunc(self, pyfunc);
2034 repr = PyObject_Repr((PyObject*)pyfunc);
2035 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2036 PYGLIB_PyUnicode_AsString(repr));
2041 retval = g_signal_handlers_disconnect_matched(self->obj,
2042 G_SIGNAL_MATCH_CLOSURE,
2046 return PYGLIB_PyLong_FromLong(retval);
2050 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2052 PyObject *pyfunc = NULL, *repr = NULL;
2053 GClosure *closure = NULL;
2056 CHECK_GOBJECT(self);
2058 if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2061 if (!PyCallable_Check(pyfunc)) {
2062 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2066 closure = gclosure_from_pyfunc(self, pyfunc);
2068 repr = PyObject_Repr((PyObject*)pyfunc);
2069 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2070 PYGLIB_PyUnicode_AsString(repr));
2075 retval = g_signal_handlers_block_matched(self->obj,
2076 G_SIGNAL_MATCH_CLOSURE,
2080 return PYGLIB_PyLong_FromLong(retval);
2084 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2086 PyObject *pyfunc = NULL, *repr = NULL;
2087 GClosure *closure = NULL;
2090 CHECK_GOBJECT(self);
2092 if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2095 if (!PyCallable_Check(pyfunc)) {
2096 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2100 closure = gclosure_from_pyfunc(self, pyfunc);
2102 repr = PyObject_Repr((PyObject*)pyfunc);
2103 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2104 PYGLIB_PyUnicode_AsString(repr));
2109 retval = g_signal_handlers_unblock_matched(self->obj,
2110 G_SIGNAL_MATCH_CLOSURE,
2114 return PYGLIB_PyLong_FromLong(retval);
2118 static PyMethodDef pygobject_methods[] = {
2119 { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2120 { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2121 { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2122 { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2123 { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS },
2124 { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2125 { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2126 { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2127 { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2128 { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2129 { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2130 { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2131 { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2132 { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2133 { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2134 { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2135 { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2141 pygobject_get_dict(PyGObject *self, void *closure)
2143 if (self->inst_dict == NULL) {
2144 self->inst_dict = PyDict_New();
2145 if (self->inst_dict == NULL)
2147 if (G_LIKELY(self->obj))
2148 pygobject_switch_to_toggle_ref(self);
2150 Py_INCREF(self->inst_dict);
2151 return self->inst_dict;
2155 pygobject_get_refcount(PyGObject *self, void *closure)
2157 if (self->obj == NULL) {
2158 PyErr_Format(PyExc_TypeError, "GObject instance is not yet created");
2161 return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2165 pygobject_get_pointer(PyGObject *self, void *closure)
2167 return PYGLIB_CPointer_WrapPointer (self->obj, NULL);
2171 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2174 PyGObject *gself = (PyGObject *) self;
2175 PyObject *inst_dict_before = gself->inst_dict;
2176 /* call parent type's setattro */
2177 res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2178 if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2179 if (G_LIKELY(gself->obj))
2180 pygobject_switch_to_toggle_ref(gself);
2185 static PyGetSetDef pygobject_getsets[] = {
2186 { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2187 { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2188 { "__gpointer__", (getter)pygobject_get_pointer, (setter)0, },
2192 /* ------------------------------------ */
2193 /* ****** GObject weak reference ****** */
2194 /* ------------------------------------ */
2200 PyObject *user_data;
2201 gboolean have_floating_ref;
2204 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2207 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2209 if (self->callback && visit(self->callback, arg) < 0)
2211 if (self->user_data && visit(self->user_data, arg) < 0)
2217 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2220 if (self->callback) {
2222 PyGILState_STATE state = pyglib_gil_state_ensure();
2223 retval = PyObject_Call(self->callback, self->user_data, NULL);
2225 if (retval != Py_None)
2226 PyErr_Format(PyExc_TypeError,
2227 "GObject weak notify callback returned a value"
2228 " of type %s, should return None",
2229 Py_TYPE(retval)->tp_name);
2234 Py_CLEAR(self->callback);
2235 Py_CLEAR(self->user_data);
2236 if (self->have_floating_ref) {
2237 self->have_floating_ref = FALSE;
2238 Py_DECREF((PyObject *) self);
2240 pyglib_gil_state_release(state);
2245 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2247 Py_CLEAR(self->callback);
2248 Py_CLEAR(self->user_data);
2250 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2257 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2259 PyObject_GC_UnTrack((PyObject *)self);
2260 pygobject_weak_ref_clear(self);
2261 PyObject_GC_Del(self);
2265 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2267 PyGObjectWeakRef *self;
2269 self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2270 self->callback = callback;
2271 self->user_data = user_data;
2272 Py_XINCREF(self->callback);
2273 Py_XINCREF(self->user_data);
2275 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2276 if (callback != NULL) {
2277 /* when we have a callback, we should INCREF the weakref
2278 * object to make it stay alive even if it goes out of scope */
2279 self->have_floating_ref = TRUE;
2280 Py_INCREF((PyObject *) self);
2282 return (PyObject *) self;
2286 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2289 PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2292 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2294 if (self->have_floating_ref) {
2295 self->have_floating_ref = FALSE;
2302 static PyMethodDef pygobject_weak_ref_methods[] = {
2303 { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2308 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2310 static char *argnames[] = {NULL};
2312 if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2316 return pygobject_new(self->obj);
2324 pyobject_copy(gpointer boxed)
2326 PyObject *object = boxed;
2327 PyGILState_STATE state;
2329 state = pyglib_gil_state_ensure();
2331 pyglib_gil_state_release(state);
2336 pyobject_free(gpointer boxed)
2338 PyObject *object = boxed;
2339 PyGILState_STATE state;
2341 state = pyglib_gil_state_ensure();
2343 pyglib_gil_state_release(state);
2347 pygobject_object_register_types(PyObject *d)
2349 PyObject *o, *descr;
2351 pygobject_custom_key = g_quark_from_static_string("PyGObject::custom");
2352 pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2353 pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2354 pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2355 pygobject_has_updated_constructor_key =
2356 g_quark_from_static_string("PyGObject::has-updated-constructor");
2357 pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2360 if (!PY_TYPE_OBJECT)
2361 PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2364 PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2365 PyGObject_Type.tp_richcompare = pygobject_richcompare;
2366 PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2367 PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2368 PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2369 PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2370 Py_TPFLAGS_HAVE_GC);
2371 PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2372 PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2373 PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2374 PyGObject_Type.tp_methods = pygobject_methods;
2375 PyGObject_Type.tp_getset = pygobject_getsets;
2376 PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2377 PyGObject_Type.tp_init = (initproc)pygobject_init;
2378 PyGObject_Type.tp_free = (freefunc)pygobject_free;
2379 PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2380 PyGObject_Type.tp_new = PyType_GenericNew;
2381 pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2382 &PyGObject_Type, NULL);
2383 PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2384 pyg_object_descr_doc_get());
2387 PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2388 PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2389 PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2390 PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2391 PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2392 PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2393 "Python attributes.";
2394 PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2395 PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2396 PyGProps_Type.tp_methods = pygobject_props_methods;
2397 if (PyType_Ready(&PyGProps_Type) < 0)
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);