tests: don't test for specific device labels
[pygobject.git] / gi / pygi-type.c
blob3ca0fc826b3be309cc36a8f79cbc12da765ca184
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygtk- Python bindings for the GTK toolkit.
3 * Copyright (C) 1998-2003 James Henstridge
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include <config.h>
21 #include "pygobject-object.h"
22 #include "pygboxed.h"
23 #include "pygenum.h"
24 #include "pygflags.h"
25 #include "pygparamspec.h"
26 #include "pygi-util.h"
27 #include "pygpointer.h"
28 #include "pyginterface.h"
30 #include "pygi-type.h"
31 #include "pygi-value.h"
32 #include "pygi-basictype.h"
34 PyObject *
35 pygi_type_import_by_name (const char *namespace_,
36 const char *name)
38 gchar *module_name;
39 PyObject *py_module;
40 PyObject *py_object;
42 module_name = g_strconcat ("gi.repository.", namespace_, NULL);
44 py_module = pygi_import_module (module_name);
46 g_free (module_name);
48 if (py_module == NULL) {
49 return NULL;
52 py_object = PyObject_GetAttrString (py_module, name);
54 Py_DECREF (py_module);
56 return py_object;
59 PyObject *
60 pygi_type_import_by_g_type (GType g_type)
62 GIRepository *repository;
63 GIBaseInfo *info;
64 PyObject *type;
66 repository = g_irepository_get_default();
68 info = g_irepository_find_by_gtype (repository, g_type);
69 if (info == NULL) {
70 return NULL;
73 type = pygi_type_import_by_gi_info (info);
74 g_base_info_unref (info);
76 return type;
79 PyObject *
80 pygi_type_import_by_gi_info (GIBaseInfo *info)
82 return pygi_type_import_by_name (g_base_info_get_namespace (info),
83 g_base_info_get_name (info));
86 PyObject *
87 pygi_type_get_from_g_type (GType g_type)
89 PyObject *py_g_type;
90 PyObject *py_type;
92 py_g_type = pyg_type_wrapper_new (g_type);
93 if (py_g_type == NULL) {
94 return NULL;
97 py_type = PyObject_GetAttrString (py_g_type, "pytype");
98 if (py_type == Py_None) {
99 py_type = pygi_type_import_by_g_type (g_type);
102 Py_DECREF (py_g_type);
104 return py_type;
107 /* -------------- __gtype__ objects ---------------------------- */
109 typedef struct {
110 PyObject_HEAD
111 GType type;
112 } PyGTypeWrapper;
114 PYGLIB_DEFINE_TYPE("gobject.GType", PyGTypeWrapper_Type, PyGTypeWrapper);
116 static PyObject*
117 generic_gsize_richcompare(gsize a, gsize b, int op)
119 PyObject *res;
121 switch (op) {
123 case Py_EQ:
124 res = (a == b) ? Py_True : Py_False;
125 Py_INCREF(res);
126 break;
128 case Py_NE:
129 res = (a != b) ? Py_True : Py_False;
130 Py_INCREF(res);
131 break;
134 case Py_LT:
135 res = (a < b) ? Py_True : Py_False;
136 Py_INCREF(res);
137 break;
139 case Py_LE:
140 res = (a <= b) ? Py_True : Py_False;
141 Py_INCREF(res);
142 break;
144 case Py_GT:
145 res = (a > b) ? Py_True : Py_False;
146 Py_INCREF(res);
147 break;
149 case Py_GE:
150 res = (a >= b) ? Py_True : Py_False;
151 Py_INCREF(res);
152 break;
154 default:
155 res = Py_NotImplemented;
156 Py_INCREF(res);
157 break;
160 return res;
163 static PyObject*
164 pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op)
166 if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type)
167 return generic_gsize_richcompare(((PyGTypeWrapper*)self)->type,
168 ((PyGTypeWrapper*)other)->type,
169 op);
170 else {
171 Py_INCREF(Py_NotImplemented);
172 return Py_NotImplemented;
176 static long
177 pyg_type_wrapper_hash(PyGTypeWrapper *self)
179 return (long)self->type;
182 static PyObject *
183 pyg_type_wrapper_repr(PyGTypeWrapper *self)
185 char buf[80];
186 const gchar *name = g_type_name(self->type);
188 g_snprintf(buf, sizeof(buf), "<GType %s (%lu)>",
189 name?name:"invalid", (unsigned long int) self->type);
190 return PYGLIB_PyUnicode_FromString(buf);
193 static void
194 pyg_type_wrapper_dealloc(PyGTypeWrapper *self)
196 PyObject_DEL(self);
199 static GQuark
200 _pyg_type_key(GType type) {
201 GQuark key;
203 if (g_type_is_a(type, G_TYPE_INTERFACE)) {
204 key = pyginterface_type_key;
205 } else if (g_type_is_a(type, G_TYPE_ENUM)) {
206 key = pygenum_class_key;
207 } else if (g_type_is_a(type, G_TYPE_FLAGS)) {
208 key = pygflags_class_key;
209 } else if (g_type_is_a(type, G_TYPE_POINTER)) {
210 key = pygpointer_class_key;
211 } else if (g_type_is_a(type, G_TYPE_BOXED)) {
212 key = pygboxed_type_key;
213 } else {
214 key = pygobject_class_key;
217 return key;
220 static PyObject *
221 _wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure)
223 GQuark key;
224 PyObject *py_type;
226 key = _pyg_type_key(self->type);
228 py_type = g_type_get_qdata(self->type, key);
229 if (!py_type)
230 py_type = Py_None;
232 Py_INCREF(py_type);
233 return py_type;
236 static int
237 _wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure)
239 GQuark key;
240 PyObject *py_type;
242 key = _pyg_type_key(self->type);
244 py_type = g_type_get_qdata(self->type, key);
245 Py_CLEAR(py_type);
246 if (value == Py_None)
247 g_type_set_qdata(self->type, key, NULL);
248 else if (PyType_Check(value)) {
249 Py_INCREF(value);
250 g_type_set_qdata(self->type, key, value);
251 } else {
252 PyErr_SetString(PyExc_TypeError, "Value must be None or a type object");
253 return -1;
256 return 0;
259 static PyObject *
260 _wrap_g_type_wrapper__get_name(PyGTypeWrapper *self, void *closure)
262 const char *name = g_type_name(self->type);
263 return PYGLIB_PyUnicode_FromString(name ? name : "invalid");
266 static PyObject *
267 _wrap_g_type_wrapper__get_parent(PyGTypeWrapper *self, void *closure)
269 return pyg_type_wrapper_new(g_type_parent(self->type));
272 static PyObject *
273 _wrap_g_type_wrapper__get_fundamental(PyGTypeWrapper *self, void *closure)
275 return pyg_type_wrapper_new(g_type_fundamental(self->type));
278 static PyObject *
279 _wrap_g_type_wrapper__get_children(PyGTypeWrapper *self, void *closure)
281 guint n_children, i;
282 GType *children;
283 PyObject *retval;
285 children = g_type_children(self->type, &n_children);
287 retval = PyList_New(n_children);
288 for (i = 0; i < n_children; i++)
289 PyList_SetItem(retval, i, pyg_type_wrapper_new(children[i]));
290 g_free(children);
292 return retval;
295 static PyObject *
296 _wrap_g_type_wrapper__get_interfaces(PyGTypeWrapper *self, void *closure)
298 guint n_interfaces, i;
299 GType *interfaces;
300 PyObject *retval;
302 interfaces = g_type_interfaces(self->type, &n_interfaces);
304 retval = PyList_New(n_interfaces);
305 for (i = 0; i < n_interfaces; i++)
306 PyList_SetItem(retval, i, pyg_type_wrapper_new(interfaces[i]));
307 g_free(interfaces);
309 return retval;
312 static PyObject *
313 _wrap_g_type_wrapper__get_depth(PyGTypeWrapper *self, void *closure)
315 return pygi_guint_to_py (g_type_depth (self->type));
318 static PyGetSetDef _PyGTypeWrapper_getsets[] = {
319 { "pytype", (getter)_wrap_g_type_wrapper__get_pytype, (setter)_wrap_g_type_wrapper__set_pytype },
320 { "name", (getter)_wrap_g_type_wrapper__get_name, (setter)0 },
321 { "fundamental", (getter)_wrap_g_type_wrapper__get_fundamental, (setter)0 },
322 { "parent", (getter)_wrap_g_type_wrapper__get_parent, (setter)0 },
323 { "children", (getter)_wrap_g_type_wrapper__get_children, (setter)0 },
324 { "interfaces", (getter)_wrap_g_type_wrapper__get_interfaces, (setter)0 },
325 { "depth", (getter)_wrap_g_type_wrapper__get_depth, (setter)0 },
326 { NULL, (getter)0, (setter)0 }
329 static PyObject*
330 _wrap_g_type_is_interface(PyGTypeWrapper *self)
332 return pygi_gboolean_to_py (G_TYPE_IS_INTERFACE (self->type));
335 static PyObject*
336 _wrap_g_type_is_classed(PyGTypeWrapper *self)
338 return pygi_gboolean_to_py (G_TYPE_IS_CLASSED (self->type));
341 static PyObject*
342 _wrap_g_type_is_instantiatable(PyGTypeWrapper *self)
344 return pygi_gboolean_to_py (G_TYPE_IS_INSTANTIATABLE(self->type));
347 static PyObject*
348 _wrap_g_type_is_derivable(PyGTypeWrapper *self)
350 return pygi_gboolean_to_py (G_TYPE_IS_DERIVABLE (self->type));
353 static PyObject*
354 _wrap_g_type_is_deep_derivable(PyGTypeWrapper *self)
356 return pygi_gboolean_to_py (G_TYPE_IS_DEEP_DERIVABLE (self->type));
359 static PyObject*
360 _wrap_g_type_is_abstract(PyGTypeWrapper *self)
362 return pygi_gboolean_to_py (G_TYPE_IS_ABSTRACT (self->type));
365 static PyObject*
366 _wrap_g_type_is_value_abstract(PyGTypeWrapper *self)
368 return pygi_gboolean_to_py (G_TYPE_IS_VALUE_ABSTRACT (self->type));
371 static PyObject*
372 _wrap_g_type_is_value_type(PyGTypeWrapper *self)
374 return pygi_gboolean_to_py (G_TYPE_IS_VALUE_TYPE (self->type));
377 static PyObject*
378 _wrap_g_type_has_value_table(PyGTypeWrapper *self)
380 return pygi_gboolean_to_py (G_TYPE_HAS_VALUE_TABLE (self->type));
383 static PyObject*
384 _wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args)
386 char *type_name;
387 GType type;
389 if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name))
390 return NULL;
392 type = g_type_from_name(type_name);
393 if (type == 0) {
394 PyErr_SetString(PyExc_RuntimeError, "unknown type name");
395 return NULL;
398 return pyg_type_wrapper_new(type);
401 static PyObject*
402 _wrap_g_type_is_a(PyGTypeWrapper *self, PyObject *args)
404 PyObject *gparent;
405 GType parent;
407 if (!PyArg_ParseTuple(args, "O:GType.is_a", &gparent))
408 return NULL;
409 else if ((parent = pyg_type_from_object(gparent)) == 0)
410 return NULL;
412 return pygi_gboolean_to_py (g_type_is_a (self->type, parent));
415 static PyMethodDef _PyGTypeWrapper_methods[] = {
416 { "is_interface", (PyCFunction)_wrap_g_type_is_interface, METH_NOARGS },
417 { "is_classed", (PyCFunction)_wrap_g_type_is_classed, METH_NOARGS },
418 { "is_instantiatable", (PyCFunction)_wrap_g_type_is_instantiatable, METH_NOARGS },
419 { "is_derivable", (PyCFunction)_wrap_g_type_is_derivable, METH_NOARGS },
420 { "is_deep_derivable", (PyCFunction)_wrap_g_type_is_deep_derivable, METH_NOARGS },
421 { "is_abstract", (PyCFunction)_wrap_g_type_is_abstract, METH_NOARGS },
422 { "is_value_abstract", (PyCFunction)_wrap_g_type_is_value_abstract, METH_NOARGS },
423 { "is_value_type", (PyCFunction)_wrap_g_type_is_value_type, METH_NOARGS },
424 { "has_value_table", (PyCFunction)_wrap_g_type_has_value_table, METH_NOARGS },
425 { "from_name", (PyCFunction)_wrap_g_type_from_name, METH_VARARGS | METH_STATIC },
426 { "is_a", (PyCFunction)_wrap_g_type_is_a, METH_VARARGS },
427 { NULL, 0, 0 }
430 static int
431 pyg_type_wrapper_init(PyGTypeWrapper *self, PyObject *args, PyObject *kwargs)
433 static char *kwlist[] = { "object", NULL };
434 PyObject *py_object;
435 GType type;
437 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
438 "O:GType.__init__",
439 kwlist, &py_object))
440 return -1;
442 if (!(type = pyg_type_from_object(py_object)))
443 return -1;
445 self->type = type;
447 return 0;
451 * pyg_type_wrapper_new:
452 * type: a GType
454 * Creates a Python wrapper for a GType.
456 * Returns: the Python wrapper.
458 PyObject *
459 pyg_type_wrapper_new(GType type)
461 PyGTypeWrapper *self;
463 g_assert (Py_TYPE (&PyGTypeWrapper_Type) != NULL);
464 self = (PyGTypeWrapper *)PyObject_NEW(PyGTypeWrapper,
465 &PyGTypeWrapper_Type);
466 if (self == NULL)
467 return NULL;
469 self->type = type;
470 return (PyObject *)self;
474 * pyg_type_from_object_strict:
475 * obj: a Python object
476 * strict: if set to TRUE, raises an exception if it can't perform the
477 * conversion
479 * converts a python object to a GType. If strict is set, raises an
480 * exception if it can't perform the conversion, otherwise returns
481 * PY_TYPE_OBJECT.
483 * Returns: the corresponding GType, or 0 on error.
486 GType
487 pyg_type_from_object_strict(PyObject *obj, gboolean strict)
489 PyObject *gtype;
490 GType type;
492 /* NULL check */
493 if (!obj) {
494 PyErr_SetString(PyExc_TypeError, "can't get type from NULL object");
495 return 0;
498 /* map some standard types to primitive GTypes ... */
499 if (obj == Py_None)
500 return G_TYPE_NONE;
501 if (PyType_Check(obj)) {
502 PyTypeObject *tp = (PyTypeObject *)obj;
504 if (tp == &PYGLIB_PyLong_Type)
505 return G_TYPE_INT;
506 else if (tp == &PyBool_Type)
507 return G_TYPE_BOOLEAN;
508 else if (tp == &PyLong_Type)
509 return G_TYPE_LONG;
510 else if (tp == &PyFloat_Type)
511 return G_TYPE_DOUBLE;
512 else if (tp == &PYGLIB_PyUnicode_Type)
513 return G_TYPE_STRING;
514 else if (tp == &PyBaseObject_Type)
515 return PY_TYPE_OBJECT;
518 if (Py_TYPE(obj) == &PyGTypeWrapper_Type) {
519 return ((PyGTypeWrapper *)obj)->type;
522 /* handle strings */
523 if (PYGLIB_PyUnicode_Check(obj)) {
524 gchar *name = PYGLIB_PyUnicode_AsString(obj);
526 type = g_type_from_name(name);
527 if (type != 0) {
528 return type;
532 /* finally, look for a __gtype__ attribute on the object */
533 gtype = PyObject_GetAttrString(obj, "__gtype__");
535 if (gtype) {
536 if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) {
537 type = ((PyGTypeWrapper *)gtype)->type;
538 Py_DECREF(gtype);
539 return type;
541 Py_DECREF(gtype);
544 PyErr_Clear();
546 /* Some API like those that take GValues can hold a python object as
547 * a pointer. This is potentially dangerous becuase everything is
548 * passed in as a PyObject so we can't actually type check it. Only
549 * fallback to PY_TYPE_OBJECT if strict checking is disabled
551 if (!strict)
552 return PY_TYPE_OBJECT;
554 PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
555 return 0;
559 * pyg_type_from_object:
560 * obj: a Python object
562 * converts a python object to a GType. Raises an exception if it
563 * can't perform the conversion.
565 * Returns: the corresponding GType, or 0 on error.
567 GType
568 pyg_type_from_object(PyObject *obj)
570 /* Legacy call always defaults to strict type checking */
571 return pyg_type_from_object_strict(obj, TRUE);
575 * pyg_enum_get_value:
576 * @enum_type: the GType of the flag.
577 * @obj: a Python object representing the flag value
578 * @val: a pointer to the location to store the integer representation of the flag.
580 * Converts a Python object to the integer equivalent. The conversion
581 * will depend on the type of the Python object. If the object is an
582 * integer, it is passed through directly. If it is a string, it will
583 * be treated as a full or short enum name as defined in the GType.
585 * Returns: 0 on success or -1 on failure
587 gint
588 pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val)
590 GEnumClass *eclass = NULL;
591 gint res = -1;
593 g_return_val_if_fail(val != NULL, -1);
594 if (!obj) {
595 *val = 0;
596 res = 0;
597 } else if (PYGLIB_PyLong_Check(obj)) {
598 if (!pygi_gint_from_py (obj, val))
599 res = -1;
600 else
601 res = 0;
603 if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
604 g_warning("expected enumeration type %s, but got %s instead",
605 g_type_name(enum_type),
606 g_type_name(((PyGEnum *) obj)->gtype));
608 /* Dumb code duplication, but probably not worth it to have yet another macro. */
609 } else if (PyLong_Check(obj)) {
610 if (!pygi_gint_from_py (obj, val))
611 res = -1;
612 else
613 res = 0;
615 if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
616 g_warning("expected enumeration type %s, but got %s instead",
617 g_type_name(enum_type),
618 g_type_name(((PyGEnum *) obj)->gtype));
620 } else if (PYGLIB_PyUnicode_Check(obj)) {
621 GEnumValue *info;
622 char *str = PYGLIB_PyUnicode_AsString(obj);
624 if (enum_type != G_TYPE_NONE)
625 eclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
626 else {
627 PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value");
628 res = -1;
630 info = g_enum_get_value_by_name(eclass, str);
631 g_type_class_unref(eclass);
633 if (!info)
634 info = g_enum_get_value_by_nick(eclass, str);
635 if (info) {
636 *val = info->value;
637 res = 0;
638 } else {
639 PyErr_SetString(PyExc_TypeError, "could not convert string");
640 res = -1;
642 } else {
643 PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints");
644 res = -1;
646 return res;
650 * pyg_flags_get_value:
651 * @flag_type: the GType of the flag.
652 * @obj: a Python object representing the flag value
653 * @val: a pointer to the location to store the integer representation of the flag.
655 * Converts a Python object to the integer equivalent. The conversion
656 * will depend on the type of the Python object. If the object is an
657 * integer, it is passed through directly. If it is a string, it will
658 * be treated as a full or short flag name as defined in the GType.
659 * If it is a tuple, then the items are treated as strings and ORed
660 * together.
662 * Returns: 0 on success or -1 on failure
664 gint
665 pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val)
667 GFlagsClass *fclass = NULL;
668 gint res = -1;
670 g_return_val_if_fail(val != NULL, -1);
671 if (!obj) {
672 *val = 0;
673 res = 0;
674 } else if (PYGLIB_PyLong_Check(obj)) {
675 if (pygi_guint_from_py (obj, val))
676 res = 0;
677 } else if (PyLong_Check(obj)) {
678 if (pygi_guint_from_py (obj, val))
679 res = 0;
680 } else if (PYGLIB_PyUnicode_Check(obj)) {
681 GFlagsValue *info;
682 char *str = PYGLIB_PyUnicode_AsString(obj);
684 if (flag_type != G_TYPE_NONE)
685 fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
686 else {
687 PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
688 res = -1;
690 info = g_flags_get_value_by_name(fclass, str);
691 g_type_class_unref(fclass);
693 if (!info)
694 info = g_flags_get_value_by_nick(fclass, str);
695 if (info) {
696 *val = info->value;
697 res = 0;
698 } else {
699 PyErr_SetString(PyExc_TypeError, "could not convert string");
700 res = -1;
702 } else if (PyTuple_Check(obj)) {
703 Py_ssize_t i, len;
705 len = PyTuple_Size(obj);
706 *val = 0;
707 res = 0;
709 if (flag_type != G_TYPE_NONE)
710 fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
711 else {
712 PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
713 res = -1;
716 for (i = 0; i < len; i++) {
717 PyObject *item = PyTuple_GetItem(obj, i);
718 char *str = PYGLIB_PyUnicode_AsString(item);
719 GFlagsValue *info = g_flags_get_value_by_name(fclass, str);
721 if (!info)
722 info = g_flags_get_value_by_nick(fclass, str);
723 if (info) {
724 *val |= info->value;
725 } else {
726 PyErr_SetString(PyExc_TypeError, "could not convert string");
727 res = -1;
728 break;
731 g_type_class_unref(fclass);
732 } else {
733 PyErr_SetString(PyExc_TypeError,
734 "flag values must be strings, ints, longs, or tuples");
735 res = -1;
737 return res;
740 static GQuark pyg_type_marshal_key = 0;
741 static GQuark pyg_type_marshal_helper_key = 0;
743 typedef enum _marshal_helper_data_e marshal_helper_data_e;
744 enum _marshal_helper_data_e {
745 MARSHAL_HELPER_NONE = 0,
746 MARSHAL_HELPER_RETURN_NULL,
747 MARSHAL_HELPER_IMPORT_DONE,
750 PyGTypeMarshal *
751 pyg_type_lookup(GType type)
753 GType ptype = type;
754 PyGTypeMarshal *tm = NULL;
755 marshal_helper_data_e marshal_helper;
757 if (type == G_TYPE_INVALID)
758 return NULL;
760 marshal_helper = GPOINTER_TO_INT (
761 g_type_get_qdata(type, pyg_type_marshal_helper_key));
763 /* If we called this function before with @type and nothing was found,
764 * return NULL early to not spend time in the loop below */
765 if (marshal_helper == MARSHAL_HELPER_RETURN_NULL)
766 return NULL;
768 /* Otherwise do recursive type lookup */
769 do {
770 if (marshal_helper == MARSHAL_HELPER_IMPORT_DONE)
771 pygi_type_import_by_g_type (ptype);
773 if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
774 break;
775 ptype = g_type_parent(ptype);
776 } while (ptype);
778 if (marshal_helper == MARSHAL_HELPER_NONE) {
779 marshal_helper = (tm == NULL) ?
780 MARSHAL_HELPER_RETURN_NULL:
781 MARSHAL_HELPER_IMPORT_DONE;
782 g_type_set_qdata(type, pyg_type_marshal_helper_key,
783 GINT_TO_POINTER(marshal_helper));
785 return tm;
789 * pyg_register_gtype_custom:
790 * @gtype: the GType for the new type
791 * @from_func: a function to convert GValues to Python objects
792 * @to_func: a function to convert Python objects to GValues
794 * In order to handle specific conversion of gboxed types or new
795 * fundamental types, you may use this function to register conversion
796 * handlers.
799 void
800 pyg_register_gtype_custom(GType gtype,
801 fromvaluefunc from_func,
802 tovaluefunc to_func)
804 PyGTypeMarshal *tm;
806 if (!pyg_type_marshal_key) {
807 pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
808 pyg_type_marshal_helper_key = g_quark_from_static_string("PyGType::marshal-helper");
811 tm = g_new(PyGTypeMarshal, 1);
812 tm->fromvalue = from_func;
813 tm->tovalue = to_func;
814 g_type_set_qdata(gtype, pyg_type_marshal_key, tm);
817 /* -------------- PyGClosure ----------------- */
819 static void
820 pyg_closure_invalidate(gpointer data, GClosure *closure)
822 PyGClosure *pc = (PyGClosure *)closure;
823 PyGILState_STATE state;
825 state = PyGILState_Ensure();
826 Py_XDECREF(pc->callback);
827 Py_XDECREF(pc->extra_args);
828 Py_XDECREF(pc->swap_data);
829 PyGILState_Release(state);
831 pc->callback = NULL;
832 pc->extra_args = NULL;
833 pc->swap_data = NULL;
836 static void
837 pyg_closure_marshal(GClosure *closure,
838 GValue *return_value,
839 guint n_param_values,
840 const GValue *param_values,
841 gpointer invocation_hint,
842 gpointer marshal_data)
844 PyGILState_STATE state;
845 PyGClosure *pc = (PyGClosure *)closure;
846 PyObject *params, *ret;
847 guint i;
849 state = PyGILState_Ensure();
851 /* construct Python tuple for the parameter values */
852 params = PyTuple_New(n_param_values);
853 for (i = 0; i < n_param_values; i++) {
854 /* swap in a different initial data for connect_object() */
855 if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) {
856 g_return_if_fail(pc->swap_data != NULL);
857 Py_INCREF(pc->swap_data);
858 PyTuple_SetItem(params, 0, pc->swap_data);
859 } else {
860 PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
862 /* error condition */
863 if (!item) {
864 if (!PyErr_Occurred ())
865 PyErr_SetString (PyExc_TypeError,
866 "can't convert parameter to desired type");
868 if (pc->exception_handler)
869 pc->exception_handler (return_value, n_param_values, param_values);
870 else
871 PyErr_Print();
873 goto out;
875 PyTuple_SetItem(params, i, item);
878 /* params passed to function may have extra arguments */
879 if (pc->extra_args) {
880 PyObject *tuple = params;
881 params = PySequence_Concat(tuple, pc->extra_args);
882 Py_DECREF(tuple);
884 ret = PyObject_CallObject(pc->callback, params);
885 if (ret == NULL) {
886 if (pc->exception_handler)
887 pc->exception_handler(return_value, n_param_values, param_values);
888 else
889 PyErr_Print();
890 goto out;
893 if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) {
894 /* If we already have an exception set, use that, otherwise set a
895 * generic one */
896 if (!PyErr_Occurred())
897 PyErr_SetString(PyExc_TypeError,
898 "can't convert return value to desired type");
900 if (pc->exception_handler)
901 pc->exception_handler(return_value, n_param_values, param_values);
902 else
903 PyErr_Print();
905 Py_DECREF(ret);
907 out:
908 Py_DECREF(params);
909 PyGILState_Release(state);
913 * pyg_closure_new:
914 * callback: a Python callable object
915 * extra_args: a tuple of extra arguments, or None/NULL.
916 * swap_data: an alternative python object to pass first.
918 * Creates a GClosure wrapping a Python callable and optionally a set
919 * of additional function arguments. This is needed to attach python
920 * handlers to signals, for instance.
922 * Returns: the new closure.
924 GClosure *
925 pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data)
927 GClosure *closure;
929 g_return_val_if_fail(callback != NULL, NULL);
930 closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
931 g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate);
932 g_closure_set_marshal(closure, pyg_closure_marshal);
933 Py_INCREF(callback);
934 ((PyGClosure *)closure)->callback = callback;
935 if (extra_args && extra_args != Py_None) {
936 Py_INCREF(extra_args);
937 if (!PyTuple_Check(extra_args)) {
938 PyObject *tmp = PyTuple_New(1);
939 PyTuple_SetItem(tmp, 0, extra_args);
940 extra_args = tmp;
942 ((PyGClosure *)closure)->extra_args = extra_args;
944 if (swap_data) {
945 Py_INCREF(swap_data);
946 ((PyGClosure *)closure)->swap_data = swap_data;
947 closure->derivative_flag = TRUE;
949 return closure;
953 * pyg_closure_set_exception_handler:
954 * @closure: a closure created with pyg_closure_new()
955 * @handler: the handler to call when an exception occurs or NULL for none
957 * Sets the handler to call when an exception occurs during closure invocation.
958 * The handler is responsible for providing a proper return value to the
959 * closure invocation. If @handler is %NULL, the default handler will be used.
960 * The default handler prints the exception to stderr and doesn't touch the
961 * closure's return value.
963 void
964 pyg_closure_set_exception_handler(GClosure *closure,
965 PyClosureExceptionHandler handler)
967 PyGClosure *pygclosure;
969 g_return_if_fail(closure != NULL);
971 pygclosure = (PyGClosure *)closure;
972 pygclosure->exception_handler = handler;
974 /* -------------- PySignalClassClosure ----------------- */
975 /* a closure used for the `class closure' of a signal. As this gets
976 * all the info from the first argument to the closure and the
977 * invocation hint, we can have a single closure that handles all
978 * class closure cases. We call a method by the name of the signal
979 * with "do_" prepended.
981 * We also remove the first argument from the * param list, as it is
982 * the instance object, which is passed * implicitly to the method
983 * object. */
985 static void
986 pyg_signal_class_closure_marshal(GClosure *closure,
987 GValue *return_value,
988 guint n_param_values,
989 const GValue *param_values,
990 gpointer invocation_hint,
991 gpointer marshal_data)
993 PyGILState_STATE state;
994 GObject *object;
995 PyObject *object_wrapper;
996 GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint;
997 gchar *method_name, *tmp;
998 PyObject *method;
999 PyObject *params, *ret;
1000 Py_ssize_t py_len;
1001 guint i, len;
1003 state = PyGILState_Ensure();
1005 g_return_if_fail(invocation_hint != NULL);
1006 /* get the object passed as the first argument to the closure */
1007 object = g_value_get_object(&param_values[0]);
1008 g_return_if_fail(object != NULL && G_IS_OBJECT(object));
1010 /* get the wrapper for this object */
1011 object_wrapper = pygobject_new(object);
1012 g_return_if_fail(object_wrapper != NULL);
1014 /* construct method name for this class closure */
1015 method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL);
1017 /* convert dashes to underscores. For some reason, g_signal_name
1018 * seems to convert all the underscores in the signal name to
1019 dashes??? */
1020 for (tmp = method_name; *tmp != '\0'; tmp++)
1021 if (*tmp == '-') *tmp = '_';
1023 method = PyObject_GetAttrString(object_wrapper, method_name);
1024 g_free(method_name);
1026 if (!method) {
1027 PyErr_Clear();
1028 Py_DECREF(object_wrapper);
1029 PyGILState_Release(state);
1030 return;
1032 Py_DECREF(object_wrapper);
1034 /* construct Python tuple for the parameter values; don't copy boxed values
1035 initially because we'll check after the call to see if a copy is needed. */
1036 params = PyTuple_New(n_param_values - 1);
1037 for (i = 1; i < n_param_values; i++) {
1038 PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
1040 /* error condition */
1041 if (!item) {
1042 Py_DECREF(params);
1043 PyGILState_Release(state);
1044 return;
1046 PyTuple_SetItem(params, i - 1, item);
1049 ret = PyObject_CallObject(method, params);
1051 /* Copy boxed values if others ref them, this needs to be done regardless of
1052 exception status. */
1053 py_len = PyTuple_Size(params);
1054 len = (guint)py_len;
1055 for (i = 0; i < len; i++) {
1056 PyObject *item = PyTuple_GetItem(params, i);
1057 if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type)
1058 && Py_REFCNT (item) != 1) {
1059 PyGBoxed* boxed_item = (PyGBoxed*)item;
1060 if (!boxed_item->free_on_dealloc) {
1061 gpointer boxed_ptr = pyg_boxed_get_ptr (boxed_item);
1062 pyg_boxed_set_ptr (boxed_item, g_boxed_copy (boxed_item->gtype, boxed_ptr));
1063 boxed_item->free_on_dealloc = TRUE;
1068 if (ret == NULL) {
1069 PyErr_Print();
1070 Py_DECREF(method);
1071 Py_DECREF(params);
1072 PyGILState_Release(state);
1073 return;
1075 Py_DECREF(method);
1076 Py_DECREF(params);
1077 if (G_IS_VALUE(return_value))
1078 pyg_value_from_pyobject(return_value, ret);
1079 Py_DECREF(ret);
1080 PyGILState_Release(state);
1084 * pyg_signal_class_closure_get:
1086 * Returns the GClosure used for the class closure of signals. When
1087 * called, it will invoke the method do_signalname (for the signal
1088 * "signalname").
1090 * Returns: the closure.
1092 GClosure *
1093 pyg_signal_class_closure_get(void)
1095 static GClosure *closure;
1097 if (closure == NULL) {
1098 closure = g_closure_new_simple(sizeof(GClosure), NULL);
1099 g_closure_set_marshal(closure, pyg_signal_class_closure_marshal);
1101 g_closure_ref(closure);
1102 g_closure_sink(closure);
1104 return closure;
1107 /* ----- __doc__ descriptor for GObject and GInterface ----- */
1109 static void
1110 object_doc_dealloc(PyObject *self)
1112 PyObject_FREE(self);
1115 /* append information about signals of a particular gtype */
1116 static void
1117 add_signal_docs(GType gtype, GString *string)
1119 GTypeClass *class = NULL;
1120 guint *signal_ids, n_ids = 0, i;
1122 if (G_TYPE_IS_CLASSED(gtype))
1123 class = g_type_class_ref(gtype);
1124 signal_ids = g_signal_list_ids(gtype, &n_ids);
1126 if (n_ids > 0) {
1127 g_string_append_printf(string, "Signals from %s:\n",
1128 g_type_name(gtype));
1130 for (i = 0; i < n_ids; i++) {
1131 GSignalQuery query;
1132 guint j;
1134 g_signal_query(signal_ids[i], &query);
1136 g_string_append(string, " ");
1137 g_string_append(string, query.signal_name);
1138 g_string_append(string, " (");
1139 for (j = 0; j < query.n_params; j++) {
1140 g_string_append(string, g_type_name(query.param_types[j]));
1141 if (j != query.n_params - 1)
1142 g_string_append(string, ", ");
1144 g_string_append(string, ")");
1145 if (query.return_type && query.return_type != G_TYPE_NONE) {
1146 g_string_append(string, " -> ");
1147 g_string_append(string, g_type_name(query.return_type));
1149 g_string_append(string, "\n");
1151 g_free(signal_ids);
1152 g_string_append(string, "\n");
1154 if (class)
1155 g_type_class_unref(class);
1158 static void
1159 add_property_docs(GType gtype, GString *string)
1161 GObjectClass *class;
1162 GParamSpec **props;
1163 guint n_props = 0, i;
1164 gboolean has_prop = FALSE;
1165 G_CONST_RETURN gchar *blurb=NULL;
1167 class = g_type_class_ref(gtype);
1168 props = g_object_class_list_properties(class, &n_props);
1170 for (i = 0; i < n_props; i++) {
1171 if (props[i]->owner_type != gtype)
1172 continue; /* these are from a parent type */
1174 /* print out the heading first */
1175 if (!has_prop) {
1176 g_string_append_printf(string, "Properties from %s:\n",
1177 g_type_name(gtype));
1178 has_prop = TRUE;
1180 g_string_append_printf(string, " %s -> %s: %s\n",
1181 g_param_spec_get_name(props[i]),
1182 g_type_name(props[i]->value_type),
1183 g_param_spec_get_nick(props[i]));
1185 /* g_string_append_printf crashes on win32 if the third
1186 argument is NULL. */
1187 blurb=g_param_spec_get_blurb(props[i]);
1188 if (blurb)
1189 g_string_append_printf(string, " %s\n",blurb);
1191 g_free(props);
1192 if (has_prop)
1193 g_string_append(string, "\n");
1194 g_type_class_unref(class);
1197 static PyObject *
1198 object_doc_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1200 GType gtype = 0;
1201 GString *string;
1202 PyObject *pystring;
1204 if (obj && pygobject_check(obj, &PyGObject_Type)) {
1205 gtype = G_OBJECT_TYPE(pygobject_get(obj));
1206 if (!gtype)
1207 PyErr_SetString(PyExc_RuntimeError, "could not get object type");
1208 } else {
1209 gtype = pyg_type_from_object(type);
1211 if (!gtype)
1212 return NULL;
1214 string = g_string_new_len(NULL, 512);
1216 if (g_type_is_a(gtype, G_TYPE_INTERFACE))
1217 g_string_append_printf(string, "Interface %s\n\n", g_type_name(gtype));
1218 else if (g_type_is_a(gtype, G_TYPE_OBJECT))
1219 g_string_append_printf(string, "Object %s\n\n", g_type_name(gtype));
1220 else
1221 g_string_append_printf(string, "%s\n\n", g_type_name(gtype));
1223 if (((PyTypeObject *) type)->tp_doc)
1224 g_string_append_printf(string, "%s\n\n", ((PyTypeObject *) type)->tp_doc);
1226 if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
1227 GType parent = G_TYPE_OBJECT;
1228 GArray *parents = g_array_new(FALSE, FALSE, sizeof(GType));
1229 int iparent;
1231 while (parent) {
1232 g_array_append_val(parents, parent);
1233 parent = g_type_next_base(gtype, parent);
1236 for (iparent = parents->len - 1; iparent >= 0; --iparent) {
1237 GType *interfaces;
1238 guint n_interfaces, i;
1240 parent = g_array_index(parents, GType, iparent);
1241 add_signal_docs(parent, string);
1242 add_property_docs(parent, string);
1244 /* add docs for implemented interfaces */
1245 interfaces = g_type_interfaces(parent, &n_interfaces);
1246 for (i = 0; i < n_interfaces; i++)
1247 add_signal_docs(interfaces[i], string);
1248 g_free(interfaces);
1250 g_array_free(parents, TRUE);
1253 pystring = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len);
1254 g_string_free(string, TRUE);
1255 return pystring;
1258 PYGLIB_DEFINE_TYPE("gobject.GObject.__doc__", PyGObjectDoc_Type, PyObject);
1261 * pyg_object_descr_doc_get:
1263 * Returns an object intended to be the __doc__ attribute of GObject
1264 * wrappers. When read in the context of the object it will return
1265 * some documentation about the signals and properties of the object.
1267 * Returns: the descriptor.
1269 PyObject *
1270 pyg_object_descr_doc_get(void)
1272 static PyObject *doc_descr = NULL;
1274 if (!doc_descr) {
1275 Py_TYPE(&PyGObjectDoc_Type) = &PyType_Type;
1276 if (PyType_Ready(&PyGObjectDoc_Type))
1277 return NULL;
1279 doc_descr = PyObject_NEW(PyObject, &PyGObjectDoc_Type);
1280 if (doc_descr == NULL)
1281 return NULL;
1283 return doc_descr;
1288 * pyg_pyobj_to_unichar_conv:
1290 * Converts PyObject value to a unichar and write result to memory
1291 * pointed to by ptr. Follows the calling convention of a ParseArgs
1292 * converter (O& format specifier) so it may be used to convert function
1293 * arguments.
1295 * Returns: 1 if the conversion succeeds and 0 otherwise. If the conversion
1296 * did not succeesd, a Python exception is raised
1298 int pyg_pyobj_to_unichar_conv(PyObject* py_obj, void* ptr)
1300 if (!pygi_gunichar_from_py (py_obj, ptr))
1301 return 0;
1302 return 1;
1305 gboolean
1306 pyg_gtype_is_custom(GType gtype)
1308 return g_type_get_qdata (gtype, pygobject_custom_key) != NULL;
1311 static PyObject *
1312 strv_from_gvalue(const GValue *value)
1314 gchar **argv;
1315 PyObject *py_argv;
1316 gsize i;
1318 argv = (gchar **) g_value_get_boxed (value);
1319 py_argv = PyList_New (0);
1321 for (i = 0; argv && argv[i]; i++) {
1322 int res;
1323 PyObject *item = pygi_utf8_to_py (argv[i]);
1324 if (item == NULL) {
1325 Py_DECREF (py_argv);
1326 return NULL;
1328 res = PyList_Append (py_argv, item);
1329 Py_DECREF (item);
1330 if (res == -1) {
1331 Py_DECREF (py_argv);
1332 return NULL;
1336 return py_argv;
1339 static int
1340 strv_to_gvalue(GValue *value, PyObject *obj)
1342 Py_ssize_t argc, i;
1343 gchar **argv;
1345 if (!(PyTuple_Check (obj) || PyList_Check (obj)))
1346 return -1;
1348 argc = PySequence_Length (obj);
1349 argv = g_new (gchar *, argc + 1);
1350 for (i = 0; i < argc; ++i) {
1351 PyObject* item = PySequence_Fast_GET_ITEM (obj, i);
1352 if (!pygi_utf8_from_py (item, &(argv[i])))
1353 goto error;
1356 argv[i] = NULL;
1357 g_value_take_boxed (value, argv);
1358 return 0;
1360 error:
1361 for (i = i - 1; i >= 0; i--) {
1362 g_free (argv[i]);
1364 g_free (argv);
1365 return -1;
1369 * Returns 0 on success, or -1 and sets an exception.
1372 pygi_type_register_types(PyObject *d)
1374 PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc;
1375 PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare;
1376 PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr;
1377 PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash;
1378 PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1379 PyGTypeWrapper_Type.tp_methods = _PyGTypeWrapper_methods;
1380 PyGTypeWrapper_Type.tp_getset = _PyGTypeWrapper_getsets;
1381 PyGTypeWrapper_Type.tp_init = (initproc)pyg_type_wrapper_init;
1382 PYGLIB_REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType");
1384 /* This type lazily registered in pyg_object_descr_doc_get */
1385 PyGObjectDoc_Type.tp_dealloc = (destructor)object_doc_dealloc;
1386 PyGObjectDoc_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1387 PyGObjectDoc_Type.tp_descr_get = (descrgetfunc)object_doc_descr_get;
1389 pyg_register_gtype_custom (G_TYPE_STRV,
1390 strv_from_gvalue,
1391 strv_to_gvalue);
1393 return 0;