pygi-argument.c 67.6 KB
Newer Older
Simon van der Linden's avatar
Simon van der Linden committed
1 2 3 4 5
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
 *
Tomeu Vizoso's avatar
Tomeu Vizoso committed
6
 *   pygi-argument.c: GIArgument - PyObject conversion functions.
Simon van der Linden's avatar
Simon van der Linden committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 */

#include "pygi-private.h"
25
#include "pygobject-private.h"
Simon van der Linden's avatar
Simon van der Linden committed
26 27 28 29 30

#include <string.h>
#include <time.h>

#include <datetime.h>
31
#include <pyglib-python-compat.h>
32
#include <pyglib.h>
33

34 35
#include "pygi-marshal-from-py.h"
#include "pygi-marshal-to-py.h"
36
#include "pygi-basictype.h"
37
#include "pygi-object.h"
38
#include "pygi-struct-marshal.h"
39 40


David Malcolm's avatar
David Malcolm committed
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
static gboolean
gi_argument_to_gssize (GIArgument *arg_in,
                       GITypeTag  type_tag,
                       gssize *gssize_out)
{
    switch (type_tag) {
      case GI_TYPE_TAG_INT8:
          *gssize_out = arg_in->v_int8;
          return TRUE;
      case GI_TYPE_TAG_UINT8:
          *gssize_out = arg_in->v_uint8;
          return TRUE;
      case GI_TYPE_TAG_INT16:
          *gssize_out = arg_in->v_int16;
          return TRUE;
      case GI_TYPE_TAG_UINT16:
          *gssize_out = arg_in->v_uint16;
          return TRUE;
      case GI_TYPE_TAG_INT32:
          *gssize_out = arg_in->v_int32;
          return TRUE;
      case GI_TYPE_TAG_UINT32:
          *gssize_out = arg_in->v_uint32;
          return TRUE;
      case GI_TYPE_TAG_INT64:
          *gssize_out = arg_in->v_int64;
          return TRUE;
      case GI_TYPE_TAG_UINT64:
          *gssize_out = arg_in->v_uint64;
          return TRUE;
      default:
          PyErr_Format (PyExc_TypeError,
                        "Unable to marshal %s to gssize",
                        g_type_tag_to_string(type_tag));
          return FALSE;
    }
}

David Malcolm's avatar
David Malcolm committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92
void
_pygi_hash_pointer_to_arg (GIArgument *arg,
                           GITypeTag  type_tag)
{
    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
            arg->v_int8 = GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_INT16:
            arg->v_int16 = GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_INT32:
            arg->v_int32 = GPOINTER_TO_INT (arg->v_pointer);
            break;
93 94 95 96 97 98 99 100 101
        case GI_TYPE_TAG_UINT8:
            arg->v_uint8 = GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT16:
            arg->v_uint16 = GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT32:
            arg->v_uint32 = GPOINTER_TO_UINT (arg->v_pointer);
            break;
David Malcolm's avatar
David Malcolm committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
        case GI_TYPE_TAG_INTERFACE:
            break;
        default:
            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
    }
}

gpointer
_pygi_arg_to_hash_pointer (const GIArgument *arg,
                           GITypeTag        type_tag)
{
    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
            return GINT_TO_POINTER (arg->v_int8);
        case GI_TYPE_TAG_UINT8:
            return GINT_TO_POINTER (arg->v_uint8);
        case GI_TYPE_TAG_INT16:
            return GINT_TO_POINTER (arg->v_int16);
        case GI_TYPE_TAG_UINT16:
            return GINT_TO_POINTER (arg->v_uint16);
        case GI_TYPE_TAG_INT32:
            return GINT_TO_POINTER (arg->v_int32);
        case GI_TYPE_TAG_UINT32:
            return GINT_TO_POINTER (arg->v_uint32);
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
        case GI_TYPE_TAG_INTERFACE:
            return arg->v_pointer;
        default:
            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
            return arg->v_pointer;
    }
}

Simon van der Linden's avatar
Simon van der Linden committed
138 139 140 141 142
static void
_pygi_g_type_tag_py_bounds (GITypeTag   type_tag,
                            PyObject  **lower,
                            PyObject  **upper)
{
143
    switch (type_tag) {
Simon van der Linden's avatar
Simon van der Linden committed
144
        case GI_TYPE_TAG_INT8:
145 146
            *lower = PYGLIB_PyLong_FromLong (-128);
            *upper = PYGLIB_PyLong_FromLong (127);
Simon van der Linden's avatar
Simon van der Linden committed
147 148
            break;
        case GI_TYPE_TAG_UINT8:
149 150
            *upper = PYGLIB_PyLong_FromLong (255);
            *lower = PYGLIB_PyLong_FromLong (0);
Simon van der Linden's avatar
Simon van der Linden committed
151 152
            break;
        case GI_TYPE_TAG_INT16:
153 154
            *lower = PYGLIB_PyLong_FromLong (-32768);
            *upper = PYGLIB_PyLong_FromLong (32767);
Simon van der Linden's avatar
Simon van der Linden committed
155 156
            break;
        case GI_TYPE_TAG_UINT16:
157 158
            *upper = PYGLIB_PyLong_FromLong (65535);
            *lower = PYGLIB_PyLong_FromLong (0);
Simon van der Linden's avatar
Simon van der Linden committed
159 160
            break;
        case GI_TYPE_TAG_INT32:
161 162
            *lower = PYGLIB_PyLong_FromLong (G_MININT32);
            *upper = PYGLIB_PyLong_FromLong (G_MAXINT32);
Simon van der Linden's avatar
Simon van der Linden committed
163 164 165
            break;
        case GI_TYPE_TAG_UINT32:
            /* Note: On 32-bit archs, this number doesn't fit in a long. */
166
            *upper = PyLong_FromLongLong (G_MAXUINT32);
167
            *lower = PYGLIB_PyLong_FromLong (0);
Simon van der Linden's avatar
Simon van der Linden committed
168 169 170
            break;
        case GI_TYPE_TAG_INT64:
            /* Note: On 32-bit archs, these numbers don't fit in a long. */
171 172
            *lower = PyLong_FromLongLong (G_MININT64);
            *upper = PyLong_FromLongLong (G_MAXINT64);
Simon van der Linden's avatar
Simon van der Linden committed
173 174
            break;
        case GI_TYPE_TAG_UINT64:
175
            *upper = PyLong_FromUnsignedLongLong (G_MAXUINT64);
176
            *lower = PYGLIB_PyLong_FromLong (0);
Simon van der Linden's avatar
Simon van der Linden committed
177 178
            break;
        case GI_TYPE_TAG_FLOAT:
179 180
            *upper = PyFloat_FromDouble (G_MAXFLOAT);
            *lower = PyFloat_FromDouble (-G_MAXFLOAT);
Simon van der Linden's avatar
Simon van der Linden committed
181 182
            break;
        case GI_TYPE_TAG_DOUBLE:
183 184
            *upper = PyFloat_FromDouble (G_MAXDOUBLE);
            *lower = PyFloat_FromDouble (-G_MAXDOUBLE);
Simon van der Linden's avatar
Simon van der Linden committed
185 186
            break;
        default:
187
            PyErr_SetString (PyExc_TypeError, "Non-numeric type tag");
Simon van der Linden's avatar
Simon van der Linden committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
            *lower = *upper = NULL;
            return;
    }
}

gint
_pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
                                           gboolean              is_instance,
                                           PyObject             *object)
{
    gint retval;

    GType g_type;
    PyObject *py_type;
    gchar *type_name_expected = NULL;
Tomeu Vizoso's avatar
Tomeu Vizoso committed
203
    GIInfoType interface_type;
Simon van der Linden's avatar
Simon van der Linden committed
204

205 206 207
    interface_type = g_base_info_get_type (info);
    if ( (interface_type == GI_INFO_TYPE_STRUCT) &&
            (g_struct_info_is_foreign ( (GIStructInfo*) info))) {
Tomeu Vizoso's avatar
Tomeu Vizoso committed
208 209 210
        /* TODO: Could we check is the correct foreign type? */
        return 1;
    }
Simon van der Linden's avatar
Simon van der Linden committed
211

212
    g_type = g_registered_type_info_get_g_type (info);
Simon van der Linden's avatar
Simon van der Linden committed
213
    if (g_type != G_TYPE_NONE) {
214
        py_type = _pygi_type_get_from_g_type (g_type);
Simon van der Linden's avatar
Simon van der Linden committed
215
    } else {
216
        py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) info);
Simon van der Linden's avatar
Simon van der Linden committed
217 218 219
    }

    if (py_type == NULL) {
Tomeu Vizoso's avatar
Tomeu Vizoso committed
220
        return 0;
Simon van der Linden's avatar
Simon van der Linden committed
221 222
    }

223
    g_assert (PyType_Check (py_type));
Simon van der Linden's avatar
Simon van der Linden committed
224 225

    if (is_instance) {
226
        retval = PyObject_IsInstance (object, py_type);
Simon van der Linden's avatar
Simon van der Linden committed
227
        if (!retval) {
228 229
            type_name_expected = _pygi_g_base_info_get_fullname (
                                     (GIBaseInfo *) info);
Simon van der Linden's avatar
Simon van der Linden committed
230 231
        }
    } else {
232
        if (!PyObject_Type (py_type)) {
Simon van der Linden's avatar
Simon van der Linden committed
233 234
            type_name_expected = "type";
            retval = 0;
235 236 237 238
        } else if (!PyType_IsSubtype ( (PyTypeObject *) object,
                                       (PyTypeObject *) py_type)) {
            type_name_expected = _pygi_g_base_info_get_fullname (
                                     (GIBaseInfo *) info);
Simon van der Linden's avatar
Simon van der Linden committed
239 240 241 242 243 244
            retval = 0;
        } else {
            retval = 1;
        }
    }

245
    Py_DECREF (py_type);
Simon van der Linden's avatar
Simon van der Linden committed
246 247 248 249 250 251 252 253

    if (!retval) {
        PyTypeObject *object_type;

        if (type_name_expected == NULL) {
            return -1;
        }

254
        object_type = (PyTypeObject *) PyObject_Type (object);
Simon van der Linden's avatar
Simon van der Linden committed
255 256 257 258
        if (object_type == NULL) {
            return -1;
        }

259 260
        PyErr_Format (PyExc_TypeError, "Must be %s, not %s",
                      type_name_expected, object_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
261

262
        g_free (type_name_expected);
Simon van der Linden's avatar
Simon van der Linden committed
263 264 265 266 267
    }

    return retval;
}

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
gint
_pygi_g_type_interface_check_object (GIBaseInfo *info,
                                     PyObject   *object)
{
    gint retval = 1;
    GIInfoType info_type;

    info_type = g_base_info_get_type (info);
    switch (info_type) {
        case GI_INFO_TYPE_CALLBACK:
            if (!PyCallable_Check (object)) {
                PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
                              object->ob_type->tp_name);
                retval = 0;
            }
            break;
        case GI_INFO_TYPE_ENUM:
            retval = 0;
            if (PyNumber_Check (object)) {
                PyObject *number = PYGLIB_PyNumber_Long (object);
                if (number == NULL)
                    PyErr_Clear();
                else {
                    glong value = PYGLIB_PyLong_AsLong (number);
                    int i;
                    for (i = 0; i < g_enum_info_get_n_values (info); i++) {
                        GIValueInfo *value_info = g_enum_info_get_value (info, i);
                        glong enum_value = g_value_info_get_value (value_info);
296
                        g_base_info_unref (value_info);
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
                        if (value == enum_value) {
                            retval = 1;
                            break;
                        }
                    }
                }
            }
            if (retval < 1)
                retval = _pygi_g_registered_type_info_check_object (
                             (GIRegisteredTypeInfo *) info, TRUE, object);
            break;
        case GI_INFO_TYPE_FLAGS:
            if (PyNumber_Check (object)) {
                /* Accept 0 as a valid flag value */
                PyObject *number = PYGLIB_PyNumber_Long (object);
                if (number == NULL)
                    PyErr_Clear();
                else {
                    long value = PYGLIB_PyLong_AsLong (number);
                    if (value == 0)
                        break;
                    else if (value == -1)
                        PyErr_Clear();
                }
            }
            retval = _pygi_g_registered_type_info_check_object (
                         (GIRegisteredTypeInfo *) info, TRUE, object);
            break;
        case GI_INFO_TYPE_STRUCT:
        {
            GType type;

            /* Handle special cases. */
            type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
331
            if (g_type_is_a (type, G_TYPE_CLOSURE)) {
John (J5) Palmieri's avatar
John (J5) Palmieri committed
332 333
                if (!(PyCallable_Check (object) ||
                      pyg_type_from_object_strict (object, FALSE) == G_TYPE_CLOSURE)) {
334 335 336 337 338
                    PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
                                  object->ob_type->tp_name);
                    retval = 0;
                }
                break;
339 340 341 342
            } else if (g_type_is_a (type, G_TYPE_VALUE)) {
                /* we can't check g_values because we don't have 
                 * enough context so just pass them through */
                break;
343 344 345 346 347 348 349
            }

            /* Fallback. */
        }
        case GI_INFO_TYPE_BOXED:
        case GI_INFO_TYPE_INTERFACE:
        case GI_INFO_TYPE_OBJECT:
350 351
            retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object);
            break;
352
        case GI_INFO_TYPE_UNION:
353 354


355
            retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object);
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389

            /* If not the same type then check to see if the object's type
             * is the same as one of the union's members
             */
            if (retval == 0) {
                gint i;
                gint n_fields;

                n_fields = g_union_info_get_n_fields ( (GIUnionInfo *) info);

                for (i = 0; i < n_fields; i++) {
                    gint member_retval;
                    GIFieldInfo *field_info;
                    GITypeInfo *field_type_info;

                    field_info =
                        g_union_info_get_field ( (GIUnionInfo *) info, i);
                    field_type_info = g_field_info_get_type (field_info);

                    member_retval = _pygi_g_type_info_check_object(
                        field_type_info,
                        object,
                        TRUE);

                    g_base_info_unref ( ( GIBaseInfo *) field_type_info);
                    g_base_info_unref ( ( GIBaseInfo *) field_info);

                    if (member_retval == 1) {
                        retval = member_retval;
                        break;
                    }
                }
            }

390 391 392 393 394 395 396 397
            break;
        default:
            g_assert_not_reached();
    }

    return retval;
}

Simon van der Linden's avatar
Simon van der Linden committed
398 399
gint
_pygi_g_type_info_check_object (GITypeInfo *type_info,
400 401
                                PyObject   *object,
                                gboolean   allow_none)
Simon van der Linden's avatar
Simon van der Linden committed
402 403 404 405
{
    GITypeTag type_tag;
    gint retval = 1;

406 407 408 409
    if (allow_none && object == Py_None) {
        return retval;
    }

410
    type_tag = g_type_info_get_tag (type_info);
Simon van der Linden's avatar
Simon van der Linden committed
411 412 413

    switch (type_tag) {
        case GI_TYPE_TAG_VOID:
Tomeu Vizoso's avatar
Tomeu Vizoso committed
414
            /* No check; VOID means undefined type */
Simon van der Linden's avatar
Simon van der Linden committed
415 416 417 418 419
            break;
        case GI_TYPE_TAG_BOOLEAN:
            /* No check; every Python object has a truth value. */
            break;
        case GI_TYPE_TAG_UINT8:
420 421
        case GI_TYPE_TAG_INT8:
            /* (U)INT8 types can be characters */
422 423 424 425 426 427 428 429 430
            if (PYGLIB_PyBytes_Check(object)) {
                if (PYGLIB_PyBytes_Size(object) != 1) {
                    PyErr_Format (PyExc_TypeError, "Must be a single character");
                    retval = 0;
                    break;
                }

                break;
            }
Simon van der Linden's avatar
Simon van der Linden committed
431 432 433 434 435 436 437 438 439 440 441
        case GI_TYPE_TAG_INT16:
        case GI_TYPE_TAG_UINT16:
        case GI_TYPE_TAG_INT32:
        case GI_TYPE_TAG_UINT32:
        case GI_TYPE_TAG_INT64:
        case GI_TYPE_TAG_UINT64:
        case GI_TYPE_TAG_FLOAT:
        case GI_TYPE_TAG_DOUBLE:
        {
            PyObject *number, *lower, *upper;

442 443 444
            if (!PyNumber_Check (object)) {
                PyErr_Format (PyExc_TypeError, "Must be number, not %s",
                              object->ob_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
445 446 447 448 449
                retval = 0;
                break;
            }

            if (type_tag == GI_TYPE_TAG_FLOAT || type_tag == GI_TYPE_TAG_DOUBLE) {
450
                number = PyNumber_Float (object);
Simon van der Linden's avatar
Simon van der Linden committed
451
            } else {
452
                number = PYGLIB_PyNumber_Long (object);
Simon van der Linden's avatar
Simon van der Linden committed
453 454
            }

455
            _pygi_g_type_tag_py_bounds (type_tag, &lower, &upper);
Simon van der Linden's avatar
Simon van der Linden committed
456 457 458 459 460 461 462

            if (lower == NULL || upper == NULL || number == NULL) {
                retval = -1;
                goto check_number_release;
            }

            /* Check bounds */
463 464
            if (PyObject_RichCompareBool (lower, number, Py_GT)
                    || PyObject_RichCompareBool (upper, number, Py_LT)) {
Simon van der Linden's avatar
Simon van der Linden committed
465 466 467 468 469 470 471 472
                PyObject *lower_str;
                PyObject *upper_str;

                if (PyErr_Occurred()) {
                    retval = -1;
                    goto check_number_release;
                }

473 474
                lower_str = PyObject_Str (lower);
                upper_str = PyObject_Str (upper);
Simon van der Linden's avatar
Simon van der Linden committed
475 476 477 478 479
                if (lower_str == NULL || upper_str == NULL) {
                    retval = -1;
                    goto check_number_error_release;
                }

480
#if PY_VERSION_HEX < 0x03000000
481 482 483
                PyErr_Format (PyExc_ValueError, "Must range from %s to %s",
                              PyString_AS_STRING (lower_str),
                              PyString_AS_STRING (upper_str));
484 485
#else
                {
Paolo Borelli's avatar
Paolo Borelli committed
486
                    PyObject *lower_pybytes_obj;
487
                    PyObject *upper_pybytes_obj;
Paolo Borelli's avatar
Paolo Borelli committed
488 489 490

                    lower_pybytes_obj = PyUnicode_AsUTF8String (lower_str);
                    if (!lower_pybytes_obj) {
491
                        goto utf8_fail;
Paolo Borelli's avatar
Paolo Borelli committed
492
                    }
493

494
                    upper_pybytes_obj = PyUnicode_AsUTF8String (upper_str);
495 496 497 498
                    if (!upper_pybytes_obj) {
                        Py_DECREF(lower_pybytes_obj);
                        goto utf8_fail;
                    }
Simon van der Linden's avatar
Simon van der Linden committed
499

500 501 502 503 504 505 506 507
                    PyErr_Format (PyExc_ValueError, "Must range from %s to %s",
                                  PyBytes_AsString (lower_pybytes_obj),
                                  PyBytes_AsString (upper_pybytes_obj));
                    Py_DECREF (lower_pybytes_obj);
                    Py_DECREF (upper_pybytes_obj);
                }
utf8_fail:
#endif
Simon van der Linden's avatar
Simon van der Linden committed
508 509 510
                retval = 0;

check_number_error_release:
511 512
                Py_XDECREF (lower_str);
                Py_XDECREF (upper_str);
Simon van der Linden's avatar
Simon van der Linden committed
513 514 515
            }

check_number_release:
516 517 518
            Py_XDECREF (number);
            Py_XDECREF (lower);
            Py_XDECREF (upper);
Simon van der Linden's avatar
Simon van der Linden committed
519 520 521 522
            break;
        }
        case GI_TYPE_TAG_GTYPE:
        {
523
            if (pyg_type_from_object (object) == 0) {
524 525
                PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
                              object->ob_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
526 527 528 529
                retval = 0;
            }
            break;
        }
Paolo Borelli's avatar
Paolo Borelli committed
530
        case GI_TYPE_TAG_UNICHAR:
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
        {
            Py_ssize_t size;
            if (PyUnicode_Check (object)) {
                size = PyUnicode_GET_SIZE (object);
#if PY_VERSION_HEX < 0x03000000
            } else if (PyString_Check (object)) {
                PyObject *pyuni = PyUnicode_FromEncodedObject (object, "UTF-8", "strict");
                size = PyUnicode_GET_SIZE (pyuni);
                Py_DECREF(pyuni);
#endif
            } else {
                PyErr_Format (PyExc_TypeError, "Must be string, not %s",
                              object->ob_type->tp_name);
                retval = 0;
                break;
            }

            if (size != 1) {
549 550
                PyErr_Format (PyExc_TypeError, "Must be a one character string, not %" G_GINT64_FORMAT " characters",
                              (gint64)size);
551 552 553 554 555 556
                retval = 0;
                break;
            }

            break;
        }
Simon van der Linden's avatar
Simon van der Linden committed
557 558
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
559
            if (!PYGLIB_PyBaseString_Check (object) ) {
560 561
                PyErr_Format (PyExc_TypeError, "Must be string, not %s",
                              object->ob_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
562 563 564 565 566 567 568 569 570 571
                retval = 0;
            }
            break;
        case GI_TYPE_TAG_ARRAY:
        {
            gssize fixed_size;
            Py_ssize_t length;
            GITypeInfo *item_type_info;
            Py_ssize_t i;

572 573 574
            if (!PySequence_Check (object)) {
                PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
                              object->ob_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
575 576 577 578
                retval = 0;
                break;
            }

579
            length = PySequence_Length (object);
Simon van der Linden's avatar
Simon van der Linden committed
580 581 582 583 584
            if (length < 0) {
                retval = -1;
                break;
            }

585
            fixed_size = g_type_info_get_array_fixed_size (type_info);
Simon van der Linden's avatar
Simon van der Linden committed
586
            if (fixed_size >= 0 && length != fixed_size) {
587 588
                PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
                              fixed_size, length);
Simon van der Linden's avatar
Simon van der Linden committed
589 590 591 592
                retval = 0;
                break;
            }

593 594
            item_type_info = g_type_info_get_param_type (type_info, 0);
            g_assert (item_type_info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
595

596 597 598 599
            /* FIXME: This is insain.  We really should only check the first
             *        object and perhaps have a debugging mode.  Large arrays
             *        will cause apps to slow to a crawl.
             */
Simon van der Linden's avatar
Simon van der Linden committed
600 601 602
            for (i = 0; i < length; i++) {
                PyObject *item;

603
                item = PySequence_GetItem (object, i);
Simon van der Linden's avatar
Simon van der Linden committed
604 605 606 607 608
                if (item == NULL) {
                    retval = -1;
                    break;
                }

609
                retval = _pygi_g_type_info_check_object (item_type_info, item, TRUE);
Simon van der Linden's avatar
Simon van der Linden committed
610

611
                Py_DECREF (item);
Simon van der Linden's avatar
Simon van der Linden committed
612 613 614 615 616

                if (retval < 0) {
                    break;
                }
                if (!retval) {
617
                    _PyGI_ERROR_PREFIX ("Item %zd: ", i);
Simon van der Linden's avatar
Simon van der Linden committed
618 619 620 621
                    break;
                }
            }

622
            g_base_info_unref ( (GIBaseInfo *) item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
623 624 625 626 627 628 629

            break;
        }
        case GI_TYPE_TAG_INTERFACE:
        {
            GIBaseInfo *info;

630 631
            info = g_type_info_get_interface (type_info);
            g_assert (info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
632

633
            retval = _pygi_g_type_interface_check_object(info, object);
Simon van der Linden's avatar
Simon van der Linden committed
634

635
            g_base_info_unref (info);
Simon van der Linden's avatar
Simon van der Linden committed
636 637 638 639 640 641 642 643 644
            break;
        }
        case GI_TYPE_TAG_GLIST:
        case GI_TYPE_TAG_GSLIST:
        {
            Py_ssize_t length;
            GITypeInfo *item_type_info;
            Py_ssize_t i;

645 646 647
            if (!PySequence_Check (object)) {
                PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
                              object->ob_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
648 649 650 651
                retval = 0;
                break;
            }

652
            length = PySequence_Length (object);
Simon van der Linden's avatar
Simon van der Linden committed
653 654 655 656 657
            if (length < 0) {
                retval = -1;
                break;
            }

658 659
            item_type_info = g_type_info_get_param_type (type_info, 0);
            g_assert (item_type_info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
660 661 662 663

            for (i = 0; i < length; i++) {
                PyObject *item;

664
                item = PySequence_GetItem (object, i);
Simon van der Linden's avatar
Simon van der Linden committed
665 666 667 668 669
                if (item == NULL) {
                    retval = -1;
                    break;
                }

670
                retval = _pygi_g_type_info_check_object (item_type_info, item, TRUE);
Simon van der Linden's avatar
Simon van der Linden committed
671

672
                Py_DECREF (item);
Simon van der Linden's avatar
Simon van der Linden committed
673 674 675 676 677

                if (retval < 0) {
                    break;
                }
                if (!retval) {
678
                    _PyGI_ERROR_PREFIX ("Item %zd: ", i);
Simon van der Linden's avatar
Simon van der Linden committed
679 680 681 682
                    break;
                }
            }

683
            g_base_info_unref ( (GIBaseInfo *) item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
684 685 686 687 688 689 690 691 692 693 694
            break;
        }
        case GI_TYPE_TAG_GHASH:
        {
            Py_ssize_t length;
            PyObject *keys;
            PyObject *values;
            GITypeInfo *key_type_info;
            GITypeInfo *value_type_info;
            Py_ssize_t i;

695 696
            keys = PyMapping_Keys (object);
            if (keys == NULL) {
697 698
                PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
                              object->ob_type->tp_name);
Simon van der Linden's avatar
Simon van der Linden committed
699 700 701 702
                retval = 0;
                break;
            }

703
            length = PyMapping_Length (object);
Simon van der Linden's avatar
Simon van der Linden committed
704
            if (length < 0) {
705
                Py_DECREF (keys);
Simon van der Linden's avatar
Simon van der Linden committed
706 707 708 709
                retval = -1;
                break;
            }

710
            values = PyMapping_Values (object);
Simon van der Linden's avatar
Simon van der Linden committed
711 712
            if (values == NULL) {
                retval = -1;
713
                Py_DECREF (keys);
Simon van der Linden's avatar
Simon van der Linden committed
714 715 716
                break;
            }

717 718
            key_type_info = g_type_info_get_param_type (type_info, 0);
            g_assert (key_type_info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
719

720 721
            value_type_info = g_type_info_get_param_type (type_info, 1);
            g_assert (value_type_info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
722 723 724 725 726

            for (i = 0; i < length; i++) {
                PyObject *key;
                PyObject *value;

727 728
                key = PyList_GET_ITEM (keys, i);
                value = PyList_GET_ITEM (values, i);
Simon van der Linden's avatar
Simon van der Linden committed
729

730
                retval = _pygi_g_type_info_check_object (key_type_info, key, TRUE);
Simon van der Linden's avatar
Simon van der Linden committed
731 732 733 734
                if (retval < 0) {
                    break;
                }
                if (!retval) {
735
                    _PyGI_ERROR_PREFIX ("Key %zd :", i);
Simon van der Linden's avatar
Simon van der Linden committed
736 737 738
                    break;
                }

739
                retval = _pygi_g_type_info_check_object (value_type_info, value, TRUE);
Simon van der Linden's avatar
Simon van der Linden committed
740 741 742 743
                if (retval < 0) {
                    break;
                }
                if (!retval) {
744
                    _PyGI_ERROR_PREFIX ("Value %zd :", i);
Simon van der Linden's avatar
Simon van der Linden committed
745 746 747 748
                    break;
                }
            }

749 750 751 752
            g_base_info_unref ( (GIBaseInfo *) key_type_info);
            g_base_info_unref ( (GIBaseInfo *) value_type_info);
            Py_DECREF (values);
            Py_DECREF (keys);
Simon van der Linden's avatar
Simon van der Linden committed
753 754 755
            break;
        }
        case GI_TYPE_TAG_ERROR:
756
            PyErr_SetString (PyExc_NotImplementedError, "Error marshalling is not supported yet");
Simon van der Linden's avatar
Simon van der Linden committed
757 758 759 760 761 762 763
            /* TODO */
            break;
    }

    return retval;
}

764 765 766 767
/**
 * _pygi_argument_to_array
 * @arg: The argument to convert
 * @args: Arguments to method invocation, possibly contaning the array length.
768 769 770 771 772 773
 *        Set to %NULL if this is not for a method call or @args_values is
 *        specified.
 * @args_values: GValue Arguments to method invocation, possibly contaning the
 *               array length. Set to %NULL if this is not for a method call or
 *               @args is specified.
 * @callable_info: Info on the callable, if this a method call; otherwise %NULL
774 775 776 777 778 779 780 781 782 783 784 785 786 787
 * @type_info: The type info for @arg
 * @out_free_array: A return location for a gboolean that indicates whether
 *                  or not the wrapped GArray should be freed
 *
 * Make sure an array type argument is wrapped in a GArray.
 *
 * Note: This method can *not* be folded into _pygi_argument_to_object() because
 * arrays are special in the sense that they might require access to @args in
 * order to get the length.
 *
 * Returns: A GArray wrapping @arg. If @out_free_array has been set to TRUE then
 *          free the array with g_array_free() without freeing the data members.
 *          Otherwise don't free the array.
 */
Simon van der Linden's avatar
Simon van der Linden committed
788
GArray *
Tomeu Vizoso's avatar
Tomeu Vizoso committed
789 790
_pygi_argument_to_array (GIArgument  *arg,
                         GIArgument  *args[],
791
                         const GValue *args_values,
David Malcolm's avatar
David Malcolm committed
792
                         GICallableInfo *callable_info,                  
793 794
                         GITypeInfo  *type_info,
                         gboolean    *out_free_array)
Simon van der Linden's avatar
Simon van der Linden committed
795 796 797 798 799 800
{
    GITypeInfo *item_type_info;
    gboolean is_zero_terminated;
    gsize item_size;
    gssize length;
    GArray *g_array;
801 802
    
    g_return_val_if_fail (g_type_info_get_tag (type_info) == GI_TYPE_TAG_ARRAY, NULL);
Simon van der Linden's avatar
Simon van der Linden committed
803

804 805 806
    if (arg->v_pointer == NULL) {
        return NULL;
    }
807 808 809 810 811
    
    switch (g_type_info_get_array_type (type_info)) {
        case GI_ARRAY_TYPE_C:
            is_zero_terminated = g_type_info_is_zero_terminated (type_info);
            item_type_info = g_type_info_get_param_type (type_info, 0);
Simon van der Linden's avatar
Simon van der Linden committed
812

813
            item_size = _pygi_g_type_info_size (item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
814

815
            g_base_info_unref ( (GIBaseInfo *) item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
816

817 818 819 820 821
            if (is_zero_terminated) {
                length = g_strv_length (arg->v_pointer);
            } else {
                length = g_type_info_get_array_fixed_size (type_info);
                if (length < 0) {
822 823 824 825
                    gint length_arg_pos;
                    GIArgInfo length_arg_info;
                    GITypeInfo length_type_info;

826
                    if (G_UNLIKELY (args == NULL && args_values == NULL)) {
827 828 829 830 831 832
                        g_critical ("Unable to determine array length for %p",
                                    arg->v_pointer);
                        g_array = g_array_new (is_zero_terminated, FALSE, item_size);
                        *out_free_array = TRUE;
                        return g_array;
                    }
Simon van der Linden's avatar
Simon van der Linden committed
833

834 835
                    length_arg_pos = g_type_info_get_array_length (type_info);
                    g_assert (length_arg_pos >= 0);
David Malcolm's avatar
David Malcolm committed
836
                    g_assert (callable_info);
Martin Pitt's avatar
Martin Pitt committed
837 838
                    g_callable_info_load_arg (callable_info, length_arg_pos, &length_arg_info);
                    g_arg_info_load_type (&length_arg_info, &length_type_info);
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853

                    if (args != NULL) {
                        if (!gi_argument_to_gssize (args[length_arg_pos],
                                                    g_type_info_get_tag (&length_type_info),
                                                    &length))
                            return NULL;
                    } else {
                        /* get it from args_values */
                        GIArgument length_arg = _pygi_argument_from_g_value (&(args_values[length_arg_pos]),
                                &length_type_info);
                        if (!gi_argument_to_gssize (&length_arg,
                                                    g_type_info_get_tag (&length_type_info),
                                                    &length))
                            return NULL;
                    }
854 855
                }
            }
Simon van der Linden's avatar
Simon van der Linden committed
856

857
            g_assert (length >= 0);
858

859
            g_array = g_array_new (is_zero_terminated, FALSE, item_size);
Simon van der Linden's avatar
Simon van der Linden committed
860

861
            g_free (g_array->data);
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
            g_array->data = arg->v_pointer;
            g_array->len = length;
            *out_free_array = TRUE;
            break;
        case GI_ARRAY_TYPE_ARRAY:
        case GI_ARRAY_TYPE_BYTE_ARRAY:
            /* Note: GByteArray is really just a GArray */
            g_array = arg->v_pointer;
            *out_free_array = FALSE;
            break;
        case GI_ARRAY_TYPE_PTR_ARRAY:
        {
            GPtrArray *ptr_array = (GPtrArray*) arg->v_pointer;
            g_array = g_array_sized_new (FALSE, FALSE,
                                         sizeof(gpointer),
                                         ptr_array->len);
             g_array->data = (char*) ptr_array->pdata;
             g_array->len = ptr_array->len;
             *out_free_array = TRUE;
             break;
        }
        default:
            g_critical ("Unexpected array type %u",
                        g_type_info_get_array_type (type_info));
            g_array = NULL;
            break;
    }
Simon van der Linden's avatar
Simon van der Linden committed
889 890 891 892

    return g_array;
}

893 894 895 896 897 898 899
GIArgument
_pygi_argument_from_object (PyObject   *object,
                            GITypeInfo *type_info,
                            GITransfer  transfer)
{
    GIArgument arg;
    GITypeTag type_tag;
900
    gpointer cleanup_data = NULL;
901 902 903 904

    memset(&arg, 0, sizeof(GIArgument));
    type_tag = g_type_info_get_tag (type_info);

905 906
    /* Ignores cleanup data for now. */
    if (_pygi_marshal_from_py_basic_type (object, &arg, type_tag, transfer, &cleanup_data) ||
907
            PyErr_Occurred()) {
908 909 910 911
        return arg;
    }

    switch (type_tag) {
Simon van der Linden's avatar
Simon van der Linden committed
912 913 914 915 916 917 918 919 920 921
        case GI_TYPE_TAG_ARRAY:
        {
            Py_ssize_t length;
            gboolean is_zero_terminated;
            GITypeInfo *item_type_info;
            gsize item_size;
            GArray *array;
            GITransfer item_transfer;
            Py_ssize_t i;

922
            if (object == Py_None) {
923 924 925 926
                arg.v_pointer = NULL;
                break;
            }

927 928
            /* Note, strings are sequences, but we cannot accept them here */
            if (!PySequence_Check (object) || 
Martin Pitt's avatar
Martin Pitt committed
929 930 931 932
#if PY_VERSION_HEX < 0x03000000
                PyString_Check (object) || 
#endif
                PyUnicode_Check (object)) {
933 934 935 936
                PyErr_SetString (PyExc_TypeError, "expected sequence");
                break;
            }

937
            length = PySequence_Length (object);
Simon van der Linden's avatar
Simon van der Linden committed
938 939 940 941
            if (length < 0) {
                break;
            }

942 943
            is_zero_terminated = g_type_info_is_zero_terminated (type_info);
            item_type_info = g_type_info_get_param_type (type_info, 0);
Simon van der Linden's avatar
Simon van der Linden committed
944

Martin Pitt's avatar
Martin Pitt committed
945 946 947 948 949
            /* we handle arrays that are really strings specially, see below */
            if (g_type_info_get_tag (item_type_info) == GI_TYPE_TAG_UINT8)
               item_size = 1;
            else
               item_size = sizeof (GIArgument);
Simon van der Linden's avatar
Simon van der Linden committed
950

951
            array = g_array_sized_new (is_zero_terminated, FALSE, item_size, length);
Simon van der Linden's avatar
Simon van der Linden committed
952
            if (array == NULL) {
953
                g_base_info_unref ( (GIBaseInfo *) item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
954 955 956 957
                PyErr_NoMemory();
                break;
            }

958 959 960 961
            if (g_type_info_get_tag (item_type_info) == GI_TYPE_TAG_UINT8 &&
                PYGLIB_PyBytes_Check(object)) {

                memcpy(array->data, PYGLIB_PyBytes_AsString(object), length);
962
                array->len = length;
963 964 965 966
                goto array_success;
            }


Simon van der Linden's avatar
Simon van der Linden committed
967 968 969 970
            item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;

            for (i = 0; i < length; i++) {
                PyObject *py_item;
Tomeu Vizoso's avatar
Tomeu Vizoso committed
971
                GIArgument item;
Simon van der Linden's avatar
Simon van der Linden committed
972

973
                py_item = PySequence_GetItem (object, i);
Simon van der Linden's avatar
Simon van der Linden committed
974 975 976 977
                if (py_item == NULL) {
                    goto array_item_error;
                }

978
                item = _pygi_argument_from_object (py_item, item_type_info, item_transfer);
Simon van der Linden's avatar
Simon van der Linden committed
979

980
                Py_DECREF (py_item);
Simon van der Linden's avatar
Simon van der Linden committed
981 982 983 984 985

                if (PyErr_Occurred()) {
                    goto array_item_error;
                }

986
                g_array_insert_val (array, i, item);
Simon van der Linden's avatar
Simon van der Linden committed
987 988 989 990
                continue;

array_item_error:
                /* Free everything we have converted so far. */
Tomeu Vizoso's avatar
Tomeu Vizoso committed
991
                _pygi_argument_release ( (GIArgument *) &array, type_info,
992
                                         GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
Simon van der Linden's avatar
Simon van der Linden committed
993 994
                array = NULL;

995
                _PyGI_ERROR_PREFIX ("Item %zd: ", i);
Simon van der Linden's avatar
Simon van der Linden committed
996 997 998
                break;
            }

999
array_success:
Simon van der Linden's avatar
Simon van der Linden committed
1000 1001
            arg.v_pointer = array;

1002
            g_base_info_unref ( (GIBaseInfo *) item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
1003 1004 1005 1006 1007 1008 1009
            break;
        }
        case GI_TYPE_TAG_INTERFACE:
        {
            GIBaseInfo *info;
            GIInfoType info_type;

1010 1011
            info = g_type_info_get_interface (type_info);
            info_type = g_base_info_get_type (info);
Simon van der Linden's avatar
Simon van der Linden committed
1012 1013 1014

            switch (info_type) {
                case GI_INFO_TYPE_CALLBACK:
1015 1016
                    /* This should be handled in invoke() */
                    g_assert_not_reached();
Simon van der Linden's avatar
Simon van der Linden committed
1017 1018 1019
                    break;
                case GI_INFO_TYPE_BOXED:
                case GI_INFO_TYPE_STRUCT:
Tomeu Vizoso's avatar
Tomeu Vizoso committed
1020
                case GI_INFO_TYPE_UNION:
Simon van der Linden's avatar
Simon van der Linden committed
1021
                {
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
                    GType g_type;
                    PyObject *py_type;

                    g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
                    py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) info);

                    /* Note for G_TYPE_VALUE g_type:
                     * This will currently leak the GValue that is allocated and
                     * stashed in arg.v_pointer. Out argument marshaling for caller
                     * allocated GValues already pass in memory for the GValue.
                     * Further re-factoring is needed to fix this leak.
                     * See: https://bugzilla.gnome.org/show_bug.cgi?id=693405
                     */
1035 1036 1037 1038 1039 1040 1041 1042
                    _pygi_marshal_from_py_interface_struct (object,
                                                            &arg,
                                                            NULL, /*arg_name*/
                                                            info, /*interface_info*/
                                                            g_type,
                                                            py_type,
                                                            transfer,
                                                            FALSE, /*copy_reference*/
1043 1044
                                                            g_struct_info_is_foreign (info),
                                                            g_type_info_is_pointer (type_info));
1045 1046

                    Py_DECREF (py_type);
Simon van der Linden's avatar
Simon van der Linden committed
1047 1048 1049 1050 1051 1052 1053
                    break;
                }
                case GI_INFO_TYPE_ENUM:
                case GI_INFO_TYPE_FLAGS:
                {
                    PyObject *int_;

1054
                    int_ = PYGLIB_PyNumber_Long (object);
Simon van der Linden's avatar
Simon van der Linden committed
1055 1056 1057 1058
                    if (int_ == NULL) {
                        break;
                    }

David Malcolm's avatar
David Malcolm committed
1059
                    arg.v_int = PYGLIB_PyLong_AsLong (int_);
Simon van der Linden's avatar
Simon van der Linden committed
1060

1061
                    Py_DECREF (int_);
Simon van der Linden's avatar
Simon van der Linden committed
1062 1063 1064

                    break;
                }
1065
                case GI_INFO_TYPE_INTERFACE:
Simon van der Linden's avatar
Simon van der Linden committed
1066
                case GI_INFO_TYPE_OBJECT:
1067
                    /* An error within this call will result in a NULL arg */
1068
                    pygi_arg_gobject_out_arg_from_py (object, &arg, transfer);
Simon van der Linden's avatar
Simon van der Linden committed
1069
                    break;
1070

Simon van der Linden's avatar
Simon van der Linden committed
1071 1072 1073
                default:
                    g_assert_not_reached();
            }
1074
            g_base_info_unref (info);
Simon van der Linden's avatar
Simon van der Linden committed
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
            break;
        }
        case GI_TYPE_TAG_GLIST:
        case GI_TYPE_TAG_GSLIST:
        {
            Py_ssize_t length;
            GITypeInfo *item_type_info;
            GSList *list = NULL;
            GITransfer item_transfer;
            Py_ssize_t i;

1086 1087 1088 1089 1090
            if (object == Py_None) {
                arg.v_pointer = NULL;
                break;
            }

1091
            length = PySequence_Length (object);
Simon van der Linden's avatar
Simon van der Linden committed
1092 1093 1094 1095
            if (length < 0) {
                break;
            }

1096 1097
            item_type_info = g_type_info_get_param_type (type_info, 0);
            g_assert (item_type_info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
1098 1099 1100 1101 1102

            item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;

            for (i = length - 1; i >= 0; i--) {
                PyObject *py_item;
Tomeu Vizoso's avatar
Tomeu Vizoso committed
1103
                GIArgument item;
Simon van der Linden's avatar
Simon van der Linden committed
1104

1105
                py_item = PySequence_GetItem (object, i);
Simon van der Linden's avatar
Simon van der Linden committed
1106 1107 1108 1109
                if (py_item == NULL) {
                    goto list_item_error;
                }

1110
                item = _pygi_argument_from_object (py_item, item_type_info, item_transfer);
Simon van der Linden's avatar
Simon van der Linden committed
1111

1112
                Py_DECREF (py_item);
Simon van der Linden's avatar
Simon van der Linden committed
1113 1114 1115 1116 1117 1118

                if (PyErr_Occurred()) {
                    goto list_item_error;
                }

                if (type_tag == GI_TYPE_TAG_GLIST) {
1119
                    list = (GSList *) g_list_prepend ( (GList *) list, item.v_pointer);
Simon van der Linden's avatar
Simon van der Linden committed
1120
                } else {
1121
                    list = g_slist_prepend (list, item.v_pointer);
Simon van der Linden's avatar
Simon van der Linden committed
1122 1123 1124 1125 1126 1127
                }

                continue;

list_item_error:
                /* Free everything we have converted so far. */
Tomeu Vizoso's avatar
Tomeu Vizoso committed
1128
                _pygi_argument_release ( (GIArgument *) &list, type_info,
1129
                                         GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
Simon van der Linden's avatar
Simon van der Linden committed
1130 1131
                list = NULL;

1132
                _PyGI_ERROR_PREFIX ("Item %zd: ", i);
Simon van der Linden's avatar
Simon van der Linden committed
1133 1134 1135 1136 1137
                break;
            }

            arg.v_pointer = list;

1138
            g_base_info_unref ( (GIBaseInfo *) item_type_info);
Simon van der Linden's avatar
Simon van der Linden committed
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156

            break;
        }
        case GI_TYPE_TAG_GHASH:
        {
            Py_ssize_t length;
            PyObject *keys;
            PyObject *values;
            GITypeInfo *key_type_info;
            GITypeInfo *value_type_info;
            GITypeTag key_type_tag;
            GHashFunc hash_func;
            GEqualFunc equal_func;
            GHashTable *hash_table;
            GITransfer item_transfer;
            Py_ssize_t i;


1157 1158
            if (object == Py_None) {
                arg.v_pointer = NULL;
1159 1160 1161
                break;
            }

1162
            length = PyMapping_Length (object);
Simon van der Linden's avatar
Simon van der Linden committed
1163 1164 1165 1166
            if (length < 0) {
                break;
            }

1167
            keys = PyMapping_Keys (object);