Remove from EXTRA_DIST files we'd already be distributing
[dbus-python-phuang.git] / _dbus_bindings / containers.c
blob44dfe8d4651f38948436e9eaeab0b4a199ee99a4
1 /* D-Bus container types: Array, Dict and Struct.
2  *
3  * Copyright (C) 2006 Collabora Ltd.
4  *
5  * Licensed under the Academic Free License version 2.1
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
25 #include <Python.h>
26 #include <structmember.h>
28 #include <stdint.h>
30 #include "dbus_bindings-internal.h"
31 #include "types-internal.h"
33 /* Array ============================================================ */
35 PyDoc_STRVAR(Array_tp_doc,
36 "An array of similar items, implemented as a subtype of list.\n"
37 "\n"
38 "As currently implemented, an Array behaves just like a list, but\n"
39 "with the addition of a ``signature`` property set by the constructor;\n"
40 "conversion of its items to D-Bus types is only done when it's sent in\n"
41 "a Message. This might change in future so validation is done earlier.\n"
42 "\n"
43 "Constructor::\n"
44 "\n"
45 "    dbus.Array([iterable][, signature][, variant_level])\n"
46 "\n"
47 "``variant_level`` must be non-negative; the default is 0.\n"
48 "\n"
49 "``signature`` is the D-Bus signature string for a single element of the\n"
50 "array, or None. If not None it must represent a single complete type, the\n"
51 "type of a single array item; the signature of the whole Array may be\n"
52 "obtained by prepending ``a`` to the given signature.\n"
53 "\n"
54 "If None (the default), when the Array is sent over\n"
55 "D-Bus, the item signature will be guessed from the first element.\n"
56 "\n"
57 ":IVariables:\n"
58 "  `variant_level` : int\n"
59 "    Indicates how many nested Variant containers this object\n"
60 "    is contained in: if a message's wire format has a variant containing a\n"
61 "    variant containing an array, this is represented in Python by an\n"
62 "    Array with variant_level==2.\n"
65 static struct PyMemberDef Array_tp_members[] = {
66     {"signature", T_OBJECT, offsetof(DBusPyArray, signature), READONLY,
67      "The D-Bus signature of each element of this Array (a Signature "
68      "instance)"},
69     {"variant_level", T_LONG, offsetof(DBusPyArray, variant_level),
70      READONLY,
71      "The number of nested variants wrapping the real data. "
72      "0 if not in a variant."},
73     {NULL},
76 static void
77 Array_tp_dealloc (DBusPyArray *self)
79     Py_XDECREF(self->signature);
80     self->signature = NULL;
81     (PyList_Type.tp_dealloc)((PyObject *)self);
84 static PyObject *
85 Array_tp_repr(DBusPyArray *self)
87     PyObject *parent_repr = (PyList_Type.tp_repr)((PyObject *)self);
88     PyObject *sig_repr = PyObject_Repr(self->signature);
89     PyObject *my_repr = NULL;
90     long variant_level = self->variant_level;
92     if (!parent_repr) goto finally;
93     if (!sig_repr) goto finally;
94     if (variant_level > 0) {
95         my_repr = PyString_FromFormat("%s(%s, signature=%s, "
96                                       "variant_level=%ld)",
97                                       self->super.ob_type->tp_name,
98                                       PyString_AS_STRING(parent_repr),
99                                       PyString_AS_STRING(sig_repr),
100                                       variant_level);
101     }
102     else {
103         my_repr = PyString_FromFormat("%s(%s, signature=%s)",
104                                       self->super.ob_type->tp_name,
105                                       PyString_AS_STRING(parent_repr),
106                                       PyString_AS_STRING(sig_repr));
107     }
108 finally:
109     Py_XDECREF(parent_repr);
110     Py_XDECREF(sig_repr);
111     return my_repr;
114 static PyObject *
115 Array_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
117     PyObject *variant_level = NULL;
118     DBusPyArray *self = (DBusPyArray *)(PyList_Type.tp_new)(cls, args, kwargs);
120     /* variant_level is immutable, so handle it in __new__ rather than 
121     __init__ */
122     if (!self) return NULL;
123     Py_INCREF(Py_None);
124     self->signature = Py_None;
125     self->variant_level = 0;
126     if (kwargs) {
127         variant_level = PyDict_GetItem(kwargs, dbus_py_variant_level_const);
128     }
129     if (variant_level) {
130         self->variant_level = PyInt_AsLong(variant_level);
131         if (PyErr_Occurred()) {
132             Py_DECREF((PyObject *)self);
133             return NULL;
134         }
135     }
136     return (PyObject *)self;
139 static int
140 Array_tp_init (DBusPyArray *self, PyObject *args, PyObject *kwargs)
142     PyObject *obj = dbus_py_empty_tuple;
143     PyObject *signature = NULL;
144     PyObject *tuple;
145     PyObject *variant_level;
146     /* variant_level is accepted but ignored - it's immutable, so
147      * __new__ handles it */
148     static char *argnames[] = {"iterable", "signature", "variant_level", NULL};
150     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO:__init__", argnames,
151                                      &obj, &signature, &variant_level)) {
152         return -1;
153     }
155   /* convert signature from a borrowed ref of unknown type to an owned ref
156   of type Signature (or None) */
157     if (!signature) signature = Py_None;
158     if (signature == Py_None
159         || PyObject_IsInstance(signature, (PyObject *)&DBusPySignature_Type)) {
160         Py_INCREF(signature);
161     }
162     else {
163         signature = PyObject_CallFunction((PyObject *)&DBusPySignature_Type,
164                                           "(O)", signature);
165         if (!signature) return -1;
166     }
168     if (signature != Py_None) {
169         const char *c_str = PyString_AS_STRING(signature);
171         if (!dbus_signature_validate_single(c_str, NULL)) {
172             Py_DECREF(signature);
173             PyErr_SetString(PyExc_ValueError,
174                             "There must be exactly one complete type in "
175                             "an Array's signature parameter");
176             return -1;
177         }
178     }
180     tuple = Py_BuildValue("(O)", obj);
181     if (!tuple) {
182         Py_DECREF(signature);
183         return -1;
184     }
185     if ((PyList_Type.tp_init)((PyObject *)self, tuple, NULL) < 0) {
186         Py_DECREF(tuple);
187         Py_DECREF(signature);
188         return -1;
189     }
190     Py_DECREF(tuple);
192     Py_XDECREF(self->signature);
193     self->signature = signature;
194     return 0;
197 PyTypeObject DBusPyArray_Type = {
198     PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
199     0,
200     "dbus.Array",
201     sizeof(DBusPyArray),
202     0,
203     (destructor)Array_tp_dealloc,           /* tp_dealloc */
204     0,                                      /* tp_print */
205     0,                                      /* tp_getattr */
206     0,                                      /* tp_setattr */
207     0,                                      /* tp_compare */
208     (reprfunc)Array_tp_repr,                /* tp_repr */
209     0,                                      /* tp_as_number */
210     0,                                      /* tp_as_sequence */
211     0,                                      /* tp_as_mapping */
212     0,                                      /* tp_hash */
213     0,                                      /* tp_call */
214     0,                                      /* tp_str */
215     0,                                      /* tp_getattro */
216     0,                                      /* tp_setattro */
217     0,                                      /* tp_as_buffer */
218     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
219     Array_tp_doc,                           /* tp_doc */
220     0,                                      /* tp_traverse */
221     0,                                      /* tp_clear */
222     0,                                      /* tp_richcompare */
223     0,                                      /* tp_weaklistoffset */
224     0,                                      /* tp_iter */
225     0,                                      /* tp_iternext */
226     0,                                      /* tp_methods */
227     Array_tp_members,                       /* tp_members */
228     0,                                      /* tp_getset */
229     0,                                      /* tp_base */
230     0,                                      /* tp_dict */
231     0,                                      /* tp_descr_get */
232     0,                                      /* tp_descr_set */
233     0,                                      /* tp_dictoffset */
234     (initproc)Array_tp_init,                /* tp_init */
235     0,                                      /* tp_alloc */
236     Array_tp_new,                           /* tp_new */
239 /* Dict ============================================================= */
241 PyDoc_STRVAR(Dict_tp_doc,
242 "An mapping whose keys are similar and whose values are similar,\n"
243 "implemented as a subtype of dict.\n"
244 "\n"
245 "As currently implemented, a Dictionary behaves just like a dict, but\n"
246 "with the addition of a ``signature`` property set by the constructor;\n"
247 "conversion of its items to D-Bus types is only done when it's sent in\n"
248 "a Message. This may change in future so validation is done earlier.\n"
249 "\n"
250 "Constructor::\n"
251 "\n"
252 "    Dictionary(mapping_or_iterable=(), signature=None, variant_level=0)\n"
253 "\n"
254 "``variant_level`` must be non-negative; the default is 0.\n"
255 "\n"
256 "``signature`` is either a string or None. If a string, it must consist\n"
257 "of exactly two complete type signatures, representing the 'key' type\n"
258 "(which must be a primitive type, i.e. one of \"bd"
259 #ifdef WITH_DBUS_FLOAT32
261 #endif
262 "ginoqstuxy\")\n"
263 "and the 'value' type. The signature of the whole Dictionary will be\n"
264 "``a{xx}`` where ``xx`` is replaced by the given signature.\n"
265 "\n"
266 "If it is None (the default), when the Dictionary is sent over\n"
267 "D-Bus, the key and value signatures will be guessed from an arbitrary\n"
268 "element of the Dictionary.\n"
269 "\n"
270 ":IVariables:\n"
271 "  `variant_level` : int\n"
272 "    Indicates how many nested Variant containers this object\n"
273 "    is contained in: if a message's wire format has a variant containing a\n"
274 "    variant containing an array of DICT_ENTRY, this is represented in\n"
275 "    Python by a Dictionary with variant_level==2.\n"
278 static struct PyMemberDef Dict_tp_members[] = {
279     {"signature", T_OBJECT, offsetof(DBusPyDict, signature), READONLY,
280      "The D-Bus signature of each key in this Dictionary, followed by "
281      "that of each value in this Dictionary, as a Signature instance."},
282     {"variant_level", T_LONG, offsetof(DBusPyDict, variant_level),
283      READONLY,
284      "The number of nested variants wrapping the real data. "
285      "0 if not in a variant."},
286     {NULL},
289 static void
290 Dict_tp_dealloc (DBusPyDict *self)
292     Py_XDECREF(self->signature);
293     self->signature = NULL;
294     (PyDict_Type.tp_dealloc)((PyObject *)self);
297 static PyObject *
298 Dict_tp_repr(DBusPyDict *self)
300     PyObject *parent_repr = (PyDict_Type.tp_repr)((PyObject *)self);
301     PyObject *sig_repr = PyObject_Repr(self->signature);
302     PyObject *my_repr = NULL;
303     long variant_level = self->variant_level;
305     if (!parent_repr) goto finally;
306     if (!sig_repr) goto finally;
307     if (variant_level > 0) {
308         my_repr = PyString_FromFormat("%s(%s, signature=%s, "
309                                       "variant_level=%ld)",
310                                       self->super.ob_type->tp_name,
311                                       PyString_AS_STRING(parent_repr),
312                                       PyString_AS_STRING(sig_repr),
313                                       variant_level);
314     }
315     else {
316         my_repr = PyString_FromFormat("%s(%s, signature=%s)",
317                                       self->super.ob_type->tp_name,
318                                       PyString_AS_STRING(parent_repr),
319                                       PyString_AS_STRING(sig_repr));
320     }
321 finally:
322     Py_XDECREF(parent_repr);
323     Py_XDECREF(sig_repr);
324     return my_repr;
327 static PyObject *
328 Dict_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
330     DBusPyDict *self = (DBusPyDict *)(PyDict_Type.tp_new)(cls, args, kwargs);
331     PyObject *variant_level = NULL;
333     /* variant_level is immutable, so handle it in __new__ rather than 
334     __init__ */
335     if (!self) return NULL;
336     Py_INCREF(Py_None);
337     self->signature = Py_None;
338     self->variant_level = 0;
339     if (kwargs) {
340         variant_level = PyDict_GetItem(kwargs, dbus_py_variant_level_const);
341     }
342     if (variant_level) {
343         self->variant_level = PyInt_AsLong(variant_level);
344         if (PyErr_Occurred()) {
345             Py_DECREF((PyObject *)self);
346             return NULL;
347         }
348     }
349     return (PyObject *)self;
352 static int
353 Dict_tp_init(DBusPyDict *self, PyObject *args, PyObject *kwargs)
355     PyObject *obj = dbus_py_empty_tuple;
356     PyObject *signature = NULL;
357     PyObject *tuple;
358     PyObject *variant_level;    /* ignored here - __new__ uses it */
359     static char *argnames[] = {"mapping_or_iterable", "signature",
360                                "variant_level", NULL};
362     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO:__init__", argnames,
363                                      &obj, &signature, &variant_level)) {
364         return -1;
365     }
367   /* convert signature from a borrowed ref of unknown type to an owned ref
368   of type Signature (or None) */
369     if (!signature) signature = Py_None;
370     if (signature == Py_None
371         || PyObject_IsInstance(signature, (PyObject *)&DBusPySignature_Type)) {
372         Py_INCREF(signature);
373     }
374     else {
375         signature = PyObject_CallFunction((PyObject *)&DBusPySignature_Type,
376                                           "(O)", signature);
377         if (!signature) return -1;
378     }
380     if (signature != Py_None) {
381         const char *c_str = PyString_AS_STRING(signature);
383         switch (c_str[0]) {
384             case DBUS_TYPE_BYTE:
385             case DBUS_TYPE_BOOLEAN:
386             case DBUS_TYPE_INT16:
387             case DBUS_TYPE_UINT16:
388             case DBUS_TYPE_INT32:
389             case DBUS_TYPE_UINT32:
390             case DBUS_TYPE_INT64:
391             case DBUS_TYPE_UINT64:
392             case DBUS_TYPE_DOUBLE:
393 #ifdef WITH_DBUS_FLOAT32
394             case DBUS_TYPE_FLOAT:
395 #endif
396             case DBUS_TYPE_STRING:
397             case DBUS_TYPE_OBJECT_PATH:
398             case DBUS_TYPE_SIGNATURE:
399                 break;
400             default:
401                 Py_DECREF(signature);
402                 PyErr_SetString(PyExc_ValueError,
403                                 "The key type in a Dictionary's signature "
404                                 "must be a primitive type");
405                 return -1;
406         }
408         if (!dbus_signature_validate_single(c_str + 1, NULL)) {
409             Py_DECREF(signature);
410             PyErr_SetString(PyExc_ValueError,
411                             "There must be exactly two complete types in "
412                             "a Dictionary's signature parameter");
413             return -1;
414         }
415     }
417     tuple = Py_BuildValue("(O)", obj);
418     if (!tuple) {
419         Py_DECREF(signature);
420         return -1;
421     }
423     if ((PyDict_Type.tp_init((PyObject *)self, tuple, NULL)) < 0) {
424         Py_DECREF(tuple);
425         Py_DECREF(signature);
426         return -1;
427     }
428     Py_DECREF(tuple);
430     Py_XDECREF(self->signature);
431     self->signature = signature;
432     return 0;
435 PyTypeObject DBusPyDict_Type = {
436     PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
437     0,
438     "dbus.Dictionary",
439     sizeof(DBusPyDict),
440     0,
441     (destructor)Dict_tp_dealloc,            /* tp_dealloc */
442     0,                                      /* tp_print */
443     0,                                      /* tp_getattr */
444     0,                                      /* tp_setattr */
445     0,                                      /* tp_compare */
446     (reprfunc)Dict_tp_repr,                 /* tp_repr */
447     0,                                      /* tp_as_number */
448     0,                                      /* tp_as_sequence */
449     0,                                      /* tp_as_mapping */
450     0,                                      /* tp_hash */
451     0,                                      /* tp_call */
452     0,                                      /* tp_str */
453     0,                                      /* tp_getattro */
454     0,                                      /* tp_setattro */
455     0,                                      /* tp_as_buffer */
456     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
457     Dict_tp_doc,                            /* tp_doc */
458     0,                                      /* tp_traverse */
459     0,                                      /* tp_clear */
460     0,                                      /* tp_richcompare */
461     0,                                      /* tp_weaklistoffset */
462     0,                                      /* tp_iter */
463     0,                                      /* tp_iternext */
464     0,                                      /* tp_methods */
465     Dict_tp_members,                        /* tp_members */
466     0,                                      /* tp_getset */
467     0,                                      /* tp_base */
468     0,                                      /* tp_dict */
469     0,                                      /* tp_descr_get */
470     0,                                      /* tp_descr_set */
471     0,                                      /* tp_dictoffset */
472     (initproc)Dict_tp_init,                 /* tp_init */
473     0,                                      /* tp_alloc */
474     Dict_tp_new,                            /* tp_new */
477 /* Struct =========================================================== */
479 PyDoc_STRVAR(Struct_tp_doc,
480 "An structure containing items of possibly distinct types.\n"
481 "\n"
482 "Constructor::\n"
483 "\n"
484 "    dbus.Struct(iterable, signature=None, variant_level=0) -> Struct\n"
485 "\n"
486 "D-Bus structs may not be empty, so the iterable argument is required and\n"
487 "may not be an empty iterable.\n"
488 "\n"
489 "``signature`` is either None, or a string representing the contents of the\n"
490 "struct as one or more complete type signatures. The overall signature of\n"
491 "the struct will be the given signature enclosed in parentheses, ``()``.\n"
492 "\n"
493 "If the signature is None (default) it will be guessed\n"
494 "from the types of the items during construction.\n"
495 "\n"
496 "``variant_level`` must be non-negative; the default is 0.\n"
497 "\n"
498 ":IVariables:\n"
499 "  `variant_level` : int\n"
500 "    Indicates how many nested Variant containers this object\n"
501 "    is contained in: if a message's wire format has a variant containing a\n"
502 "    variant containing a struct, this is represented in Python by a\n"
503 "    Struct with variant_level==2.\n"
506 static PyObject *
507 Struct_tp_repr(PyObject *self)
509     PyObject *parent_repr = (PyTuple_Type.tp_repr)((PyObject *)self);
510     PyObject *sig, *sig_repr = NULL;
511     PyObject *vl_obj;
512     long variant_level;
513     PyObject *my_repr = NULL;
515     if (!parent_repr) goto finally;
516     sig = PyObject_GetAttr(self, dbus_py_signature_const);
517     if (!sig) goto finally;
518     sig_repr = PyObject_Repr(sig);
519     if (!sig_repr) goto finally;
520     vl_obj = PyObject_GetAttr(self, dbus_py_variant_level_const);
521     if (!vl_obj) goto finally;
522     variant_level = PyInt_AsLong(vl_obj);
523     if (variant_level > 0) {
524         my_repr = PyString_FromFormat("%s(%s, signature=%s, "
525                                       "variant_level=%ld)",
526                                       self->ob_type->tp_name,
527                                       PyString_AS_STRING(parent_repr),
528                                       PyString_AS_STRING(sig_repr),
529                                       variant_level);
530     }
531     else {
532         my_repr = PyString_FromFormat("%s(%s, signature=%s)",
533                                       self->ob_type->tp_name,
534                                       PyString_AS_STRING(parent_repr),
535                                       PyString_AS_STRING(sig_repr));
536     }
538 finally:
539     Py_XDECREF(parent_repr);
540     Py_XDECREF(sig_repr);
541     return my_repr;
544 static PyObject *
545 Struct_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
547     PyObject *signature = NULL;
548     PyObject *variantness = NULL;
549     PyObject *self;
550     static char *argnames[] = {"signature", "variant_level", NULL};
552     if (PyTuple_Size(args) != 1) {
553         PyErr_SetString(PyExc_TypeError,
554                         "__new__ takes exactly one positional parameter");
555         return NULL;
556     }
557     if (!PyArg_ParseTupleAndKeywords(dbus_py_empty_tuple, kwargs,
558                                      "|OO!:__new__", argnames,
559                                      &signature, &PyInt_Type,
560                                      &variantness)) {
561         return NULL;
562     }
563     if (!variantness) {
564         variantness = PyInt_FromLong(0);
565     }
567     self = (PyTuple_Type.tp_new)(cls, args, NULL);
568     if (!self)
569         return NULL;
570     if (PyTuple_Size(self) < 1) {
571         PyErr_SetString(PyExc_ValueError, "D-Bus structs may not be empty");
572         Py_DECREF(self);
573         return NULL;
574     }
576     if (PyObject_GenericSetAttr(self, dbus_py_variant_level_const, variantness) < 0) {
577         Py_DECREF(self);
578         return NULL;
579     }
581     /* convert signature from a borrowed ref of unknown type to an owned ref
582     of type Signature (or None) */
583     if (!signature) signature = Py_None;
584     if (signature == Py_None
585         || PyObject_IsInstance(signature, (PyObject *)&DBusPySignature_Type)) {
586         Py_INCREF(signature);
587     }
588     else {
589         signature = PyObject_CallFunction((PyObject *)&DBusPySignature_Type,
590                                           "(O)", signature);
591         if (!signature) {
592             Py_DECREF(self);
593             return NULL;
594         }
595     }
597     if (PyObject_GenericSetAttr(self, dbus_py_signature_const, signature) < 0) {
598         Py_DECREF(self);
599         Py_DECREF(signature);
600         return NULL;
601     }
602     Py_DECREF(signature);
603     return self;
606 PyTypeObject DBusPyStruct_Type = {
607     PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
608     0,
609     "dbus.Struct",
610     INT_MAX, /* placeholder */
611     0,
612     0,                                      /* tp_dealloc */
613     0,                                      /* tp_print */
614     0,                                      /* tp_getattr */
615     0,                                      /* tp_setattr */
616     0,                                      /* tp_compare */
617     (reprfunc)Struct_tp_repr,               /* tp_repr */
618     0,                                      /* tp_as_number */
619     0,                                      /* tp_as_sequence */
620     0,                                      /* tp_as_mapping */
621     0,                                      /* tp_hash */
622     0,                                      /* tp_call */
623     0,                                      /* tp_str */
624     PyObject_GenericGetAttr,                /* tp_getattro */
625     dbus_py_immutable_setattro,             /* tp_setattro */
626     0,                                      /* tp_as_buffer */
627     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
628     Struct_tp_doc,                          /* tp_doc */
629     0,                                      /* tp_traverse */
630     0,                                      /* tp_clear */
631     0,                                      /* tp_richcompare */
632     0,                                      /* tp_weaklistoffset */
633     0,                                      /* tp_iter */
634     0,                                      /* tp_iternext */
635     0,                                      /* tp_methods */
636     0,                                      /* tp_members */
637     0,                                      /* tp_getset */
638     0,                                      /* tp_base */
639     0,                                      /* tp_dict */
640     0,                                      /* tp_descr_get */
641     0,                                      /* tp_descr_set */
642     -sizeof(PyObject *),                    /* tp_dictoffset */
643     0,                                      /* tp_init */
644     0,                                      /* tp_alloc */
645     Struct_tp_new,                          /* tp_new */
648 dbus_bool_t
649 dbus_py_init_container_types(void)
651     DBusPyArray_Type.tp_base = &PyList_Type;
652     if (PyType_Ready(&DBusPyArray_Type) < 0) return 0;
653     DBusPyArray_Type.tp_print = NULL;
655     DBusPyDict_Type.tp_base = &PyDict_Type;
656     if (PyType_Ready(&DBusPyDict_Type) < 0) return 0;
657     DBusPyDict_Type.tp_print = NULL;
659     DBusPyStruct_Type.tp_basicsize = PyTuple_Type.tp_basicsize
660                                      + 2*sizeof(PyObject *) - 1;
661     DBusPyStruct_Type.tp_basicsize /= sizeof(PyObject *);
662     DBusPyStruct_Type.tp_basicsize *= sizeof(PyObject *);
663     DBusPyStruct_Type.tp_base = &PyTuple_Type;
664     if (PyType_Ready(&DBusPyStruct_Type) < 0) return 0;
665     DBusPyStruct_Type.tp_print = NULL;
667     return 1;
670 dbus_bool_t
671 dbus_py_insert_container_types(PyObject *this_module)
673     Py_INCREF(&DBusPyArray_Type);
674     if (PyModule_AddObject(this_module, "Array",
675                            (PyObject *)&DBusPyArray_Type) < 0) return 0;
677     Py_INCREF(&DBusPyDict_Type);
678     if (PyModule_AddObject(this_module, "Dictionary",
679                            (PyObject *)&DBusPyDict_Type) < 0) return 0;
681     Py_INCREF(&DBusPyStruct_Type);
682     if (PyModule_AddObject(this_module, "Struct",
683                            (PyObject *)&DBusPyStruct_Type) < 0) return 0;
685     return 1;
688 /* vim:set ft=c cino< sw=4 sts=4 et: */