functions: revert the function init order to make pylint happy again. See #217
[pygobject.git] / gi / pygobject-object.c
blobdbf46e1eb6267368d1d78b180295dfb554749643
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/>.
21 #include <config.h>
23 #include "pygobject-object.h"
24 #include "pyginterface.h"
25 #include "pygparamspec.h"
26 #include "pygi-type.h"
27 #include "pygboxed.h"
28 #include "gimodule.h"
30 #include "pygi-util.h"
31 #include "pygi-value.h"
32 #include "pygi-type.h"
33 #include "pygi-property.h"
34 #include "pygi-signal-closure.h"
35 #include "pygi-basictype.h"
37 extern PyObject *PyGIDeprecationWarning;
39 static void pygobject_dealloc(PyGObject *self);
40 static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
41 static PyObject * pyg_type_get_bases(GType gtype);
42 static inline int pygobject_clear(PyGObject *self);
43 static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
44 static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases,
45 gboolean check_for_present);
46 static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
47 gboolean check_for_present);
48 GType PY_TYPE_OBJECT = 0;
49 GQuark pygobject_custom_key;
50 GQuark pygobject_class_key;
51 GQuark pygobject_class_init_key;
52 GQuark pygobject_wrapper_key;
53 GQuark pygobject_has_updated_constructor_key;
54 GQuark pygobject_instance_data_key;
56 /* PyPy doesn't support tp_dictoffset, so we have to work around it */
57 #ifndef PYPY_VERSION
58 #define PYGI_OBJECT_USE_CUSTOM_DICT
59 #endif
61 GClosure *
62 gclosure_from_pyfunc(PyGObject *object, PyObject *func)
64 GSList *l;
65 PyGObjectData *inst_data;
66 inst_data = pyg_object_peek_inst_data(object->obj);
67 if (inst_data) {
68 for (l = inst_data->closures; l; l = l->next) {
69 PyGClosure *pyclosure = l->data;
70 int res = PyObject_RichCompareBool(pyclosure->callback, func, Py_EQ);
71 if (res == -1) {
72 PyErr_Clear(); /* Is there anything else to do? */
73 } else if (res) {
74 return (GClosure*)pyclosure;
78 return NULL;
81 /* Copied from glib. gobject uses hyphens in property names, but in Python
82 * we can only represent hyphens as underscores. Convert underscores to
83 * hyphens for glib compatibility. */
84 static void
85 canonicalize_key (gchar *key)
87 gchar *p;
89 for (p = key; *p != 0; p++)
91 gchar c = *p;
93 if (c != '-' &&
94 (c < '0' || c > '9') &&
95 (c < 'A' || c > 'Z') &&
96 (c < 'a' || c > 'z'))
97 *p = '-';
101 /* -------------- class <-> wrapper manipulation --------------- */
103 static void
104 pygobject_data_free(PyGObjectData *data)
106 /* This function may be called after the python interpreter has already
107 * been shut down. If this happens, we cannot do any python calls, so just
108 * free the memory. */
109 PyGILState_STATE state = 0;
110 PyThreadState *_save = NULL;
111 gboolean state_saved;
112 GSList *closures, *tmp;
114 state_saved = Py_IsInitialized();
115 if (state_saved) {
116 state = PyGILState_Ensure();
117 Py_DECREF(data->type);
118 /* We cannot use Py_BEGIN_ALLOW_THREADS here because this is inside
119 * a branch. */
120 Py_UNBLOCK_THREADS; /* Modifies _save */
123 tmp = closures = data->closures;
124 #ifndef NDEBUG
125 data->closures = NULL;
126 data->type = NULL;
127 #endif
128 while (tmp) {
129 GClosure *closure = tmp->data;
131 /* we get next item first, because the current link gets
132 * invalidated by pygobject_unwatch_closure */
133 tmp = tmp->next;
134 g_closure_invalidate(closure);
137 if (data->closures != NULL)
138 g_warning("invalidated all closures, but data->closures != NULL !");
140 g_free(data);
142 if (state_saved && Py_IsInitialized ()) {
143 Py_BLOCK_THREADS; /* Restores _save */
144 PyGILState_Release(state);
148 static inline PyGObjectData *
149 pygobject_data_new(void)
151 PyGObjectData *data;
152 data = g_new0(PyGObjectData, 1);
153 return data;
156 static inline PyGObjectData *
157 pygobject_get_inst_data(PyGObject *self)
159 PyGObjectData *inst_data;
161 if (G_UNLIKELY(!self->obj))
162 return NULL;
163 inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
164 if (inst_data == NULL)
166 inst_data = pygobject_data_new();
168 inst_data->type = Py_TYPE(self);
169 Py_INCREF((PyObject *) inst_data->type);
171 g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
172 inst_data, (GDestroyNotify) pygobject_data_free);
174 return inst_data;
178 PyTypeObject *PyGObject_MetaType = NULL;
181 * pygobject_sink:
182 * @obj: a GObject
184 * As Python handles reference counting for us, the "floating
185 * reference" code in GTK is not all that useful. In fact, it can
186 * cause leaks. This function should be called to remove the floating
187 * references on objects on construction.
189 void
190 pygobject_sink(GObject *obj)
192 /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink().
193 * - if the object is new and owned by someone else, its ref has been sunk and
194 * we need to keep the one from that someone and add our own "fresh ref"
195 * - if the object is not and owned by nobody, its ref is floating and we need
196 * to transform it into a regular ref.
198 if (G_IS_INITIALLY_UNOWNED(obj)) {
199 g_object_ref_sink(obj);
203 typedef struct {
204 PyObject_HEAD
205 GParamSpec **props;
206 guint n_props;
207 guint index;
208 } PyGPropsIter;
210 PYGLIB_DEFINE_TYPE("gi._gi.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
212 static void
213 pyg_props_iter_dealloc(PyGPropsIter *self)
215 g_free(self->props);
216 PyObject_Del((PyObject*) self);
219 static PyObject*
220 pygobject_props_iter_next(PyGPropsIter *iter)
222 if (iter->index < iter->n_props)
223 return pyg_param_spec_new(iter->props[iter->index++]);
224 else {
225 PyErr_SetNone(PyExc_StopIteration);
226 return NULL;
230 typedef struct {
231 PyObject_HEAD
232 /* a reference to the object containing the properties */
233 PyGObject *pygobject;
234 GType gtype;
235 } PyGProps;
237 static void
238 PyGProps_dealloc(PyGProps* self)
240 PyGObject *tmp;
242 PyObject_GC_UnTrack((PyObject*)self);
244 tmp = self->pygobject;
245 self->pygobject = NULL;
246 Py_XDECREF(tmp);
248 PyObject_GC_Del((PyObject*)self);
251 static PyObject*
252 build_parameter_list(GObjectClass *class)
254 GParamSpec **props;
255 guint n_props = 0, i;
256 PyObject *prop_str;
257 PyObject *props_list;
259 props = g_object_class_list_properties(class, &n_props);
260 props_list = PyList_New(n_props);
261 for (i = 0; i < n_props; i++) {
262 char *name;
263 name = g_strdup(g_param_spec_get_name(props[i]));
264 /* hyphens cannot belong in identifiers */
265 g_strdelimit(name, "-", '_');
266 prop_str = PYGLIB_PyUnicode_FromString(name);
268 PyList_SetItem(props_list, i, prop_str);
269 g_free(name);
272 if (props)
273 g_free(props);
275 return props_list;
278 static PyObject*
279 PyGProps_getattro(PyGProps *self, PyObject *attr)
281 char *attr_name, *property_name;
282 GObjectClass *class;
283 GParamSpec *pspec;
285 attr_name = PYGLIB_PyUnicode_AsString(attr);
286 if (!attr_name) {
287 PyErr_Clear();
288 return PyObject_GenericGetAttr((PyObject *)self, attr);
291 class = g_type_class_ref(self->gtype);
293 /* g_object_class_find_property recurses through the class hierarchy,
294 * so the resulting pspec tells us the owner_type that owns the property
295 * we're dealing with. */
296 property_name = g_strdup(attr_name);
297 canonicalize_key(property_name);
298 pspec = g_object_class_find_property(class, property_name);
299 g_free(property_name);
300 g_type_class_unref(class);
302 if (!pspec) {
303 return PyObject_GenericGetAttr((PyObject *)self, attr);
306 if (!self->pygobject) {
307 /* If we're doing it without an instance, return a GParamSpec */
308 return pyg_param_spec_new(pspec);
311 return pygi_get_property_value (self->pygobject, pspec);
314 static gboolean
315 set_property_from_pspec(GObject *obj,
316 GParamSpec *pspec,
317 PyObject *pvalue)
319 GValue value = { 0, };
321 if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
322 PyErr_Format(PyExc_TypeError,
323 "property '%s' can only be set in constructor",
324 pspec->name);
325 return FALSE;
328 if (!(pspec->flags & G_PARAM_WRITABLE)) {
329 PyErr_Format(PyExc_TypeError,
330 "property '%s' is not writable", pspec->name);
331 return FALSE;
334 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
335 if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
336 PyObject *pvalue_str = PyObject_Repr(pvalue);
337 PyErr_Format(PyExc_TypeError,
338 "could not convert %s to type '%s' when setting property '%s.%s'",
339 PYGLIB_PyUnicode_AsString(pvalue_str),
340 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)),
341 G_OBJECT_TYPE_NAME(obj),
342 pspec->name);
343 Py_DECREF(pvalue_str);
344 return FALSE;
347 Py_BEGIN_ALLOW_THREADS;
348 g_object_set_property(obj, pspec->name, &value);
349 g_value_unset(&value);
350 Py_END_ALLOW_THREADS;
352 return TRUE;
355 PYGLIB_DEFINE_TYPE("gi._gi.GProps", PyGProps_Type, PyGProps);
357 static int
358 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
360 GParamSpec *pspec;
361 char *attr_name, *property_name;
362 GObject *obj;
363 int ret = -1;
365 if (pvalue == NULL) {
366 PyErr_SetString(PyExc_TypeError, "properties cannot be "
367 "deleted");
368 return -1;
371 attr_name = PYGLIB_PyUnicode_AsString(attr);
372 if (!attr_name) {
373 PyErr_Clear();
374 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
377 if (!self->pygobject) {
378 PyErr_SetString(PyExc_TypeError,
379 "cannot set GOject properties without an instance");
380 return -1;
383 obj = self->pygobject->obj;
385 property_name = g_strdup(attr_name);
386 canonicalize_key(property_name);
388 /* g_object_class_find_property recurses through the class hierarchy,
389 * so the resulting pspec tells us the owner_type that owns the property
390 * we're dealing with. */
391 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj),
392 property_name);
393 g_free(property_name);
394 if (!pspec) {
395 return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
397 if (!pyg_gtype_is_custom (pspec->owner_type)) {
398 /* This GType is not implemented in Python: see if we can set the
399 * property via gi. */
400 ret = pygi_set_property_value (self->pygobject, pspec, pvalue);
401 if (ret == 0)
402 return 0;
403 else if (ret == -1 && PyErr_Occurred())
404 return -1;
407 /* This GType is implemented in Python, or we failed to set it via gi:
408 * do a straightforward set. */
409 if (!set_property_from_pspec(obj, pspec, pvalue))
410 return -1;
412 return 0;
415 static int
416 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
418 if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
419 return -1;
420 return 0;
423 static PyObject*
424 pygobject_props_get_iter(PyGProps *self)
426 PyGPropsIter *iter;
427 GObjectClass *class;
429 iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
430 class = g_type_class_ref(self->gtype);
431 iter->props = g_object_class_list_properties(class, &iter->n_props);
432 iter->index = 0;
433 g_type_class_unref(class);
434 return (PyObject *) iter;
437 static PyObject*
438 pygobject_props_dir(PyGProps *self)
440 PyObject *ret;
441 GObjectClass *class;
443 class = g_type_class_ref (self->gtype);
444 ret = build_parameter_list (class);
445 g_type_class_unref (class);
447 return ret;
450 static PyMethodDef pygobject_props_methods[] = {
451 { "__dir__", (PyCFunction)pygobject_props_dir, METH_NOARGS},
452 { NULL, NULL, 0}
456 static Py_ssize_t
457 PyGProps_length(PyGProps *self)
459 GObjectClass *class;
460 GParamSpec **props;
461 guint n_props;
463 class = g_type_class_ref(self->gtype);
464 props = g_object_class_list_properties(class, &n_props);
465 g_type_class_unref(class);
466 g_free(props);
468 return (Py_ssize_t)n_props;
471 static PySequenceMethods _PyGProps_as_sequence = {
472 (lenfunc) PyGProps_length,
481 PYGLIB_DEFINE_TYPE("gi._gi.GPropsDescr", PyGPropsDescr_Type, PyObject);
483 static PyObject *
484 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
486 PyGProps *gprops;
488 gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
489 if (obj == NULL || obj == Py_None) {
490 gprops->pygobject = NULL;
491 gprops->gtype = pyg_type_from_object(type);
492 } else {
493 if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
494 PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
495 " descriptor on non-GObject instances");
496 return NULL;
498 Py_INCREF(obj);
499 gprops->pygobject = (PyGObject *) obj;
500 gprops->gtype = pyg_type_from_object(obj);
502 return (PyObject *) gprops;
506 * pygobject_register_class:
507 * @dict: the module dictionary. A reference to the type will be stored here.
508 * @type_name: not used ?
509 * @gtype: the GType of the GObject subclass.
510 * @type: the Python type object for this wrapper.
511 * @static_bases: a tuple of Python type objects that are the bases of
512 * this type
514 * This function is used to register a Python type as the wrapper for
515 * a particular GObject subclass. It will also insert a reference to
516 * the wrapper class into the module dictionary passed as a reference,
517 * which simplifies initialisation.
519 void
520 pygobject_register_class(PyObject *dict, const gchar *type_name,
521 GType gtype, PyTypeObject *type,
522 PyObject *static_bases)
524 PyObject *o;
525 const char *class_name, *s;
526 PyObject *runtime_bases;
527 PyObject *bases_list, *bases, *mod_name;
528 int i;
530 class_name = type->tp_name;
531 s = strrchr(class_name, '.');
532 if (s != NULL)
533 class_name = s + 1;
535 runtime_bases = pyg_type_get_bases(gtype);
536 if (static_bases) {
537 PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
538 bases_list = PySequence_List(static_bases);
539 /* we start at index 1 because we want to skip the primary
540 * base, otherwise we might get MRO conflict */
541 for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
543 PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
544 int contains = PySequence_Contains(bases_list, base);
545 if (contains < 0)
546 PyErr_Print();
547 else if (!contains) {
548 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
549 #if 0
550 g_message("Adding missing base %s to type %s",
551 ((PyTypeObject *)base)->tp_name, type->tp_name);
552 #endif
553 PyList_Append(bases_list, base);
557 bases = PySequence_Tuple(bases_list);
558 Py_DECREF(bases_list);
559 Py_DECREF(runtime_bases);
560 } else
561 bases = runtime_bases;
563 Py_TYPE(type) = PyGObject_MetaType;
564 type->tp_bases = bases;
565 if (G_LIKELY(bases)) {
566 type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
567 Py_INCREF(type->tp_base);
570 pygobject_inherit_slots(type, bases, TRUE);
572 if (PyType_Ready(type) < 0) {
573 g_warning ("couldn't make the type `%s' ready", type->tp_name);
574 return;
577 /* Set type.__module__ to the name of the module,
578 * otherwise it'll default to 'gobject', see #376099
580 s = strrchr(type->tp_name, '.');
581 if (s != NULL) {
582 mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
583 PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
584 Py_DECREF(mod_name);
587 if (gtype) {
588 o = pyg_type_wrapper_new(gtype);
589 PyDict_SetItemString(type->tp_dict, "__gtype__", o);
590 Py_DECREF(o);
592 /* stash a pointer to the python class with the GType */
593 Py_INCREF(type);
594 g_type_set_qdata(gtype, pygobject_class_key, type);
597 /* set up __doc__ descriptor on type */
598 PyDict_SetItemString(type->tp_dict, "__doc__",
599 pyg_object_descr_doc_get());
601 PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
604 static void
605 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
607 PyGObject *self;
608 PyGILState_STATE state;
610 state = PyGILState_Ensure();
612 /* Avoid thread safety problems by using qdata for wrapper retrieval
613 * instead of the user data argument.
614 * See: https://bugzilla.gnome.org/show_bug.cgi?id=709223
616 self = (PyGObject *)g_object_get_qdata (object, pygobject_wrapper_key);
617 if (self) {
618 if (is_last_ref)
619 Py_DECREF(self);
620 else
621 Py_INCREF(self);
624 PyGILState_Release(state);
627 static inline gboolean
628 pygobject_toggle_ref_is_required (PyGObject *self)
630 #ifdef PYGI_OBJECT_USE_CUSTOM_DICT
631 return self->inst_dict != NULL;
632 #else
633 PyObject *dict;
634 gboolean result;
635 dict = PyObject_GetAttrString ((PyObject *)self, "__dict__");
636 if (!dict) {
637 PyErr_Clear ();
638 return FALSE;
640 result = PyDict_Size (dict) != 0;
641 Py_DECREF (dict);
642 return result;
643 #endif
646 static inline gboolean
647 pygobject_toggle_ref_is_active (PyGObject *self)
649 return self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF;
652 /* Called when the inst_dict is first created; switches the
653 reference counting strategy to start using toggle ref to keep the
654 wrapper alive while the GObject lives. In contrast, while
655 inst_dict was NULL the python wrapper is allowed to die at
656 will and is recreated on demand. */
657 static inline void
658 pygobject_toggle_ref_ensure (PyGObject *self)
660 if (pygobject_toggle_ref_is_active (self))
661 return;
663 if (!pygobject_toggle_ref_is_required (self))
664 return;
666 if (self->obj == NULL)
667 return;
669 g_assert(self->obj->ref_count >= 1);
670 self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
671 /* Note that add_toggle_ref will never immediately call back into
672 pyg_toggle_notify */
673 Py_INCREF((PyObject *) self);
674 g_object_add_toggle_ref(self->obj, pyg_toggle_notify, NULL);
675 g_object_unref(self->obj);
678 /* Called when an custom gobject is initalized via g_object_new instead of
679 its constructor. The next time the wrapper is access via
680 pygobject_new_full it will sink the floating reference instead of
681 adding a new reference and causing a leak */
683 void
684 pygobject_ref_float(PyGObject *self)
686 /* should only be floated once */
687 g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
689 self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
692 /* Called by gobject_new_full, if the floating flag is set remove it, otherwise
693 ref the pyobject */
694 void
695 pygobject_ref_sink(PyGObject *self)
697 if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
698 self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
699 else
700 Py_INCREF ( (PyObject *) self);
704 * pygobject_register_wrapper:
705 * @self: the wrapper instance
707 * In the constructor of PyGTK wrappers, this function should be
708 * called after setting the obj member. It will tie the wrapper
709 * instance to the GObject so that the same wrapper instance will
710 * always be used for this GObject instance.
712 void
713 pygobject_register_wrapper(PyObject *self)
715 PyGObject *gself;
717 g_return_if_fail(self != NULL);
718 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
720 gself = (PyGObject *)self;
722 g_assert(gself->obj->ref_count >= 1);
723 /* save wrapper pointer so we can access it later */
724 g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
726 pygobject_toggle_ref_ensure (gself);
729 static PyObject *
730 pyg_type_get_bases(GType gtype)
732 GType *interfaces, parent_type, interface_type;
733 guint n_interfaces;
734 PyTypeObject *py_parent_type, *py_interface_type;
735 PyObject *bases;
736 guint i;
738 if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
739 return NULL;
741 /* Lookup the parent type */
742 parent_type = g_type_parent(gtype);
743 py_parent_type = pygobject_lookup_class(parent_type);
744 interfaces = g_type_interfaces(gtype, &n_interfaces);
745 bases = PyTuple_New(n_interfaces + 1);
746 /* We will always put the parent at the first position in bases */
747 Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
748 PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
750 /* And traverse interfaces */
751 if (n_interfaces) {
752 for (i = 0; i < n_interfaces; i++) {
753 interface_type = interfaces[i];
754 py_interface_type = pygobject_lookup_class(interface_type);
755 Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
756 PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
759 g_free(interfaces);
760 return bases;
764 * pygobject_new_with_interfaces
765 * @gtype: the GType of the GObject subclass.
767 * Creates a new PyTypeObject from the given GType with interfaces attached in
768 * bases.
770 * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
772 static PyTypeObject *
773 pygobject_new_with_interfaces(GType gtype)
775 PyGILState_STATE state;
776 PyObject *o;
777 PyTypeObject *type;
778 PyObject *dict;
779 PyTypeObject *py_parent_type;
780 PyObject *bases;
782 state = PyGILState_Ensure();
784 bases = pyg_type_get_bases(gtype);
785 py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
787 dict = PyDict_New();
789 o = pyg_type_wrapper_new(gtype);
790 PyDict_SetItemString(dict, "__gtype__", o);
791 Py_DECREF(o);
793 /* set up __doc__ descriptor on type */
794 PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
796 /* Something special to point out that it's not accessible through
797 * gi.repository */
798 o = PYGLIB_PyUnicode_FromString ("__gi__");
799 PyDict_SetItemString (dict, "__module__", o);
800 Py_DECREF (o);
802 type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
803 "sNN", g_type_name (gtype), bases, dict);
805 if (type == NULL) {
806 PyErr_Print();
807 PyGILState_Release(state);
808 return NULL;
811 /* Workaround python tp_(get|set)attr slot inheritance bug.
812 * Fixes bug #144135. */
813 if (!type->tp_getattr && py_parent_type->tp_getattr) {
814 type->tp_getattro = NULL;
815 type->tp_getattr = py_parent_type->tp_getattr;
817 if (!type->tp_setattr && py_parent_type->tp_setattr) {
818 type->tp_setattro = NULL;
819 type->tp_setattr = py_parent_type->tp_setattr;
821 /* override more python stupid hacks behind our back */
822 type->tp_dealloc = py_parent_type->tp_dealloc;
823 type->tp_alloc = py_parent_type->tp_alloc;
824 type->tp_free = py_parent_type->tp_free;
825 type->tp_traverse = py_parent_type->tp_traverse;
826 type->tp_clear = py_parent_type->tp_clear;
828 pygobject_inherit_slots(type, bases, FALSE);
830 if (PyType_Ready(type) < 0) {
831 g_warning ("couldn't make the type `%s' ready", type->tp_name);
832 PyGILState_Release(state);
833 return NULL;
836 /* stash a pointer to the python class with the GType */
837 Py_INCREF(type);
838 g_type_set_qdata(gtype, pygobject_class_key, type);
840 PyGILState_Release(state);
842 return type;
845 /* Pick appropriate value for given slot (at slot_offset inside
846 * PyTypeObject structure). It must be a pointer, e.g. a pointer to a
847 * function. We use the following heuristic:
849 * - Scan all types listed as bases of the type.
850 * - If for exactly one base type slot value is non-NULL and
851 * different from that of 'object' and 'GObject', set current type
852 * slot into that value.
853 * - Otherwise (if there is more than one such base type or none at
854 * all) don't touch it and live with Python default.
856 * The intention here is to propagate slot from custom wrappers to
857 * wrappers created at runtime when appropriate. We prefer to be on
858 * the safe side, so if there is potential collision (more than one
859 * custom slot value), we discard custom overrides altogether.
861 * When registering type with pygobject_register_class(), i.e. a type
862 * that has been manually created (likely with Codegen help),
863 * `check_for_present' should be set to TRUE. In this case, the
864 * function will never overwrite any non-NULL slots already present in
865 * the type. If `check_for_present' is FALSE, such non-NULL slots are
866 * though to be set by Python interpreter and so will be overwritten
867 * if heuristic above says so.
869 static void
870 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
872 static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
873 #if PY_VERSION_HEX < 0x03000000
874 offsetof(PyTypeObject, tp_compare),
875 #endif
876 offsetof(PyTypeObject, tp_richcompare),
877 offsetof(PyTypeObject, tp_hash),
878 offsetof(PyTypeObject, tp_iter),
879 offsetof(PyTypeObject, tp_repr),
880 offsetof(PyTypeObject, tp_str),
881 offsetof(PyTypeObject, tp_print) };
882 gsize i;
884 /* Happens when registering gobject.GObject itself, at least. */
885 if (!bases)
886 return;
888 for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
889 pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
892 static void
893 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
894 gboolean check_for_present)
896 #define TYPE_SLOT(type) (* (void **) (void *) (((char *) (type)) + slot_offset))
898 void *found_slot = NULL;
899 Py_ssize_t num_bases = PyTuple_Size(bases);
900 Py_ssize_t i;
902 if (check_for_present && TYPE_SLOT(type) != NULL) {
903 /* We are requested to check if there is any custom slot value
904 * in this type already and there actually is. Don't
905 * overwrite it.
907 return;
910 for (i = 0; i < num_bases; ++i) {
911 PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
912 void *slot = TYPE_SLOT(base_type);
914 if (slot == NULL)
915 continue;
916 if (slot == TYPE_SLOT(&PyGObject_Type) ||
917 slot == TYPE_SLOT(&PyBaseObject_Type))
918 continue;
920 if (found_slot != NULL && found_slot != slot) {
921 /* We have a conflict: more than one base use different
922 * custom slots. To be on the safe side, we bail out.
924 return;
927 found_slot = slot;
930 /* Only perform the final assignment if at least one base has a
931 * custom value. Otherwise just leave this type's slot untouched.
933 if (found_slot != NULL)
934 TYPE_SLOT(type) = found_slot;
936 #undef TYPE_SLOT
940 * pygobject_lookup_class:
941 * @gtype: the GType of the GObject subclass.
943 * This function looks up the wrapper class used to represent
944 * instances of a GObject represented by @gtype. If no wrapper class
945 * or interface has been registered for the given GType, then a new
946 * type will be created.
948 * Does not set an exception when NULL is returned.
950 * Returns: The wrapper class for the GObject or NULL if the
951 * GType has no registered type and a new type couldn't be created
953 PyTypeObject *
954 pygobject_lookup_class(GType gtype)
956 PyTypeObject *py_type;
958 if (gtype == G_TYPE_INTERFACE)
959 return &PyGInterface_Type;
961 py_type = g_type_get_qdata(gtype, pygobject_class_key);
962 if (py_type == NULL) {
963 py_type = g_type_get_qdata(gtype, pyginterface_type_key);
965 if (py_type == NULL) {
966 py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
967 PyErr_Clear ();
970 if (py_type == NULL) {
971 py_type = pygobject_new_with_interfaces(gtype);
972 PyErr_Clear ();
973 g_type_set_qdata(gtype, pyginterface_type_key, py_type);
977 return py_type;
981 * pygobject_new_full:
982 * @obj: a GObject instance.
983 * @steal: whether to steal a ref from the GObject or add (sink) a new one.
984 * @g_class: the GObjectClass
986 * This function gets a reference to a wrapper for the given GObject
987 * instance. If a wrapper has already been created, a new reference
988 * to that wrapper will be returned. Otherwise, a wrapper instance
989 * will be created.
991 * Returns: a reference to the wrapper for the GObject.
993 PyObject *
994 pygobject_new_full(GObject *obj, gboolean steal, gpointer g_class)
996 PyGObject *self;
998 if (obj == NULL) {
999 Py_RETURN_NONE;
1002 /* If the GObject already has a PyObject wrapper stashed in its qdata, re-use it.
1004 self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
1005 if (self != NULL) {
1006 /* Note the use of "pygobject_ref_sink" here only deals with PyObject
1007 * wrapper ref counts and has nothing to do with GObject.
1009 pygobject_ref_sink(self);
1011 /* If steal is true, we also want to decref the incoming GObjects which
1012 * already have a Python wrapper because the wrapper is already holding a
1013 * strong reference.
1015 if (steal)
1016 g_object_unref (obj);
1018 } else {
1019 /* create wrapper */
1020 PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
1021 PyTypeObject *tp;
1022 if (inst_data)
1023 tp = inst_data->type;
1024 else {
1025 if (g_class)
1026 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
1027 else
1028 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
1030 g_assert(tp != NULL);
1032 /* need to bump type refcount if created with
1033 pygobject_new_with_interfaces(). fixes bug #141042 */
1034 if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
1035 Py_INCREF(tp);
1036 self = PyObject_GC_New(PyGObject, tp);
1037 if (self == NULL)
1038 return NULL;
1039 self->inst_dict = NULL;
1040 self->weakreflist = NULL;
1041 self->private_flags.flags = 0;
1042 self->obj = obj;
1044 /* If we are not stealing a ref or the object is floating,
1045 * add a regular ref or sink the object. */
1046 if (g_object_is_floating (obj))
1047 self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING;
1048 if (!steal || self->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING)
1049 g_object_ref_sink (obj);
1051 pygobject_register_wrapper((PyObject *)self);
1052 PyObject_GC_Track((PyObject *)self);
1055 return (PyObject *)self;
1059 PyObject *
1060 pygobject_new(GObject *obj)
1062 return pygobject_new_full(obj,
1063 /*steal=*/FALSE,
1064 NULL);
1067 static void
1068 pygobject_unwatch_closure(gpointer data, GClosure *closure)
1070 PyGObjectData *inst_data = data;
1072 /* Despite no Python API is called the list inst_data->closures
1073 * must be protected by GIL as it is used by GC in
1074 * pygobject_traverse */
1075 PyGILState_STATE state = PyGILState_Ensure();
1076 inst_data->closures = g_slist_remove (inst_data->closures, closure);
1077 PyGILState_Release(state);
1081 * pygobject_watch_closure:
1082 * @self: a GObject wrapper instance
1083 * @closure: a GClosure to watch
1085 * Adds a closure to the list of watched closures for the wrapper.
1086 * The closure must be one returned by pyg_closure_new(). When the
1087 * cycle GC traverses the wrapper instance, it will enumerate the
1088 * references to Python objects stored in watched closures. If the
1089 * cycle GC tells the wrapper to clear itself, the watched closures
1090 * will be invalidated.
1092 void
1093 pygobject_watch_closure(PyObject *self, GClosure *closure)
1095 PyGObject *gself;
1096 PyGObjectData *data;
1098 g_return_if_fail(self != NULL);
1099 g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
1100 g_return_if_fail(closure != NULL);
1102 gself = (PyGObject *)self;
1103 data = pygobject_get_inst_data(gself);
1104 g_return_if_fail(data != NULL);
1105 g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
1106 data->closures = g_slist_prepend(data->closures, closure);
1107 g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
1111 /* -------------- PyGObject behaviour ----------------- */
1113 PYGLIB_DEFINE_TYPE("gi._gi.GObject", PyGObject_Type, PyGObject);
1115 static void
1116 pygobject_dealloc(PyGObject *self)
1118 /* Untrack must be done first. This is because followup calls such as
1119 * ClearWeakRefs could call into Python and cause new allocations to
1120 * happen, which could in turn could trigger the garbage collector,
1121 * which would then get confused as it is tracking this half-deallocated
1122 * object. */
1123 PyObject_GC_UnTrack((PyObject *)self);
1125 if (self->weakreflist != NULL)
1126 PyObject_ClearWeakRefs((PyObject *)self);
1128 /* this forces inst_data->type to be updated, which could prove
1129 * important if a new wrapper has to be created and it is of a
1130 * unregistered type */
1131 pygobject_get_inst_data(self);
1132 pygobject_clear(self);
1133 /* the following causes problems with subclassed types */
1134 /* Py_TYPE(self)->tp_free((PyObject *)self); */
1135 PyObject_GC_Del(self);
1138 static PyObject*
1139 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1141 int isinst;
1143 isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1144 if (isinst == -1)
1145 return NULL;
1146 if (!isinst) {
1147 Py_INCREF(Py_NotImplemented);
1148 return Py_NotImplemented;
1150 isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1151 if (isinst == -1)
1152 return NULL;
1153 if (!isinst) {
1154 Py_INCREF(Py_NotImplemented);
1155 return Py_NotImplemented;
1158 return pyg_ptr_richcompare(((PyGObject*)self)->obj,
1159 ((PyGObject*)other)->obj,
1160 op);
1163 static PYGLIB_Py_hash_t
1164 pygobject_hash(PyGObject *self)
1166 return PYGLIB_Py_hash_t_FromVoidPtr (self->obj);
1169 static PyObject *
1170 pygobject_repr(PyGObject *self)
1172 PyObject *module, *repr;
1173 gchar *module_str, *namespace;
1175 module = PyObject_GetAttrString ((PyObject *)self, "__module__");
1176 if (module == NULL)
1177 return NULL;
1179 if (!PYGLIB_PyUnicode_Check (module)) {
1180 Py_DECREF (module);
1181 return NULL;
1184 module_str = PYGLIB_PyUnicode_AsString (module);
1185 namespace = g_strrstr (module_str, ".");
1186 if (namespace == NULL) {
1187 namespace = module_str;
1188 } else {
1189 namespace += 1;
1192 repr = PYGLIB_PyUnicode_FromFormat ("<%s.%s object at %p (%s at %p)>",
1193 namespace, Py_TYPE (self)->tp_name, self,
1194 self->obj ? G_OBJECT_TYPE_NAME (self->obj) : "uninitialized",
1195 self->obj);
1196 Py_DECREF (module);
1197 return repr;
1201 static int
1202 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1204 int ret = 0;
1205 GSList *tmp;
1206 PyGObjectData *data = pygobject_get_inst_data(self);
1208 if (self->inst_dict) ret = visit(self->inst_dict, arg);
1209 if (ret != 0) return ret;
1211 /* Only let the GC track the closures when tp_clear() would free them.
1212 * https://bugzilla.gnome.org/show_bug.cgi?id=731501
1214 if (data && self->obj->ref_count == 1) {
1215 for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1216 PyGClosure *closure = tmp->data;
1218 if (closure->callback) ret = visit(closure->callback, arg);
1219 if (ret != 0) return ret;
1221 if (closure->extra_args) ret = visit(closure->extra_args, arg);
1222 if (ret != 0) return ret;
1224 if (closure->swap_data) ret = visit(closure->swap_data, arg);
1225 if (ret != 0) return ret;
1228 return ret;
1231 static inline int
1232 pygobject_clear(PyGObject *self)
1234 if (self->obj) {
1235 g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1236 if (pygobject_toggle_ref_is_active (self)) {
1237 g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, NULL);
1238 self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1239 } else {
1240 Py_BEGIN_ALLOW_THREADS;
1241 g_object_unref(self->obj);
1242 Py_END_ALLOW_THREADS;
1244 self->obj = NULL;
1246 Py_CLEAR(self->inst_dict);
1247 return 0;
1250 static void
1251 pygobject_free(PyObject *op)
1253 PyObject_GC_Del(op);
1256 gboolean
1257 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1258 guint *n_params, GParameter **params)
1260 *n_params = 0;
1261 *params = NULL;
1263 if (kwargs) {
1264 Py_ssize_t pos = 0;
1265 PyObject *key;
1266 PyObject *value;
1268 *params = g_new0(GParameter, PyDict_Size(kwargs));
1269 while (PyDict_Next(kwargs, &pos, &key, &value)) {
1270 GParamSpec *pspec;
1271 GParameter *param = &(*params)[*n_params];
1272 const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1274 pspec = g_object_class_find_property(class, key_str);
1275 if (!pspec) {
1276 PyErr_Format(PyExc_TypeError,
1277 "gobject `%s' doesn't support property `%s'",
1278 G_OBJECT_CLASS_NAME(class), key_str);
1279 return FALSE;
1281 g_value_init(&param->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1282 if (pyg_param_gvalue_from_pyobject(&param->value, value, pspec) < 0) {
1283 PyErr_Format(PyExc_TypeError,
1284 "could not convert value for property `%s' from %s to %s",
1285 key_str, Py_TYPE(value)->tp_name,
1286 g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1287 return FALSE;
1289 param->name = g_strdup(key_str);
1290 ++(*n_params);
1293 return TRUE;
1296 /* ---------------- PyGObject methods ----------------- */
1298 static int
1299 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1301 GType object_type;
1302 guint n_params = 0, i;
1303 GParameter *params = NULL;
1304 GObjectClass *class;
1306 /* Only do GObject creation and property setting if the GObject hasn't
1307 * already been created. The case where self->obj already exists can occur
1308 * when C constructors are called directly (Gtk.Button.new_with_label)
1309 * and we are simply wrapping the result with a PyGObject.
1310 * In these cases we want to ignore any keyword arguments passed along
1311 * to __init__ and simply return.
1313 * See: https://bugzilla.gnome.org/show_bug.cgi?id=705810
1315 if (self->obj != NULL)
1316 return 0;
1318 if (!PyArg_ParseTuple(args, ":GObject.__init__", NULL))
1319 return -1;
1321 object_type = pyg_type_from_object((PyObject *)self);
1322 if (!object_type)
1323 return -1;
1325 if (G_TYPE_IS_ABSTRACT(object_type)) {
1326 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1327 "(non-instantiable) type `%s'", g_type_name(object_type));
1328 return -1;
1331 if ((class = g_type_class_ref (object_type)) == NULL) {
1332 PyErr_SetString(PyExc_TypeError,
1333 "could not get a reference to type class");
1334 return -1;
1337 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, &params))
1338 goto cleanup;
1340 if (pygobject_constructv(self, n_params, params))
1341 PyErr_SetString(PyExc_RuntimeError, "could not create object");
1343 cleanup:
1344 for (i = 0; i < n_params; i++) {
1345 g_free((gchar *) params[i].name);
1346 g_value_unset(&params[i].value);
1348 g_free(params);
1349 g_type_class_unref(class);
1351 return (self->obj) ? 0 : -1;
1354 #define CHECK_GOBJECT(self) \
1355 if (!G_IS_OBJECT(self->obj)) { \
1356 PyErr_Format(PyExc_TypeError, \
1357 "object at %p of type %s is not initialized", \
1358 self, Py_TYPE(self)->tp_name); \
1359 return NULL; \
1362 static PyObject *
1363 pygobject_get_property (PyGObject *self, PyObject *args)
1365 gchar *param_name;
1367 if (!PyArg_ParseTuple (args, "s:GObject.get_property", &param_name)) {
1368 return NULL;
1371 CHECK_GOBJECT(self);
1373 return pygi_get_property_value_by_name (self, param_name);
1376 static PyObject *
1377 pygobject_get_properties(PyGObject *self, PyObject *args)
1379 Py_ssize_t len, i;
1380 PyObject *tuple;
1382 if ((len = PyTuple_Size(args)) < 1) {
1383 PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1384 return NULL;
1387 tuple = PyTuple_New(len);
1388 for (i = 0; i < len; i++) {
1389 PyObject *py_property = PyTuple_GetItem(args, i);
1390 gchar *property_name;
1391 PyObject *item;
1393 if (!PYGLIB_PyUnicode_Check(py_property)) {
1394 PyErr_SetString(PyExc_TypeError,
1395 "Expected string argument for property.");
1396 goto fail;
1399 property_name = PYGLIB_PyUnicode_AsString(py_property);
1400 item = pygi_get_property_value_by_name (self, property_name);
1401 PyTuple_SetItem (tuple, i, item);
1404 return tuple;
1406 fail:
1407 Py_DECREF (tuple);
1408 return NULL;
1411 static PyObject *
1412 pygobject_set_property(PyGObject *self, PyObject *args)
1414 gchar *param_name;
1415 GParamSpec *pspec;
1416 PyObject *pvalue;
1417 int ret = -1;
1419 if (!PyArg_ParseTuple(args, "sO:GObject.set_property", &param_name,
1420 &pvalue))
1421 return NULL;
1423 CHECK_GOBJECT(self);
1425 pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1426 param_name);
1427 if (!pspec) {
1428 PyErr_Format(PyExc_TypeError,
1429 "object of type `%s' does not have property `%s'",
1430 g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1431 return NULL;
1434 ret = pygi_set_property_value (self, pspec, pvalue);
1435 if (ret == 0)
1436 goto done;
1437 else if (PyErr_Occurred())
1438 return NULL;
1440 if (!set_property_from_pspec(self->obj, pspec, pvalue))
1441 return NULL;
1443 done:
1445 Py_INCREF(Py_None);
1446 return Py_None;
1449 static PyObject *
1450 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1452 GObjectClass *class;
1453 Py_ssize_t pos;
1454 PyObject *value;
1455 PyObject *key;
1456 PyObject *result = NULL;
1458 CHECK_GOBJECT(self);
1460 class = G_OBJECT_GET_CLASS(self->obj);
1462 g_object_freeze_notify (G_OBJECT(self->obj));
1463 pos = 0;
1465 while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1466 gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1467 GParamSpec *pspec;
1468 int ret = -1;
1470 pspec = g_object_class_find_property(class, key_str);
1471 if (!pspec) {
1472 gchar buf[512];
1474 g_snprintf(buf, sizeof(buf),
1475 "object `%s' doesn't support property `%s'",
1476 g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1477 PyErr_SetString(PyExc_TypeError, buf);
1478 goto exit;
1481 ret = pygi_set_property_value (self, pspec, value);
1482 if (ret != 0) {
1483 /* Non-zero return code means that either an error occured ...*/
1484 if (PyErr_Occurred())
1485 goto exit;
1487 /* ... or the property couldn't be found , so let's try the default
1488 * call. */
1489 if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value))
1490 goto exit;
1494 result = Py_None;
1496 exit:
1497 g_object_thaw_notify (G_OBJECT(self->obj));
1498 Py_XINCREF(result);
1499 return result;
1502 /* custom closure for gobject bindings */
1503 static void
1504 pygbinding_closure_invalidate(gpointer data, GClosure *closure)
1506 PyGClosure *pc = (PyGClosure *)closure;
1507 PyGILState_STATE state;
1509 state = PyGILState_Ensure();
1510 Py_XDECREF(pc->callback);
1511 Py_XDECREF(pc->extra_args);
1512 PyGILState_Release(state);
1514 pc->callback = NULL;
1515 pc->extra_args = NULL;
1518 static void
1519 pygbinding_marshal (GClosure *closure,
1520 GValue *return_value,
1521 guint n_param_values,
1522 const GValue *param_values,
1523 gpointer invocation_hint,
1524 gpointer marshal_data)
1526 PyGILState_STATE state;
1527 PyGClosure *pc = (PyGClosure *)closure;
1528 PyObject *params, *ret;
1529 GValue *out_value;
1531 state = PyGILState_Ensure();
1533 /* construct Python tuple for the parameter values */
1534 params = PyTuple_New(2);
1535 PyTuple_SetItem (params, 0, pyg_value_as_pyobject(&param_values[0], FALSE));
1536 PyTuple_SetItem (params, 1, pyg_value_as_pyobject(&param_values[1], FALSE));
1538 /* params passed to function may have extra arguments */
1539 if (pc->extra_args) {
1540 PyObject *tuple = params;
1541 params = PySequence_Concat(tuple, pc->extra_args);
1542 Py_DECREF(tuple);
1544 ret = PyObject_CallObject(pc->callback, params);
1545 if (!ret) {
1546 PyErr_Print ();
1547 goto out;
1548 } else if (ret == Py_None) {
1549 g_value_set_boolean (return_value, FALSE);
1550 goto out;
1553 out_value = g_value_get_boxed (&param_values[2]);
1554 if (pyg_value_from_pyobject (out_value, ret) != 0) {
1555 PyErr_SetString (PyExc_ValueError, "can't convert value");
1556 PyErr_Print ();
1557 g_value_set_boolean (return_value, FALSE);
1558 } else {
1559 g_value_set_boolean (return_value, TRUE);
1562 Py_DECREF(ret);
1564 out:
1565 Py_DECREF(params);
1566 PyGILState_Release(state);
1569 static GClosure *
1570 pygbinding_closure_new (PyObject *callback, PyObject *extra_args)
1572 GClosure *closure;
1574 g_return_val_if_fail(callback != NULL, NULL);
1575 closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
1576 g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate);
1577 g_closure_set_marshal(closure, pygbinding_marshal);
1578 Py_INCREF(callback);
1579 ((PyGClosure *)closure)->callback = callback;
1580 if (extra_args && extra_args != Py_None) {
1581 Py_INCREF(extra_args);
1582 if (!PyTuple_Check(extra_args)) {
1583 PyObject *tmp = PyTuple_New(1);
1584 PyTuple_SetItem(tmp, 0, extra_args);
1585 extra_args = tmp;
1587 ((PyGClosure *)closure)->extra_args = extra_args;
1589 return closure;
1592 static PyObject *
1593 pygobject_bind_property(PyGObject *self, PyObject *args)
1595 gchar *source_name, *target_name;
1596 gchar *source_canon, *target_canon;
1597 PyObject *target, *source_repr, *target_repr;
1598 PyObject *transform_to, *transform_from, *user_data = NULL;
1599 GBinding *binding;
1600 GBindingFlags flags = G_BINDING_DEFAULT;
1601 GClosure *to_closure = NULL, *from_closure = NULL;
1603 transform_from = NULL;
1604 transform_to = NULL;
1606 if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property",
1607 &source_name, &target, &target_name, &flags,
1608 &transform_to, &transform_from, &user_data))
1609 return NULL;
1611 CHECK_GOBJECT(self);
1612 if (!PyObject_TypeCheck(target, &PyGObject_Type)) {
1613 PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject");
1614 return NULL;
1617 if (transform_to && transform_to != Py_None) {
1618 if (!PyCallable_Check (transform_to)) {
1619 PyErr_SetString (PyExc_TypeError,
1620 "transform_to must be callable or None");
1621 return NULL;
1623 to_closure = pygbinding_closure_new (transform_to, user_data);
1626 if (transform_from && transform_from != Py_None) {
1627 if (!PyCallable_Check (transform_from)) {
1628 PyErr_SetString (PyExc_TypeError,
1629 "transform_from must be callable or None");
1630 return NULL;
1632 from_closure = pygbinding_closure_new (transform_from, user_data);
1635 /* Canonicalize underscores to hyphens. Note the results must be freed. */
1636 source_canon = g_strdelimit(g_strdup(source_name), "_", '-');
1637 target_canon = g_strdelimit(g_strdup(target_name), "_", '-');
1639 binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon,
1640 pygobject_get(target), target_canon,
1641 flags, to_closure, from_closure);
1642 g_free(source_canon);
1643 g_free(target_canon);
1644 source_canon = target_canon = NULL;
1646 if (binding == NULL) {
1647 source_repr = PyObject_Repr((PyObject*)self);
1648 target_repr = PyObject_Repr(target);
1649 PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s",
1650 PYGLIB_PyUnicode_AsString(source_repr), source_name,
1651 PYGLIB_PyUnicode_AsString(target_repr), target_name);
1652 Py_DECREF(source_repr);
1653 Py_DECREF(target_repr);
1654 return NULL;
1657 return pygobject_new (G_OBJECT (binding));
1660 static PyObject *
1661 connect_helper(PyGObject *self, gchar *name, PyObject *callback, PyObject *extra_args, PyObject *object, gboolean after)
1663 guint sigid;
1664 GQuark detail = 0;
1665 GClosure *closure = NULL;
1666 gulong handlerid;
1667 GSignalQuery query_info;
1669 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1670 &sigid, &detail, TRUE)) {
1671 PyObject *repr = PyObject_Repr((PyObject*)self);
1672 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1673 PYGLIB_PyUnicode_AsString(repr),
1674 name);
1675 Py_DECREF(repr);
1676 return NULL;
1679 if (object && !PyObject_TypeCheck (object, &PyGObject_Type)) {
1680 if (PyErr_WarnEx (PyGIDeprecationWarning,
1681 "Using non GObject arguments for connect_object() is deprecated, use: "
1682 "connect_data(signal, callback, data, connect_flags=GObject.ConnectFlags.SWAPPED)",
1683 1)) {
1684 return NULL;
1688 g_signal_query (sigid, &query_info);
1689 if (!pyg_gtype_is_custom (query_info.itype)) {
1690 /* The signal is implemented by a non-Python class, probably
1691 * something in the gi repository. */
1692 closure = pygi_signal_closure_new (self, query_info.itype,
1693 query_info.signal_name, callback,
1694 extra_args, object);
1697 if (!closure) {
1698 /* The signal is either implemented at the Python level, or it comes
1699 * from a foreign class that we don't have introspection data for. */
1700 closure = pyg_closure_new (callback, extra_args, object);
1703 pygobject_watch_closure((PyObject *)self, closure);
1704 handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1705 closure, after);
1706 return pygi_gulong_to_py (handlerid);
1709 static PyObject *
1710 pygobject_connect(PyGObject *self, PyObject *args)
1712 PyObject *first, *callback, *extra_args, *ret;
1713 gchar *name;
1714 Py_ssize_t len;
1716 len = PyTuple_Size(args);
1717 if (len < 2) {
1718 PyErr_SetString(PyExc_TypeError,
1719 "GObject.connect requires at least 2 arguments");
1720 return NULL;
1722 first = PySequence_GetSlice(args, 0, 2);
1723 if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1724 Py_DECREF(first);
1725 return NULL;
1727 Py_DECREF(first);
1728 if (!PyCallable_Check(callback)) {
1729 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1730 return NULL;
1733 CHECK_GOBJECT(self);
1735 extra_args = PySequence_GetSlice(args, 2, len);
1736 if (extra_args == NULL)
1737 return NULL;
1739 ret = connect_helper(self, name, callback, extra_args, NULL, FALSE);
1740 Py_DECREF(extra_args);
1741 return ret;
1744 static PyObject *
1745 pygobject_connect_after(PyGObject *self, PyObject *args)
1747 PyObject *first, *callback, *extra_args, *ret;
1748 gchar *name;
1749 Py_ssize_t len;
1751 len = PyTuple_Size(args);
1752 if (len < 2) {
1753 PyErr_SetString(PyExc_TypeError,
1754 "GObject.connect_after requires at least 2 arguments");
1755 return NULL;
1757 first = PySequence_GetSlice(args, 0, 2);
1758 if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1759 &name, &callback)) {
1760 Py_DECREF(first);
1761 return NULL;
1763 Py_DECREF(first);
1764 if (!PyCallable_Check(callback)) {
1765 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1766 return NULL;
1769 CHECK_GOBJECT(self);
1771 extra_args = PySequence_GetSlice(args, 2, len);
1772 if (extra_args == NULL)
1773 return NULL;
1775 ret = connect_helper(self, name, callback, extra_args, NULL, TRUE);
1776 Py_DECREF(extra_args);
1777 return ret;
1780 static PyObject *
1781 pygobject_connect_object(PyGObject *self, PyObject *args)
1783 PyObject *first, *callback, *extra_args, *object, *ret;
1784 gchar *name;
1785 Py_ssize_t len;
1787 len = PyTuple_Size(args);
1788 if (len < 3) {
1789 PyErr_SetString(PyExc_TypeError,
1790 "GObject.connect_object requires at least 3 arguments");
1791 return NULL;
1793 first = PySequence_GetSlice(args, 0, 3);
1794 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1795 &name, &callback, &object)) {
1796 Py_DECREF(first);
1797 return NULL;
1799 Py_DECREF(first);
1800 if (!PyCallable_Check(callback)) {
1801 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1802 return NULL;
1805 CHECK_GOBJECT(self);
1807 extra_args = PySequence_GetSlice(args, 3, len);
1808 if (extra_args == NULL)
1809 return NULL;
1811 ret = connect_helper(self, name, callback, extra_args, object, FALSE);
1812 Py_DECREF(extra_args);
1813 return ret;
1816 static PyObject *
1817 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1819 PyObject *first, *callback, *extra_args, *object, *ret;
1820 gchar *name;
1821 Py_ssize_t len;
1823 len = PyTuple_Size(args);
1824 if (len < 3) {
1825 PyErr_SetString(PyExc_TypeError,
1826 "GObject.connect_object_after requires at least 3 arguments");
1827 return NULL;
1829 first = PySequence_GetSlice(args, 0, 3);
1830 if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1831 &name, &callback, &object)) {
1832 Py_DECREF(first);
1833 return NULL;
1835 Py_DECREF(first);
1836 if (!PyCallable_Check(callback)) {
1837 PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1838 return NULL;
1841 CHECK_GOBJECT(self);
1843 extra_args = PySequence_GetSlice(args, 3, len);
1844 if (extra_args == NULL)
1845 return NULL;
1847 ret = connect_helper(self, name, callback, extra_args, object, TRUE);
1848 Py_DECREF(extra_args);
1849 return ret;
1852 static PyObject *
1853 pygobject_emit(PyGObject *self, PyObject *args)
1855 guint signal_id, i, j;
1856 Py_ssize_t len;
1857 GQuark detail;
1858 PyObject *first, *py_ret, *repr = NULL;
1859 gchar *name;
1860 GSignalQuery query;
1861 GValue *params, ret = { 0, };
1863 len = PyTuple_Size(args);
1864 if (len < 1) {
1865 PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1866 return NULL;
1868 first = PySequence_GetSlice(args, 0, 1);
1869 if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1870 Py_DECREF(first);
1871 return NULL;
1873 Py_DECREF(first);
1875 CHECK_GOBJECT(self);
1877 if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1878 &signal_id, &detail, TRUE)) {
1879 repr = PyObject_Repr((PyObject*)self);
1880 PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1881 PYGLIB_PyUnicode_AsString(repr),
1882 name);
1883 Py_DECREF(repr);
1884 return NULL;
1886 g_signal_query(signal_id, &query);
1887 if ((gsize)len != query.n_params + 1) {
1888 gchar buf[128];
1890 g_snprintf(buf, sizeof(buf),
1891 "%d parameters needed for signal %s; %ld given",
1892 query.n_params, name, (long int) (len - 1));
1893 PyErr_SetString(PyExc_TypeError, buf);
1894 return NULL;
1897 params = g_new0(GValue, query.n_params + 1);
1898 g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1899 g_value_set_object(&params[0], G_OBJECT(self->obj));
1901 for (i = 0; i < query.n_params; i++)
1902 g_value_init(&params[i + 1],
1903 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1904 for (i = 0; i < query.n_params; i++) {
1905 PyObject *item = PyTuple_GetItem(args, i+1);
1907 if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1908 gchar buf[128];
1909 g_snprintf(buf, sizeof(buf),
1910 "could not convert type %s to %s required for parameter %d",
1911 Py_TYPE(item)->tp_name,
1912 G_VALUE_TYPE_NAME(&params[i+1]), i);
1913 PyErr_SetString(PyExc_TypeError, buf);
1915 for (j = 0; j <= i; j++)
1916 g_value_unset(&params[j]);
1918 g_free(params);
1919 return NULL;
1923 if (query.return_type != G_TYPE_NONE)
1924 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1926 Py_BEGIN_ALLOW_THREADS;
1927 g_signal_emitv(params, signal_id, detail, &ret);
1928 Py_END_ALLOW_THREADS;
1930 for (i = 0; i < query.n_params + 1; i++)
1931 g_value_unset(&params[i]);
1933 g_free(params);
1934 if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1935 py_ret = pyg_value_as_pyobject(&ret, TRUE);
1936 g_value_unset(&ret);
1937 } else {
1938 Py_INCREF(Py_None);
1939 py_ret = Py_None;
1942 return py_ret;
1945 static PyObject *
1946 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1948 GSignalInvocationHint *ihint;
1949 guint signal_id, i;
1950 Py_ssize_t len;
1951 PyObject *py_ret;
1952 const gchar *name;
1953 GSignalQuery query;
1954 GValue *params, ret = { 0, };
1956 CHECK_GOBJECT(self);
1958 ihint = g_signal_get_invocation_hint(self->obj);
1959 if (!ihint) {
1960 PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1961 "information for this object.");
1962 return NULL;
1965 signal_id = ihint->signal_id;
1966 name = g_signal_name(signal_id);
1968 len = PyTuple_Size(args);
1969 if (signal_id == 0) {
1970 PyErr_SetString(PyExc_TypeError, "unknown signal name");
1971 return NULL;
1973 g_signal_query(signal_id, &query);
1974 if (len < 0 || (gsize)len != query.n_params) {
1975 gchar buf[128];
1977 g_snprintf(buf, sizeof(buf),
1978 "%d parameters needed for signal %s; %ld given",
1979 query.n_params, name, (long int) len);
1980 PyErr_SetString(PyExc_TypeError, buf);
1981 return NULL;
1983 params = g_new0(GValue, query.n_params + 1);
1984 g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1985 g_value_set_object(&params[0], G_OBJECT(self->obj));
1987 for (i = 0; i < query.n_params; i++)
1988 g_value_init(&params[i + 1],
1989 query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1990 for (i = 0; i < query.n_params; i++) {
1991 PyObject *item = PyTuple_GetItem(args, i);
1993 if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1994 g_value_set_static_boxed(&params[i+1], pyg_boxed_get(item, void));
1996 else if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1997 gchar buf[128];
1999 g_snprintf(buf, sizeof(buf),
2000 "could not convert type %s to %s required for parameter %d",
2001 Py_TYPE(item)->tp_name,
2002 g_type_name(G_VALUE_TYPE(&params[i+1])), i);
2003 PyErr_SetString(PyExc_TypeError, buf);
2004 for (i = 0; i < query.n_params + 1; i++)
2005 g_value_unset(&params[i]);
2006 g_free(params);
2007 return NULL;
2010 if (query.return_type != G_TYPE_NONE)
2011 g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2012 g_signal_chain_from_overridden(params, &ret);
2013 for (i = 0; i < query.n_params + 1; i++)
2014 g_value_unset(&params[i]);
2015 g_free(params);
2016 if (query.return_type != G_TYPE_NONE) {
2017 py_ret = pyg_value_as_pyobject(&ret, TRUE);
2018 g_value_unset(&ret);
2019 } else {
2020 Py_INCREF(Py_None);
2021 py_ret = Py_None;
2023 return py_ret;
2027 static PyObject *
2028 pygobject_weak_ref(PyGObject *self, PyObject *args)
2030 Py_ssize_t len;
2031 PyObject *callback = NULL, *user_data = NULL;
2032 PyObject *retval;
2034 CHECK_GOBJECT(self);
2036 if ((len = PySequence_Length(args)) >= 1) {
2037 callback = PySequence_ITEM(args, 0);
2038 user_data = PySequence_GetSlice(args, 1, len);
2040 retval = pygobject_weak_ref_new(self->obj, callback, user_data);
2041 Py_XDECREF(callback);
2042 Py_XDECREF(user_data);
2043 return retval;
2047 static PyObject *
2048 pygobject_copy(PyGObject *self)
2050 PyErr_SetString(PyExc_TypeError,
2051 "GObject descendants' instances are non-copyable");
2052 return NULL;
2055 static PyObject *
2056 pygobject_deepcopy(PyGObject *self, PyObject *args)
2058 PyErr_SetString(PyExc_TypeError,
2059 "GObject descendants' instances are non-copyable");
2060 return NULL;
2064 static PyObject *
2065 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
2067 PyObject *pyfunc = NULL, *repr = NULL;
2068 GClosure *closure = NULL;
2069 guint retval;
2071 CHECK_GOBJECT(self);
2073 if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2074 return NULL;
2076 if (!PyCallable_Check(pyfunc)) {
2077 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2078 return NULL;
2081 closure = gclosure_from_pyfunc(self, pyfunc);
2082 if (!closure) {
2083 repr = PyObject_Repr((PyObject*)pyfunc);
2084 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2085 PYGLIB_PyUnicode_AsString(repr));
2086 Py_DECREF(repr);
2087 return NULL;
2090 retval = g_signal_handlers_disconnect_matched(self->obj,
2091 G_SIGNAL_MATCH_CLOSURE,
2092 0, 0,
2093 closure,
2094 NULL, NULL);
2095 return pygi_guint_to_py (retval);
2098 static PyObject *
2099 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2101 PyObject *pyfunc = NULL, *repr = NULL;
2102 GClosure *closure = NULL;
2103 guint retval;
2105 CHECK_GOBJECT(self);
2107 if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2108 return NULL;
2110 if (!PyCallable_Check(pyfunc)) {
2111 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2112 return NULL;
2115 closure = gclosure_from_pyfunc(self, pyfunc);
2116 if (!closure) {
2117 repr = PyObject_Repr((PyObject*)pyfunc);
2118 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2119 PYGLIB_PyUnicode_AsString(repr));
2120 Py_DECREF(repr);
2121 return NULL;
2124 retval = g_signal_handlers_block_matched(self->obj,
2125 G_SIGNAL_MATCH_CLOSURE,
2126 0, 0,
2127 closure,
2128 NULL, NULL);
2129 return pygi_guint_to_py (retval);
2132 static PyObject *
2133 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2135 PyObject *pyfunc = NULL, *repr = NULL;
2136 GClosure *closure = NULL;
2137 guint retval;
2139 CHECK_GOBJECT(self);
2141 if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2142 return NULL;
2144 if (!PyCallable_Check(pyfunc)) {
2145 PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2146 return NULL;
2149 closure = gclosure_from_pyfunc(self, pyfunc);
2150 if (!closure) {
2151 repr = PyObject_Repr((PyObject*)pyfunc);
2152 PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2153 PYGLIB_PyUnicode_AsString(repr));
2154 Py_DECREF(repr);
2155 return NULL;
2158 retval = g_signal_handlers_unblock_matched(self->obj,
2159 G_SIGNAL_MATCH_CLOSURE,
2160 0, 0,
2161 closure,
2162 NULL, NULL);
2163 return pygi_guint_to_py (retval);
2167 static PyMethodDef pygobject_methods[] = {
2168 { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2169 { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2170 { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2171 { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2172 { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS },
2173 { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2174 { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2175 { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2176 { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2177 { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2178 { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2179 { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2180 { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2181 { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2182 { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2183 { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2184 { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2185 { NULL, NULL, 0 }
2188 #ifdef PYGI_OBJECT_USE_CUSTOM_DICT
2189 static PyObject *
2190 pygobject_get_dict(PyGObject *self, void *closure)
2192 if (self->inst_dict == NULL) {
2193 self->inst_dict = PyDict_New();
2194 pygobject_toggle_ref_ensure (self);
2196 Py_INCREF(self->inst_dict);
2197 return self->inst_dict;
2199 #endif
2201 static PyObject *
2202 pygobject_get_refcount(PyGObject *self, void *closure)
2204 if (self->obj == NULL) {
2205 PyErr_Format(PyExc_TypeError, "GObject instance is not yet created");
2206 return NULL;
2208 return pygi_guint_to_py (self->obj->ref_count);
2211 static PyObject *
2212 pygobject_get_pointer(PyGObject *self, void *closure)
2214 return PyCapsule_New (self->obj, NULL, NULL);
2217 static int
2218 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2220 int res;
2221 res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2222 pygobject_toggle_ref_ensure ((PyGObject *) self);
2223 return res;
2226 static PyGetSetDef pygobject_getsets[] = {
2227 #ifdef PYGI_OBJECT_USE_CUSTOM_DICT
2228 { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2229 #endif
2230 { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2231 { "__gpointer__", (getter)pygobject_get_pointer, (setter)0, },
2232 { NULL, 0, 0 }
2235 /* ------------------------------------ */
2236 /* ****** GObject weak reference ****** */
2237 /* ------------------------------------ */
2239 typedef struct {
2240 PyObject_HEAD
2241 GObject *obj;
2242 PyObject *callback;
2243 PyObject *user_data;
2244 gboolean have_floating_ref;
2245 } PyGObjectWeakRef;
2247 PYGLIB_DEFINE_TYPE("gi._gi.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2249 static int
2250 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2252 if (self->callback && visit(self->callback, arg) < 0)
2253 return -1;
2254 if (self->user_data && visit(self->user_data, arg) < 0)
2255 return -1;
2256 return 0;
2259 static void
2260 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2262 self->obj = NULL;
2263 if (self->callback) {
2264 PyObject *retval;
2265 PyGILState_STATE state = PyGILState_Ensure();
2266 retval = PyObject_Call(self->callback, self->user_data, NULL);
2267 if (retval) {
2268 if (retval != Py_None)
2269 PyErr_Format(PyExc_TypeError,
2270 "GObject weak notify callback returned a value"
2271 " of type %s, should return None",
2272 Py_TYPE(retval)->tp_name);
2273 Py_DECREF(retval);
2274 PyErr_Print();
2275 } else
2276 PyErr_Print();
2277 Py_CLEAR(self->callback);
2278 Py_CLEAR(self->user_data);
2279 if (self->have_floating_ref) {
2280 self->have_floating_ref = FALSE;
2281 Py_DECREF((PyObject *) self);
2283 PyGILState_Release(state);
2287 static inline int
2288 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2290 Py_CLEAR(self->callback);
2291 Py_CLEAR(self->user_data);
2292 if (self->obj) {
2293 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2294 self->obj = NULL;
2296 return 0;
2299 static void
2300 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2302 PyObject_GC_UnTrack((PyObject *)self);
2303 pygobject_weak_ref_clear(self);
2304 PyObject_GC_Del(self);
2307 static PyObject *
2308 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2310 PyGObjectWeakRef *self;
2312 self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2313 self->callback = callback;
2314 self->user_data = user_data;
2315 Py_XINCREF(self->callback);
2316 Py_XINCREF(self->user_data);
2317 self->obj = obj;
2318 g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2319 if (callback != NULL) {
2320 /* when we have a callback, we should INCREF the weakref
2321 * object to make it stay alive even if it goes out of scope */
2322 self->have_floating_ref = TRUE;
2323 Py_INCREF((PyObject *) self);
2325 return (PyObject *) self;
2328 static PyObject *
2329 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2331 if (!self->obj) {
2332 PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2333 return NULL;
2335 g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2336 self->obj = NULL;
2337 if (self->have_floating_ref) {
2338 self->have_floating_ref = FALSE;
2339 Py_DECREF(self);
2341 Py_INCREF(Py_None);
2342 return Py_None;
2345 static PyMethodDef pygobject_weak_ref_methods[] = {
2346 { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2347 { NULL, NULL, 0}
2350 static PyObject *
2351 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2353 static char *argnames[] = {NULL};
2355 if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2356 return NULL;
2358 if (self->obj)
2359 return pygobject_new(self->obj);
2360 else {
2361 Py_INCREF(Py_None);
2362 return Py_None;
2366 static gpointer
2367 pyobject_copy(gpointer boxed)
2369 PyObject *object = boxed;
2370 PyGILState_STATE state;
2372 state = PyGILState_Ensure();
2373 Py_INCREF(object);
2374 PyGILState_Release(state);
2375 return object;
2378 static void
2379 pyobject_free(gpointer boxed)
2381 PyObject *object = boxed;
2382 PyGILState_STATE state;
2384 state = PyGILState_Ensure();
2385 Py_DECREF(object);
2386 PyGILState_Release(state);
2390 * Returns 0 on success, or -1 and sets an exception.
2393 pyi_object_register_types(PyObject *d)
2395 PyObject *o, *descr;
2397 pygobject_custom_key = g_quark_from_static_string("PyGObject::custom");
2398 pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2399 pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2400 pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2401 pygobject_has_updated_constructor_key =
2402 g_quark_from_static_string("PyGObject::has-updated-constructor");
2403 pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2405 /* GObject */
2406 if (!PY_TYPE_OBJECT)
2407 PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2408 pyobject_copy,
2409 pyobject_free);
2410 PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2411 PyGObject_Type.tp_richcompare = pygobject_richcompare;
2412 PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2413 PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2414 PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2415 PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2416 Py_TPFLAGS_HAVE_GC);
2417 PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2418 PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2419 PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2420 PyGObject_Type.tp_methods = pygobject_methods;
2421 PyGObject_Type.tp_getset = pygobject_getsets;
2422 #ifdef PYGI_OBJECT_USE_CUSTOM_DICT
2423 PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2424 #endif
2425 PyGObject_Type.tp_init = (initproc)pygobject_init;
2426 PyGObject_Type.tp_free = (freefunc)pygobject_free;
2427 PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2428 PyGObject_Type.tp_new = PyType_GenericNew;
2429 pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2430 &PyGObject_Type, NULL);
2431 PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2432 pyg_object_descr_doc_get());
2434 /* GProps */
2435 PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2436 PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2437 PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2438 PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2439 PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2440 PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2441 "Python attributes.";
2442 PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2443 PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2444 PyGProps_Type.tp_methods = pygobject_props_methods;
2445 if (PyType_Ready(&PyGProps_Type) < 0)
2446 return -1;
2448 /* GPropsDescr */
2449 PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2450 PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2451 if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2452 return -1;
2453 descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2454 PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2455 PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2456 o=PYGLIB_PyUnicode_FromString("gi._gi"));
2457 Py_DECREF(o);
2459 /* GPropsIter */
2460 PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2461 PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2462 PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2463 PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2464 if (PyType_Ready(&PyGPropsIter_Type) < 0)
2465 return -1;
2467 PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2468 PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2469 PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2470 PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2471 PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2472 PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2473 PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2474 if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2475 return -1;
2476 PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
2478 return 0;
2481 PyObject *
2482 pyg_object_new (PyGObject *self, PyObject *args, PyObject *kwargs)
2484 PyObject *pytype;
2485 GType type;
2486 GObject *obj = NULL;
2487 GObjectClass *class;
2488 guint n_params = 0, i;
2489 GParameter *params = NULL;
2491 if (!PyArg_ParseTuple (args, "O:gobject.new", &pytype)) {
2492 return NULL;
2495 if ((type = pyg_type_from_object (pytype)) == 0)
2496 return NULL;
2498 if (G_TYPE_IS_ABSTRACT(type)) {
2499 PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
2500 "(non-instantiable) type `%s'", g_type_name(type));
2501 return NULL;
2504 if ((class = g_type_class_ref (type)) == NULL) {
2505 PyErr_SetString(PyExc_TypeError,
2506 "could not get a reference to type class");
2507 return NULL;
2510 if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, &params))
2511 goto cleanup;
2513 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2514 obj = g_object_newv(type, n_params, params);
2515 G_GNUC_END_IGNORE_DEPRECATIONS
2517 if (!obj)
2518 PyErr_SetString (PyExc_RuntimeError, "could not create object");
2520 cleanup:
2521 for (i = 0; i < n_params; i++) {
2522 g_free((gchar *) params[i].name);
2523 g_value_unset(&params[i].value);
2525 g_free(params);
2526 g_type_class_unref(class);
2528 if (obj) {
2529 pygobject_sink (obj);
2530 self = (PyGObject *) pygobject_new((GObject *)obj);
2531 g_object_unref(obj);
2532 } else
2533 self = NULL;
2535 return (PyObject *) self;