Imported Upstream version 2.90.4
[platform/upstream/pygobject2.git] / gi / pygi-marshal-from-py.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>,  Red Hat, Inc.
5  *
6  *   pygi-marshal-from-py.c: Functions to convert PyObjects to C types.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23
24 #include "pygi-private.h"
25
26 #include <string.h>
27 #include <time.h>
28
29 #include <datetime.h>
30 #include <pygobject.h>
31 #include <pyglib-python-compat.h>
32
33 #include "pygi-cache.h"
34 #include "pygi-marshal-cleanup.h"
35 #include "pygi-marshal-from-py.h"
36
37 gboolean
38 _pygi_marshal_from_py_void (PyGIInvokeState   *state,
39                             PyGICallableCache *callable_cache,
40                             PyGIArgCache      *arg_cache,
41                             PyObject          *py_arg,
42                             GIArgument        *arg)
43 {
44     g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING);
45
46     arg->v_pointer = py_arg;
47
48     return TRUE;
49 }
50
51 gboolean
52 _pygi_marshal_from_py_boolean (PyGIInvokeState   *state,
53                                PyGICallableCache *callable_cache,
54                                PyGIArgCache      *arg_cache,
55                                PyObject          *py_arg,
56                                GIArgument        *arg)
57 {
58     arg->v_boolean = PyObject_IsTrue (py_arg);
59
60     return TRUE;
61 }
62
63 gboolean
64 _pygi_marshal_from_py_int8 (PyGIInvokeState   *state,
65                             PyGICallableCache *callable_cache,
66                             PyGIArgCache      *arg_cache,
67                             PyObject          *py_arg,
68                             GIArgument        *arg)
69 {
70     PyObject *py_long;
71     long long_;
72
73     if (!PyNumber_Check (py_arg)) {
74         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
75                       py_arg->ob_type->tp_name);
76         return FALSE;
77     }
78
79     py_long = PYGLIB_PyNumber_Long (py_arg);
80     if (!py_long)
81         return FALSE;
82
83     long_ = PYGLIB_PyLong_AsLong (py_long);
84     Py_DECREF (py_long);
85
86     if (PyErr_Occurred ()) {
87         PyErr_Clear ();
88         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -128, 127);
89         return FALSE;
90     }
91
92     if (long_ < -128 || long_ > 127) {
93         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -128, 127);
94         return FALSE;
95     }
96
97     arg->v_long = long_;
98
99     return TRUE;
100 }
101
102 gboolean
103 _pygi_marshal_from_py_uint8 (PyGIInvokeState   *state,
104                              PyGICallableCache *callable_cache,
105                              PyGIArgCache      *arg_cache,
106                              PyObject          *py_arg,
107                              GIArgument        *arg)
108 {
109     unsigned long long_;
110
111     if (PYGLIB_PyBytes_Check (py_arg)) {
112
113         if (PYGLIB_PyBytes_Size (py_arg) != 1) {
114             PyErr_Format (PyExc_TypeError, "Must be a single character");
115             return FALSE;
116         }
117
118         long_ = (unsigned char)(PYGLIB_PyBytes_AsString (py_arg)[0]);
119
120     } else if (PyNumber_Check (py_arg)) {
121         PyObject *py_long;
122         py_long = PYGLIB_PyNumber_Long (py_arg);
123         if (!py_long)
124             return FALSE;
125
126         long_ = PYGLIB_PyLong_AsLong (py_long);
127         Py_DECREF (py_long);
128
129         if (PyErr_Occurred ()) {
130             PyErr_Clear();
131
132             PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, 0, 255);
133             return FALSE;
134         }
135     } else {
136         PyErr_Format (PyExc_TypeError, "Must be number or single byte string, not %s",
137                       py_arg->ob_type->tp_name);
138         return FALSE;
139     }
140
141     if (long_ < 0 || long_ > 255) {
142         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, 0, 255);
143         return FALSE;
144     }
145
146     arg->v_long = long_;
147
148     return TRUE;
149 }
150
151 gboolean
152 _pygi_marshal_from_py_int16 (PyGIInvokeState   *state,
153                              PyGICallableCache *callable_cache,
154                              PyGIArgCache      *arg_cache,
155                              PyObject          *py_arg,
156                              GIArgument        *arg)
157 {
158     PyObject *py_long;
159     long long_;
160
161     if (!PyNumber_Check (py_arg)) {
162         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
163                       py_arg->ob_type->tp_name);
164         return FALSE;
165     }
166
167     py_long = PYGLIB_PyNumber_Long (py_arg);
168     if (!py_long)
169         return FALSE;
170
171     long_ = PYGLIB_PyLong_AsLong (py_long);
172     Py_DECREF (py_long);
173
174     if (PyErr_Occurred ()) {
175         PyErr_Clear ();
176         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -32768, 32767);
177         return FALSE;
178     }
179
180     if (long_ < -32768 || long_ > 32767) {
181         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -32768, 32767);
182         return FALSE;
183     }
184
185     arg->v_long = long_;
186
187     return TRUE;
188 }
189
190 gboolean
191 _pygi_marshal_from_py_uint16 (PyGIInvokeState   *state,
192                               PyGICallableCache *callable_cache,
193                               PyGIArgCache      *arg_cache,
194                               PyObject          *py_arg,
195                               GIArgument        *arg)
196 {
197     PyObject *py_long;
198     long long_;
199
200     if (!PyNumber_Check (py_arg)) {
201         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
202                       py_arg->ob_type->tp_name);
203         return FALSE;
204     }
205
206     py_long = PYGLIB_PyNumber_Long (py_arg);
207     if (!py_long)
208         return FALSE;
209
210     long_ = PYGLIB_PyLong_AsLong (py_long);
211     Py_DECREF (py_long);
212
213     if (PyErr_Occurred ()) {
214         PyErr_Clear ();
215         PyErr_Format (PyExc_ValueError, "%li not in range %d to %d", long_, 0, 65535);
216         return FALSE;
217     }
218
219     if (long_ < 0 || long_ > 65535) {
220         PyErr_Format (PyExc_ValueError, "%li not in range %d to %d", long_, 0, 65535);
221         return FALSE;
222     }
223
224     arg->v_long = long_;
225
226     return TRUE;
227 }
228
229 gboolean
230 _pygi_marshal_from_py_int32 (PyGIInvokeState   *state,
231                              PyGICallableCache *callable_cache,
232                              PyGIArgCache      *arg_cache,
233                              PyObject          *py_arg,
234                              GIArgument        *arg)
235 {
236     PyObject *py_long;
237     long long_;
238
239     if (!PyNumber_Check (py_arg)) {
240         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
241                       py_arg->ob_type->tp_name);
242         return FALSE;
243     }
244
245     py_long = PYGLIB_PyNumber_Long (py_arg);
246     if (!py_long)
247         return FALSE;
248
249     long_ = PYGLIB_PyLong_AsLong (py_long);
250     Py_DECREF (py_long);
251
252     if (PyErr_Occurred ()) {
253         PyErr_Clear();
254         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, G_MININT32, G_MAXINT32);
255         return FALSE;
256     }
257
258     if (long_ < G_MININT32 || long_ > G_MAXINT32) {
259         PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, G_MININT32, G_MAXINT32);
260         return FALSE;
261     }
262
263     arg->v_long = long_;
264
265     return TRUE;
266 }
267
268 gboolean
269 _pygi_marshal_from_py_uint32 (PyGIInvokeState   *state,
270                               PyGICallableCache *callable_cache,
271                               PyGIArgCache      *arg_cache,
272                               PyObject          *py_arg,
273                               GIArgument        *arg)
274 {
275     PyObject *py_long;
276     long long long_;
277
278     if (!PyNumber_Check (py_arg)) {
279         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
280                       py_arg->ob_type->tp_name);
281         return FALSE;
282     }
283
284     py_long = PYGLIB_PyNumber_Long (py_arg);
285     if (!py_long)
286         return FALSE;
287
288 #if PY_VERSION_HEX < 0x03000000
289     if (PyInt_Check (py_long))
290         long_ = PyInt_AsLong (py_long);
291     else
292 #endif
293         long_ = PyLong_AsLongLong (py_long);
294
295     Py_DECREF (py_long);
296
297     if (PyErr_Occurred ()) {
298         PyErr_Clear ();
299         PyErr_Format (PyExc_ValueError, "%lli not in range %i to %u", long_, 0, G_MAXUINT32);
300         return FALSE;
301     }
302
303     if (long_ < 0 || long_ > G_MAXUINT32) {
304         PyErr_Format (PyExc_ValueError, "%lli not in range %i to %u", long_, 0, G_MAXUINT32);
305         return FALSE;
306     }
307
308     arg->v_uint64 = long_;
309
310     return TRUE;
311 }
312
313 gboolean
314 _pygi_marshal_from_py_int64 (PyGIInvokeState   *state,
315                              PyGICallableCache *callable_cache,
316                              PyGIArgCache      *arg_cache,
317                              PyObject          *py_arg,
318                              GIArgument        *arg)
319 {
320     PyObject *py_long;
321     long long long_;
322
323     if (!PyNumber_Check (py_arg)) {
324         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
325                       py_arg->ob_type->tp_name);
326         return FALSE;
327     }
328
329     py_long = PYGLIB_PyNumber_Long (py_arg);
330     if (!py_long)
331         return FALSE;
332
333 #if PY_VERSION_HEX < 0x03000000
334     if (PyInt_Check (py_long))
335         long_ = PyInt_AS_LONG (py_long);
336     else
337 #endif
338         long_ = PyLong_AsLongLong (py_long);
339
340     Py_DECREF (py_long);
341
342     if (PyErr_Occurred ()) {
343         /* OverflowError occured but range errors should be returned as ValueError */
344         char *long_str;
345         PyObject *py_str;
346
347         PyErr_Clear ();
348
349         py_str = PyObject_Str (py_long);
350
351         if (PyUnicode_Check (py_str)) {
352             PyObject *py_bytes = PyUnicode_AsUTF8String (py_str);
353             if (py_bytes == NULL)
354                 return FALSE;
355
356             long_str = g_strdup (PYGLIB_PyBytes_AsString (py_bytes));
357             if (long_str == NULL) {
358                 PyErr_NoMemory ();
359                 return FALSE;
360             }
361
362             Py_DECREF (py_bytes);
363         } else {
364             long_str = g_strdup (PYGLIB_PyBytes_AsString(py_str));
365         }
366
367         Py_DECREF (py_str);
368         PyErr_Format (PyExc_ValueError, "%s not in range %ld to %ld",
369                       long_str, G_MININT64, G_MAXINT64);
370
371         g_free (long_str);
372         return FALSE;
373     }
374
375     if (long_ < G_MININT64 || long_ > G_MAXINT64) {
376         PyErr_Format (PyExc_ValueError, "%lld not in range %ld to %ld", long_, G_MININT64, G_MAXINT64);
377         return FALSE;
378     }
379
380     arg->v_int64 = long_;
381
382     return TRUE;
383 }
384
385 gboolean
386 _pygi_marshal_from_py_uint64 (PyGIInvokeState   *state,
387                               PyGICallableCache *callable_cache,
388                               PyGIArgCache      *arg_cache,
389                               PyObject          *py_arg,
390                               GIArgument        *arg)
391 {
392     PyObject *py_long;
393     guint64 ulong_;
394
395     if (!PyNumber_Check (py_arg)) {
396         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
397                       py_arg->ob_type->tp_name);
398         return FALSE;
399     }
400
401     py_long = PYGLIB_PyNumber_Long (py_arg);
402     if (!py_long)
403         return FALSE;
404
405 #if PY_VERSION_HEX < 0x03000000
406     if (PyInt_Check (py_long)) {
407         long long_ = PyInt_AsLong (py_long);
408         if (long_ < 0) {
409             PyErr_Format (PyExc_ValueError, "%ld not in range %d to %llu",
410                           long_, 0, G_MAXUINT64);
411             return FALSE;
412         }
413         ulong_ = long_;
414     } else
415 #endif
416         ulong_ = PyLong_AsUnsignedLongLong (py_long);
417
418     Py_DECREF (py_long);
419
420     if (PyErr_Occurred ()) {
421         /* OverflowError occured but range errors should be returned as ValueError */
422         char *long_str;
423         PyObject *py_str;
424
425         PyErr_Clear ();
426
427         py_str = PyObject_Str (py_long);
428
429         if (PyUnicode_Check (py_str)) {
430             PyObject *py_bytes = PyUnicode_AsUTF8String (py_str);
431             if (py_bytes == NULL)
432                 return FALSE;
433
434             long_str = g_strdup (PYGLIB_PyBytes_AsString (py_bytes));
435             if (long_str == NULL) {
436                 PyErr_NoMemory ();
437                 return FALSE;
438             }
439
440             Py_DECREF (py_bytes);
441         } else {
442             long_str = g_strdup (PYGLIB_PyBytes_AsString (py_str));
443         }
444
445         Py_DECREF (py_str);
446
447         PyErr_Format (PyExc_ValueError, "%s not in range %d to %llu",
448                       long_str, 0, G_MAXUINT64);
449
450         g_free (long_str);
451         return FALSE;
452     }
453
454     if (ulong_ > G_MAXUINT64) {
455         PyErr_Format (PyExc_ValueError, "%llu not in range %d to %llu", ulong_, 0, G_MAXUINT64);
456         return FALSE;
457     }
458
459     arg->v_uint64 = ulong_;
460
461     return TRUE;
462 }
463
464 gboolean
465 _pygi_marshal_from_py_float (PyGIInvokeState   *state,
466                              PyGICallableCache *callable_cache,
467                              PyGIArgCache      *arg_cache,
468                              PyObject          *py_arg,
469                              GIArgument        *arg)
470 {
471     PyObject *py_float;
472     double double_;
473
474     if (!PyNumber_Check (py_arg)) {
475         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
476                       py_arg->ob_type->tp_name);
477         return FALSE;
478     }
479
480     py_float = PyNumber_Float (py_arg);
481     if (!py_float)
482         return FALSE;
483
484     double_ = PyFloat_AsDouble (py_float);
485     Py_DECREF (py_float);
486
487     if (PyErr_Occurred ()) {
488         PyErr_Clear ();
489         PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXFLOAT, G_MAXFLOAT);
490         return FALSE;
491     }
492
493     if (double_ < -G_MAXFLOAT || double_ > G_MAXFLOAT) {
494         PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXFLOAT, G_MAXFLOAT);
495         return FALSE;
496     }
497
498     arg->v_float = double_;
499
500     return TRUE;
501 }
502
503 gboolean
504 _pygi_marshal_from_py_double (PyGIInvokeState   *state,
505                               PyGICallableCache *callable_cache,
506                               PyGIArgCache      *arg_cache,
507                               PyObject          *py_arg,
508                               GIArgument        *arg)
509 {
510     PyObject *py_float;
511     double double_;
512
513     if (!PyNumber_Check (py_arg)) {
514         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
515                       py_arg->ob_type->tp_name);
516         return FALSE;
517     }
518
519     py_float = PyNumber_Float (py_arg);
520     if (!py_float)
521         return FALSE;
522
523     double_ = PyFloat_AsDouble (py_float);
524     Py_DECREF (py_float);
525
526     if (PyErr_Occurred ()) {
527         PyErr_Clear ();
528         PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXDOUBLE, G_MAXDOUBLE);
529         return FALSE;
530     }
531
532     if (double_ < -G_MAXDOUBLE || double_ > G_MAXDOUBLE) {
533         PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXDOUBLE, G_MAXDOUBLE);
534         return FALSE;
535     }
536
537     arg->v_double = double_;
538
539     return TRUE;
540 }
541
542 gboolean
543 _pygi_marshal_from_py_unichar (PyGIInvokeState   *state,
544                                PyGICallableCache *callable_cache,
545                                PyGIArgCache      *arg_cache,
546                                PyObject          *py_arg,
547                                GIArgument        *arg)
548 {
549     Py_ssize_t size;
550     gchar *string_;
551
552     if (PyUnicode_Check (py_arg)) {
553        PyObject *py_bytes;
554
555        size = PyUnicode_GET_SIZE (py_arg);
556        py_bytes = PyUnicode_AsUTF8String (py_arg);
557        string_ = strdup(PYGLIB_PyBytes_AsString (py_bytes));
558        Py_DECREF (py_bytes);
559
560 #if PY_VERSION_HEX < 0x03000000
561     } else if (PyString_Check (py_arg)) {
562        PyObject *pyuni = PyUnicode_FromEncodedObject (py_arg, "UTF-8", "strict");
563        if (!pyuni)
564            return FALSE;
565
566        size = PyUnicode_GET_SIZE (pyuni);
567        string_ = g_strdup (PyString_AsString(py_arg));
568        Py_DECREF (pyuni);
569 #endif
570     } else {
571        PyErr_Format (PyExc_TypeError, "Must be string, not %s",
572                      py_arg->ob_type->tp_name);
573        return FALSE;
574     }
575
576     if (size != 1) {
577        PyErr_Format (PyExc_TypeError, "Must be a one character string, not %ld characters",
578                      size);
579        g_free (string_);
580        return FALSE;
581     }
582
583     arg->v_uint32 = g_utf8_get_char (string_);
584     g_free (string_);
585
586     return TRUE;
587 }
588 gboolean
589 _pygi_marshal_from_py_gtype (PyGIInvokeState   *state,
590                              PyGICallableCache *callable_cache,
591                              PyGIArgCache      *arg_cache,
592                              PyObject          *py_arg,
593                              GIArgument        *arg)
594 {
595     long type_ = pyg_type_from_object (py_arg);
596
597     if (type_ == 0) {
598         PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
599                       py_arg->ob_type->tp_name);
600         return FALSE;
601     }
602
603     arg->v_long = type_;
604     return TRUE;
605 }
606 gboolean
607 _pygi_marshal_from_py_utf8 (PyGIInvokeState   *state,
608                             PyGICallableCache *callable_cache,
609                             PyGIArgCache      *arg_cache,
610                             PyObject          *py_arg,
611                             GIArgument        *arg)
612 {
613     gchar *string_;
614
615     if (py_arg == Py_None) {
616         arg->v_pointer = NULL;
617         return TRUE;
618     }
619
620     if (PyUnicode_Check (py_arg)) {
621         PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
622         if (!pystr_obj)
623             return FALSE;
624
625         string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
626         Py_DECREF (pystr_obj);
627     }
628 #if PY_VERSION_HEX < 0x03000000
629     else if (PyString_Check (py_arg)) {
630         string_ = g_strdup (PyString_AsString (py_arg));
631     }
632 #endif
633     else {
634         PyErr_Format (PyExc_TypeError, "Must be string, not %s",
635                       py_arg->ob_type->tp_name);
636         return FALSE;
637     }
638
639     arg->v_string = string_;
640     return TRUE;
641 }
642
643 gboolean
644 _pygi_marshal_from_py_filename (PyGIInvokeState   *state,
645                                 PyGICallableCache *callable_cache,
646                                 PyGIArgCache      *arg_cache,
647                                 PyObject          *py_arg,
648                                 GIArgument        *arg)
649 {
650     gchar *string_;
651     GError *error = NULL;
652
653     if (PyUnicode_Check (py_arg)) {
654         PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
655         if (!pystr_obj)
656             return FALSE;
657
658         string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
659         Py_DECREF (pystr_obj);
660     }
661 #if PY_VERSION_HEX < 0x03000000
662     else if (PyString_Check (py_arg)) {
663         string_ = g_strdup (PyString_AsString (py_arg));
664     }
665 #endif
666     else {
667         PyErr_Format (PyExc_TypeError, "Must be string, not %s",
668                       py_arg->ob_type->tp_name);
669         return FALSE;
670     }
671
672     arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error);
673     g_free (string_);
674
675     if (arg->v_string == NULL) {
676         PyErr_SetString (PyExc_Exception, error->message);
677         g_error_free (error);
678         /* TODO: Convert the error to an exception. */
679         return FALSE;
680     }
681
682     return TRUE;
683 }
684
685 gboolean
686 _pygi_marshal_from_py_array (PyGIInvokeState   *state,
687                              PyGICallableCache *callable_cache,
688                              PyGIArgCache      *arg_cache,
689                              PyObject          *py_arg,
690                              GIArgument        *arg)
691 {
692     PyGIMarshalFromPyFunc from_py_marshaller;
693     int i;
694     Py_ssize_t length;
695     gssize item_size;
696     gboolean is_ptr_array;
697     GArray *array_ = NULL;
698     PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
699
700
701     if (py_arg == Py_None) {
702         arg->v_pointer = NULL;
703         return TRUE;
704     }
705
706     if (!PySequence_Check (py_arg)) {
707         PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
708                       py_arg->ob_type->tp_name);
709         return FALSE;
710     }
711
712     length = PySequence_Length (py_arg);
713     if (length < 0)
714         return FALSE;
715
716     if (sequence_cache->fixed_size >= 0 &&
717         sequence_cache->fixed_size != length) {
718         PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
719                       sequence_cache->fixed_size, length);
720
721         return FALSE;
722     }
723
724     item_size = sequence_cache->item_size;
725     is_ptr_array = (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY);
726     if (is_ptr_array) {
727         array_ = (GArray *)g_ptr_array_new ();
728     } else {
729         array_ = g_array_sized_new (sequence_cache->is_zero_terminated,
730                                     FALSE,
731                                     item_size,
732                                     length);
733     }
734
735     if (array_ == NULL) {
736         PyErr_NoMemory ();
737         return FALSE;
738     }
739
740     if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 &&
741         PYGLIB_PyBytes_Check (py_arg)) {
742         memcpy(array_->data, PYGLIB_PyBytes_AsString (py_arg), length);
743
744         goto array_success;
745     }
746
747     from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
748     for (i = 0; i < length; i++) {
749         GIArgument item;
750         PyObject *py_item = PySequence_GetItem (py_arg, i);
751         if (py_item == NULL)
752             goto err;
753
754         if (!from_py_marshaller ( state,
755                                   callable_cache,
756                                   sequence_cache->item_cache,
757                                   py_item,
758                                  &item))
759             goto err;
760
761         /* FIXME: it is much more efficent to have seperate marshaller
762          *        for ptr arrays than doing the evaluation
763          *        and casting each loop iteration
764          */
765         if (is_ptr_array) {
766             g_ptr_array_add((GPtrArray *)array_, item.v_pointer);
767         } else if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
768             PyGIInterfaceCache *item_iface_cache = (PyGIInterfaceCache *) sequence_cache->item_cache;
769             GIBaseInfo *base_info = (GIBaseInfo *) item_iface_cache->interface_info;
770             GIInfoType info_type = g_base_info_get_type (base_info);
771
772             switch (info_type) {
773                 case GI_INFO_TYPE_UNION:
774                 case GI_INFO_TYPE_STRUCT:
775                 {
776                     PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache;
777                     PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup;
778                     gboolean is_boxed = g_type_is_a (item_iface_cache->g_type, G_TYPE_BOXED);
779                     gboolean is_gvalue = item_iface_cache->g_type == G_TYPE_VALUE;
780
781                     if (!is_boxed || is_gvalue) {
782                         memcpy (array_->data + (i * item_size), item.v_pointer, item_size);
783                         if (from_py_cleanup)
784                             from_py_cleanup (state, item_arg_cache, item.v_pointer, TRUE);
785                     } else {
786                         g_array_insert_val (array_, i, item);
787                     }
788                     break;
789                 }
790                 default:
791                     g_array_insert_val (array_, i, item);
792             }
793         } else {
794             g_array_insert_val (array_, i, item);
795         }
796         continue;
797 err:
798         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
799             gsize j;
800             PyGIMarshalCleanupFunc cleanup_func =
801                 sequence_cache->item_cache->from_py_cleanup;
802
803             for(j = 0; j < i; j++) {
804                 cleanup_func (state,
805                               sequence_cache->item_cache,
806                               g_array_index (array_, gpointer, j),
807                               TRUE);
808             }
809         }
810
811         if (is_ptr_array)
812             g_ptr_array_free ( ( GPtrArray *)array_, TRUE);
813         else
814             g_array_free (array_, TRUE);
815         _PyGI_ERROR_PREFIX ("Item %i: ", i);
816         return FALSE;
817     }
818
819 array_success:
820     if (sequence_cache->len_arg_index >= 0) {
821         /* we have an child arg to handle */
822         PyGIArgCache *child_cache =
823             callable_cache->args_cache[sequence_cache->len_arg_index];
824
825         if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) {
826             gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer;
827             /* if we are not setup yet just set the in arg */
828             if (len_arg == NULL)
829                 state->in_args[child_cache->c_arg_index].v_long = length;
830             else
831                 *len_arg = length;
832         } else {
833             state->in_args[child_cache->c_arg_index].v_long = length;
834         }
835     }
836
837     if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
838         arg->v_pointer = array_->data;
839         g_array_free (array_, FALSE);
840     } else {
841         arg->v_pointer = array_;
842     }
843
844     return TRUE;
845 }
846
847 gboolean
848 _pygi_marshal_from_py_glist (PyGIInvokeState   *state,
849                              PyGICallableCache *callable_cache,
850                              PyGIArgCache      *arg_cache,
851                              PyObject          *py_arg,
852                              GIArgument        *arg)
853 {
854     PyGIMarshalFromPyFunc from_py_marshaller;
855     int i;
856     Py_ssize_t length;
857     GList *list_ = NULL;
858     PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
859
860
861     if (py_arg == Py_None) {
862         arg->v_pointer = NULL;
863         return TRUE;
864     }
865
866     if (!PySequence_Check (py_arg)) {
867         PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
868                       py_arg->ob_type->tp_name);
869         return FALSE;
870     }
871
872     length = PySequence_Length (py_arg);
873     if (length < 0)
874         return FALSE;
875
876     if (sequence_cache->fixed_size >= 0 &&
877         sequence_cache->fixed_size != length) {
878         PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
879                       sequence_cache->fixed_size, length);
880
881         return FALSE;
882     }
883
884     from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
885     for (i = 0; i < length; i++) {
886         GIArgument item;
887         PyObject *py_item = PySequence_GetItem (py_arg, i);
888         if (py_item == NULL)
889             goto err;
890
891         if (!from_py_marshaller ( state,
892                                   callable_cache,
893                                   sequence_cache->item_cache,
894                                   py_item,
895                                  &item))
896             goto err;
897
898         list_ = g_list_append (list_, item.v_pointer);
899         continue;
900 err:
901         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
902             PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup;
903         }
904
905         g_list_free (list_);
906         _PyGI_ERROR_PREFIX ("Item %i: ", i);
907         return FALSE;
908     }
909
910     arg->v_pointer = list_;
911     return TRUE;
912 }
913
914 gboolean
915 _pygi_marshal_from_py_gslist (PyGIInvokeState   *state,
916                               PyGICallableCache *callable_cache,
917                               PyGIArgCache      *arg_cache,
918                               PyObject          *py_arg,
919                               GIArgument        *arg)
920 {
921     PyGIMarshalFromPyFunc from_py_marshaller;
922     int i;
923     Py_ssize_t length;
924     GSList *list_ = NULL;
925     PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
926
927     if (py_arg == Py_None) {
928         arg->v_pointer = NULL;
929         return TRUE;
930     }
931
932     if (!PySequence_Check (py_arg)) {
933         PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
934                       py_arg->ob_type->tp_name);
935         return FALSE;
936     }
937
938     length = PySequence_Length (py_arg);
939     if (length < 0)
940         return FALSE;
941
942     if (sequence_cache->fixed_size >= 0 &&
943         sequence_cache->fixed_size != length) {
944         PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
945                       sequence_cache->fixed_size, length);
946
947         return FALSE;
948     }
949
950     from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
951     for (i = 0; i < length; i++) {
952         GIArgument item;
953         PyObject *py_item = PySequence_GetItem (py_arg, i);
954         if (py_item == NULL)
955             goto err;
956
957         if (!from_py_marshaller ( state,
958                              callable_cache,
959                              sequence_cache->item_cache,
960                              py_item,
961                             &item))
962             goto err;
963
964         list_ = g_slist_append (list_, item.v_pointer);
965         continue;
966 err:
967         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
968             PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup;
969         }
970
971         g_slist_free (list_);
972         _PyGI_ERROR_PREFIX ("Item %i: ", i);
973         return FALSE;
974     }
975
976     arg->v_pointer = list_;
977     return TRUE;
978 }
979
980 gboolean
981 _pygi_marshal_from_py_ghash (PyGIInvokeState   *state,
982                              PyGICallableCache *callable_cache,
983                              PyGIArgCache      *arg_cache,
984                              PyObject          *py_arg,
985                              GIArgument        *arg)
986 {
987     PyGIMarshalFromPyFunc key_from_py_marshaller;
988     PyGIMarshalFromPyFunc value_from_py_marshaller;
989
990     int i;
991     Py_ssize_t length;
992     PyObject *py_keys, *py_values;
993
994     GHashFunc hash_func;
995     GEqualFunc equal_func;
996
997     GHashTable *hash_ = NULL;
998     PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
999
1000     if (py_arg == Py_None) {
1001         arg->v_pointer = NULL;
1002         return TRUE;
1003     }
1004
1005     py_keys = PyMapping_Keys (py_arg);
1006     if (py_keys == NULL) {
1007         PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
1008                       py_arg->ob_type->tp_name);
1009         return FALSE;
1010     }
1011
1012     length = PyMapping_Length (py_arg);
1013     if (length < 0) {
1014         Py_DECREF (py_keys);
1015         return FALSE;
1016     }
1017
1018     py_values = PyMapping_Values (py_arg);
1019     if (py_values == NULL) {
1020         Py_DECREF (py_keys);
1021         return FALSE;
1022     }
1023
1024     key_from_py_marshaller = hash_cache->key_cache->from_py_marshaller;
1025     value_from_py_marshaller = hash_cache->value_cache->from_py_marshaller;
1026
1027     switch (hash_cache->key_cache->type_tag) {
1028         case GI_TYPE_TAG_UTF8:
1029         case GI_TYPE_TAG_FILENAME:
1030             hash_func = g_str_hash;
1031             equal_func = g_str_equal;
1032             break;
1033         default:
1034             hash_func = NULL;
1035             equal_func = NULL;
1036     }
1037
1038     hash_ = g_hash_table_new (hash_func, equal_func);
1039     if (hash_ == NULL) {
1040         PyErr_NoMemory ();
1041         Py_DECREF (py_keys);
1042         Py_DECREF (py_values);
1043         return FALSE;
1044     }
1045
1046     for (i = 0; i < length; i++) {
1047         GIArgument key, value;
1048         PyObject *py_key = PyList_GET_ITEM (py_keys, i);
1049         PyObject *py_value = PyList_GET_ITEM (py_values, i);
1050         if (py_key == NULL || py_value == NULL)
1051             goto err;
1052
1053         if (!key_from_py_marshaller ( state,
1054                                       callable_cache,
1055                                       hash_cache->key_cache,
1056                                       py_key,
1057                                      &key))
1058             goto err;
1059
1060         if (!value_from_py_marshaller ( state,
1061                                         callable_cache,
1062                                         hash_cache->value_cache,
1063                                         py_value,
1064                                        &value))
1065             goto err;
1066
1067         g_hash_table_insert (hash_, key.v_pointer, value.v_pointer);
1068         continue;
1069 err:
1070         /* FIXME: cleanup hash keys and values */
1071         Py_XDECREF (py_key);
1072         Py_XDECREF (py_value);
1073         Py_DECREF (py_keys);
1074         Py_DECREF (py_values);
1075         g_hash_table_unref (hash_);
1076         _PyGI_ERROR_PREFIX ("Item %i: ", i);
1077         return FALSE;
1078     }
1079
1080     arg->v_pointer = hash_;
1081     return TRUE;
1082 }
1083
1084 gboolean
1085 _pygi_marshal_from_py_gerror (PyGIInvokeState   *state,
1086                               PyGICallableCache *callable_cache,
1087                               PyGIArgCache      *arg_cache,
1088                               PyObject          *py_arg,
1089                               GIArgument        *arg)
1090 {
1091     PyErr_Format (PyExc_NotImplementedError,
1092                   "Marshalling for GErrors is not implemented");
1093     return FALSE;
1094 }
1095
1096 gboolean
1097 _pygi_marshal_from_py_interface_callback (PyGIInvokeState   *state,
1098                                           PyGICallableCache *callable_cache,
1099                                           PyGIArgCache      *arg_cache,
1100                                           PyObject          *py_arg,
1101                                           GIArgument        *arg)
1102 {
1103     GICallableInfo *callable_info;
1104     PyGICClosure *closure;
1105     PyGIArgCache *user_data_cache = NULL;
1106     PyGIArgCache *destroy_cache = NULL;
1107     PyGICallbackCache *callback_cache;
1108     PyObject *py_user_data = NULL;
1109
1110     callback_cache = (PyGICallbackCache *)arg_cache;
1111
1112     if (callback_cache->user_data_index > 0) {
1113         user_data_cache = callable_cache->args_cache[callback_cache->user_data_index];
1114         if (user_data_cache->py_arg_index < state->n_py_in_args) {
1115             py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index);
1116             if (!py_user_data)
1117                 return FALSE;
1118         } else {
1119             py_user_data = Py_None;
1120             Py_INCREF (Py_None);
1121         }
1122     }
1123
1124     if (py_arg == Py_None && !(py_user_data == Py_None || py_user_data == NULL)) {
1125         Py_DECREF (py_user_data);
1126         PyErr_Format (PyExc_TypeError,
1127                       "When passing None for a callback userdata must also be None");
1128
1129         return FALSE;
1130     }
1131
1132     if (py_arg == Py_None) {
1133         Py_XDECREF (py_user_data);
1134         return TRUE;
1135     }
1136
1137     if (!PyCallable_Check (py_arg)) {
1138         Py_XDECREF (py_user_data);
1139         PyErr_Format (PyExc_TypeError,
1140                       "Callback needs to be a function or method not %s",
1141                       py_arg->ob_type->tp_name);
1142
1143         return FALSE;
1144     }
1145
1146     if (callback_cache->destroy_notify_index > 0)
1147         destroy_cache = callable_cache->args_cache[callback_cache->destroy_notify_index];
1148
1149     callable_info = (GICallableInfo *)callback_cache->interface_info;
1150
1151     closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data);
1152     arg->v_pointer = closure->closure;
1153     if (user_data_cache != NULL) {
1154         state->in_args[user_data_cache->c_arg_index].v_pointer = closure;
1155     }
1156
1157     if (destroy_cache) {
1158         PyGICClosure *destroy_notify = _pygi_destroy_notify_create ();
1159         state->in_args[destroy_cache->c_arg_index].v_pointer = destroy_notify->closure;
1160     }
1161
1162     return TRUE;
1163 }
1164
1165 gboolean
1166 _pygi_marshal_from_py_interface_enum (PyGIInvokeState   *state,
1167                                       PyGICallableCache *callable_cache,
1168                                       PyGIArgCache      *arg_cache,
1169                                       PyObject          *py_arg,
1170                                       GIArgument        *arg)
1171 {
1172     PyObject *int_;
1173     gint is_instance;
1174     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
1175
1176     is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
1177
1178     int_ = PYGLIB_PyNumber_Long (py_arg);
1179     if (int_ == NULL) {
1180         PyErr_Clear();
1181         goto err;
1182     }
1183
1184     arg->v_long = PYGLIB_PyLong_AsLong (int_);
1185     Py_DECREF (int_);
1186
1187     /* If this is not an instance of the Enum type that we want
1188      * we need to check if the value is equivilant to one of the
1189      * Enum's memebers */
1190     if (!is_instance) {
1191         int i;
1192         gboolean is_found = FALSE;
1193
1194         for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) {
1195             GIValueInfo *value_info =
1196                 g_enum_info_get_value (iface_cache->interface_info, i);
1197             glong enum_value = g_value_info_get_value (value_info);
1198             g_base_info_unref ( (GIBaseInfo *)value_info);
1199             if (arg->v_long == enum_value) {
1200                 is_found = TRUE;
1201                 break;
1202             }
1203         }
1204
1205         if (!is_found)
1206             goto err;
1207     }
1208
1209     return TRUE;
1210
1211 err:
1212     PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
1213                   iface_cache->type_name, py_arg->ob_type->tp_name);
1214     return FALSE;
1215 }
1216
1217 gboolean
1218 _pygi_marshal_from_py_interface_flags (PyGIInvokeState   *state,
1219                                        PyGICallableCache *callable_cache,
1220                                        PyGIArgCache      *arg_cache,
1221                                        PyObject          *py_arg,
1222                                        GIArgument        *arg)
1223 {
1224     PyObject *int_;
1225     gint is_instance;
1226     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
1227
1228     is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
1229
1230     int_ = PYGLIB_PyNumber_Long (py_arg);
1231     if (int_ == NULL) {
1232         PyErr_Clear ();
1233         goto err;
1234     }
1235
1236     arg->v_long = PYGLIB_PyLong_AsLong (int_);
1237     Py_DECREF (int_);
1238
1239     /* only 0 or argument of type Flag is allowed */
1240     if (!is_instance && arg->v_long != 0)
1241         goto err;
1242
1243     return TRUE;
1244
1245 err:
1246     PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
1247                   iface_cache->type_name, py_arg->ob_type->tp_name);
1248     return FALSE;
1249
1250 }
1251
1252 gboolean
1253 _pygi_marshal_from_py_interface_struct (PyGIInvokeState   *state,
1254                                         PyGICallableCache *callable_cache,
1255                                         PyGIArgCache      *arg_cache,
1256                                         PyObject          *py_arg,
1257                                         GIArgument        *arg)
1258 {
1259     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
1260
1261     if (py_arg == Py_None) {
1262         arg->v_pointer = NULL;
1263         return TRUE;
1264     }
1265
1266     /* FIXME: handle this large if statement in the cache
1267      *        and set the correct marshaller
1268      */
1269
1270     if (iface_cache->g_type == G_TYPE_CLOSURE) {
1271         GClosure *closure;
1272         GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE);
1273
1274         if ( !(PyCallable_Check(py_arg) || 
1275                g_type_is_a (object_gtype, G_TYPE_CLOSURE))) {
1276             PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
1277                           py_arg->ob_type->tp_name);
1278             return FALSE;
1279         }
1280
1281         if (g_type_is_a (object_gtype, G_TYPE_CLOSURE))
1282             closure = (GClosure *)pyg_boxed_get (py_arg, void);
1283         else
1284             closure = pyg_closure_new (py_arg, NULL, NULL);
1285
1286         if (closure == NULL) {
1287             PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
1288             return FALSE;
1289         }
1290
1291         arg->v_pointer = closure;
1292         return TRUE;
1293     } else if (iface_cache->g_type == G_TYPE_VALUE) {
1294         GValue *value;
1295         GType object_type;
1296
1297         object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
1298         if (object_type == G_TYPE_INVALID) {
1299             PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType");
1300             return FALSE;
1301         }
1302
1303         /* if already a gvalue, use that, else marshal into gvalue */
1304         if (object_type == G_TYPE_VALUE) {
1305             value = (GValue *)( (PyGObject *)py_arg)->obj;
1306         } else {
1307             value = g_slice_new0 (GValue);
1308             g_value_init (value, object_type);
1309             if (pyg_value_from_pyobject (value, py_arg) < 0) {
1310                 g_slice_free (GValue, value);
1311                 PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
1312                 return FALSE;
1313             }
1314         }
1315
1316         arg->v_pointer = value;
1317         return TRUE;
1318     } else if (iface_cache->is_foreign) {
1319         gboolean success;
1320         success = pygi_struct_foreign_convert_to_g_argument (py_arg,
1321                                                              iface_cache->interface_info,
1322                                                              arg_cache->transfer,
1323                                                              arg);
1324
1325         return success;
1326     } else if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
1327         PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
1328                       iface_cache->type_name,
1329                       iface_cache->py_type->ob_type->tp_name);
1330         return FALSE;
1331     }
1332
1333     if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
1334         arg->v_pointer = pyg_boxed_get (py_arg, void);
1335         if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
1336             arg->v_pointer = g_boxed_copy (iface_cache->g_type, arg->v_pointer);
1337         }
1338     } else if (g_type_is_a (iface_cache->g_type, G_TYPE_POINTER) ||
1339                    g_type_is_a (iface_cache->g_type, G_TYPE_VARIANT) ||
1340                        iface_cache->g_type  == G_TYPE_NONE) {
1341         arg->v_pointer = pyg_pointer_get (py_arg, void);
1342     } else {
1343         PyErr_Format (PyExc_NotImplementedError,
1344                       "structure type '%s' is not supported yet",
1345                       g_type_name(iface_cache->g_type));
1346         return FALSE;
1347     }
1348     return TRUE;
1349 }
1350
1351 gboolean
1352 _pygi_marshal_from_py_interface_boxed (PyGIInvokeState   *state,
1353                                        PyGICallableCache *callable_cache,
1354                                        PyGIArgCache      *arg_cache,
1355                                        PyObject          *py_arg,
1356                                        GIArgument        *arg)
1357 {
1358     PyErr_Format (PyExc_NotImplementedError,
1359                   "Marshalling for this type is not implemented yet");
1360     return FALSE;
1361 }
1362
1363 gboolean
1364 _pygi_marshal_from_py_interface_object (PyGIInvokeState   *state,
1365                                         PyGICallableCache *callable_cache,
1366                                         PyGIArgCache      *arg_cache,
1367                                         PyObject          *py_arg,
1368                                         GIArgument        *arg)
1369 {
1370     if (py_arg == Py_None) {
1371         arg->v_pointer = NULL;
1372         return TRUE;
1373     }
1374
1375     if (!PyObject_IsInstance (py_arg, ( (PyGIInterfaceCache *)arg_cache)->py_type)) {
1376         PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
1377                       ( (PyGIInterfaceCache *)arg_cache)->type_name,
1378                       ( (PyGIInterfaceCache *)arg_cache)->py_type->ob_type->tp_name);
1379         return FALSE;
1380     }
1381
1382     arg->v_pointer = pygobject_get(py_arg);
1383     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
1384         g_object_ref (arg->v_pointer);
1385
1386     return TRUE;
1387 }
1388
1389 gboolean
1390 _pygi_marshal_from_py_interface_union (PyGIInvokeState   *state,
1391                                        PyGICallableCache *callable_cache,
1392                                        PyGIArgCache      *arg_cache,
1393                                        PyObject          *py_arg,
1394                                        GIArgument        *arg)
1395 {
1396     PyErr_Format(PyExc_NotImplementedError,
1397                  "Marshalling for this type is not implemented yet");
1398     return FALSE;
1399 }
1400
1401 gboolean _pygi_marshal_from_py_interface_instance (PyGIInvokeState   *state,
1402                                                    PyGICallableCache *callable_cache,
1403                                                    PyGIArgCache      *arg_cache,
1404                                                    PyObject          *py_arg,
1405                                                    GIArgument        *arg)
1406 {
1407     GIInfoType info_type;
1408     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
1409
1410     info_type = g_base_info_get_type (iface_cache->interface_info);
1411     switch (info_type) {
1412         case GI_INFO_TYPE_UNION:
1413         case GI_INFO_TYPE_STRUCT:
1414         {
1415             GType type = iface_cache->g_type;
1416
1417             if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
1418                 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
1419                               iface_cache->type_name,
1420                               py_arg->ob_type->tp_name);
1421                 return FALSE;
1422             }
1423
1424             if (g_type_is_a (type, G_TYPE_BOXED)) {
1425                 arg->v_pointer = pyg_boxed_get (py_arg, void);
1426             } else if (g_type_is_a (type, G_TYPE_POINTER) ||
1427                            g_type_is_a (type, G_TYPE_VARIANT) ||
1428                                type == G_TYPE_NONE) {
1429                 arg->v_pointer = pyg_pointer_get (py_arg, void);
1430             } else {
1431                  PyErr_Format (PyExc_TypeError, "unable to convert an instance of '%s'", g_type_name (type));
1432                  return FALSE;
1433             }
1434
1435             break;
1436         }
1437         case GI_INFO_TYPE_OBJECT:
1438         case GI_INFO_TYPE_INTERFACE:
1439             arg->v_pointer = pygobject_get (py_arg);
1440             if (arg->v_pointer != NULL) {
1441                 GType obj_type = G_OBJECT_TYPE (( GObject *)arg->v_pointer);
1442                 GType expected_type = iface_cache->g_type;
1443
1444                 if (!g_type_is_a (obj_type, expected_type)) {
1445                     PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
1446                                   iface_cache->type_name,
1447                                   py_arg->ob_type->tp_name);
1448                     return FALSE;
1449                 }
1450             }
1451             break;
1452         default:
1453             /* Other types don't have methods. */
1454             g_assert_not_reached ();
1455    }
1456
1457    return TRUE;
1458 }