release 3.27.0
[pygobject.git] / gi / pygtype.c
blob85a6d8295ca7fa170af72caeddf45d36f3baa6ab
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygtk- Python bindings for the GTK toolkit.
3 * Copyright (C) 1998-2003 James Henstridge
5 * pygtype.c: glue code to wrap the GType code.
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 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
25 #include <pyglib.h>
27 #include "pygobject-object.h"
28 #include "pygboxed.h"
29 #include "pygenum.h"
30 #include "pygflags.h"
31 #include "pygparamspec.h"
32 #include "pygtype.h"
33 #include "pygpointer.h"
34 #include "pyginterface.h"
36 #include "pygi-type.h"
37 #include "pygi-value.h"
39 /* -------------- __gtype__ objects ---------------------------- */
41 typedef struct {
42 PyObject_HEAD
43 GType type;
44 } PyGTypeWrapper;
46 PYGLIB_DEFINE_TYPE("gobject.GType", PyGTypeWrapper_Type, PyGTypeWrapper);
48 static PyObject*
49 pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op)
51 if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type)
52 return _pyglib_generic_long_richcompare(((PyGTypeWrapper*)self)->type,
53 ((PyGTypeWrapper*)other)->type,
54 op);
55 else {
56 Py_INCREF(Py_NotImplemented);
57 return Py_NotImplemented;
61 static long
62 pyg_type_wrapper_hash(PyGTypeWrapper *self)
64 return (long)self->type;
67 static PyObject *
68 pyg_type_wrapper_repr(PyGTypeWrapper *self)
70 char buf[80];
71 const gchar *name = g_type_name(self->type);
73 g_snprintf(buf, sizeof(buf), "<GType %s (%lu)>",
74 name?name:"invalid", (unsigned long int) self->type);
75 return PYGLIB_PyUnicode_FromString(buf);
78 static void
79 pyg_type_wrapper_dealloc(PyGTypeWrapper *self)
81 PyObject_DEL(self);
84 static GQuark
85 _pyg_type_key(GType type) {
86 GQuark key;
88 if (g_type_is_a(type, G_TYPE_INTERFACE)) {
89 key = pyginterface_type_key;
90 } else if (g_type_is_a(type, G_TYPE_ENUM)) {
91 key = pygenum_class_key;
92 } else if (g_type_is_a(type, G_TYPE_FLAGS)) {
93 key = pygflags_class_key;
94 } else if (g_type_is_a(type, G_TYPE_POINTER)) {
95 key = pygpointer_class_key;
96 } else if (g_type_is_a(type, G_TYPE_BOXED)) {
97 key = pygboxed_type_key;
98 } else {
99 key = pygobject_class_key;
102 return key;
105 static PyObject *
106 _wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure)
108 GQuark key;
109 PyObject *py_type;
111 key = _pyg_type_key(self->type);
113 py_type = g_type_get_qdata(self->type, key);
114 if (!py_type)
115 py_type = Py_None;
117 Py_INCREF(py_type);
118 return py_type;
121 static int
122 _wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure)
124 GQuark key;
125 PyObject *py_type;
127 key = _pyg_type_key(self->type);
129 py_type = g_type_get_qdata(self->type, key);
130 Py_CLEAR(py_type);
131 if (value == Py_None)
132 g_type_set_qdata(self->type, key, NULL);
133 else if (PyType_Check(value)) {
134 Py_INCREF(value);
135 g_type_set_qdata(self->type, key, value);
136 } else {
137 PyErr_SetString(PyExc_TypeError, "Value must be None or a type object");
138 return -1;
141 return 0;
144 static PyObject *
145 _wrap_g_type_wrapper__get_name(PyGTypeWrapper *self, void *closure)
147 const char *name = g_type_name(self->type);
148 return PYGLIB_PyUnicode_FromString(name ? name : "invalid");
151 static PyObject *
152 _wrap_g_type_wrapper__get_parent(PyGTypeWrapper *self, void *closure)
154 return pyg_type_wrapper_new(g_type_parent(self->type));
157 static PyObject *
158 _wrap_g_type_wrapper__get_fundamental(PyGTypeWrapper *self, void *closure)
160 return pyg_type_wrapper_new(g_type_fundamental(self->type));
163 static PyObject *
164 _wrap_g_type_wrapper__get_children(PyGTypeWrapper *self, void *closure)
166 guint n_children, i;
167 GType *children;
168 PyObject *retval;
170 children = g_type_children(self->type, &n_children);
172 retval = PyList_New(n_children);
173 for (i = 0; i < n_children; i++)
174 PyList_SetItem(retval, i, pyg_type_wrapper_new(children[i]));
175 g_free(children);
177 return retval;
180 static PyObject *
181 _wrap_g_type_wrapper__get_interfaces(PyGTypeWrapper *self, void *closure)
183 guint n_interfaces, i;
184 GType *interfaces;
185 PyObject *retval;
187 interfaces = g_type_interfaces(self->type, &n_interfaces);
189 retval = PyList_New(n_interfaces);
190 for (i = 0; i < n_interfaces; i++)
191 PyList_SetItem(retval, i, pyg_type_wrapper_new(interfaces[i]));
192 g_free(interfaces);
194 return retval;
197 static PyObject *
198 _wrap_g_type_wrapper__get_depth(PyGTypeWrapper *self, void *closure)
200 return PYGLIB_PyLong_FromLong(g_type_depth(self->type));
203 static PyGetSetDef _PyGTypeWrapper_getsets[] = {
204 { "pytype", (getter)_wrap_g_type_wrapper__get_pytype, (setter)_wrap_g_type_wrapper__set_pytype },
205 { "name", (getter)_wrap_g_type_wrapper__get_name, (setter)0 },
206 { "fundamental", (getter)_wrap_g_type_wrapper__get_fundamental, (setter)0 },
207 { "parent", (getter)_wrap_g_type_wrapper__get_parent, (setter)0 },
208 { "children", (getter)_wrap_g_type_wrapper__get_children, (setter)0 },
209 { "interfaces", (getter)_wrap_g_type_wrapper__get_interfaces, (setter)0 },
210 { "depth", (getter)_wrap_g_type_wrapper__get_depth, (setter)0 },
211 { NULL, (getter)0, (setter)0 }
214 static PyObject*
215 _wrap_g_type_is_interface(PyGTypeWrapper *self)
217 return PyBool_FromLong(G_TYPE_IS_INTERFACE(self->type));
220 static PyObject*
221 _wrap_g_type_is_classed(PyGTypeWrapper *self)
223 return PyBool_FromLong(G_TYPE_IS_CLASSED(self->type));
226 static PyObject*
227 _wrap_g_type_is_instantiatable(PyGTypeWrapper *self)
229 return PyBool_FromLong(G_TYPE_IS_INSTANTIATABLE(self->type));
232 static PyObject*
233 _wrap_g_type_is_derivable(PyGTypeWrapper *self)
235 return PyBool_FromLong(G_TYPE_IS_DERIVABLE(self->type));
238 static PyObject*
239 _wrap_g_type_is_deep_derivable(PyGTypeWrapper *self)
241 return PyBool_FromLong(G_TYPE_IS_DEEP_DERIVABLE(self->type));
244 static PyObject*
245 _wrap_g_type_is_abstract(PyGTypeWrapper *self)
247 return PyBool_FromLong(G_TYPE_IS_ABSTRACT(self->type));
250 static PyObject*
251 _wrap_g_type_is_value_abstract(PyGTypeWrapper *self)
253 return PyBool_FromLong(G_TYPE_IS_VALUE_ABSTRACT(self->type));
256 static PyObject*
257 _wrap_g_type_is_value_type(PyGTypeWrapper *self)
259 return PyBool_FromLong(G_TYPE_IS_VALUE_TYPE(self->type));
262 static PyObject*
263 _wrap_g_type_has_value_table(PyGTypeWrapper *self)
265 return PyBool_FromLong(G_TYPE_HAS_VALUE_TABLE(self->type));
268 static PyObject*
269 _wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args)
271 char *type_name;
272 GType type;
274 if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name))
275 return NULL;
277 type = g_type_from_name(type_name);
278 if (type == 0) {
279 PyErr_SetString(PyExc_RuntimeError, "unknown type name");
280 return NULL;
283 return pyg_type_wrapper_new(type);
286 static PyObject*
287 _wrap_g_type_is_a(PyGTypeWrapper *self, PyObject *args)
289 PyObject *gparent;
290 GType parent;
292 if (!PyArg_ParseTuple(args, "O:GType.is_a", &gparent))
293 return NULL;
294 else if ((parent = pyg_type_from_object(gparent)) == 0)
295 return NULL;
297 return PyBool_FromLong(g_type_is_a(self->type, parent));
300 static PyMethodDef _PyGTypeWrapper_methods[] = {
301 { "is_interface", (PyCFunction)_wrap_g_type_is_interface, METH_NOARGS },
302 { "is_classed", (PyCFunction)_wrap_g_type_is_classed, METH_NOARGS },
303 { "is_instantiatable", (PyCFunction)_wrap_g_type_is_instantiatable, METH_NOARGS },
304 { "is_derivable", (PyCFunction)_wrap_g_type_is_derivable, METH_NOARGS },
305 { "is_deep_derivable", (PyCFunction)_wrap_g_type_is_deep_derivable, METH_NOARGS },
306 { "is_abstract", (PyCFunction)_wrap_g_type_is_abstract, METH_NOARGS },
307 { "is_value_abstract", (PyCFunction)_wrap_g_type_is_value_abstract, METH_NOARGS },
308 { "is_value_type", (PyCFunction)_wrap_g_type_is_value_type, METH_NOARGS },
309 { "has_value_table", (PyCFunction)_wrap_g_type_has_value_table, METH_NOARGS },
310 { "from_name", (PyCFunction)_wrap_g_type_from_name, METH_VARARGS | METH_STATIC },
311 { "is_a", (PyCFunction)_wrap_g_type_is_a, METH_VARARGS },
312 { NULL, 0, 0 }
315 static int
316 pyg_type_wrapper_init(PyGTypeWrapper *self, PyObject *args, PyObject *kwargs)
318 static char *kwlist[] = { "object", NULL };
319 PyObject *py_object;
320 GType type;
322 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
323 "O:GType.__init__",
324 kwlist, &py_object))
325 return -1;
327 if (!(type = pyg_type_from_object(py_object)))
328 return -1;
330 self->type = type;
332 return 0;
336 * pyg_type_wrapper_new:
337 * type: a GType
339 * Creates a Python wrapper for a GType.
341 * Returns: the Python wrapper.
343 PyObject *
344 pyg_type_wrapper_new(GType type)
346 PyGTypeWrapper *self;
348 self = (PyGTypeWrapper *)PyObject_NEW(PyGTypeWrapper,
349 &PyGTypeWrapper_Type);
350 if (self == NULL)
351 return NULL;
353 self->type = type;
354 return (PyObject *)self;
358 * pyg_type_from_object_strict:
359 * obj: a Python object
360 * strict: if set to TRUE, raises an exception if it can't perform the
361 * conversion
363 * converts a python object to a GType. If strict is set, raises an
364 * exception if it can't perform the conversion, otherwise returns
365 * PY_TYPE_OBJECT.
367 * Returns: the corresponding GType, or 0 on error.
370 GType
371 pyg_type_from_object_strict(PyObject *obj, gboolean strict)
373 PyObject *gtype;
374 GType type;
376 /* NULL check */
377 if (!obj) {
378 PyErr_SetString(PyExc_TypeError, "can't get type from NULL object");
379 return 0;
382 /* map some standard types to primitive GTypes ... */
383 if (obj == Py_None)
384 return G_TYPE_NONE;
385 if (PyType_Check(obj)) {
386 PyTypeObject *tp = (PyTypeObject *)obj;
388 if (tp == &PYGLIB_PyLong_Type)
389 return G_TYPE_INT;
390 else if (tp == &PyBool_Type)
391 return G_TYPE_BOOLEAN;
392 else if (tp == &PyLong_Type)
393 return G_TYPE_LONG;
394 else if (tp == &PyFloat_Type)
395 return G_TYPE_DOUBLE;
396 else if (tp == &PYGLIB_PyUnicode_Type)
397 return G_TYPE_STRING;
398 else if (tp == &PyBaseObject_Type)
399 return PY_TYPE_OBJECT;
402 if (Py_TYPE(obj) == &PyGTypeWrapper_Type) {
403 return ((PyGTypeWrapper *)obj)->type;
406 /* handle strings */
407 if (PYGLIB_PyUnicode_Check(obj)) {
408 gchar *name = PYGLIB_PyUnicode_AsString(obj);
410 type = g_type_from_name(name);
411 if (type != 0) {
412 return type;
416 /* finally, look for a __gtype__ attribute on the object */
417 gtype = PyObject_GetAttrString(obj, "__gtype__");
419 if (gtype) {
420 if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) {
421 type = ((PyGTypeWrapper *)gtype)->type;
422 Py_DECREF(gtype);
423 return type;
425 Py_DECREF(gtype);
428 PyErr_Clear();
430 /* Some API like those that take GValues can hold a python object as
431 * a pointer. This is potentially dangerous becuase everything is
432 * passed in as a PyObject so we can't actually type check it. Only
433 * fallback to PY_TYPE_OBJECT if strict checking is disabled
435 if (!strict)
436 return PY_TYPE_OBJECT;
438 PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
439 return 0;
443 * pyg_type_from_object:
444 * obj: a Python object
446 * converts a python object to a GType. Raises an exception if it
447 * can't perform the conversion.
449 * Returns: the corresponding GType, or 0 on error.
451 GType
452 pyg_type_from_object(PyObject *obj)
454 /* Legacy call always defaults to strict type checking */
455 return pyg_type_from_object_strict(obj, TRUE);
459 * pyg_enum_get_value:
460 * @enum_type: the GType of the flag.
461 * @obj: a Python object representing the flag value
462 * @val: a pointer to the location to store the integer representation of the flag.
464 * Converts a Python object to the integer equivalent. The conversion
465 * will depend on the type of the Python object. If the object is an
466 * integer, it is passed through directly. If it is a string, it will
467 * be treated as a full or short enum name as defined in the GType.
469 * Returns: 0 on success or -1 on failure
471 gint
472 pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val)
474 GEnumClass *eclass = NULL;
475 gint res = -1;
477 g_return_val_if_fail(val != NULL, -1);
478 if (!obj) {
479 *val = 0;
480 res = 0;
481 } else if (PYGLIB_PyLong_Check(obj)) {
482 *val = PYGLIB_PyLong_AsLong(obj);
483 res = 0;
485 if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
486 g_warning("expected enumeration type %s, but got %s instead",
487 g_type_name(enum_type),
488 g_type_name(((PyGEnum *) obj)->gtype));
490 /* Dumb code duplication, but probably not worth it to have yet another macro. */
491 } else if (PyLong_Check(obj)) {
492 *val = PyLong_AsLong(obj);
493 res = 0;
495 if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
496 g_warning("expected enumeration type %s, but got %s instead",
497 g_type_name(enum_type),
498 g_type_name(((PyGEnum *) obj)->gtype));
500 } else if (PYGLIB_PyUnicode_Check(obj)) {
501 GEnumValue *info;
502 char *str = PYGLIB_PyUnicode_AsString(obj);
504 if (enum_type != G_TYPE_NONE)
505 eclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
506 else {
507 PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value");
508 res = -1;
510 info = g_enum_get_value_by_name(eclass, str);
511 g_type_class_unref(eclass);
513 if (!info)
514 info = g_enum_get_value_by_nick(eclass, str);
515 if (info) {
516 *val = info->value;
517 res = 0;
518 } else {
519 PyErr_SetString(PyExc_TypeError, "could not convert string");
520 res = -1;
522 } else {
523 PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints");
524 res = -1;
526 return res;
530 * pyg_flags_get_value:
531 * @flag_type: the GType of the flag.
532 * @obj: a Python object representing the flag value
533 * @val: a pointer to the location to store the integer representation of the flag.
535 * Converts a Python object to the integer equivalent. The conversion
536 * will depend on the type of the Python object. If the object is an
537 * integer, it is passed through directly. If it is a string, it will
538 * be treated as a full or short flag name as defined in the GType.
539 * If it is a tuple, then the items are treated as strings and ORed
540 * together.
542 * Returns: 0 on success or -1 on failure
544 gint
545 pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val)
547 GFlagsClass *fclass = NULL;
548 gint res = -1;
550 g_return_val_if_fail(val != NULL, -1);
551 if (!obj) {
552 *val = 0;
553 res = 0;
554 } else if (PYGLIB_PyLong_Check(obj)) {
555 *val = PYGLIB_PyLong_AsUnsignedLong(obj);
556 res = 0;
557 } else if (PyLong_Check(obj)) {
558 *val = PyLong_AsLongLong(obj);
559 res = 0;
560 } else if (PYGLIB_PyUnicode_Check(obj)) {
561 GFlagsValue *info;
562 char *str = PYGLIB_PyUnicode_AsString(obj);
564 if (flag_type != G_TYPE_NONE)
565 fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
566 else {
567 PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
568 res = -1;
570 info = g_flags_get_value_by_name(fclass, str);
571 g_type_class_unref(fclass);
573 if (!info)
574 info = g_flags_get_value_by_nick(fclass, str);
575 if (info) {
576 *val = info->value;
577 res = 0;
578 } else {
579 PyErr_SetString(PyExc_TypeError, "could not convert string");
580 res = -1;
582 } else if (PyTuple_Check(obj)) {
583 int i, len;
585 len = PyTuple_Size(obj);
586 *val = 0;
587 res = 0;
589 if (flag_type != G_TYPE_NONE)
590 fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
591 else {
592 PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
593 res = -1;
596 for (i = 0; i < len; i++) {
597 PyObject *item = PyTuple_GetItem(obj, i);
598 char *str = PYGLIB_PyUnicode_AsString(item);
599 GFlagsValue *info = g_flags_get_value_by_name(fclass, str);
601 if (!info)
602 info = g_flags_get_value_by_nick(fclass, str);
603 if (info) {
604 *val |= info->value;
605 } else {
606 PyErr_SetString(PyExc_TypeError, "could not convert string");
607 res = -1;
608 break;
611 g_type_class_unref(fclass);
612 } else {
613 PyErr_SetString(PyExc_TypeError,
614 "flag values must be strings, ints, longs, or tuples");
615 res = -1;
617 return res;
620 static GQuark pyg_type_marshal_key = 0;
622 PyGTypeMarshal *
623 pyg_type_lookup(GType type)
625 GType ptype = type;
626 PyGTypeMarshal *tm = NULL;
628 /* recursively lookup types */
629 while (ptype) {
630 pygi_type_import_by_g_type (ptype);
631 if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
632 break;
633 ptype = g_type_parent(ptype);
635 return tm;
639 * pyg_register_gtype_custom:
640 * @gtype: the GType for the new type
641 * @from_func: a function to convert GValues to Python objects
642 * @to_func: a function to convert Python objects to GValues
644 * In order to handle specific conversion of gboxed types or new
645 * fundamental types, you may use this function to register conversion
646 * handlers.
649 void
650 pyg_register_gtype_custom(GType gtype,
651 fromvaluefunc from_func,
652 tovaluefunc to_func)
654 PyGTypeMarshal *tm;
656 if (!pyg_type_marshal_key)
657 pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
659 tm = g_new(PyGTypeMarshal, 1);
660 tm->fromvalue = from_func;
661 tm->tovalue = to_func;
662 g_type_set_qdata(gtype, pyg_type_marshal_key, tm);
665 /* -------------- PyGClosure ----------------- */
667 static void
668 pyg_closure_invalidate(gpointer data, GClosure *closure)
670 PyGClosure *pc = (PyGClosure *)closure;
671 PyGILState_STATE state;
673 state = PyGILState_Ensure();
674 Py_XDECREF(pc->callback);
675 Py_XDECREF(pc->extra_args);
676 Py_XDECREF(pc->swap_data);
677 PyGILState_Release(state);
679 pc->callback = NULL;
680 pc->extra_args = NULL;
681 pc->swap_data = NULL;
684 static void
685 pyg_closure_marshal(GClosure *closure,
686 GValue *return_value,
687 guint n_param_values,
688 const GValue *param_values,
689 gpointer invocation_hint,
690 gpointer marshal_data)
692 PyGILState_STATE state;
693 PyGClosure *pc = (PyGClosure *)closure;
694 PyObject *params, *ret;
695 guint i;
697 state = PyGILState_Ensure();
699 /* construct Python tuple for the parameter values */
700 params = PyTuple_New(n_param_values);
701 for (i = 0; i < n_param_values; i++) {
702 /* swap in a different initial data for connect_object() */
703 if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) {
704 g_return_if_fail(pc->swap_data != NULL);
705 Py_INCREF(pc->swap_data);
706 PyTuple_SetItem(params, 0, pc->swap_data);
707 } else {
708 PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
710 /* error condition */
711 if (!item) {
712 if (!PyErr_Occurred ())
713 PyErr_SetString (PyExc_TypeError,
714 "can't convert parameter to desired type");
716 if (pc->exception_handler)
717 pc->exception_handler (return_value, n_param_values, param_values);
718 else
719 PyErr_Print();
721 goto out;
723 PyTuple_SetItem(params, i, item);
726 /* params passed to function may have extra arguments */
727 if (pc->extra_args) {
728 PyObject *tuple = params;
729 params = PySequence_Concat(tuple, pc->extra_args);
730 Py_DECREF(tuple);
732 ret = PyObject_CallObject(pc->callback, params);
733 if (ret == NULL) {
734 if (pc->exception_handler)
735 pc->exception_handler(return_value, n_param_values, param_values);
736 else
737 PyErr_Print();
738 goto out;
741 if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) {
742 /* If we already have an exception set, use that, otherwise set a
743 * generic one */
744 if (!PyErr_Occurred())
745 PyErr_SetString(PyExc_TypeError,
746 "can't convert return value to desired type");
748 if (pc->exception_handler)
749 pc->exception_handler(return_value, n_param_values, param_values);
750 else
751 PyErr_Print();
753 Py_DECREF(ret);
755 out:
756 Py_DECREF(params);
757 PyGILState_Release(state);
761 * pyg_closure_new:
762 * callback: a Python callable object
763 * extra_args: a tuple of extra arguments, or None/NULL.
764 * swap_data: an alternative python object to pass first.
766 * Creates a GClosure wrapping a Python callable and optionally a set
767 * of additional function arguments. This is needed to attach python
768 * handlers to signals, for instance.
770 * Returns: the new closure.
772 GClosure *
773 pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data)
775 GClosure *closure;
777 g_return_val_if_fail(callback != NULL, NULL);
778 closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
779 g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate);
780 g_closure_set_marshal(closure, pyg_closure_marshal);
781 Py_INCREF(callback);
782 ((PyGClosure *)closure)->callback = callback;
783 if (extra_args && extra_args != Py_None) {
784 Py_INCREF(extra_args);
785 if (!PyTuple_Check(extra_args)) {
786 PyObject *tmp = PyTuple_New(1);
787 PyTuple_SetItem(tmp, 0, extra_args);
788 extra_args = tmp;
790 ((PyGClosure *)closure)->extra_args = extra_args;
792 if (swap_data) {
793 Py_INCREF(swap_data);
794 ((PyGClosure *)closure)->swap_data = swap_data;
795 closure->derivative_flag = TRUE;
797 return closure;
801 * pyg_closure_set_exception_handler:
802 * @closure: a closure created with pyg_closure_new()
803 * @handler: the handler to call when an exception occurs or NULL for none
805 * Sets the handler to call when an exception occurs during closure invocation.
806 * The handler is responsible for providing a proper return value to the
807 * closure invocation. If @handler is %NULL, the default handler will be used.
808 * The default handler prints the exception to stderr and doesn't touch the
809 * closure's return value.
811 void
812 pyg_closure_set_exception_handler(GClosure *closure,
813 PyClosureExceptionHandler handler)
815 PyGClosure *pygclosure;
817 g_return_if_fail(closure != NULL);
819 pygclosure = (PyGClosure *)closure;
820 pygclosure->exception_handler = handler;
822 /* -------------- PySignalClassClosure ----------------- */
823 /* a closure used for the `class closure' of a signal. As this gets
824 * all the info from the first argument to the closure and the
825 * invocation hint, we can have a single closure that handles all
826 * class closure cases. We call a method by the name of the signal
827 * with "do_" prepended.
829 * We also remove the first argument from the * param list, as it is
830 * the instance object, which is passed * implicitly to the method
831 * object. */
833 static void
834 pyg_signal_class_closure_marshal(GClosure *closure,
835 GValue *return_value,
836 guint n_param_values,
837 const GValue *param_values,
838 gpointer invocation_hint,
839 gpointer marshal_data)
841 PyGILState_STATE state;
842 GObject *object;
843 PyObject *object_wrapper;
844 GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint;
845 gchar *method_name, *tmp;
846 PyObject *method;
847 PyObject *params, *ret;
848 guint i, len;
850 state = PyGILState_Ensure();
852 g_return_if_fail(invocation_hint != NULL);
853 /* get the object passed as the first argument to the closure */
854 object = g_value_get_object(&param_values[0]);
855 g_return_if_fail(object != NULL && G_IS_OBJECT(object));
857 /* get the wrapper for this object */
858 object_wrapper = pygobject_new(object);
859 g_return_if_fail(object_wrapper != NULL);
861 /* construct method name for this class closure */
862 method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL);
864 /* convert dashes to underscores. For some reason, g_signal_name
865 * seems to convert all the underscores in the signal name to
866 dashes??? */
867 for (tmp = method_name; *tmp != '\0'; tmp++)
868 if (*tmp == '-') *tmp = '_';
870 method = PyObject_GetAttrString(object_wrapper, method_name);
871 g_free(method_name);
873 if (!method) {
874 PyErr_Clear();
875 Py_DECREF(object_wrapper);
876 PyGILState_Release(state);
877 return;
879 Py_DECREF(object_wrapper);
881 /* construct Python tuple for the parameter values; don't copy boxed values
882 initially because we'll check after the call to see if a copy is needed. */
883 params = PyTuple_New(n_param_values - 1);
884 for (i = 1; i < n_param_values; i++) {
885 PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
887 /* error condition */
888 if (!item) {
889 Py_DECREF(params);
890 PyGILState_Release(state);
891 return;
893 PyTuple_SetItem(params, i - 1, item);
896 ret = PyObject_CallObject(method, params);
898 /* Copy boxed values if others ref them, this needs to be done regardless of
899 exception status. */
900 len = PyTuple_Size(params);
901 for (i = 0; i < len; i++) {
902 PyObject *item = PyTuple_GetItem(params, i);
903 if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type)
904 && item->ob_refcnt != 1) {
905 PyGBoxed* boxed_item = (PyGBoxed*)item;
906 if (!boxed_item->free_on_dealloc) {
907 gpointer boxed_ptr = pyg_boxed_get_ptr (boxed_item);
908 pyg_boxed_set_ptr (boxed_item, g_boxed_copy (boxed_item->gtype, boxed_ptr));
909 boxed_item->free_on_dealloc = TRUE;
914 if (ret == NULL) {
915 PyErr_Print();
916 Py_DECREF(method);
917 Py_DECREF(params);
918 PyGILState_Release(state);
919 return;
921 Py_DECREF(method);
922 Py_DECREF(params);
923 if (G_IS_VALUE(return_value))
924 pyg_value_from_pyobject(return_value, ret);
925 Py_DECREF(ret);
926 PyGILState_Release(state);
930 * pyg_signal_class_closure_get:
932 * Returns the GClosure used for the class closure of signals. When
933 * called, it will invoke the method do_signalname (for the signal
934 * "signalname").
936 * Returns: the closure.
938 GClosure *
939 pyg_signal_class_closure_get(void)
941 static GClosure *closure;
943 if (closure == NULL) {
944 closure = g_closure_new_simple(sizeof(GClosure), NULL);
945 g_closure_set_marshal(closure, pyg_signal_class_closure_marshal);
947 g_closure_ref(closure);
948 g_closure_sink(closure);
950 return closure;
953 /* ----- __doc__ descriptor for GObject and GInterface ----- */
955 static void
956 object_doc_dealloc(PyObject *self)
958 PyObject_FREE(self);
961 /* append information about signals of a particular gtype */
962 static void
963 add_signal_docs(GType gtype, GString *string)
965 GTypeClass *class = NULL;
966 guint *signal_ids, n_ids = 0, i;
968 if (G_TYPE_IS_CLASSED(gtype))
969 class = g_type_class_ref(gtype);
970 signal_ids = g_signal_list_ids(gtype, &n_ids);
972 if (n_ids > 0) {
973 g_string_append_printf(string, "Signals from %s:\n",
974 g_type_name(gtype));
976 for (i = 0; i < n_ids; i++) {
977 GSignalQuery query;
978 guint j;
980 g_signal_query(signal_ids[i], &query);
982 g_string_append(string, " ");
983 g_string_append(string, query.signal_name);
984 g_string_append(string, " (");
985 for (j = 0; j < query.n_params; j++) {
986 g_string_append(string, g_type_name(query.param_types[j]));
987 if (j != query.n_params - 1)
988 g_string_append(string, ", ");
990 g_string_append(string, ")");
991 if (query.return_type && query.return_type != G_TYPE_NONE) {
992 g_string_append(string, " -> ");
993 g_string_append(string, g_type_name(query.return_type));
995 g_string_append(string, "\n");
997 g_free(signal_ids);
998 g_string_append(string, "\n");
1000 if (class)
1001 g_type_class_unref(class);
1004 static void
1005 add_property_docs(GType gtype, GString *string)
1007 GObjectClass *class;
1008 GParamSpec **props;
1009 guint n_props = 0, i;
1010 gboolean has_prop = FALSE;
1011 G_CONST_RETURN gchar *blurb=NULL;
1013 class = g_type_class_ref(gtype);
1014 props = g_object_class_list_properties(class, &n_props);
1016 for (i = 0; i < n_props; i++) {
1017 if (props[i]->owner_type != gtype)
1018 continue; /* these are from a parent type */
1020 /* print out the heading first */
1021 if (!has_prop) {
1022 g_string_append_printf(string, "Properties from %s:\n",
1023 g_type_name(gtype));
1024 has_prop = TRUE;
1026 g_string_append_printf(string, " %s -> %s: %s\n",
1027 g_param_spec_get_name(props[i]),
1028 g_type_name(props[i]->value_type),
1029 g_param_spec_get_nick(props[i]));
1031 /* g_string_append_printf crashes on win32 if the third
1032 argument is NULL. */
1033 blurb=g_param_spec_get_blurb(props[i]);
1034 if (blurb)
1035 g_string_append_printf(string, " %s\n",blurb);
1037 g_free(props);
1038 if (has_prop)
1039 g_string_append(string, "\n");
1040 g_type_class_unref(class);
1043 static PyObject *
1044 object_doc_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1046 GType gtype = 0;
1047 GString *string;
1048 PyObject *pystring;
1050 if (obj && pygobject_check(obj, &PyGObject_Type)) {
1051 gtype = G_OBJECT_TYPE(pygobject_get(obj));
1052 if (!gtype)
1053 PyErr_SetString(PyExc_RuntimeError, "could not get object type");
1054 } else {
1055 gtype = pyg_type_from_object(type);
1057 if (!gtype)
1058 return NULL;
1060 string = g_string_new_len(NULL, 512);
1062 if (g_type_is_a(gtype, G_TYPE_INTERFACE))
1063 g_string_append_printf(string, "Interface %s\n\n", g_type_name(gtype));
1064 else if (g_type_is_a(gtype, G_TYPE_OBJECT))
1065 g_string_append_printf(string, "Object %s\n\n", g_type_name(gtype));
1066 else
1067 g_string_append_printf(string, "%s\n\n", g_type_name(gtype));
1069 if (((PyTypeObject *) type)->tp_doc)
1070 g_string_append_printf(string, "%s\n\n", ((PyTypeObject *) type)->tp_doc);
1072 if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
1073 GType parent = G_TYPE_OBJECT;
1074 GArray *parents = g_array_new(FALSE, FALSE, sizeof(GType));
1075 int iparent;
1077 while (parent) {
1078 g_array_append_val(parents, parent);
1079 parent = g_type_next_base(gtype, parent);
1082 for (iparent = parents->len - 1; iparent >= 0; --iparent) {
1083 GType *interfaces;
1084 guint n_interfaces, i;
1086 parent = g_array_index(parents, GType, iparent);
1087 add_signal_docs(parent, string);
1088 add_property_docs(parent, string);
1090 /* add docs for implemented interfaces */
1091 interfaces = g_type_interfaces(parent, &n_interfaces);
1092 for (i = 0; i < n_interfaces; i++)
1093 add_signal_docs(interfaces[i], string);
1094 g_free(interfaces);
1096 g_array_free(parents, TRUE);
1099 pystring = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len);
1100 g_string_free(string, TRUE);
1101 return pystring;
1104 PYGLIB_DEFINE_TYPE("gobject.GObject.__doc__", PyGObjectDoc_Type, PyObject);
1107 * pyg_object_descr_doc_get:
1109 * Returns an object intended to be the __doc__ attribute of GObject
1110 * wrappers. When read in the context of the object it will return
1111 * some documentation about the signals and properties of the object.
1113 * Returns: the descriptor.
1115 PyObject *
1116 pyg_object_descr_doc_get(void)
1118 static PyObject *doc_descr = NULL;
1120 if (!doc_descr) {
1121 Py_TYPE(&PyGObjectDoc_Type) = &PyType_Type;
1122 if (PyType_Ready(&PyGObjectDoc_Type))
1123 return NULL;
1125 doc_descr = PyObject_NEW(PyObject, &PyGObjectDoc_Type);
1126 if (doc_descr == NULL)
1127 return NULL;
1129 return doc_descr;
1134 * pyg_pyobj_to_unichar_conv:
1136 * Converts PyObject value to a unichar and write result to memory
1137 * pointed to by ptr. Follows the calling convention of a ParseArgs
1138 * converter (O& format specifier) so it may be used to convert function
1139 * arguments.
1141 * Returns: 1 if the conversion succeeds and 0 otherwise. If the conversion
1142 * did not succeesd, a Python exception is raised
1144 int pyg_pyobj_to_unichar_conv(PyObject* py_obj, void* ptr)
1146 gunichar* u = ptr;
1147 const Py_UNICODE* uni_buffer;
1148 PyObject* tmp_uni = NULL;
1150 if (PyUnicode_Check(py_obj)) {
1151 tmp_uni = py_obj;
1152 Py_INCREF(tmp_uni);
1154 else {
1155 tmp_uni = PyUnicode_FromObject(py_obj);
1156 if (tmp_uni == NULL)
1157 goto failure;
1160 if ( PyUnicode_GetSize(tmp_uni) != 1) {
1161 PyErr_SetString(PyExc_ValueError, "unicode character value must be 1 character uniode string");
1162 goto failure;
1164 uni_buffer = PyUnicode_AsUnicode(tmp_uni);
1165 if ( uni_buffer == NULL)
1166 goto failure;
1167 *u = uni_buffer[0];
1169 Py_DECREF(tmp_uni);
1170 return 1;
1172 failure:
1173 Py_XDECREF(tmp_uni);
1174 return 0;
1177 gboolean
1178 pyg_gtype_is_custom(GType gtype)
1180 return g_type_get_qdata (gtype, pygobject_custom_key) != NULL;
1183 void
1184 pygobject_type_register_types(PyObject *d)
1186 PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc;
1187 PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare;
1188 PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr;
1189 PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash;
1190 PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1191 PyGTypeWrapper_Type.tp_methods = _PyGTypeWrapper_methods;
1192 PyGTypeWrapper_Type.tp_getset = _PyGTypeWrapper_getsets;
1193 PyGTypeWrapper_Type.tp_init = (initproc)pyg_type_wrapper_init;
1194 PYGLIB_REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType");
1196 /* This type lazily registered in pyg_object_descr_doc_get */
1197 PyGObjectDoc_Type.tp_dealloc = (destructor)object_doc_dealloc;
1198 PyGObjectDoc_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1199 PyGObjectDoc_Type.tp_descr_get = (descrgetfunc)object_doc_descr_get;
1201 pyg_register_gtype_custom(G_TYPE_STRV,
1202 pyg_strv_from_gvalue,
1203 pyg_strv_to_gvalue);