_dbus_bindings: debug-impl.h -> debug.c
[dbus-python-phuang.git] / _dbus_bindings / abstract-impl.h
blobc0362ba2809cfc276d42dcf59e60440c9d0d16e2
1 /* Subclasses of built-in Python types supporting extra D-Bus functionality.
3 * Copyright (C) 2006 Collabora Ltd.
5 * Licensed under the Academic Free License version 2.1
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.
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.
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
25 static PyObject *variant_level_const;
27 /* Support code for int subclasses. ================================== */
29 static PyTypeObject DBusPythonIntType;
30 DEFINE_CHECK(DBusPythonInt)
32 typedef struct {
33 PyIntObject base;
34 long variant_level;
35 } DBusPythonInt;
37 static PyMemberDef DBusPythonInt_tp_members[] = {
38 {"variant_level", T_LONG, offsetof(DBusPythonInt, variant_level),
39 READONLY,
40 "The number of nested variants wrapping the real data. "
41 "0 if not in a variant."},
42 {NULL},
45 static PyObject *
46 DBusPythonInt_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
48 PyObject *self;
49 long variantness = 0;
50 static char *argnames[] = {"variant_level", NULL};
52 if (PyTuple_Size(args) > 1) {
53 PyErr_SetString(PyExc_TypeError,
54 "__new__ takes at most one positional parameter");
55 return NULL;
57 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwargs,
58 "|l:__new__", argnames,
59 &variantness)) return NULL;
60 if (variantness < 0) {
61 PyErr_SetString(PyExc_ValueError,
62 "variant_level must be non-negative");
63 return NULL;
66 self = (PyInt_Type.tp_new)(cls, args, NULL);
67 if (self) {
68 ((DBusPythonInt *)self)->variant_level = variantness;
70 return self;
73 static PyObject *
74 DBusPythonInt_tp_repr(PyObject *self)
76 PyObject *parent_repr = (PyInt_Type.tp_repr)(self);
77 long variant_level = ((DBusPythonInt *)self)->variant_level;
78 PyObject *my_repr;
80 if (!parent_repr) return NULL;
81 if (variant_level > 0) {
82 my_repr = PyString_FromFormat("%s(%s, variant_level=%ld)",
83 self->ob_type->tp_name,
84 PyString_AS_STRING(parent_repr),
85 variant_level);
87 else {
88 my_repr = PyString_FromFormat("%s(%s)", self->ob_type->tp_name,
89 PyString_AS_STRING(parent_repr));
91 /* whether my_repr is NULL or not: */
92 Py_DECREF(parent_repr);
93 return my_repr;
96 static PyTypeObject DBusPythonIntType = {
97 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
99 "_dbus_bindings._DBusPythonInt",
100 sizeof(DBusPythonInt),
102 0, /* tp_dealloc */
103 0, /* tp_print */
104 0, /* tp_getattr */
105 0, /* tp_setattr */
106 0, /* tp_compare */
107 DBusPythonInt_tp_repr, /* tp_repr */
108 0, /* tp_as_number */
109 0, /* tp_as_sequence */
110 0, /* tp_as_mapping */
111 0, /* tp_hash */
112 0, /* tp_call */
113 0, /* tp_str */
114 0, /* tp_getattro */
115 0, /* tp_setattro */
116 0, /* tp_as_buffer */
117 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
118 "", /* tp_doc */
119 0, /* tp_traverse */
120 0, /* tp_clear */
121 0, /* tp_richcompare */
122 0, /* tp_weaklistoffset */
123 0, /* tp_iter */
124 0, /* tp_iternext */
125 0, /* tp_methods */
126 DBusPythonInt_tp_members, /* tp_members */
127 0, /* tp_getset */
128 DEFERRED_ADDRESS(&PyInt_Type), /* tp_base */
129 0, /* tp_dict */
130 0, /* tp_descr_get */
131 0, /* tp_descr_set */
132 0, /* tp_dictoffset */
133 0, /* tp_init */
134 0, /* tp_alloc */
135 DBusPythonInt_tp_new, /* tp_new */
138 /* Support code for float subclasses. ================================ */
140 /* There's only one subclass at the moment (Double) but these are factored
141 out to make room for Float later. (Float is implemented and #if'd out) */
143 static PyTypeObject DBusPythonFloatType;
144 DEFINE_CHECK(DBusPythonFloat)
146 typedef struct {
147 PyFloatObject base;
148 long variant_level;
149 } DBusPythonFloat;
151 static PyMemberDef DBusPythonFloat_tp_members[] = {
152 {"variant_level", T_LONG, offsetof(DBusPythonFloat, variant_level),
153 READONLY,
154 "The number of nested variants wrapping the real data. "
155 "0 if not in a variant."},
156 {NULL},
159 static PyObject *
160 DBusPythonFloat_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
162 PyObject *self;
163 long variantness = 0;
164 static char *argnames[] = {"variant_level", NULL};
166 if (PyTuple_Size(args) > 1) {
167 PyErr_SetString(PyExc_TypeError,
168 "__new__ takes at most one positional parameter");
169 return NULL;
171 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwargs,
172 "|l:__new__", argnames,
173 &variantness)) return NULL;
174 if (variantness < 0) {
175 PyErr_SetString(PyExc_ValueError,
176 "variant_level must be non-negative");
177 return NULL;
180 self = (PyFloat_Type.tp_new)(cls, args, NULL);
181 if (self) {
182 ((DBusPythonFloat *)self)->variant_level = variantness;
184 return self;
187 static PyObject *
188 DBusPythonFloat_tp_repr(PyObject *self)
190 PyObject *parent_repr = (PyFloat_Type.tp_repr)(self);
191 long variant_level = ((DBusPythonFloat *)self)->variant_level;
192 PyObject *my_repr;
194 if (!parent_repr) return NULL;
195 if (variant_level > 0) {
196 my_repr = PyString_FromFormat("%s(%s, variant_level=%ld)",
197 self->ob_type->tp_name,
198 PyString_AS_STRING(parent_repr),
199 variant_level);
201 else {
202 my_repr = PyString_FromFormat("%s(%s)", self->ob_type->tp_name,
203 PyString_AS_STRING(parent_repr));
205 /* whether my_repr is NULL or not: */
206 Py_DECREF(parent_repr);
207 return my_repr;
210 static PyTypeObject DBusPythonFloatType = {
211 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
213 "_dbus_bindings._DBusPythonFloat",
214 sizeof(DBusPythonFloat),
216 0, /* tp_dealloc */
217 0, /* tp_print */
218 0, /* tp_getattr */
219 0, /* tp_setattr */
220 0, /* tp_compare */
221 DBusPythonFloat_tp_repr, /* tp_repr */
222 0, /* tp_as_number */
223 0, /* tp_as_sequence */
224 0, /* tp_as_mapping */
225 0, /* tp_hash */
226 0, /* tp_call */
227 0, /* tp_str */
228 0, /* tp_getattro */
229 0, /* tp_setattro */
230 0, /* tp_as_buffer */
231 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
232 "", /* tp_doc */
233 0, /* tp_traverse */
234 0, /* tp_clear */
235 0, /* tp_richcompare */
236 0, /* tp_weaklistoffset */
237 0, /* tp_iter */
238 0, /* tp_iternext */
239 0, /* tp_methods */
240 DBusPythonFloat_tp_members, /* tp_members */
241 0, /* tp_getset */
242 DEFERRED_ADDRESS(&PyFloat_Type), /* tp_base */
243 0, /* tp_dict */
244 0, /* tp_descr_get */
245 0, /* tp_descr_set */
246 0, /* tp_dictoffset */
247 0, /* tp_init */
248 0, /* tp_alloc */
249 DBusPythonFloat_tp_new, /* tp_new */
252 /* Support code for str subclasses ================================== */
254 static PyTypeObject DBusPythonStringType;
255 DEFINE_CHECK(DBusPythonString)
257 static PyObject *
258 DBusPythonString_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
260 PyObject *self;
261 PyObject *variantness = NULL;
262 static char *argnames[] = {"variant_level", NULL};
264 if (PyTuple_Size(args) > 1) {
265 PyErr_SetString(PyExc_TypeError,
266 "__new__ takes at most one positional parameter");
267 return NULL;
269 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwargs,
270 "|O!:__new__", argnames,
271 &PyInt_Type, &variantness)) return NULL;
272 if (!variantness) {
273 variantness = PyInt_FromLong(0);
274 if (!variantness) return NULL;
276 if (PyInt_AS_LONG(variantness) < 0) {
277 PyErr_SetString(PyExc_ValueError,
278 "variant_level must be non-negative");
279 return NULL;
282 self = (PyString_Type.tp_new)(cls, args, NULL);
283 if (self) {
284 PyObject_GenericSetAttr(self, variant_level_const, variantness);
286 return self;
289 static PyObject *
290 DBusPythonString_tp_repr(PyObject *self)
292 PyObject *parent_repr = (PyString_Type.tp_repr)(self);
293 PyObject *vl_obj;
294 PyObject *my_repr;
295 long variant_level;
297 if (!parent_repr) return NULL;
298 vl_obj = PyObject_GetAttr(self, variant_level_const);
299 if (!vl_obj) return NULL;
300 variant_level = PyInt_AsLong(vl_obj);
301 if (variant_level > 0) {
302 my_repr = PyString_FromFormat("%s(%s, variant_level=%ld)",
303 self->ob_type->tp_name,
304 PyString_AS_STRING(parent_repr),
305 variant_level);
307 else {
308 my_repr = PyString_FromFormat("%s(%s)", self->ob_type->tp_name,
309 PyString_AS_STRING(parent_repr));
311 /* whether my_repr is NULL or not: */
312 Py_DECREF(parent_repr);
313 return my_repr;
316 static PyTypeObject DBusPythonStringType = {
317 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
319 "_dbus_bindings._DBusPythonString",
320 INT_MAX, /* placeholder */
322 0, /* tp_dealloc */
323 0, /* tp_print */
324 0, /* tp_getattr */
325 0, /* tp_setattr */
326 0, /* tp_compare */
327 DBusPythonString_tp_repr, /* tp_repr */
328 0, /* tp_as_number */
329 0, /* tp_as_sequence */
330 0, /* tp_as_mapping */
331 0, /* tp_hash */
332 0, /* tp_call */
333 0, /* tp_str */
334 PyObject_GenericGetAttr, /* tp_getattro */
335 Glue_immutable_setattro, /* tp_setattro */
336 0, /* tp_as_buffer */
337 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
338 "", /* tp_doc */
339 0, /* tp_traverse */
340 0, /* tp_clear */
341 0, /* tp_richcompare */
342 0, /* tp_weaklistoffset */
343 0, /* tp_iter */
344 0, /* tp_iternext */
345 0, /* tp_methods */
346 0, /* tp_members */
347 0, /* tp_getset */
348 DEFERRED_ADDRESS(&PyString_Type), /* tp_base */
349 0, /* tp_dict */
350 0, /* tp_descr_get */
351 0, /* tp_descr_set */
352 -sizeof(void *), /* tp_dictoffset */
353 0, /* tp_init */
354 0, /* tp_alloc */
355 DBusPythonString_tp_new, /* tp_new */
358 /* Support code for long subclasses ================================= */
360 static PyTypeObject DBusPythonLongType;
361 DEFINE_CHECK(DBusPythonLong)
363 static PyObject *
364 DBusPythonLong_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
366 PyObject *self;
367 PyObject *variantness = NULL;
368 static char *argnames[] = {"variant_level", NULL};
370 if (PyTuple_Size(args) > 1) {
371 PyErr_SetString(PyExc_TypeError,
372 "__new__ takes at most one positional parameter");
373 return NULL;
375 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwargs,
376 "|O!:__new__", argnames,
377 &PyInt_Type, &variantness)) return NULL;
378 if (!variantness) {
379 variantness = PyInt_FromLong(0);
380 if (!variantness) return NULL;
382 if (PyInt_AS_LONG(variantness) < 0) {
383 PyErr_SetString(PyExc_ValueError,
384 "variant_level must be non-negative");
385 return NULL;
388 self = (PyLong_Type.tp_new)(cls, args, NULL);
389 if (self) {
390 PyObject_GenericSetAttr(self, variant_level_const, variantness);
392 return self;
395 static PyObject *
396 DBusPythonLong_tp_repr(PyObject *self)
398 PyObject *parent_repr = (PyLong_Type.tp_repr)(self);
399 PyObject *vl_obj;
400 PyObject *my_repr;
401 long variant_level;
403 if (!parent_repr) return NULL;
404 vl_obj = PyObject_GetAttr(self, variant_level_const);
405 if (!vl_obj) return 0;
406 variant_level = PyInt_AsLong(vl_obj);
407 if (variant_level) {
408 my_repr = PyString_FromFormat("%s(%s, variant_level=%ld)",
409 self->ob_type->tp_name,
410 PyString_AS_STRING(parent_repr),
411 variant_level);
413 else {
414 my_repr = PyString_FromFormat("%s(%s)", self->ob_type->tp_name,
415 PyString_AS_STRING(parent_repr));
417 /* whether my_repr is NULL or not: */
418 Py_DECREF(parent_repr);
419 return my_repr;
422 static PyTypeObject DBusPythonLongType = {
423 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
425 "_dbus_bindings._DBusPythonLong",
426 INT_MAX, /* placeholder */
428 0, /* tp_dealloc */
429 0, /* tp_print */
430 0, /* tp_getattr */
431 0, /* tp_setattr */
432 0, /* tp_compare */
433 DBusPythonLong_tp_repr, /* tp_repr */
434 0, /* tp_as_number */
435 0, /* tp_as_sequence */
436 0, /* tp_as_mapping */
437 0, /* tp_hash */
438 0, /* tp_call */
439 0, /* tp_str */
440 PyObject_GenericGetAttr, /* tp_getattro */
441 Glue_immutable_setattro, /* tp_setattro */
442 0, /* tp_as_buffer */
443 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
444 "", /* tp_doc */
445 0, /* tp_traverse */
446 0, /* tp_clear */
447 0, /* tp_richcompare */
448 0, /* tp_weaklistoffset */
449 0, /* tp_iter */
450 0, /* tp_iternext */
451 0, /* tp_methods */
452 0, /* tp_members */
453 0, /* tp_getset */
454 DEFERRED_ADDRESS(&PyLong_Type), /* tp_base */
455 0, /* tp_dict */
456 0, /* tp_descr_get */
457 0, /* tp_descr_set */
458 -sizeof(PyObject *), /* tp_dictoffset */
459 0, /* tp_init */
460 0, /* tp_alloc */
461 DBusPythonLong_tp_new, /* tp_new */
464 static inline int
465 init_abstract(void)
467 variant_level_const = PyString_InternFromString("variant_level");
468 if (!variant_level_const) return 0;
470 DBusPythonIntType.tp_base = &PyInt_Type;
471 if (PyType_Ready(&DBusPythonIntType) < 0) return 0;
472 /* disable the tp_print copied from PyInt_Type, so tp_repr gets called as
473 desired */
474 DBusPythonIntType.tp_print = NULL;
476 DBusPythonFloatType.tp_base = &PyFloat_Type;
477 if (PyType_Ready(&DBusPythonFloatType) < 0) return 0;
478 DBusPythonFloatType.tp_print = NULL;
480 /* Add a pointer for the instance dict, aligning to sizeof(PyObject *)
481 * to make sure the offset of -sizeof(PyObject *) is right. */
482 DBusPythonLongType.tp_basicsize = PyLong_Type.tp_basicsize
483 + 2*sizeof(PyObject *) - 1;
484 DBusPythonLongType.tp_basicsize /= sizeof(PyObject *);
485 DBusPythonLongType.tp_basicsize *= sizeof(PyObject *);
486 DBusPythonLongType.tp_base = &PyLong_Type;
487 if (PyType_Ready(&DBusPythonLongType) < 0) return 0;
488 DBusPythonLongType.tp_print = NULL;
490 DBusPythonStringType.tp_basicsize = PyString_Type.tp_basicsize
491 + 2*sizeof(PyObject *) - 1;
492 DBusPythonStringType.tp_basicsize /= sizeof(PyObject *);
493 DBusPythonStringType.tp_basicsize *= sizeof(PyObject *);
494 DBusPythonStringType.tp_base = &PyString_Type;
495 if (PyType_Ready(&DBusPythonStringType) < 0) return 0;
496 DBusPythonStringType.tp_print = NULL;
498 return 1;
501 static inline int
502 insert_abstract_types(PyObject *this_module)
504 Py_INCREF(&DBusPythonIntType);
505 Py_INCREF(&DBusPythonLongType);
506 Py_INCREF(&DBusPythonStringType);
507 Py_INCREF(&DBusPythonFloatType);
508 if (PyModule_AddObject(this_module, "_DBusPythonInt",
509 (PyObject *)&DBusPythonIntType) < 0) return 0;
510 if (PyModule_AddObject(this_module, "_DBusPythonLong",
511 (PyObject *)&DBusPythonLongType) < 0) return 0;
512 if (PyModule_AddObject(this_module, "_DBusPythonString",
513 (PyObject *)&DBusPythonStringType) < 0) return 0;
514 if (PyModule_AddObject(this_module, "_DBusPythonFloat",
515 (PyObject *)&DBusPythonFloatType) < 0) return 0;
517 return 1;