tests: Remove TestMainLoop.test_concurrency
[pygobject.git] / gi / pygi-value.c
blob6e3eb0906f7cf886ef92e9921f2431b3b9851f72
2 /* -*- Mode: C; c-basic-offset: 4 -*-
3 * vim: tabstop=4 shiftwidth=4 expandtab
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 <Python.h>
20 #include "pygi-value.h"
21 #include "pygi-struct.h"
22 #include "pyglib-python-compat.h"
23 #include "pygobject-object.h"
24 #include "pygtype.h"
25 #include "pygenum.h"
26 #include "pygpointer.h"
27 #include "pygboxed.h"
28 #include "pygflags.h"
29 #include "pygparamspec.h"
31 GIArgument
32 _pygi_argument_from_g_value(const GValue *value,
33 GITypeInfo *type_info)
35 GIArgument arg = { 0, };
37 GITypeTag type_tag = g_type_info_get_tag (type_info);
39 /* For the long handling: long can be equivalent to
40 int32 or int64, depending on the architecture, but
41 gi doesn't tell us (and same for ulong)
43 switch (type_tag) {
44 case GI_TYPE_TAG_BOOLEAN:
45 arg.v_boolean = g_value_get_boolean (value);
46 break;
47 case GI_TYPE_TAG_INT8:
48 arg.v_int8 = g_value_get_schar (value);
49 break;
50 case GI_TYPE_TAG_INT16:
51 case GI_TYPE_TAG_INT32:
52 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_LONG))
53 arg.v_int = g_value_get_long (value);
54 else
55 arg.v_int = g_value_get_int (value);
56 break;
57 case GI_TYPE_TAG_INT64:
58 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_LONG))
59 arg.v_int64 = g_value_get_long (value);
60 else
61 arg.v_int64 = g_value_get_int64 (value);
62 break;
63 case GI_TYPE_TAG_UINT8:
64 arg.v_uint8 = g_value_get_uchar (value);
65 break;
66 case GI_TYPE_TAG_UINT16:
67 case GI_TYPE_TAG_UINT32:
68 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ULONG))
69 arg.v_uint = g_value_get_ulong (value);
70 else
71 arg.v_uint = g_value_get_uint (value);
72 break;
73 case GI_TYPE_TAG_UINT64:
74 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ULONG))
75 arg.v_uint64 = g_value_get_ulong (value);
76 else
77 arg.v_uint64 = g_value_get_uint64 (value);
78 break;
79 case GI_TYPE_TAG_UNICHAR:
80 arg.v_uint32 = g_value_get_schar (value);
81 break;
82 case GI_TYPE_TAG_FLOAT:
83 arg.v_float = g_value_get_float (value);
84 break;
85 case GI_TYPE_TAG_DOUBLE:
86 arg.v_double = g_value_get_double (value);
87 break;
88 case GI_TYPE_TAG_GTYPE:
89 arg.v_long = g_value_get_gtype (value);
90 break;
91 case GI_TYPE_TAG_UTF8:
92 case GI_TYPE_TAG_FILENAME:
93 /* Callers are responsible for ensuring the GValue stays alive
94 * long enough for the string to be copied. */
95 arg.v_string = (char *)g_value_get_string (value);
96 break;
97 case GI_TYPE_TAG_GLIST:
98 case GI_TYPE_TAG_GSLIST:
99 case GI_TYPE_TAG_ARRAY:
100 case GI_TYPE_TAG_GHASH:
101 if (G_VALUE_HOLDS_BOXED (value))
102 arg.v_pointer = g_value_get_boxed (value);
103 else
104 /* e. g. GSettings::change-event */
105 arg.v_pointer = g_value_get_pointer (value);
106 break;
107 case GI_TYPE_TAG_INTERFACE:
109 GIBaseInfo *info;
110 GIInfoType info_type;
112 info = g_type_info_get_interface (type_info);
113 info_type = g_base_info_get_type (info);
115 g_base_info_unref (info);
117 switch (info_type) {
118 case GI_INFO_TYPE_FLAGS:
119 arg.v_uint = g_value_get_flags (value);
120 break;
121 case GI_INFO_TYPE_ENUM:
122 arg.v_int = g_value_get_enum (value);
123 break;
124 case GI_INFO_TYPE_INTERFACE:
125 case GI_INFO_TYPE_OBJECT:
126 if (G_VALUE_HOLDS_PARAM (value))
127 arg.v_pointer = g_value_get_param (value);
128 else
129 arg.v_pointer = g_value_get_object (value);
130 break;
131 case GI_INFO_TYPE_BOXED:
132 case GI_INFO_TYPE_STRUCT:
133 case GI_INFO_TYPE_UNION:
134 if (G_VALUE_HOLDS (value, G_TYPE_BOXED)) {
135 arg.v_pointer = g_value_get_boxed (value);
136 } else if (G_VALUE_HOLDS (value, G_TYPE_VARIANT)) {
137 arg.v_pointer = g_value_get_variant (value);
138 } else if (G_VALUE_HOLDS (value, G_TYPE_POINTER)) {
139 arg.v_pointer = g_value_get_pointer (value);
140 } else {
141 PyErr_Format (PyExc_NotImplementedError,
142 "Converting GValue's of type '%s' is not implemented.",
143 g_type_name (G_VALUE_TYPE (value)));
145 break;
146 default:
147 PyErr_Format (PyExc_NotImplementedError,
148 "Converting GValue's of type '%s' is not implemented.",
149 g_info_type_to_string (info_type));
150 break;
152 break;
154 case GI_TYPE_TAG_ERROR:
155 arg.v_pointer = g_value_get_boxed (value);
156 break;
157 case GI_TYPE_TAG_VOID:
158 arg.v_pointer = g_value_get_pointer (value);
159 break;
160 default:
161 break;
164 return arg;
168 /* Ignore g_value_array deprecations. Although they are deprecated,
169 * we still need to support the marshaling of them in PyGObject.
171 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
173 static int
174 pyg_value_array_from_pyobject(GValue *value,
175 PyObject *obj,
176 const GParamSpecValueArray *pspec)
178 Py_ssize_t seq_len;
179 GValueArray *value_array;
180 guint len, i;
182 seq_len = PySequence_Length(obj);
183 if (seq_len == -1) {
184 PyErr_Clear();
185 return -1;
187 len = (guint)seq_len;
189 if (pspec && pspec->fixed_n_elements > 0 && len != pspec->fixed_n_elements)
190 return -1;
192 value_array = g_value_array_new(len);
194 for (i = 0; i < len; ++i) {
195 PyObject *item = PySequence_GetItem(obj, i);
196 GType type;
197 GValue item_value = { 0, };
198 int status;
200 if (! item) {
201 PyErr_Clear();
202 g_value_array_free(value_array);
203 return -1;
206 if (pspec && pspec->element_spec)
207 type = G_PARAM_SPEC_VALUE_TYPE(pspec->element_spec);
208 else if (item == Py_None)
209 type = G_TYPE_POINTER; /* store None as NULL */
210 else {
211 type = pyg_type_from_object((PyObject*)Py_TYPE(item));
212 if (! type) {
213 PyErr_Clear();
214 g_value_array_free(value_array);
215 Py_DECREF(item);
216 return -1;
220 g_value_init(&item_value, type);
221 status = (pspec && pspec->element_spec)
222 ? pyg_param_gvalue_from_pyobject(&item_value, item, pspec->element_spec)
223 : pyg_value_from_pyobject(&item_value, item);
224 Py_DECREF(item);
226 if (status == -1) {
227 g_value_array_free(value_array);
228 g_value_unset(&item_value);
229 return -1;
232 g_value_array_append(value_array, &item_value);
233 g_value_unset(&item_value);
236 g_value_take_boxed(value, value_array);
237 return 0;
240 G_GNUC_END_IGNORE_DEPRECATIONS
242 static int
243 pyg_array_from_pyobject(GValue *value,
244 PyObject *obj)
246 int len;
247 GArray *array;
248 int i;
250 len = PySequence_Length(obj);
251 if (len == -1) {
252 PyErr_Clear();
253 return -1;
256 array = g_array_new(FALSE, TRUE, sizeof(GValue));
258 for (i = 0; i < len; ++i) {
259 PyObject *item = PySequence_GetItem(obj, i);
260 GType type;
261 GValue item_value = { 0, };
262 int status;
264 if (! item) {
265 PyErr_Clear();
266 g_array_free(array, FALSE);
267 return -1;
270 if (item == Py_None)
271 type = G_TYPE_POINTER; /* store None as NULL */
272 else {
273 type = pyg_type_from_object((PyObject*)Py_TYPE(item));
274 if (! type) {
275 PyErr_Clear();
276 g_array_free(array, FALSE);
277 Py_DECREF(item);
278 return -1;
282 g_value_init(&item_value, type);
283 status = pyg_value_from_pyobject(&item_value, item);
284 Py_DECREF(item);
286 if (status == -1) {
287 g_array_free(array, FALSE);
288 g_value_unset(&item_value);
289 return -1;
292 g_array_append_val(array, item_value);
295 g_value_take_boxed(value, array);
296 return 0;
300 * pyg_value_from_pyobject_with_error:
301 * @value: the GValue object to store the converted value in.
302 * @obj: the Python object to convert.
304 * This function converts a Python object and stores the result in a
305 * GValue. The GValue must be initialised in advance with
306 * g_value_init(). If the Python object can't be converted to the
307 * type of the GValue, then an error is returned.
309 * Returns: 0 on success, -1 on error.
312 pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj)
314 PyObject *tmp;
315 GType value_type = G_VALUE_TYPE(value);
317 switch (G_TYPE_FUNDAMENTAL(value_type)) {
318 case G_TYPE_INTERFACE:
319 /* we only handle interface types that have a GObject prereq */
320 if (g_type_is_a(value_type, G_TYPE_OBJECT)) {
321 if (obj == Py_None)
322 g_value_set_object(value, NULL);
323 else {
324 if (!PyObject_TypeCheck(obj, &PyGObject_Type)) {
325 PyErr_SetString(PyExc_TypeError, "GObject is required");
326 return -1;
328 if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
329 value_type)) {
330 PyErr_SetString(PyExc_TypeError, "Invalid GObject type for assignment");
331 return -1;
333 g_value_set_object(value, pygobject_get(obj));
335 } else {
336 PyErr_SetString(PyExc_TypeError, "Unsupported conversion");
337 return -1;
339 break;
340 case G_TYPE_CHAR:
341 if (PYGLIB_PyLong_Check(obj)) {
342 glong val;
343 val = PYGLIB_PyLong_AsLong(obj);
344 if (val >= -128 && val <= 127)
345 g_value_set_schar(value, (gchar) val);
346 else
347 return -1;
349 #if PY_VERSION_HEX < 0x03000000
350 else if (PyString_Check(obj)) {
351 g_value_set_schar(value, PyString_AsString(obj)[0]);
353 #endif
354 else if (PyUnicode_Check(obj)) {
355 tmp = PyUnicode_AsUTF8String(obj);
356 g_value_set_schar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
357 Py_DECREF(tmp);
358 } else {
359 PyErr_SetString(PyExc_TypeError, "Cannot convert to TYPE_CHAR");
360 return -1;
363 break;
364 case G_TYPE_UCHAR:
365 if (PYGLIB_PyLong_Check(obj)) {
366 glong val;
367 val = PYGLIB_PyLong_AsLong(obj);
368 if (val >= 0 && val <= 255)
369 g_value_set_uchar(value, (guchar) val);
370 else
371 return -1;
372 #if PY_VERSION_HEX < 0x03000000
373 } else if (PyString_Check(obj)) {
374 g_value_set_uchar(value, PyString_AsString(obj)[0]);
375 #endif
376 } else if (PyUnicode_Check(obj)) {
377 tmp = PyUnicode_AsUTF8String(obj);
378 g_value_set_uchar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
379 Py_DECREF(tmp);
380 } else {
381 PyErr_Clear();
382 return -1;
384 break;
385 case G_TYPE_BOOLEAN:
386 g_value_set_boolean(value, PyObject_IsTrue(obj));
387 break;
388 case G_TYPE_INT:
389 g_value_set_int(value, PYGLIB_PyLong_AsLong(obj));
390 break;
391 case G_TYPE_UINT:
393 if (PYGLIB_PyLong_Check(obj)) {
394 gulong val;
396 /* check that number is not negative */
397 if (PyLong_AsLongLong(obj) < 0)
398 return -1;
400 val = PyLong_AsUnsignedLong(obj);
401 if (val <= G_MAXUINT)
402 g_value_set_uint(value, (guint) val);
403 else
404 return -1;
405 } else {
406 g_value_set_uint(value, PyLong_AsUnsignedLong(obj));
409 break;
410 case G_TYPE_LONG:
411 g_value_set_long(value, PYGLIB_PyLong_AsLong(obj));
412 break;
413 case G_TYPE_ULONG:
414 #if PY_VERSION_HEX < 0x03000000
415 if (PyInt_Check(obj)) {
416 long val;
418 val = PYGLIB_PyLong_AsLong(obj);
419 if (val < 0) {
420 PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
421 return -1;
423 g_value_set_ulong(value, (gulong)val);
424 } else
425 #endif
426 if (PyLong_Check(obj))
427 g_value_set_ulong(value, PyLong_AsUnsignedLong(obj));
428 else
429 return -1;
430 break;
431 case G_TYPE_INT64:
432 g_value_set_int64(value, PyLong_AsLongLong(obj));
433 break;
434 case G_TYPE_UINT64:
435 #if PY_VERSION_HEX < 0x03000000
436 if (PyInt_Check(obj)) {
437 long v = PyInt_AsLong(obj);
438 if (v < 0) {
439 PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
440 return -1;
442 g_value_set_uint64(value, v);
443 } else
444 #endif
445 if (PyLong_Check(obj))
446 g_value_set_uint64(value, PyLong_AsUnsignedLongLong(obj));
447 else
448 return -1;
449 break;
450 case G_TYPE_ENUM:
452 gint val = 0;
453 if (pyg_enum_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
454 return -1;
456 g_value_set_enum(value, val);
458 break;
459 case G_TYPE_FLAGS:
461 guint val = 0;
462 if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
463 return -1;
465 g_value_set_flags(value, val);
467 break;
468 case G_TYPE_FLOAT:
469 g_value_set_float(value, PyFloat_AsDouble(obj));
470 break;
471 case G_TYPE_DOUBLE:
472 g_value_set_double(value, PyFloat_AsDouble(obj));
473 break;
474 case G_TYPE_STRING:
475 if (obj == Py_None) {
476 g_value_set_string(value, NULL);
477 } else {
478 PyObject* tmp_str = PyObject_Str(obj);
479 if (tmp_str == NULL) {
480 PyErr_Clear();
481 if (PyUnicode_Check(obj)) {
482 tmp = PyUnicode_AsUTF8String(obj);
483 g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp));
484 Py_DECREF(tmp);
485 } else {
486 PyErr_SetString(PyExc_TypeError, "Expected string");
487 return -1;
489 } else {
490 #if PY_VERSION_HEX < 0x03000000
491 g_value_set_string(value, PyString_AsString(tmp_str));
492 #else
493 tmp = PyUnicode_AsUTF8String(tmp_str);
494 g_value_set_string(value, PyBytes_AsString(tmp));
495 Py_DECREF(tmp);
496 #endif
498 Py_XDECREF(tmp_str);
500 break;
501 case G_TYPE_POINTER:
502 if (obj == Py_None)
503 g_value_set_pointer(value, NULL);
504 else if (PyObject_TypeCheck(obj, &PyGPointer_Type) &&
505 G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype))
506 g_value_set_pointer(value, pyg_pointer_get(obj, gpointer));
507 else if (PYGLIB_CPointer_Check(obj))
508 g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL));
509 else if (G_VALUE_HOLDS_GTYPE (value))
510 g_value_set_gtype (value, pyg_type_from_object (obj));
511 else {
512 PyErr_SetString(PyExc_TypeError, "Expected pointer");
513 return -1;
515 break;
516 case G_TYPE_BOXED: {
517 PyGTypeMarshal *bm;
518 gboolean holds_value_array;
520 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
521 holds_value_array = G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY);
522 G_GNUC_END_IGNORE_DEPRECATIONS
524 if (obj == Py_None)
525 g_value_set_boxed(value, NULL);
526 else if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT))
527 g_value_set_boxed(value, obj);
528 else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) &&
529 G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype))
530 g_value_set_boxed(value, pyg_boxed_get(obj, gpointer));
531 else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
532 GType type;
533 GValue *n_value;
535 type = pyg_type_from_object((PyObject*)Py_TYPE(obj));
536 if (G_UNLIKELY (! type)) {
537 return -1;
539 n_value = g_new0 (GValue, 1);
540 g_value_init (n_value, type);
541 g_value_take_boxed (value, n_value);
542 return pyg_value_from_pyobject_with_error (n_value, obj);
544 else if (PySequence_Check(obj) && holds_value_array)
545 return pyg_value_array_from_pyobject(value, obj, NULL);
547 else if (PySequence_Check(obj) &&
548 G_VALUE_HOLDS(value, G_TYPE_ARRAY))
549 return pyg_array_from_pyobject(value, obj);
550 else if (PYGLIB_PyUnicode_Check(obj) &&
551 G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
552 GString *string;
553 char *buffer;
554 Py_ssize_t len;
555 if (PYGLIB_PyUnicode_AsStringAndSize(obj, &buffer, &len))
556 return -1;
557 string = g_string_new_len(buffer, len);
558 g_value_set_boxed(value, string);
559 g_string_free (string, TRUE);
560 break;
562 else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
563 return bm->tovalue(value, obj);
564 else if (PYGLIB_CPointer_Check(obj))
565 g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL));
566 else {
567 PyErr_SetString(PyExc_TypeError, "Expected Boxed");
568 return -1;
570 break;
572 case G_TYPE_PARAM:
573 /* we need to support both the wrapped _gobject.GParamSpec and the GI
574 * GObject.ParamSpec */
575 if (G_IS_PARAM_SPEC (pygobject_get (obj)))
576 g_value_set_param(value, G_PARAM_SPEC (pygobject_get (obj)));
577 else if (pyg_param_spec_check (obj))
578 g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
579 else {
580 PyErr_SetString(PyExc_TypeError, "Expected ParamSpec");
581 return -1;
583 break;
584 case G_TYPE_OBJECT:
585 if (obj == Py_None) {
586 g_value_set_object(value, NULL);
587 } else if (PyObject_TypeCheck(obj, &PyGObject_Type) &&
588 G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
589 G_VALUE_TYPE(value))) {
590 g_value_set_object(value, pygobject_get(obj));
591 } else {
592 PyErr_SetString(PyExc_TypeError, "Expected GObject");
593 return -1;
595 break;
596 case G_TYPE_VARIANT:
598 if (obj == Py_None)
599 g_value_set_variant(value, NULL);
600 else if (pyg_type_from_object_strict(obj, FALSE) == G_TYPE_VARIANT)
601 g_value_set_variant(value, pyg_boxed_get(obj, GVariant));
602 else {
603 PyErr_SetString(PyExc_TypeError, "Expected Variant");
604 return -1;
606 break;
608 default:
610 PyGTypeMarshal *bm;
611 if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL) {
612 return bm->tovalue(value, obj);
613 } else {
614 PyErr_SetString(PyExc_TypeError, "Unknown value type");
615 return -1;
617 break;
621 /* If an error occurred, unset the GValue but don't clear the Python error. */
622 if (PyErr_Occurred()) {
623 g_value_unset(value);
624 return -1;
627 return 0;
631 * pyg_value_from_pyobject:
632 * @value: the GValue object to store the converted value in.
633 * @obj: the Python object to convert.
635 * Same basic function as pyg_value_from_pyobject_with_error but clears
636 * any Python errors before returning.
638 * Returns: 0 on success, -1 on error.
641 pyg_value_from_pyobject(GValue *value, PyObject *obj)
643 int res = pyg_value_from_pyobject_with_error (value, obj);
645 if (PyErr_Occurred()) {
646 PyErr_Clear();
647 return -1;
649 return res;
653 * pygi_value_to_py_basic_type:
654 * @value: the GValue object.
656 * This function creates/returns a Python wrapper object that
657 * represents the GValue passed as an argument limited to supporting basic types
658 * like ints, bools, and strings.
660 * Returns: a PyObject representing the value.
662 PyObject *
663 pygi_value_to_py_basic_type (const GValue *value, GType fundamental)
665 switch (fundamental) {
666 case G_TYPE_CHAR:
667 return PYGLIB_PyLong_FromLong (g_value_get_schar (value));
669 case G_TYPE_UCHAR:
670 return PYGLIB_PyLong_FromLong (g_value_get_uchar (value));
672 case G_TYPE_BOOLEAN: {
673 return PyBool_FromLong(g_value_get_boolean(value));
675 case G_TYPE_INT:
676 return PYGLIB_PyLong_FromLong(g_value_get_int(value));
677 case G_TYPE_UINT:
679 /* in Python, the Int object is backed by a long. If a
680 long can hold the whole value of an unsigned int, use
681 an Int. Otherwise, use a Long object to avoid overflow.
682 This matches the ULongArg behavior in codegen/argtypes.h */
683 #if (G_MAXUINT <= G_MAXLONG)
684 return PYGLIB_PyLong_FromLong((glong) g_value_get_uint(value));
685 #else
686 return PyLong_FromUnsignedLong((gulong) g_value_get_uint(value));
687 #endif
689 case G_TYPE_LONG:
690 return PYGLIB_PyLong_FromLong(g_value_get_long(value));
691 case G_TYPE_ULONG:
693 gulong val = g_value_get_ulong(value);
695 if (val <= G_MAXLONG)
696 return PYGLIB_PyLong_FromLong((glong) val);
697 else
698 return PyLong_FromUnsignedLong(val);
700 case G_TYPE_INT64:
702 gint64 val = g_value_get_int64(value);
704 if (G_MINLONG <= val && val <= G_MAXLONG)
705 return PYGLIB_PyLong_FromLong((glong) val);
706 else
707 return PyLong_FromLongLong(val);
709 case G_TYPE_UINT64:
711 guint64 val = g_value_get_uint64(value);
713 if (val <= G_MAXLONG)
714 return PYGLIB_PyLong_FromLong((glong) val);
715 else
716 return PyLong_FromUnsignedLongLong(val);
718 case G_TYPE_ENUM:
719 return pyg_enum_from_gtype(G_VALUE_TYPE(value), g_value_get_enum(value));
720 case G_TYPE_FLAGS:
721 return pyg_flags_from_gtype(G_VALUE_TYPE(value), g_value_get_flags(value));
722 case G_TYPE_FLOAT:
723 return PyFloat_FromDouble(g_value_get_float(value));
724 case G_TYPE_DOUBLE:
725 return PyFloat_FromDouble(g_value_get_double(value));
726 case G_TYPE_STRING:
728 const gchar *str = g_value_get_string(value);
730 if (str)
731 return PYGLIB_PyUnicode_FromString(str);
732 Py_INCREF(Py_None);
733 return Py_None;
735 default:
736 return NULL;
741 * pygi_value_to_py_structured_type:
742 * @value: the GValue object.
743 * @copy_boxed: true if boxed values should be copied.
745 * This function creates/returns a Python wrapper object that
746 * represents the GValue passed as an argument.
748 * Returns: a PyObject representing the value.
750 PyObject *
751 pygi_value_to_py_structured_type (const GValue *value, GType fundamental, gboolean copy_boxed)
753 switch (fundamental) {
754 case G_TYPE_INTERFACE:
755 if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_OBJECT))
756 return pygobject_new(g_value_get_object(value));
757 else
758 break;
760 case G_TYPE_POINTER:
761 if (G_VALUE_HOLDS_GTYPE (value))
762 return pyg_type_wrapper_new (g_value_get_gtype (value));
763 else
764 return pyg_pointer_new(G_VALUE_TYPE(value),
765 g_value_get_pointer(value));
766 case G_TYPE_BOXED: {
767 PyGTypeMarshal *bm;
768 gboolean holds_value_array;
770 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
771 holds_value_array = G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY);
772 G_GNUC_END_IGNORE_DEPRECATIONS
774 if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) {
775 PyObject *ret = (PyObject *)g_value_dup_boxed(value);
776 if (ret == NULL) {
777 Py_INCREF(Py_None);
778 return Py_None;
780 return ret;
781 } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
782 GValue *n_value = g_value_get_boxed (value);
783 return pyg_value_as_pyobject(n_value, copy_boxed);
784 } else if (holds_value_array) {
785 GValueArray *array = (GValueArray *) g_value_get_boxed(value);
786 Py_ssize_t n_values = array ? array->n_values : 0;
787 PyObject *ret = PyList_New(n_values);
788 int i;
789 for (i = 0; i < n_values; ++i)
790 PyList_SET_ITEM(ret, i, pyg_value_as_pyobject
791 (array->values + i, copy_boxed));
792 return ret;
793 } else if (G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
794 GString *string = (GString *) g_value_get_boxed(value);
795 PyObject *ret = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len);
796 return ret;
798 bm = pyg_type_lookup(G_VALUE_TYPE(value));
799 if (bm) {
800 return bm->fromvalue(value);
801 } else {
802 if (copy_boxed)
803 return pyg_boxed_new(G_VALUE_TYPE(value),
804 g_value_get_boxed(value), TRUE, TRUE);
805 else
806 return pyg_boxed_new(G_VALUE_TYPE(value),
807 g_value_get_boxed(value),FALSE,FALSE);
810 case G_TYPE_PARAM:
811 return pyg_param_spec_new(g_value_get_param(value));
812 case G_TYPE_OBJECT:
813 return pygobject_new(g_value_get_object(value));
814 case G_TYPE_VARIANT:
816 GVariant *v = g_value_get_variant(value);
817 if (v == NULL) {
818 Py_INCREF(Py_None);
819 return Py_None;
821 return _pygi_struct_new_from_g_type (G_TYPE_VARIANT, g_variant_ref(v), FALSE);
823 default:
825 PyGTypeMarshal *bm;
826 if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))))
827 return bm->fromvalue(value);
828 break;
832 return NULL;
837 * pyg_value_as_pyobject:
838 * @value: the GValue object.
839 * @copy_boxed: true if boxed values should be copied.
841 * This function creates/returns a Python wrapper object that
842 * represents the GValue passed as an argument.
844 * Returns: a PyObject representing the value or %NULL and sets an exception.
846 PyObject *
847 pyg_value_as_pyobject (const GValue *value, gboolean copy_boxed)
849 PyObject *pyobj;
850 const gchar *type_name;
851 GType fundamental = G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value));
853 /* HACK: special case char and uchar to return PyBytes intstead of integers
854 * in the general case. Property access will skip this by calling
855 * pygi_value_to_py_basic_type() directly.
856 * See: https://bugzilla.gnome.org/show_bug.cgi?id=733893 */
857 if (fundamental == G_TYPE_CHAR) {
858 gint8 val = g_value_get_schar(value);
859 return PYGLIB_PyUnicode_FromStringAndSize ((char *)&val, 1);
860 } else if (fundamental == G_TYPE_UCHAR) {
861 guint8 val = g_value_get_uchar(value);
862 return PYGLIB_PyBytes_FromStringAndSize ((char *)&val, 1);
865 pyobj = pygi_value_to_py_basic_type (value, fundamental);
866 if (pyobj) {
867 return pyobj;
870 pyobj = pygi_value_to_py_structured_type (value, fundamental, copy_boxed);
871 if (pyobj) {
872 return pyobj;
875 if (!PyErr_Occurred ()) {
876 type_name = g_type_name (G_VALUE_TYPE (value));
877 if (type_name == NULL) {
878 type_name = "(null)";
880 PyErr_Format (PyExc_TypeError, "unknown type %s", type_name);
883 return NULL;
889 pyg_param_gvalue_from_pyobject(GValue* value,
890 PyObject* py_obj,
891 const GParamSpec* pspec)
893 if (G_IS_PARAM_SPEC_UNICHAR(pspec)) {
894 gunichar u;
896 if (!pyg_pyobj_to_unichar_conv(py_obj, &u)) {
897 PyErr_Clear();
898 return -1;
900 g_value_set_uint(value, u);
901 return 0;
903 else if (G_IS_PARAM_SPEC_VALUE_ARRAY(pspec))
904 return pyg_value_array_from_pyobject(value, py_obj,
905 G_PARAM_SPEC_VALUE_ARRAY(pspec));
906 else {
907 return pyg_value_from_pyobject(value, py_obj);
911 PyObject*
912 pyg_param_gvalue_as_pyobject(const GValue* gvalue,
913 gboolean copy_boxed,
914 const GParamSpec* pspec)
916 if (G_IS_PARAM_SPEC_UNICHAR(pspec)) {
917 gunichar u;
918 Py_UNICODE uni_buffer[2] = { 0, 0 };
920 u = g_value_get_uint(gvalue);
921 uni_buffer[0] = u;
922 return PyUnicode_FromUnicode(uni_buffer, 1);
924 else {
925 return pyg_value_as_pyobject(gvalue, copy_boxed);
929 PyObject *
930 pyg_strv_from_gvalue(const GValue *value)
932 gchar **argv = (gchar **) g_value_get_boxed(value);
933 int argc = 0, i;
934 PyObject *py_argv;
936 if (argv) {
937 while (argv[argc])
938 argc++;
940 py_argv = PyList_New(argc);
941 for (i = 0; i < argc; ++i)
942 PyList_SET_ITEM(py_argv, i, PYGLIB_PyUnicode_FromString(argv[i]));
943 return py_argv;
947 pyg_strv_to_gvalue(GValue *value, PyObject *obj)
949 Py_ssize_t argc, i;
950 gchar **argv;
952 if (!(PyTuple_Check (obj) || PyList_Check (obj)))
953 return -1;
955 argc = PySequence_Length (obj);
956 argv = g_new (gchar *, argc + 1);
957 for (i = 0; i < argc; ++i) {
958 PyObject* item = PySequence_Fast_GET_ITEM (obj, i);
959 /* same as _pygi_marshal_from_py_utf8 */
960 if (PyUnicode_Check (item)) {
961 PyObject *pystr_obj = PyUnicode_AsUTF8String (item);
962 if (!pystr_obj) {
963 goto error;
965 argv[i] = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
966 Py_DECREF (pystr_obj);
968 #if PY_VERSION_HEX < 0x03000000
969 else if (PyString_Check (item)) {
970 argv[i] = g_strdup (PyString_AsString (item));
972 #endif
973 else {
974 goto error;
978 argv[i] = NULL;
979 g_value_take_boxed (value, argv);
980 return 0;
982 error:
983 for (i = i - 1; i >= 0; i--) {
984 g_free (argv[i]);
986 g_free (argv);
987 return -1;