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 PyObject * pygbinding_weak_ref_new(GObject *obj);
42 static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
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;
54 /* Copied from glib. gobject uses hyphens in property names, but in Python
55 * we can only represent hyphens as underscores. Convert underscores to
56 * hyphens for glib compatibility. */
58 canonicalize_key (gchar *key)
62 for (p = key; *p != 0; p++)
67 (c < '0' || c > '9') &&
68 (c < 'A' || c > 'Z') &&
74 /* -------------- class <-> wrapper manipulation --------------- */
77 pygobject_data_free(PyGObjectData *data)
79 /* This function may be called after the python interpreter has already
80 * been shut down. If this happens, we cannot do any python calls, so just
82 PyGILState_STATE state;
83 PyThreadState *_save = NULL;
85 GSList *closures, *tmp;
87 if (Py_IsInitialized()) {
88 state = pyglib_gil_state_ensure();
89 Py_DECREF(data->type);
90 /* We cannot use pyg_begin_allow_threads here because this is inside
92 if (pyg_threads_enabled)
93 _save = PyEval_SaveThread();
96 tmp = closures = data->closures;
98 data->closures = NULL;
102 GClosure *closure = tmp->data;
104 /* we get next item first, because the current link gets
105 * invalidated by pygobject_unwatch_closure */
107 g_closure_invalidate(closure);
110 if (data->closures != NULL)
111 g_warning("invalidated all closures, but data->closures != NULL !");
115 if (Py_IsInitialized()) {
116 if (pyg_threads_enabled)
117 PyEval_RestoreThread(_save);
118 pyglib_gil_state_release(state);
122 static inline PyGObjectData *
123 pygobject_data_new(void)
126 data = g_new0(PyGObjectData, 1);
130 static inline PyGObjectData *
131 pygobject_get_inst_data(PyGObject *self)
133 PyGObjectData *inst_data;
135 if (G_UNLIKELY(!self->obj))
137 inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
138 if (inst_data == NULL)
140 inst_data = pygobject_data_new();
142 inst_data->type = Py_TYPE(self);
143 Py_INCREF((PyObject *) inst_data->type);
145 g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
146 inst_data, (GDestroyNotify) pygobject_data_free);
152 GHashTable *custom_type_registration = NULL;
154 PyTypeObject *PyGObject_MetaType = NULL;
160 * As Python handles reference counting for us, the "floating
161 * reference" code in GTK is not all that useful. In fact, it can
162 * cause leaks. This function should be called to remove the floating
163 * references on objects on construction.
166 pygobject_sink(GObject *obj)
168 /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink().
169 * - if the object is new and owned by someone else, its ref has been sunk and
170 * we need to keep the one from that someone and add our own "fresh ref"
171 * - if the object is not and owned by nobody, its ref is floating and we need
172 * to transform it into a regular ref.
174 if (G_IS_INITIALLY_UNOWNED(obj)) {
175 g_object_ref_sink(obj);
186 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
189 pyg_props_iter_dealloc(PyGPropsIter *self)
192 PyObject_Del((PyObject*) self);
196 pygobject_props_iter_next(PyGPropsIter *iter)
198 if (iter->index < iter->n_props)
199 return pyg_param_spec_new(iter->props[iter->index++]);
201 PyErr_SetNone(PyExc_StopIteration);
208 /* a reference to the object containing the properties */
209 PyGObject *pygobject;
214 PyGProps_dealloc(PyGProps* self)
218 PyObject_GC_UnTrack((PyObject*)self);
220 tmp = self->pygobject;
221 self->pygobject = NULL;
224 PyObject_GC_Del((PyObject*)self);
228 build_parameter_list(GObjectClass *class)
231 guint n_props = 0, i;
233 PyObject *props_list;
235 props = g_object_class_list_properties(class, &n_props);
236 props_list = PyList_New(n_props);
237 for (i = 0; i < n_props; i++) {
239 name = g_strdup(g_param_spec_get_name(props[i]));
240 /* hyphens cannot belong in identifiers */
241 g_strdelimit(name, "-", '_');
242 prop_str = PYGLIB_PyUnicode_FromString(name);
244 PyList_SetItem(props_list, i, prop_str);
248 g_type_class_unref(class);
257 PyGProps_getattro(PyGProps *self, PyObject *attr)
259 char *attr_name, *property_name;
262 GValue value = { 0, };
265 attr_name = PYGLIB_PyUnicode_AsString(attr);
268 return PyObject_GenericGetAttr((PyObject *)self, attr);
271 class = g_type_class_ref(self->gtype);
273 if (!strcmp(attr_name, "__members__")) {
274 ret = build_parameter_list(class);
275 g_type_class_unref(class);
279 /* g_object_class_find_property recurses through the class hierarchy,
280 * so the resulting pspec tells us the owner_type that owns the property
281 * we're dealing with. */
282 property_name = g_strdup(attr_name);
283 canonicalize_key(property_name);
284 pspec = g_object_class_find_property(class, property_name);
285 g_free(property_name);
286 g_type_class_unref(class);
289 return PyObject_GenericGetAttr((PyObject *)self, attr);
292 if (!(pspec->flags & G_PARAM_READABLE)) {
293 PyErr_Format(PyExc_TypeError,
294 "property '%s' is not readable", attr_name);
298 if (!self->pygobject) {
299 /* If we're doing it without an instance, return a GParamSpec */
300 return pyg_param_spec_new(pspec);
303 /* See if the property's class is from the gi repository. If so,
304 * use gi to correctly read the property value. */
305 ret = pygi_get_property_value (self->pygobject, pspec);
310 /* If we reach here, it must be a property defined outside of gi.
311 * Just do a straightforward read. */
312 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
313 pyg_begin_allow_threads;
314 g_object_get_property(self->pygobject->obj, pspec->name, &value);
315 pyg_end_allow_threads;
316 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
317 g_value_unset(&value);
323 set_property_from_pspec(GObject *obj,
327 GValue value = { 0, };
329 if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
330 PyErr_Format(PyExc_TypeError,
331 "property '%s' can only be set in constructor",
336 if (!(pspec->flags & G_PARAM_WRITABLE)) {
337 PyErr_Format(PyExc_TypeError,
338 "property '%s' is not writable", pspec->name);
342 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
343 if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
344 PyErr_SetString(PyExc_TypeError,
345 "could not convert argument to correct param type");
349 pyg_begin_allow_threads;
350 g_object_set_property(obj, pspec->name, &value);
351 pyg_end_allow_threads;
353 g_value_unset(&value);
358 PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps);
361 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
364 char *attr_name, *property_name;
368 if (pvalue == NULL) {
369 PyErr_SetString(PyExc_TypeError, "properties cannot be "
374 attr_name = PYGLIB_PyUnicode_AsString(attr);
377 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
380 if (!self->pygobject) {
381 PyErr_SetString(PyExc_TypeError,
382 "cannot set GOject properties without an instance");
386 obj = self->pygobject->obj;
388 property_name = g_strdup(attr_name);
389 canonicalize_key(property_name);
391 /* g_object_class_find_property recurses through the class hierarchy,
392 * so the resulting pspec tells us the owner_type that owns the property
393 * we're dealing with. */
394 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj),
396 g_free(property_name);
398 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
401 /* See if the property's class is from the gi repository. If so,
402 * use gi to correctly read the property value. */
403 ret = pygi_set_property_value (self->pygobject, pspec, pvalue);
407 if (PyErr_Occurred())
410 /* If we reach here, it must be a property defined outside of gi.
411 * Just do a straightforward set. */
412 if (!set_property_from_pspec(obj, pspec, pvalue))
419 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
421 if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
427 pygobject_props_get_iter(PyGProps *self)
432 iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
433 class = g_type_class_ref(self->gtype);
434 iter->props = g_object_class_list_properties(class, &iter->n_props);
436 g_type_class_unref(class);
437 return (PyObject *) iter;
441 PyGProps_length(PyGProps *self)
447 class = g_type_class_ref(self->gtype);
448 props = g_object_class_list_properties(class, &n_props);
449 g_type_class_unref(class);
452 return (Py_ssize_t)n_props;
455 static PySequenceMethods _PyGProps_as_sequence = {
456 (lenfunc) PyGProps_length,
465 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject);
468 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
472 gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
473 if (obj == NULL || obj == Py_None) {
474 gprops->pygobject = NULL;
475 gprops->gtype = pyg_type_from_object(type);
477 if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
478 PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
479 " descriptor on non-GObject instances");
483 gprops->pygobject = (PyGObject *) obj;
484 gprops->gtype = pyg_type_from_object(obj);
486 return (PyObject *) gprops;
490 * pygobject_register_class:
491 * @dict: the module dictionary. A reference to the type will be stored here.
492 * @type_name: not used ?
493 * @gtype: the GType of the GObject subclass.
494 * @type: the Python type object for this wrapper.
495 * @static_bases: a tuple of Python type objects that are the bases of
498 * This function is used to register a Python type as the wrapper for
499 * a particular GObject subclass. It will also insert a reference to
500 * the wrapper class into the module dictionary passed as a reference,
501 * which simplifies initialisation.
504 pygobject_register_class(PyObject *dict, const gchar *type_name,
505 GType gtype, PyTypeObject *type,
506 PyObject *static_bases)
509 const char *class_name, *s;
510 PyObject *runtime_bases;
511 PyObject *bases_list, *bases, *mod_name;
514 class_name = type->tp_name;
515 s = strrchr(class_name, '.');
519 runtime_bases = pyg_type_get_bases(gtype);
521 PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
522 bases_list = PySequence_List(static_bases);
523 /* we start at index 1 because we want to skip the primary
524 * base, otherwise we might get MRO conflict */
525 for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
527 PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
528 int contains = PySequence_Contains(bases_list, base);
531 else if (!contains) {
532 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
534 g_message("Adding missing base %s to type %s",
535 ((PyTypeObject *)base)->tp_name, type->tp_name);
537 PyList_Append(bases_list, base);
541 bases = PySequence_Tuple(bases_list);
542 Py_DECREF(bases_list);
543 Py_DECREF(runtime_bases);
545 bases = runtime_bases;
547 Py_TYPE(type) = PyGObject_MetaType;
548 type->tp_bases = bases;
549 if (G_LIKELY(bases)) {
550 type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
551 Py_INCREF(type->tp_base);
554 pygobject_inherit_slots(type, bases, TRUE);
556 if (PyType_Ready(type) < 0) {
557 g_warning ("couldn't make the type `%s' ready", type->tp_name);
561 /* Set type.__module__ to the name of the module,
562 * otherwise it'll default to 'gobject', see #376099
564 s = strrchr(type->tp_name, '.');
566 mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
567 PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
572 o = pyg_type_wrapper_new(gtype);
573 PyDict_SetItemString(type->tp_dict, "__gtype__", o);
576 /* stash a pointer to the python class with the GType */
578 g_type_set_qdata(gtype, pygobject_class_key, type);
581 /* set up __doc__ descriptor on type */
582 PyDict_SetItemString(type->tp_dict, "__doc__",
583 pyg_object_descr_doc_get());
585 PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
589 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
591 PyGObject *self = (PyGObject*) data;
592 PyGILState_STATE state;
594 state = pyglib_gil_state_ensure();
601 pyglib_gil_state_release(state);
604 /* Called when the inst_dict is first created; switches the
605 reference counting strategy to start using toggle ref to keep the
606 wrapper alive while the GObject lives. In contrast, while
607 inst_dict was NULL the python wrapper is allowed to die at
608 will and is recreated on demand. */
610 pygobject_switch_to_toggle_ref(PyGObject *self)
612 g_assert(self->obj->ref_count >= 1);
614 if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF)
615 return; /* already using toggle ref */
616 self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
617 /* Note that add_toggle_ref will never immediately call back into
619 Py_INCREF((PyObject *) self);
620 g_object_add_toggle_ref(self->obj, pyg_toggle_notify, self);
621 g_object_unref(self->obj);
624 /* Called when an custom gobject is initalized via g_object_new instead of
625 its constructor. The next time the wrapper is access via
626 pygobject_new_full it will sink the floating reference instead of
627 adding a new reference and causing a leak */
630 pygobject_ref_float(PyGObject *self)
632 /* should only be floated once */
633 g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
635 self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
638 /* Called by gobject_new_full, if the floating flag is set remove it, otherwise
641 pygobject_ref_sink(PyGObject *self)
643 if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
644 self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
646 Py_INCREF ( (PyObject *) self);
650 * pygobject_register_wrapper:
651 * @self: the wrapper instance
653 * In the constructor of PyGTK wrappers, this function should be
654 * called after setting the obj member. It will tie the wrapper
655 * instance to the GObject so that the same wrapper instance will
656 * always be used for this GObject instance.
659 pygobject_register_wrapper(PyObject *self)
663 g_return_if_fail(self != NULL);
664 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
666 gself = (PyGObject *)self;
668 g_assert(gself->obj->ref_count >= 1);
669 /* save wrapper pointer so we can access it later */
670 g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
671 if (gself->inst_dict)
672 pygobject_switch_to_toggle_ref(gself);
676 pyg_type_get_bases(GType gtype)
678 GType *interfaces, parent_type, interface_type;
680 PyTypeObject *py_parent_type, *py_interface_type;
684 if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
687 /* Lookup the parent type */
688 parent_type = g_type_parent(gtype);
689 py_parent_type = pygobject_lookup_class(parent_type);
690 interfaces = g_type_interfaces(gtype, &n_interfaces);
691 bases = PyTuple_New(n_interfaces + 1);
692 /* We will always put the parent at the first position in bases */
693 Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
694 PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
696 /* And traverse interfaces */
698 for (i = 0; i < n_interfaces; i++) {
699 interface_type = interfaces[i];
700 py_interface_type = pygobject_lookup_class(interface_type);
701 Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
702 PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
710 * pygobject_new_with_interfaces
711 * @gtype: the GType of the GObject subclass.
713 * Creates a new PyTypeObject from the given GType with interfaces attached in
716 * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
718 static PyTypeObject *
719 pygobject_new_with_interfaces(GType gtype)
721 PyGILState_STATE state;
725 PyTypeObject *py_parent_type;
727 PyObject *modules, *module;
728 gchar *type_name, *mod_name, *gtype_name;
730 state = pyglib_gil_state_ensure();
732 bases = pyg_type_get_bases(gtype);
733 py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
737 o = pyg_type_wrapper_new(gtype);
738 PyDict_SetItemString(dict, "__gtype__", o);
741 /* set up __doc__ descriptor on type */
742 PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
744 /* generate the pygtk module name and extract the base type name */
745 gtype_name = (gchar*)g_type_name(gtype);
746 if (g_str_has_prefix(gtype_name, "Gtk")) {
749 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
750 } else if (g_str_has_prefix(gtype_name, "Gdk")) {
751 mod_name = "gtk.gdk";
753 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
754 } else if (g_str_has_prefix(gtype_name, "Atk")) {
757 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
758 } else if (g_str_has_prefix(gtype_name, "Pango")) {
761 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
763 mod_name = "__main__";
764 type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
767 type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
768 "sNN", type_name, bases, dict);
773 pyglib_gil_state_release(state);
777 /* Workaround python tp_(get|set)attr slot inheritance bug.
778 * Fixes bug #144135. */
779 if (!type->tp_getattr && py_parent_type->tp_getattr) {
780 type->tp_getattro = NULL;
781 type->tp_getattr = py_parent_type->tp_getattr;
783 if (!type->tp_setattr && py_parent_type->tp_setattr) {
784 type->tp_setattro = NULL;
785 type->tp_setattr = py_parent_type->tp_setattr;
787 /* override more python stupid hacks behind our back */
788 type->tp_dealloc = py_parent_type->tp_dealloc;
789 type->tp_alloc = py_parent_type->tp_alloc;
790 type->tp_free = py_parent_type->tp_free;
791 type->tp_traverse = py_parent_type->tp_traverse;
792 type->tp_clear = py_parent_type->tp_clear;
794 pygobject_inherit_slots(type, bases, FALSE);
796 if (PyType_Ready(type) < 0) {
797 g_warning ("couldn't make the type `%s' ready", type->tp_name);
798 pyglib_gil_state_release(state);
801 /* insert type name in module dict */
802 modules = PyImport_GetModuleDict();
803 if ((module = PyDict_GetItemString(modules, mod_name)) != NULL) {
804 if (PyObject_SetAttrString(module, gtype_name, (PyObject *)type) < 0)
808 /* stash a pointer to the python class with the GType */
810 g_type_set_qdata(gtype, pygobject_class_key, type);
812 pyglib_gil_state_release(state);
817 /* Pick appropriate value for given slot (at slot_offset inside
818 * PyTypeObject structure). It must be a pointer, e.g. a pointer to a
819 * function. We use the following heuristic:
821 * - Scan all types listed as bases of the type.
822 * - If for exactly one base type slot value is non-NULL and
823 * different from that of 'object' and 'GObject', set current type
824 * slot into that value.
825 * - Otherwise (if there is more than one such base type or none at
826 * all) don't touch it and live with Python default.
828 * The intention here is to propagate slot from custom wrappers to
829 * wrappers created at runtime when appropriate. We prefer to be on
830 * the safe side, so if there is potential collision (more than one
831 * custom slot value), we discard custom overrides altogether.
833 * When registering type with pygobject_register_class(), i.e. a type
834 * that has been manually created (likely with Codegen help),
835 * `check_for_present' should be set to TRUE. In this case, the
836 * function will never overwrite any non-NULL slots already present in
837 * the type. If `check_for_present' is FALSE, such non-NULL slots are
838 * though to be set by Python interpreter and so will be overwritten
839 * if heuristic above says so.
842 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
844 static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
845 #if PY_VERSION_HEX < 0x03000000
846 offsetof(PyTypeObject, tp_compare),
848 offsetof(PyTypeObject, tp_richcompare),
849 offsetof(PyTypeObject, tp_hash),
850 offsetof(PyTypeObject, tp_iter),
851 offsetof(PyTypeObject, tp_repr),
852 offsetof(PyTypeObject, tp_str),
853 offsetof(PyTypeObject, tp_print) };
856 /* Happens when registering gobject.GObject itself, at least. */
860 for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
861 pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
865 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
866 gboolean check_for_present)
868 #define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset))
870 void *found_slot = NULL;
871 int num_bases = PyTuple_Size(bases);
874 if (check_for_present && TYPE_SLOT(type) != NULL) {
875 /* We are requested to check if there is any custom slot value
876 * in this type already and there actually is. Don't
882 for (i = 0; i < num_bases; ++i) {
883 PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
884 void *slot = TYPE_SLOT(base_type);
888 if (slot == TYPE_SLOT(&PyGObject_Type) ||
889 slot == TYPE_SLOT(&PyBaseObject_Type))
892 if (found_slot != NULL && found_slot != slot) {
893 /* We have a conflict: more than one base use different
894 * custom slots. To be on the safe side, we bail out.
902 /* Only perform the final assignment if at least one base has a
903 * custom value. Otherwise just leave this type's slot untouched.
905 if (found_slot != NULL)
906 TYPE_SLOT(type) = found_slot;
912 * pygobject_lookup_class:
913 * @gtype: the GType of the GObject subclass.
915 * This function looks up the wrapper class used to represent
916 * instances of a GObject represented by @gtype. If no wrapper class
917 * or interface has been registered for the given GType, then a new
918 * type will be created.
920 * Returns: The wrapper class for the GObject or NULL if the
921 * GType has no registered type and a new type couldn't be created
924 pygobject_lookup_class(GType gtype)
926 PyTypeObject *py_type;
928 if (gtype == G_TYPE_INTERFACE)
929 return &PyGInterface_Type;
931 py_type = pyg_type_get_custom(g_type_name(gtype));
935 py_type = g_type_get_qdata(gtype, pygobject_class_key);
936 if (py_type == NULL) {
937 py_type = g_type_get_qdata(gtype, pyginterface_type_key);
940 py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
942 if (py_type == NULL) {
943 py_type = pygobject_new_with_interfaces(gtype);
944 g_type_set_qdata(gtype, pyginterface_type_key, py_type);
952 * pygobject_new_full:
953 * @obj: a GObject instance.
954 * @sink: whether to sink any floating reference found on the GObject. DEPRECATED.
955 * @g_class: the GObjectClass
957 * This function gets a reference to a wrapper for the given GObject
958 * instance. If a wrapper has already been created, a new reference
959 * to that wrapper will be returned. Otherwise, a wrapper instance
962 * Returns: a reference to the wrapper for the GObject.
965 pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
974 /* we already have a wrapper for this object -- return it. */
975 self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
977 pygobject_ref_sink(self);
980 PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
983 tp = inst_data->type;
986 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
988 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
990 g_assert(tp != NULL);
992 /* need to bump type refcount if created with
993 pygobject_new_with_interfaces(). fixes bug #141042 */
994 if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
996 self = PyObject_GC_New(PyGObject, tp);
999 self->inst_dict = NULL;
1000 self->weakreflist = NULL;
1001 self->private_flags.flags = 0;
1003 /* if we are creating a wrapper around a newly created object, it can have
1004 a floating ref (e.g. for methods like Gtk.Button.new()). Bug 640868 */
1005 g_object_ref_sink(obj);
1006 pygobject_register_wrapper((PyObject *)self);
1007 PyObject_GC_Track((PyObject *)self);
1010 return (PyObject *)self;
1015 pygobject_new(GObject *obj)
1017 return pygobject_new_full(obj, TRUE, NULL);
1021 pygobject_unwatch_closure(gpointer data, GClosure *closure)
1023 PyGObjectData *inst_data = data;
1025 inst_data->closures = g_slist_remove (inst_data->closures, closure);
1029 * pygobject_watch_closure:
1030 * @self: a GObject wrapper instance
1031 * @closure: a GClosure to watch
1033 * Adds a closure to the list of watched closures for the wrapper.
1034 * The closure must be one returned by pyg_closure_new(). When the
1035 * cycle GC traverses the wrapper instance, it will enumerate the
1036 * references to Python objects stored in watched closures. If the
1037 * cycle GC tells the wrapper to clear itself, the watched closures
1038 * will be invalidated.
1041 pygobject_watch_closure(PyObject *self, GClosure *closure)
1044 PyGObjectData *data;
1046 g_return_if_fail(self != NULL);
1047 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
1048 g_return_if_fail(closure != NULL);
1050 gself = (PyGObject *)self;
1051 data = pygobject_get_inst_data(gself);
1052 g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
1053 data->closures = g_slist_prepend(data->closures, closure);
1054 g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
1058 /* -------------- PyGObject behaviour ----------------- */
1060 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
1063 pygobject_dealloc(PyGObject *self)
1065 /* Untrack must be done first. This is because followup calls such as
1066 * ClearWeakRefs could call into Python and cause new allocations to
1067 * happen, which could in turn could trigger the garbage collector,
1068 * which would then get confused as it is tracking this half-deallocated
1070 PyObject_GC_UnTrack((PyObject *)self);
1072 PyObject_ClearWeakRefs((PyObject *)self);
1073 /* this forces inst_data->type to be updated, which could prove
1074 * important if a new wrapper has to be created and it is of a
1075 * unregistered type */
1076 pygobject_get_inst_data(self);
1077 pygobject_clear(self);
1078 /* the following causes problems with subclassed types */
1079 /* Py_TYPE(self)->tp_free((PyObject *)self); */
1080 PyObject_GC_Del(self);
1084 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1088 isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1092 Py_INCREF(Py_NotImplemented);
1093 return Py_NotImplemented;
1095 isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1099 Py_INCREF(Py_NotImplemented);
1100 return Py_NotImplemented;
1103 return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1104 ((PyGObject*)other)->obj,
1109 pygobject_hash(PyGObject *self)
1111 return (long)self->obj;
1115 pygobject_repr(PyGObject *self)
1119 g_snprintf(buf, sizeof(buf),
1120 "<%s object at 0x%lx (%s at 0x%lx)>",
1121 Py_TYPE(self)->tp_name,
1123 self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
1125 return PYGLIB_PyUnicode_FromString(buf);
1130 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1134 PyGObjectData *data = pygobject_get_inst_data(self);
1136 if (self->inst_dict) ret = visit(self->inst_dict, arg);
1137 if (ret != 0) return ret;
1141 for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1142 PyGClosure *closure = tmp->data;
1144 if (closure->callback) ret = visit(closure->callback, arg);
1145 if (ret != 0) return ret;
1147 if (closure->extra_args) ret = visit(closure->extra_args, arg);
1148 if (ret != 0) return ret;
1150 if (closure->swap_data) ret = visit(closure->swap_data, arg);
1151 if (ret != 0) return ret;
1158 pygobject_clear(PyGObject *self)
1161 g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1162 if (self->inst_dict) {
1163 g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
1164 self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1166 pyg_begin_allow_threads;
1167 g_object_unref(self->obj);
1168 pyg_end_allow_threads;
1172 Py_CLEAR(self->inst_dict);
1177 pygobject_free(PyObject *op)
1179 PyObject_GC_Del(op);
1183 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1184 guint *n_params, GParameter **params)
1194 *params = g_new0(GParameter, PyDict_Size(kwargs));
1195 while (PyDict_Next(kwargs, &pos, &key, &value)) {
1197 GParameter *param = &(*params)[*n_params];
1198 const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1200 pspec = g_object_class_find_property(class, key_str);
1202 PyErr_Format(PyExc_TypeError,
1203 "gobject `%s' doesn't support property `%s'",
1204 G_OBJECT_CLASS_NAME(class), key_str);
1207 g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1208 if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) {
1209 PyErr_Format(PyExc_TypeError,
1210 "could not convert value for property `%s' from %s to %s",
1211 key_str, Py_TYPE(value)->tp_name,
1212 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1215 param->name = g_strdup(key_str);
1222 /* ---------------- PyGObject methods ----------------- */
1225 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1228 guint n_params = 0, i;
1229 GParameter *params = NULL;
1230 GObjectClass *class;
1232 if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
1235 object_type = pyg_type_from_object((PyObject *)self);
1239 if (G_TYPE_IS_ABSTRACT(object_type)) {
1240 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1241 "(non-instantiable) type `%s'", g_type_name(object_type));
1245 if ((class = g_type_class_ref (object_type)) == NULL) {
1246 PyErr_SetString(PyExc_TypeError,
1247 "could not get a reference to type class");
1251 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms))
1254 if (pygobject_constructv(self, n_params, params))
1255 PyErr_SetString(PyExc_RuntimeError, "could not create object");
1258 for (i = 0; i < n_params; i++) {
1259 g_free((gchar *) params[i].name);
1260 g_value_unset(¶ms[i].value);
1263 g_type_class_unref(class);
1265 return (self->obj) ? 0 : -1;
1268 #define CHECK_GOBJECT(self) \
1269 if (!G_IS_OBJECT(self->obj)) { \
1270 PyErr_Format(PyExc_TypeError, \
1271 "object at %p of type %s is not initialized", \
1272 self, Py_TYPE(self)->tp_name); \
1277 pygobject_get_property(PyGObject *self, PyObject *args)
1281 GValue value = { 0, };
1284 if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name))
1287 CHECK_GOBJECT(self);
1289 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1292 PyErr_Format(PyExc_TypeError,
1293 "object of type `%s' does not have property `%s'",
1294 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1297 if (!(pspec->flags & G_PARAM_READABLE)) {
1298 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1302 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1303 pyg_begin_allow_threads;
1304 g_object_get_property(self->obj, param_name, &value);
1305 pyg_end_allow_threads;
1306 ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
1307 g_value_unset(&value);
1312 pygobject_get_properties(PyGObject *self, PyObject *args)
1314 GObjectClass *class;
1318 if ((len = PyTuple_Size(args)) < 1) {
1319 PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1323 tuple = PyTuple_New(len);
1324 class = G_OBJECT_GET_CLASS(self->obj);
1325 for (i = 0; i < len; i++) {
1326 PyObject *py_property = PyTuple_GetItem(args, i);
1327 gchar *property_name;
1329 GValue value = { 0 };
1332 if (!PYGLIB_PyUnicode_Check(py_property)) {
1333 PyErr_SetString(PyExc_TypeError,
1334 "Expected string argument for property.");
1338 property_name = PYGLIB_PyUnicode_AsString(py_property);
1340 pspec = g_object_class_find_property(class,
1343 PyErr_Format(PyExc_TypeError,
1344 "object of type `%s' does not have property `%s'",
1345 g_type_name(G_OBJECT_TYPE(self->obj)), property_name);
1348 if (!(pspec->flags & G_PARAM_READABLE)) {
1349 PyErr_Format(PyExc_TypeError, "property %s is not readable",
1353 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1355 pyg_begin_allow_threads;
1356 g_object_get_property(self->obj, property_name, &value);
1357 pyg_end_allow_threads;
1359 item = pyg_value_as_pyobject(&value, TRUE);
1360 PyTuple_SetItem(tuple, i, item);
1362 g_value_unset(&value);
1369 pygobject_set_property(PyGObject *self, PyObject *args)
1375 if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name,
1379 CHECK_GOBJECT(self);
1381 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1384 PyErr_Format(PyExc_TypeError,
1385 "object of type `%s' does not have property `%s'",
1386 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1390 if (!set_property_from_pspec(self->obj, pspec, pvalue))
1398 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1400 GObjectClass *class;
1404 PyObject *result = NULL;
1406 CHECK_GOBJECT(self);
1408 class = G_OBJECT_GET_CLASS(self->obj);
1410 g_object_freeze_notify (G_OBJECT(self->obj));
1413 while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1414 gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1417 pspec = g_object_class_find_property(class, key_str);
1421 g_snprintf(buf, sizeof(buf),
1422 "object `%s' doesn't support property `%s'",
1423 g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1424 PyErr_SetString(PyExc_TypeError, buf);
1428 if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value))
1435 g_object_thaw_notify (G_OBJECT(self->obj));
1440 /* custom closure for gobject bindings */
1442 pygbinding_closure_invalidate(gpointer data, GClosure *closure)
1444 PyGClosure *pc = (PyGClosure *)closure;
1445 PyGILState_STATE state;
1447 state = pyglib_gil_state_ensure();
1448 Py_XDECREF(pc->callback);
1449 Py_XDECREF(pc->extra_args);
1450 pyglib_gil_state_release(state);
1452 pc->callback = NULL;
1453 pc->extra_args = NULL;
1457 pygbinding_marshal (GClosure *closure,
1458 GValue *return_value,
1459 guint n_param_values,
1460 const GValue *param_values,
1461 gpointer invocation_hint,
1462 gpointer marshal_data)
1464 PyGILState_STATE state;
1465 PyGClosure *pc = (PyGClosure *)closure;
1466 PyObject *params, *ret;
1469 state = pyglib_gil_state_ensure();
1471 /* construct Python tuple for the parameter values */
1472 params = PyTuple_New(2);
1473 PyTuple_SetItem (params, 0, pyg_value_as_pyobject(¶m_values[0], FALSE));
1474 PyTuple_SetItem (params, 1, pyg_value_as_pyobject(¶m_values[1], FALSE));
1476 /* params passed to function may have extra arguments */
1477 if (pc->extra_args) {
1478 PyObject *tuple = params;
1479 params = PySequence_Concat(tuple, pc->extra_args);
1482 ret = PyObject_CallObject(pc->callback, params);
1486 } else if (ret == Py_None) {
1487 g_value_set_boolean (return_value, FALSE);
1491 out_value = g_value_get_boxed (¶m_values[2]);
1492 if (pyg_value_from_pyobject (out_value, ret) != 0) {
1493 PyErr_SetString (PyExc_ValueError, "can't convert value");
1495 g_value_set_boolean (return_value, FALSE);
1497 g_value_set_boolean (return_value, TRUE);
1504 pyglib_gil_state_release(state);
1508 pygbinding_closure_new (PyObject *callback, PyObject *extra_args)
1512 g_return_val_if_fail(callback != NULL, NULL);
1513 closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
1514 g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate);
1515 g_closure_set_marshal(closure, pygbinding_marshal);
1516 Py_INCREF(callback);
1517 ((PyGClosure *)closure)->callback = callback;
1518 if (extra_args && extra_args != Py_None) {
1519 Py_INCREF(extra_args);
1520 if (!PyTuple_Check(extra_args)) {
1521 PyObject *tmp = PyTuple_New(1);
1522 PyTuple_SetItem(tmp, 0, extra_args);
1525 ((PyGClosure *)closure)->extra_args = extra_args;
1531 pygobject_bind_property(PyGObject *self, PyObject *args)
1533 gchar *source_name, *target_name;
1534 gchar *source_canon, *target_canon;
1535 PyObject *target, *source_repr, *target_repr;
1536 PyObject *transform_to, *transform_from, *user_data = NULL;
1538 GBindingFlags flags = G_BINDING_DEFAULT;
1539 GClosure *to_closure = NULL, *from_closure = NULL;
1541 transform_from = NULL;
1542 transform_to = NULL;
1544 if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property",
1545 &source_name, &target, &target_name, &flags,
1546 &transform_to, &transform_from, &user_data))
1549 CHECK_GOBJECT(self);
1550 if (!PyObject_TypeCheck(target, &PyGObject_Type)) {
1551 PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject");
1555 if (transform_to && transform_to != Py_None) {
1556 if (!PyCallable_Check (transform_to)) {
1557 PyErr_SetString (PyExc_TypeError,
1558 "transform_to must be callable or None");
1561 to_closure = pygbinding_closure_new (transform_to, user_data);
1564 if (transform_from && transform_from != Py_None) {
1565 if (!PyCallable_Check (transform_from)) {
1566 PyErr_SetString (PyExc_TypeError,
1567 "transform_from must be callable or None");
1570 from_closure = pygbinding_closure_new (transform_from, user_data);
1573 /* Canonicalize underscores to hyphens. Note the results must be freed. */
1574 source_canon = g_strdelimit(g_strdup(source_name), "_", '-');
1575 target_canon = g_strdelimit(g_strdup(target_name), "_", '-');
1577 binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon,
1578 pygobject_get(target), target_canon,
1579 flags, to_closure, from_closure);
1580 g_free(source_canon);
1581 g_free(target_canon);
1582 source_canon = target_canon = NULL;
1584 if (binding == NULL) {
1585 source_repr = PyObject_Repr((PyObject*)self);
1586 target_repr = PyObject_Repr(target);
1587 PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s",
1588 PYGLIB_PyUnicode_AsString(source_repr), source_name,
1589 PYGLIB_PyUnicode_AsString(target_repr), target_name);
1590 Py_DECREF(source_repr);
1591 Py_DECREF(target_repr);
1595 return pygbinding_weak_ref_new(G_OBJECT (binding));
1599 pygobject_connect(PyGObject *self, PyObject *args)
1601 PyObject *first, *callback, *extra_args, *repr = NULL;
1608 len = PyTuple_Size(args);
1610 PyErr_SetString(PyExc_TypeError,
1611 "GObject.connect requires at least 2 arguments");
1614 first = PySequence_GetSlice(args, 0, 2);
1615 if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1620 if (!PyCallable_Check(callback)) {
1621 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1625 CHECK_GOBJECT(self);
1627 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1628 &sigid, &detail, TRUE)) {
1629 repr = PyObject_Repr((PyObject*)self);
1630 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1631 PYGLIB_PyUnicode_AsString(repr),
1636 extra_args = PySequence_GetSlice(args, 2, len);
1637 if (extra_args == NULL)
1640 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1641 if (closure == NULL)
1642 closure = pyg_closure_new(callback, extra_args, NULL);
1644 pygobject_watch_closure((PyObject *)self, closure);
1645 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1647 Py_DECREF(extra_args);
1648 return PyLong_FromUnsignedLong(handlerid);
1652 pygobject_connect_after(PyGObject *self, PyObject *args)
1654 PyObject *first, *callback, *extra_args, *repr = NULL;
1662 len = PyTuple_Size(args);
1664 PyErr_SetString(PyExc_TypeError,
1665 "GObject.connect_after requires at least 2 arguments");
1668 first = PySequence_GetSlice(args, 0, 2);
1669 if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1670 &name, &callback)) {
1675 if (!PyCallable_Check(callback)) {
1676 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1680 CHECK_GOBJECT(self);
1682 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1683 &sigid, &detail, TRUE)) {
1684 repr = PyObject_Repr((PyObject*)self);
1685 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1686 PYGLIB_PyUnicode_AsString(repr),
1691 extra_args = PySequence_GetSlice(args, 2, len);
1692 if (extra_args == NULL)
1695 closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1696 if (closure == NULL)
1697 closure = pyg_closure_new(callback, extra_args, NULL);
1699 pygobject_watch_closure((PyObject *)self, closure);
1700 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1702 Py_DECREF(extra_args);
1703 return PyLong_FromUnsignedLong(handlerid);
1707 pygobject_connect_object(PyGObject *self, PyObject *args)
1709 PyObject *first, *callback, *extra_args, *object, *repr = NULL;
1717 len = PyTuple_Size(args);
1719 PyErr_SetString(PyExc_TypeError,
1720 "GObject.connect_object requires at least 3 arguments");
1723 first = PySequence_GetSlice(args, 0, 3);
1724 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1725 &name, &callback, &object)) {
1730 if (!PyCallable_Check(callback)) {
1731 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1735 CHECK_GOBJECT(self);
1737 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1738 &sigid, &detail, TRUE)) {
1739 repr = PyObject_Repr((PyObject*)self);
1740 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1741 PYGLIB_PyUnicode_AsString(repr),
1746 extra_args = PySequence_GetSlice(args, 3, len);
1747 if (extra_args == NULL)
1750 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1751 if (closure == NULL)
1752 closure = pyg_closure_new(callback, extra_args, object);
1754 pygobject_watch_closure((PyObject *)self, closure);
1755 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1757 Py_DECREF(extra_args);
1758 return PyLong_FromUnsignedLong(handlerid);
1762 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1764 PyObject *first, *callback, *extra_args, *object, *repr = NULL;
1772 len = PyTuple_Size(args);
1774 PyErr_SetString(PyExc_TypeError,
1775 "GObject.connect_object_after requires at least 3 arguments");
1778 first = PySequence_GetSlice(args, 0, 3);
1779 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1780 &name, &callback, &object)) {
1785 if (!PyCallable_Check(callback)) {
1786 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1790 CHECK_GOBJECT(self);
1792 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1793 &sigid, &detail, TRUE)) {
1794 repr = PyObject_Repr((PyObject*)self);
1795 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1796 PYGLIB_PyUnicode_AsString(repr),
1801 extra_args = PySequence_GetSlice(args, 3, len);
1802 if (extra_args == NULL)
1805 closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1806 if (closure == NULL)
1807 closure = pyg_closure_new(callback, extra_args, object);
1809 pygobject_watch_closure((PyObject *)self, closure);
1810 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1812 Py_DECREF(extra_args);
1813 return PyLong_FromUnsignedLong(handlerid);
1817 pygobject_disconnect(PyGObject *self, PyObject *args)
1821 if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
1824 CHECK_GOBJECT(self);
1826 g_signal_handler_disconnect(self->obj, handler_id);
1832 pygobject_handler_is_connected(PyGObject *self, PyObject *args)
1836 if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
1840 CHECK_GOBJECT(self);
1842 return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
1846 pygobject_handler_block(PyGObject *self, PyObject *args)
1850 if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
1853 CHECK_GOBJECT(self);
1855 g_signal_handler_block(self->obj, handler_id);
1861 pygobject_handler_unblock(PyGObject *self, PyObject *args)
1865 if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
1867 g_signal_handler_unblock(self->obj, handler_id);
1873 pygobject_emit(PyGObject *self, PyObject *args)
1875 guint signal_id, i, j;
1878 PyObject *first, *py_ret, *repr = NULL;
1881 GValue *params, ret = { 0, };
1883 len = PyTuple_Size(args);
1885 PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1888 first = PySequence_GetSlice(args, 0, 1);
1889 if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1895 CHECK_GOBJECT(self);
1897 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1898 &signal_id, &detail, TRUE)) {
1899 repr = PyObject_Repr((PyObject*)self);
1900 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1901 PYGLIB_PyUnicode_AsString(repr),
1906 g_signal_query(signal_id, &query);
1907 if (len != query.n_params + 1) {
1910 g_snprintf(buf, sizeof(buf),
1911 "%d parameters needed for signal %s; %ld given",
1912 query.n_params, name, (long int) (len - 1));
1913 PyErr_SetString(PyExc_TypeError, buf);
1917 params = g_new0(GValue, query.n_params + 1);
1918 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
1919 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
1921 for (i = 0; i < query.n_params; i++)
1922 g_value_init(¶ms[i + 1],
1923 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1924 for (i = 0; i < query.n_params; i++) {
1925 PyObject *item = PyTuple_GetItem(args, i+1);
1927 if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
1929 g_snprintf(buf, sizeof(buf),
1930 "could not convert type %s to %s required for parameter %d",
1931 Py_TYPE(item)->tp_name,
1932 G_VALUE_TYPE_NAME(¶ms[i+1]), i);
1933 PyErr_SetString(PyExc_TypeError, buf);
1935 for (j = 0; j <= i; j++)
1936 g_value_unset(¶ms[j]);
1943 if (query.return_type != G_TYPE_NONE)
1944 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1946 g_signal_emitv(params, signal_id, detail, &ret);
1948 for (i = 0; i < query.n_params + 1; i++)
1949 g_value_unset(¶ms[i]);
1952 if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1953 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1954 g_value_unset(&ret);
1964 pygobject_stop_emission(PyGObject *self, PyObject *args)
1969 PyObject *repr = NULL;
1971 if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
1974 CHECK_GOBJECT(self);
1976 if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
1977 &signal_id, &detail, TRUE)) {
1978 repr = PyObject_Repr((PyObject*)self);
1979 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1980 PYGLIB_PyUnicode_AsString(repr),
1985 g_signal_stop_emission(self->obj, signal_id, detail);
1991 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1993 GSignalInvocationHint *ihint;
1999 GValue *params, ret = { 0, };
2001 CHECK_GOBJECT(self);
2003 ihint = g_signal_get_invocation_hint(self->obj);
2005 PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
2006 "information for this object.");
2010 signal_id = ihint->signal_id;
2011 name = g_signal_name(signal_id);
2013 len = PyTuple_Size(args);
2014 if (signal_id == 0) {
2015 PyErr_SetString(PyExc_TypeError, "unknown signal name");
2018 g_signal_query(signal_id, &query);
2019 if (len != query.n_params) {
2022 g_snprintf(buf, sizeof(buf),
2023 "%d parameters needed for signal %s; %ld given",
2024 query.n_params, name, (long int) len);
2025 PyErr_SetString(PyExc_TypeError, buf);
2028 params = g_new0(GValue, query.n_params + 1);
2029 g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj));
2030 g_value_set_object(¶ms[0], G_OBJECT(self->obj));
2032 for (i = 0; i < query.n_params; i++)
2033 g_value_init(¶ms[i + 1],
2034 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2035 for (i = 0; i < query.n_params; i++) {
2036 PyObject *item = PyTuple_GetItem(args, i);
2038 if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
2039 g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void));
2041 else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) {
2044 g_snprintf(buf, sizeof(buf),
2045 "could not convert type %s to %s required for parameter %d",
2046 Py_TYPE(item)->tp_name,
2047 g_type_name(G_VALUE_TYPE(¶ms[i+1])), i);
2048 PyErr_SetString(PyExc_TypeError, buf);
2049 for (i = 0; i < query.n_params + 1; i++)
2050 g_value_unset(¶ms[i]);
2055 if (query.return_type != G_TYPE_NONE)
2056 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2057 g_signal_chain_from_overridden(params, &ret);
2058 for (i = 0; i < query.n_params + 1; i++)
2059 g_value_unset(¶ms[i]);
2061 if (query.return_type != G_TYPE_NONE) {
2062 py_ret = pyg_value_as_pyobject(&ret, TRUE);
2063 g_value_unset(&ret);
2073 pygobject_weak_ref(PyGObject *self, PyObject *args)
2076 PyObject *callback = NULL, *user_data = NULL;
2079 CHECK_GOBJECT(self);
2081 if ((len = PySequence_Length(args)) >= 1) {
2082 callback = PySequence_ITEM(args, 0);
2083 user_data = PySequence_GetSlice(args, 1, len);
2085 retval = pygobject_weak_ref_new(self->obj, callback, user_data);
2086 Py_XDECREF(callback);
2087 Py_XDECREF(user_data);
2093 pygobject_copy(PyGObject *self)
2095 PyErr_SetString(PyExc_TypeError,
2096 "GObject descendants' instances are non-copyable");
2101 pygobject_deepcopy(PyGObject *self, PyObject *args)
2103 PyErr_SetString(PyExc_TypeError,
2104 "GObject descendants' instances are non-copyable");
2110 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
2112 PyObject *pyfunc = NULL, *repr = NULL;
2113 GClosure *closure = NULL;
2116 CHECK_GOBJECT(self);
2118 if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2121 if (!PyCallable_Check(pyfunc)) {
2122 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2126 closure = gclosure_from_pyfunc(self, pyfunc);
2128 repr = PyObject_Repr((PyObject*)pyfunc);
2129 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2130 PYGLIB_PyUnicode_AsString(repr));
2135 retval = g_signal_handlers_disconnect_matched(self->obj,
2136 G_SIGNAL_MATCH_CLOSURE,
2140 return PYGLIB_PyLong_FromLong(retval);
2144 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2146 PyObject *pyfunc = NULL, *repr = NULL;
2147 GClosure *closure = NULL;
2150 CHECK_GOBJECT(self);
2152 if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2155 if (!PyCallable_Check(pyfunc)) {
2156 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2160 closure = gclosure_from_pyfunc(self, pyfunc);
2162 repr = PyObject_Repr((PyObject*)pyfunc);
2163 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2164 PYGLIB_PyUnicode_AsString(repr));
2169 retval = g_signal_handlers_block_matched(self->obj,
2170 G_SIGNAL_MATCH_CLOSURE,
2174 return PYGLIB_PyLong_FromLong(retval);
2178 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2180 PyObject *pyfunc = NULL, *repr = NULL;
2181 GClosure *closure = NULL;
2184 CHECK_GOBJECT(self);
2186 if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2189 if (!PyCallable_Check(pyfunc)) {
2190 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2194 closure = gclosure_from_pyfunc(self, pyfunc);
2196 repr = PyObject_Repr((PyObject*)pyfunc);
2197 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2198 PYGLIB_PyUnicode_AsString(repr));
2203 retval = g_signal_handlers_unblock_matched(self->obj,
2204 G_SIGNAL_MATCH_CLOSURE,
2208 return PYGLIB_PyLong_FromLong(retval);
2212 static PyMethodDef pygobject_methods[] = {
2213 { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2214 { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2215 { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2216 { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2217 { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS },
2218 { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2219 { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2220 { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2221 { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2222 { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2223 { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2224 { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2225 { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
2226 { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
2227 { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
2228 { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2229 { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2230 { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2231 { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
2232 { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
2233 { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2234 { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2235 { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2236 { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2242 pygobject_get_dict(PyGObject *self, void *closure)
2244 if (self->inst_dict == NULL) {
2245 self->inst_dict = PyDict_New();
2246 if (self->inst_dict == NULL)
2248 if (G_LIKELY(self->obj))
2249 pygobject_switch_to_toggle_ref(self);
2251 Py_INCREF(self->inst_dict);
2252 return self->inst_dict;
2256 pygobject_get_refcount(PyGObject *self, void *closure)
2258 if (self->obj == NULL) {
2259 PyErr_Format(PyExc_TypeError, "GObject instance is not yet created");
2262 return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2266 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2269 PyGObject *gself = (PyGObject *) self;
2270 PyObject *inst_dict_before = gself->inst_dict;
2271 /* call parent type's setattro */
2272 res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2273 if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2274 if (G_LIKELY(gself->obj))
2275 pygobject_switch_to_toggle_ref(gself);
2280 static PyGetSetDef pygobject_getsets[] = {
2281 { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2282 { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2286 /* ------------------------------------ */
2287 /* ****** GObject weak reference ****** */
2288 /* ------------------------------------ */
2294 PyObject *user_data;
2295 gboolean have_floating_ref;
2298 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2301 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2303 if (self->callback && visit(self->callback, arg) < 0)
2305 if (self->user_data && visit(self->user_data, arg) < 0)
2311 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2314 if (self->callback) {
2316 PyGILState_STATE state = pyglib_gil_state_ensure();
2317 retval = PyObject_Call(self->callback, self->user_data, NULL);
2319 if (retval != Py_None)
2320 PyErr_Format(PyExc_TypeError,
2321 "GObject weak notify callback returned a value"
2322 " of type %s, should return None",
2323 Py_TYPE(retval)->tp_name);
2328 Py_CLEAR(self->callback);
2329 Py_CLEAR(self->user_data);
2330 if (self->have_floating_ref) {
2331 self->have_floating_ref = FALSE;
2332 Py_DECREF((PyObject *) self);
2334 pyglib_gil_state_release(state);
2339 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2341 Py_CLEAR(self->callback);
2342 Py_CLEAR(self->user_data);
2344 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2351 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2353 PyObject_GC_UnTrack((PyObject *)self);
2354 pygobject_weak_ref_clear(self);
2355 PyObject_GC_Del(self);
2359 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2361 PyGObjectWeakRef *self;
2363 self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2364 self->callback = callback;
2365 self->user_data = user_data;
2366 Py_XINCREF(self->callback);
2367 Py_XINCREF(self->user_data);
2369 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2370 if (callback != NULL) {
2371 /* when we have a callback, we should INCREF the weakref
2372 * object to make it stay alive even if it goes out of scope */
2373 self->have_floating_ref = TRUE;
2374 Py_INCREF((PyObject *) self);
2376 return (PyObject *) self;
2380 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2383 PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2386 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2388 if (self->have_floating_ref) {
2389 self->have_floating_ref = FALSE;
2396 static PyMethodDef pygobject_weak_ref_methods[] = {
2397 { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2402 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2404 static char *argnames[] = {NULL};
2406 if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2410 return pygobject_new_full(self->obj, FALSE, NULL);
2418 /* -------------- GBinding Weak Reference ----------------- */
2423 * The BindingWeakRef object is used to manage GBinding objects within python
2424 * created through GObject.bind_property. It is a sub-class PyGObjectWeakRef so
2425 * that we can maintain the same reference counting semantics between Python
2426 * and GObject Binding objects. This gives explicit direct control of the
2427 * binding lifetime by using the "unbind" method on the BindingWeakRef object
2428 * along with implicit management based on the lifetime of the source or
2432 PYGLIB_DEFINE_TYPE("gi._gobject.GBindingWeakRef", PyGBindingWeakRef_Type, PyGObjectWeakRef);
2435 pygbinding_weak_ref_new(GObject *obj)
2437 PyGObjectWeakRef *self;
2439 self = PyObject_GC_New(PyGObjectWeakRef, &PyGBindingWeakRef_Type);
2440 self->callback = NULL;
2441 self->user_data = NULL;
2443 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2444 return (PyObject *) self;
2448 pygbinding_weak_ref_unbind(PyGObjectWeakRef *self, PyObject *args)
2451 PyErr_SetString(PyExc_ValueError, "weak binding ref already unreffed");
2454 g_object_unref(self->obj);
2459 static PyMethodDef pygbinding_weak_ref_methods[] = {
2460 { "unbind", (PyCFunction)pygbinding_weak_ref_unbind, METH_NOARGS},
2466 pyobject_copy(gpointer boxed)
2468 PyObject *object = boxed;
2475 pyobject_free(gpointer boxed)
2477 PyObject *object = boxed;
2478 PyGILState_STATE state;
2480 state = pyglib_gil_state_ensure();
2482 pyglib_gil_state_release(state);
2486 pygobject_object_register_types(PyObject *d)
2488 PyObject *o, *descr;
2490 pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2491 pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2492 pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2493 pygobject_has_updated_constructor_key =
2494 g_quark_from_static_string("PyGObject::has-updated-constructor");
2495 pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2498 if (!PY_TYPE_OBJECT)
2499 PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2502 PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2503 PyGObject_Type.tp_richcompare = pygobject_richcompare;
2504 PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2505 PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2506 PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2507 PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2508 Py_TPFLAGS_HAVE_GC);
2509 PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2510 PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2511 PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2512 PyGObject_Type.tp_methods = pygobject_methods;
2513 PyGObject_Type.tp_getset = pygobject_getsets;
2514 PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2515 PyGObject_Type.tp_init = (initproc)pygobject_init;
2516 PyGObject_Type.tp_free = (freefunc)pygobject_free;
2517 PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2518 PyGObject_Type.tp_new = PyType_GenericNew;
2519 pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2520 &PyGObject_Type, NULL);
2521 PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2522 pyg_object_descr_doc_get());
2525 PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2526 PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2527 PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2528 PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2529 PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2530 PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2531 "Python attributes.";
2532 PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2533 PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2534 if (PyType_Ready(&PyGProps_Type) < 0)
2538 PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2539 PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2540 if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2542 descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2543 PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2544 PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2545 o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject"));
2549 PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2550 PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2551 PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2552 PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2553 if (PyType_Ready(&PyGPropsIter_Type) < 0)
2556 PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2557 PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2558 PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2559 PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2560 PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2561 PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2562 PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2563 if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2565 PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
2567 PyGBindingWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2568 PyGBindingWeakRef_Type.tp_doc = "A GBinding weak reference";
2569 PyGBindingWeakRef_Type.tp_methods = pygbinding_weak_ref_methods;
2570 PyGBindingWeakRef_Type.tp_base = &PyGObjectWeakRef_Type;
2571 if (PyType_Ready(&PyGBindingWeakRef_Type) < 0)
2573 PyDict_SetItemString(d, "GBindingWeakRef", (PyObject *) &PyGBindingWeakRef_Type);