~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/python/generic/IDProp.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: IDProp.c 27639 2010-03-21 01:14:04Z gsrb3d $
3
 
 *
4
 
 * ***** BEGIN GPL LICENSE BLOCK *****
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU General Public License
8
 
 * as published by the Free Software Foundation; either version 2
9
 
 * of the License, or (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software Foundation,
18
 
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 
 *
20
 
 *
21
 
 * Contributor(s): Joseph Eagar, Campbell Barton
22
 
 *
23
 
 * ***** END GPL LICENSE BLOCK *****
24
 
 */
25
 
 
26
 
#include "BKE_idprop.h"
27
 
#include "IDProp.h"
28
 
#include "MEM_guardedalloc.h"
29
 
 
30
 
/*** Function to wrap ID properties ***/
31
 
PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent);
32
 
 
33
 
extern PyTypeObject IDArray_Type;
34
 
extern PyTypeObject IDGroup_Iter_Type;
35
 
 
36
 
/*********************** ID Property Main Wrapper Stuff ***************/
37
 
 
38
 
PyObject *IDGroup_repr( BPy_IDProperty *self )
39
 
{
40
 
        return PyUnicode_FromFormat( "<bpy ID property from \"%s\">", self->id->name);
41
 
}
42
 
 
43
 
extern PyTypeObject IDGroup_Type;
44
 
 
45
 
PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
46
 
{
47
 
        switch ( prop->type ) {
48
 
                case IDP_STRING:
49
 
                        return PyUnicode_FromString( prop->data.pointer );
50
 
                case IDP_INT:
51
 
                        return PyLong_FromLong( (long)prop->data.val );
52
 
                case IDP_FLOAT:
53
 
                        return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) );
54
 
                case IDP_DOUBLE:
55
 
                        return PyFloat_FromDouble( (*(double*)(&prop->data.val)) );
56
 
                case IDP_GROUP:
57
 
                        /*blegh*/
58
 
                        {
59
 
                                BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &IDGroup_Type);
60
 
                                group->id = id;
61
 
                                group->prop = prop;
62
 
                                return (PyObject*) group;
63
 
                        }
64
 
                case IDP_ARRAY:
65
 
                        {
66
 
                                BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &IDArray_Type);
67
 
                                array->id = id;
68
 
                                array->prop = prop;
69
 
                                return (PyObject*) array;
70
 
                        }
71
 
                case IDP_IDPARRAY: /* this could be better a internal type */
72
 
                        {
73
 
                                PyObject *seq = PyList_New(prop->len), *wrap;
74
 
                                IDProperty *array= IDP_IDPArray(prop);
75
 
                                int i;
76
 
 
77
 
                                if (!seq) {
78
 
                                        PyErr_Format( PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len);
79
 
                                        return NULL;
80
 
                                }
81
 
 
82
 
                                for (i=0; i<prop->len; i++) {
83
 
                                        wrap= BPy_IDGroup_WrapData(id, array++);
84
 
 
85
 
                                        if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */
86
 
                                                return NULL;
87
 
 
88
 
                                        PyList_SET_ITEM(seq, i, wrap);
89
 
                                }
90
 
 
91
 
                                return seq;
92
 
                        }
93
 
                /* case IDP_IDPARRAY: TODO */
94
 
        }
95
 
        Py_RETURN_NONE;
96
 
}
97
 
 
98
 
int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
99
 
{
100
 
        switch (prop->type) {
101
 
                case IDP_STRING:
102
 
                {
103
 
                        char *st;
104
 
                        if (!PyUnicode_Check(value)) {
105
 
                                PyErr_SetString(PyExc_TypeError, "expected a string!");
106
 
                                return -1;
107
 
                        }
108
 
 
109
 
                        st = _PyUnicode_AsString(value);
110
 
                        IDP_ResizeArray(prop, strlen(st)+1);
111
 
                        strcpy(prop->data.pointer, st);
112
 
                        return 0;
113
 
                }
114
 
 
115
 
                case IDP_INT:
116
 
                {
117
 
                        int ivalue= PyLong_AsSsize_t(value);
118
 
                        if (ivalue==-1 && PyErr_Occurred()) {
119
 
                                PyErr_SetString(PyExc_TypeError, "expected an int type");
120
 
                                return -1;
121
 
                        }
122
 
                        prop->data.val = ivalue;
123
 
                        break;
124
 
                }
125
 
                case IDP_FLOAT:
126
 
                {
127
 
                        float fvalue= (float)PyFloat_AsDouble(value);
128
 
                        if (fvalue==-1 && PyErr_Occurred()) {
129
 
                                PyErr_SetString(PyExc_TypeError, "expected a float");
130
 
                                return -1;
131
 
                        }
132
 
                        *(float*)&self->prop->data.val = fvalue;
133
 
                        break;
134
 
                }
135
 
                case IDP_DOUBLE:
136
 
                {
137
 
                        double dvalue= PyFloat_AsDouble(value);
138
 
                        if (dvalue==-1 && PyErr_Occurred()) {
139
 
                                PyErr_SetString(PyExc_TypeError, "expected a float");
140
 
                                return -1;
141
 
                        }
142
 
                        *(double*)&self->prop->data.val = dvalue;
143
 
                        break;
144
 
                }
145
 
                default:
146
 
                        PyErr_SetString(PyExc_AttributeError, "attempt to set read-only attribute!");
147
 
                        return -1;
148
 
        }
149
 
        return 0;
150
 
}
151
 
 
152
 
PyObject *BPy_IDGroup_GetName(BPy_IDProperty *self, void *bleh)
153
 
{
154
 
        return PyUnicode_FromString(self->prop->name);
155
 
}
156
 
 
157
 
static int BPy_IDGroup_SetName(BPy_IDProperty *self, PyObject *value, void *bleh)
158
 
{
159
 
        char *st;
160
 
        if (!PyUnicode_Check(value)) {
161
 
                PyErr_SetString(PyExc_TypeError, "expected a string!");
162
 
                return -1;
163
 
        }
164
 
 
165
 
        st = _PyUnicode_AsString(value);
166
 
        if (strlen(st) >= MAX_IDPROP_NAME) {
167
 
                PyErr_SetString(PyExc_TypeError, "string length cannot exceed 31 characters!");
168
 
                return -1;
169
 
        }
170
 
 
171
 
        strcpy(self->prop->name, st);
172
 
        return 0;
173
 
}
174
 
 
175
 
#if 0
176
 
static PyObject *BPy_IDGroup_GetType(BPy_IDProperty *self)
177
 
{
178
 
        return PyLong_FromSsize_t(self->prop->type);
179
 
}
180
 
#endif
181
 
 
182
 
static PyGetSetDef BPy_IDGroup_getseters[] = {
183
 
        {"name",
184
 
         (getter)BPy_IDGroup_GetName, (setter)BPy_IDGroup_SetName,
185
 
         "The name of this Group.",
186
 
         NULL},
187
 
         {NULL, NULL, NULL, NULL, NULL}
188
 
};
189
 
 
190
 
static Py_ssize_t BPy_IDGroup_Map_Len(BPy_IDProperty *self)
191
 
{
192
 
        if (self->prop->type != IDP_GROUP) {
193
 
                PyErr_SetString( PyExc_TypeError, "len() of unsized object");
194
 
                return -1;
195
 
        }
196
 
 
197
 
        return self->prop->len;
198
 
}
199
 
 
200
 
static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item)
201
 
{
202
 
        IDProperty *idprop;
203
 
        char *name;
204
 
 
205
 
        if (self->prop->type  != IDP_GROUP) {
206
 
                PyErr_SetString( PyExc_TypeError, "unsubscriptable object");
207
 
                return NULL;
208
 
        }
209
 
 
210
 
        name= _PyUnicode_AsString(item);
211
 
 
212
 
        if (name == NULL) {
213
 
                PyErr_SetString( PyExc_TypeError, "only strings are allowed as keys of ID properties");
214
 
                return NULL;
215
 
        }
216
 
 
217
 
        idprop= IDP_GetPropertyFromGroup(self->prop, name);
218
 
 
219
 
        if(idprop==NULL) {
220
 
                PyErr_SetString( PyExc_KeyError, "key not in subgroup dict");
221
 
                return NULL;
222
 
        }
223
 
 
224
 
        return BPy_IDGroup_WrapData(self->id, idprop);
225
 
 
226
 
}
227
 
 
228
 
/*returns NULL on success, error string on failure*/
229
 
static int idp_sequence_type(PyObject *seq)
230
 
{
231
 
        PyObject *item;
232
 
        int type= IDP_INT;
233
 
 
234
 
        int i, len = PySequence_Length(seq);
235
 
        for (i=0; i < len; i++) {
236
 
                item = PySequence_GetItem(seq, i);
237
 
                if (PyFloat_Check(item)) {
238
 
                        if(type == IDP_IDPARRAY) { /* mixed dict/int */
239
 
                                Py_DECREF(item);
240
 
                                return -1;
241
 
                        }
242
 
                        type= IDP_DOUBLE;
243
 
                }
244
 
                else if (PyLong_Check(item)) {
245
 
                        if(type == IDP_IDPARRAY) { /* mixed dict/int */
246
 
                                Py_DECREF(item);
247
 
                                return -1;
248
 
                        }
249
 
                }
250
 
                else if (PyMapping_Check(item)) {
251
 
                        if(i != 0 && (type != IDP_IDPARRAY)) { /* mixed dict/int */
252
 
                                Py_DECREF(item);
253
 
                                return -1;
254
 
                        }
255
 
                        type= IDP_IDPARRAY;
256
 
                }
257
 
                else {
258
 
                        Py_XDECREF(item);
259
 
                        return -1;
260
 
                }
261
 
 
262
 
                Py_DECREF(item);
263
 
        }
264
 
 
265
 
        return type;
266
 
}
267
 
 
268
 
/* note: group can be a pointer array or a group */
269
 
char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObject *ob)
270
 
{
271
 
        IDProperty *prop = NULL;
272
 
        IDPropertyTemplate val = {0};
273
 
 
274
 
        if(strlen(name) >= sizeof(group->name))
275
 
                return "the length of IDProperty names is limited to 31 characters";
276
 
 
277
 
        if (PyFloat_Check(ob)) {
278
 
                val.d = PyFloat_AsDouble(ob);
279
 
                prop = IDP_New(IDP_DOUBLE, val, name);
280
 
        } else if (PyLong_Check(ob)) {
281
 
                val.i = (int) PyLong_AsSsize_t(ob);
282
 
                prop = IDP_New(IDP_INT, val, name);
283
 
        } else if (PyUnicode_Check(ob)) {
284
 
                val.str = _PyUnicode_AsString(ob);
285
 
                prop = IDP_New(IDP_STRING, val, name);
286
 
        } else if (PySequence_Check(ob)) {
287
 
                PyObject *item;
288
 
                int i;
289
 
 
290
 
                if((val.array.type= idp_sequence_type(ob)) == -1)
291
 
                        return "only floats, ints and dicts are allowed in ID property arrays";
292
 
 
293
 
                /*validate sequence and derive type.
294
 
                we assume IDP_INT unless we hit a float
295
 
                number; then we assume it's */
296
 
 
297
 
                val.array.len = PySequence_Length(ob);
298
 
 
299
 
                switch(val.array.type) {
300
 
                case IDP_DOUBLE:
301
 
                        prop = IDP_New(IDP_ARRAY, val, name);
302
 
                        for (i=0; i<val.array.len; i++) {
303
 
                                item = PySequence_GetItem(ob, i);
304
 
                                ((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
305
 
                                Py_DECREF(item);
306
 
                        }
307
 
                        break;
308
 
                case IDP_INT:
309
 
                        prop = IDP_New(IDP_ARRAY, val, name);
310
 
                        for (i=0; i<val.array.len; i++) {
311
 
                                item = PySequence_GetItem(ob, i);
312
 
                                ((int*)prop->data.pointer)[i] = (int)PyLong_AsSsize_t(item);
313
 
                                Py_DECREF(item);
314
 
                        }
315
 
                        break;
316
 
                case IDP_IDPARRAY:
317
 
                        prop= IDP_NewIDPArray(name);
318
 
                        for (i=0; i<val.array.len; i++) {
319
 
                                char *error;
320
 
                                item = PySequence_GetItem(ob, i);
321
 
                                error= BPy_IDProperty_Map_ValidateAndCreate("", prop, item);
322
 
                                Py_DECREF(item);
323
 
 
324
 
                                if(error)
325
 
                                        return error;
326
 
                        }
327
 
                        break;
328
 
                }
329
 
        } else if (PyMapping_Check(ob)) {
330
 
                PyObject *keys, *vals, *key, *pval;
331
 
                int i, len;
332
 
                /*yay! we get into recursive stuff now!*/
333
 
                keys = PyMapping_Keys(ob);
334
 
                vals = PyMapping_Values(ob);
335
 
 
336
 
                /*we allocate the group first; if we hit any invalid data,
337
 
                  we can delete it easily enough.*/
338
 
                prop = IDP_New(IDP_GROUP, val, name);
339
 
                len = PyMapping_Length(ob);
340
 
                for (i=0; i<len; i++) {
341
 
                        key = PySequence_GetItem(keys, i);
342
 
                        pval = PySequence_GetItem(vals, i);
343
 
                        if (!PyUnicode_Check(key)) {
344
 
                                IDP_FreeProperty(prop);
345
 
                                MEM_freeN(prop);
346
 
                                Py_XDECREF(keys);
347
 
                                Py_XDECREF(vals);
348
 
                                Py_XDECREF(key);
349
 
                                Py_XDECREF(pval);
350
 
                                return "invalid element in subgroup dict template!";
351
 
                        }
352
 
                        if (BPy_IDProperty_Map_ValidateAndCreate(_PyUnicode_AsString(key), prop, pval)) {
353
 
                                IDP_FreeProperty(prop);
354
 
                                MEM_freeN(prop);
355
 
                                Py_XDECREF(keys);
356
 
                                Py_XDECREF(vals);
357
 
                                Py_XDECREF(key);
358
 
                                Py_XDECREF(pval);
359
 
                                return "invalid element in subgroup dict template!";
360
 
                        }
361
 
                        Py_XDECREF(key);
362
 
                        Py_XDECREF(pval);
363
 
                }
364
 
                Py_XDECREF(keys);
365
 
                Py_XDECREF(vals);
366
 
        } else return "invalid property value";
367
 
 
368
 
        if(group->type==IDP_IDPARRAY) {
369
 
                IDP_AppendArray(group, prop);
370
 
                // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
371
 
                MEM_freeN(prop);
372
 
        } else {
373
 
                IDP_ReplaceInGroup(group, prop);
374
 
        }
375
 
 
376
 
        return NULL;
377
 
}
378
 
 
379
 
int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val)
380
 
{
381
 
        if (prop->type  != IDP_GROUP) {
382
 
                PyErr_SetString( PyExc_TypeError, "unsubscriptable object");
383
 
                return -1;
384
 
        }
385
 
 
386
 
        if (val == NULL) { /* del idprop[key] */
387
 
                IDProperty *pkey = IDP_GetPropertyFromGroup(prop, _PyUnicode_AsString(key));
388
 
                if (pkey) {
389
 
                        IDP_RemFromGroup(prop, pkey);
390
 
                        IDP_FreeProperty(pkey);
391
 
                        MEM_freeN(pkey);
392
 
                        return 0;
393
 
                } else {
394
 
                        PyErr_SetString( PyExc_KeyError, "property not found in group" );
395
 
                        return -1;
396
 
                }
397
 
        }
398
 
        else {
399
 
                char *err;
400
 
 
401
 
                if (!PyUnicode_Check(key)) {
402
 
                        PyErr_SetString( PyExc_TypeError, "only strings are allowed as subgroup keys" );
403
 
                        return -1;
404
 
                }
405
 
 
406
 
                err = BPy_IDProperty_Map_ValidateAndCreate(_PyUnicode_AsString(key), prop, val);
407
 
                if (err) {
408
 
                        PyErr_SetString( PyExc_KeyError, err );
409
 
                        return -1;
410
 
                }
411
 
 
412
 
                return 0;
413
 
        }
414
 
}
415
 
 
416
 
static int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject *val)
417
 
{
418
 
        return BPy_Wrap_SetMapItem(self->prop, key, val);
419
 
}
420
 
 
421
 
static PyObject *BPy_IDGroup_SpawnIterator(BPy_IDProperty *self)
422
 
{
423
 
        BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &IDGroup_Iter_Type);
424
 
        iter->group = self;
425
 
        iter->mode = IDPROP_ITER_KEYS;
426
 
        iter->cur = self->prop->data.group.first;
427
 
        Py_XINCREF(iter);
428
 
        return (PyObject*) iter;
429
 
}
430
 
 
431
 
static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
432
 
{
433
 
        switch (prop->type) {
434
 
                case IDP_STRING:
435
 
                        return PyUnicode_FromString(prop->data.pointer);
436
 
                        break;
437
 
                case IDP_FLOAT:
438
 
                        return PyFloat_FromDouble(*((float*)&prop->data.val));
439
 
                        break;
440
 
                case IDP_DOUBLE:
441
 
                        return PyFloat_FromDouble(*((double*)&prop->data.val));
442
 
                        break;
443
 
                case IDP_INT:
444
 
                        return PyLong_FromSsize_t( prop->data.val );
445
 
                        break;
446
 
                case IDP_ARRAY:
447
 
                {
448
 
                        PyObject *seq = PyList_New(prop->len);
449
 
                        int i;
450
 
 
451
 
                        if (!seq) {
452
 
                                PyErr_Format( PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_ARRAY: PyList_New(%d) failed", prop->len);
453
 
                                return NULL;
454
 
                        }
455
 
 
456
 
                        for (i=0; i<prop->len; i++) {
457
 
                                if (prop->subtype == IDP_FLOAT) {
458
 
                                        PyList_SET_ITEM(seq, i,
459
 
                                                PyFloat_FromDouble(((float*)prop->data.pointer)[i]));
460
 
                                } else if (prop->subtype == IDP_DOUBLE) {
461
 
                                        PyList_SET_ITEM(seq, i,
462
 
                                                PyFloat_FromDouble(((double*)prop->data.pointer)[i]));
463
 
                                } else  {
464
 
                                        PyList_SET_ITEM(seq, i,
465
 
                                                  PyLong_FromLong(((int*)prop->data.pointer)[i]));
466
 
                                }
467
 
                        }
468
 
                        return seq;
469
 
                }
470
 
                case IDP_IDPARRAY:
471
 
                {
472
 
                        PyObject *seq = PyList_New(prop->len), *wrap;
473
 
                        IDProperty *array= IDP_IDPArray(prop);
474
 
                        int i;
475
 
 
476
 
                        if (!seq) {
477
 
                                PyErr_Format( PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len);
478
 
                                return NULL;
479
 
                        }
480
 
 
481
 
                        for (i=0; i<prop->len; i++) {
482
 
                                wrap= BPy_IDGroup_MapDataToPy(array++);
483
 
 
484
 
                                if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */
485
 
                                        return NULL;
486
 
 
487
 
                                PyList_SET_ITEM(seq, i, wrap);
488
 
                        }
489
 
                        return seq;
490
 
                }
491
 
                case IDP_GROUP:
492
 
                {
493
 
                        PyObject *dict = PyDict_New(), *wrap;
494
 
                        IDProperty *loop;
495
 
 
496
 
                        for (loop=prop->data.group.first; loop; loop=loop->next) {
497
 
                                wrap = BPy_IDGroup_MapDataToPy(loop);
498
 
 
499
 
                                if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */
500
 
                                        return NULL;
501
 
 
502
 
                                PyDict_SetItemString(dict, loop->name, wrap);
503
 
                        }
504
 
                        return dict;
505
 
                }
506
 
        }
507
 
 
508
 
        PyErr_Format(PyExc_RuntimeError, "eek!! '%s' property exists with a bad type code '%d' !!!", prop->name, prop->type);
509
 
        return NULL;
510
 
}
511
 
 
512
 
static PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value)
513
 
{
514
 
        IDProperty *idprop;
515
 
        PyObject *pyform;
516
 
        char *name = _PyUnicode_AsString(value);
517
 
 
518
 
        if (!name) {
519
 
                PyErr_SetString( PyExc_TypeError, "pop expected at least 1 argument, got 0" );
520
 
                return NULL;
521
 
        }
522
 
 
523
 
        idprop= IDP_GetPropertyFromGroup(self->prop, name);
524
 
 
525
 
        if(idprop) {
526
 
                pyform = BPy_IDGroup_MapDataToPy(idprop);
527
 
 
528
 
                if (!pyform) {
529
 
                        /*ok something bad happened with the pyobject,
530
 
                          so don't remove the prop from the group.  if pyform is
531
 
                          NULL, then it already should have raised an exception.*/
532
 
                          return NULL;
533
 
                }
534
 
 
535
 
                IDP_RemFromGroup(self->prop, idprop);
536
 
                return pyform;
537
 
        }
538
 
 
539
 
        PyErr_SetString( PyExc_KeyError, "item not in group" );
540
 
        return NULL;
541
 
}
542
 
 
543
 
static PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self)
544
 
{
545
 
        BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &IDGroup_Iter_Type);
546
 
        iter->group = self;
547
 
        iter->mode = IDPROP_ITER_ITEMS;
548
 
        iter->cur = self->prop->data.group.first;
549
 
        Py_XINCREF(iter);
550
 
        return (PyObject*) iter;
551
 
}
552
 
 
553
 
/* utility function */
554
 
static void BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len)
555
 
{
556
 
        int j;
557
 
 
558
 
        printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys/Values/Items!\n");
559
 
 
560
 
        /*fill rest of list with valid references to None*/
561
 
        for (j=len; j<prop->len; j++) {
562
 
                Py_INCREF(Py_None);
563
 
                PyList_SET_ITEM(seq, j, Py_None);
564
 
        }
565
 
 
566
 
        /*set correct group length*/
567
 
        prop->len = len;
568
 
}
569
 
 
570
 
PyObject *BPy_Wrap_GetKeys(IDProperty *prop)
571
 
{
572
 
        PyObject *seq = PyList_New(prop->len);
573
 
        IDProperty *loop;
574
 
        int i;
575
 
 
576
 
        for (i=0, loop=prop->data.group.first; loop && (i < prop->len); loop=loop->next, i++)
577
 
                PyList_SET_ITEM(seq, i, PyUnicode_FromString(loop->name));
578
 
 
579
 
        /* if the id prop is corrupt, count the remaining */
580
 
        for (; loop; loop=loop->next, i++) {}
581
 
 
582
 
        if (i != prop->len) { /* if the loop didnt finish, we know the length is wrong */
583
 
                BPy_IDGroup_CorrectListLen(prop, seq, i);
584
 
                Py_DECREF(seq); /*free the list*/
585
 
                /*call self again*/
586
 
                return BPy_Wrap_GetKeys(prop);
587
 
        }
588
 
 
589
 
        return seq;
590
 
}
591
 
 
592
 
PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop)
593
 
{
594
 
        PyObject *seq = PyList_New(prop->len);
595
 
        IDProperty *loop;
596
 
        int i;
597
 
 
598
 
        for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) {
599
 
                PyList_SET_ITEM(seq, i, BPy_IDGroup_WrapData(id, loop));
600
 
        }
601
 
 
602
 
        if (i != prop->len) {
603
 
                BPy_IDGroup_CorrectListLen(prop, seq, i);
604
 
                Py_DECREF(seq); /*free the list*/
605
 
                /*call self again*/
606
 
                return BPy_Wrap_GetValues(id, prop);
607
 
        }
608
 
 
609
 
        return seq;
610
 
}
611
 
 
612
 
PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop)
613
 
{
614
 
        PyObject *seq = PyList_New(prop->len);
615
 
        IDProperty *loop;
616
 
        int i;
617
 
 
618
 
        for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) {
619
 
                PyObject *item= PyTuple_New(2);
620
 
                PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(loop->name));
621
 
                PyTuple_SET_ITEM(item, 1, BPy_IDGroup_WrapData(id, loop));
622
 
                PyList_SET_ITEM(seq, i, item);
623
 
        }
624
 
 
625
 
        if (i != prop->len) {
626
 
                BPy_IDGroup_CorrectListLen(prop, seq, i);
627
 
                Py_DECREF(seq); /*free the list*/
628
 
                /*call self again*/
629
 
                return BPy_Wrap_GetItems(id, prop);
630
 
        }
631
 
 
632
 
        return seq;
633
 
}
634
 
 
635
 
 
636
 
static PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
637
 
{
638
 
        return BPy_Wrap_GetKeys(self->prop);
639
 
}
640
 
 
641
 
static PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
642
 
{
643
 
        return BPy_Wrap_GetValues(self->id, self->prop);
644
 
}
645
 
 
646
 
static PyObject *BPy_IDGroup_GetItems(BPy_IDProperty *self)
647
 
{
648
 
        return BPy_Wrap_GetItems(self->id, self->prop);
649
 
}
650
 
 
651
 
static int BPy_IDGroup_Contains(BPy_IDProperty *self, PyObject *value)
652
 
{
653
 
        char *name = _PyUnicode_AsString(value);
654
 
 
655
 
        if (!name) {
656
 
                PyErr_SetString( PyExc_TypeError, "expected a string");
657
 
                return -1;
658
 
        }
659
 
 
660
 
        return IDP_GetPropertyFromGroup(self->prop, name) ? 1:0;
661
 
}
662
 
 
663
 
static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value)
664
 
{
665
 
        PyObject *pkey, *pval;
666
 
        Py_ssize_t i=0;
667
 
 
668
 
        if (!PyDict_Check(value)) {
669
 
                PyErr_SetString( PyExc_TypeError, "expected an object derived from dict.");
670
 
                return NULL;
671
 
        }
672
 
 
673
 
        while (PyDict_Next(value, &i, &pkey, &pval)) {
674
 
                BPy_IDGroup_Map_SetItem(self, pkey, pval);
675
 
                if (PyErr_Occurred()) return NULL;
676
 
        }
677
 
 
678
 
        Py_RETURN_NONE;
679
 
}
680
 
 
681
 
static PyObject *BPy_IDGroup_ConvertToPy(BPy_IDProperty *self)
682
 
{
683
 
        return BPy_IDGroup_MapDataToPy(self->prop);
684
 
}
685
 
 
686
 
 
687
 
/* Matches python dict.get(key, [default]) */
688
 
PyObject* BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args)
689
 
{
690
 
        IDProperty *idprop;
691
 
        char *key;
692
 
        PyObject* def = Py_None;
693
 
 
694
 
        if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
695
 
                return NULL;
696
 
 
697
 
        idprop= IDP_GetPropertyFromGroup(self->prop, key);
698
 
        if (idprop) {
699
 
                PyObject* pyobj = BPy_IDGroup_WrapData(self->id, idprop);
700
 
                if (pyobj)
701
 
                        return pyobj;
702
 
        }
703
 
 
704
 
        Py_INCREF(def);
705
 
        return def;
706
 
}
707
 
 
708
 
static struct PyMethodDef BPy_IDGroup_methods[] = {
709
 
        {"pop", (PyCFunction)BPy_IDGroup_Pop, METH_O,
710
 
                "pop an item from the group; raises KeyError if the item doesn't exist"},
711
 
        {"iteritems", (PyCFunction)BPy_IDGroup_IterItems, METH_NOARGS,
712
 
                "iterate through the items in the dict; behaves like dictionary method iteritems"},
713
 
        {"keys", (PyCFunction)BPy_IDGroup_GetKeys, METH_NOARGS,
714
 
                "get the keys associated with this group as a list of strings"},
715
 
        {"values", (PyCFunction)BPy_IDGroup_GetValues, METH_NOARGS,
716
 
                "get the values associated with this group"},
717
 
        {"items", (PyCFunction)BPy_IDGroup_GetItems, METH_NOARGS,
718
 
                "get the items associated with this group"},
719
 
        {"update", (PyCFunction)BPy_IDGroup_Update, METH_O,
720
 
                "updates the values in the group with the values of another or a dict"},
721
 
        {"get", (PyCFunction)BPy_IDGroup_Get, METH_VARARGS,
722
 
                "idprop.get(k[,d]) -> idprop[k] if k in idprop, else d.  d defaults to None"},
723
 
        {"convert_to_pyobject", (PyCFunction)BPy_IDGroup_ConvertToPy, METH_NOARGS,
724
 
                "return a purely python version of the group"},
725
 
        {0, NULL, 0, NULL}
726
 
};
727
 
 
728
 
static PySequenceMethods BPy_IDGroup_Seq = {
729
 
        (lenfunc) BPy_IDGroup_Map_Len,                  /* lenfunc sq_length */
730
 
        0,                                                                      /* binaryfunc sq_concat */
731
 
        0,                                                                      /* ssizeargfunc sq_repeat */
732
 
        0,                                                                      /* ssizeargfunc sq_item */ /* TODO - setting this will allow PySequence_Check to return True */
733
 
        0,                                                                      /* intintargfunc ***was_sq_slice*** */
734
 
        0,                                                                      /* intobjargproc sq_ass_item */
735
 
        0,                                                                      /* ssizeobjargproc ***was_sq_ass_slice*** */
736
 
        (objobjproc) BPy_IDGroup_Contains,      /* objobjproc sq_contains */
737
 
        0,                                                                      /* binaryfunc sq_inplace_concat */
738
 
        0,                                                                      /* ssizeargfunc sq_inplace_repeat */
739
 
};
740
 
 
741
 
PyMappingMethods BPy_IDGroup_Mapping = {
742
 
        (lenfunc)BPy_IDGroup_Map_Len,                   /*inquiry mp_length */
743
 
        (binaryfunc)BPy_IDGroup_Map_GetItem,            /*binaryfunc mp_subscript */
744
 
        (objobjargproc)BPy_IDGroup_Map_SetItem, /*objobjargproc mp_ass_subscript */
745
 
};
746
 
 
747
 
PyTypeObject IDGroup_Type = {
748
 
        PyVarObject_HEAD_INIT(NULL, 0)
749
 
        /*  For printing, in format "<module>.<name>" */
750
 
        "Blender IDProperty",           /* char *tp_name; */
751
 
        sizeof( BPy_IDProperty ),       /* int tp_basicsize; */
752
 
        0,                          /* tp_itemsize;  For allocation */
753
 
 
754
 
        /* Methods to implement standard operations */
755
 
 
756
 
        NULL,                                           /* destructor tp_dealloc; */
757
 
        NULL,                       /* printfunc tp_print; */
758
 
        NULL,     /* getattrfunc tp_getattr; */
759
 
        NULL,     /* setattrfunc tp_setattr; */
760
 
        NULL,                       /* cmpfunc tp_compare; */
761
 
        ( reprfunc ) IDGroup_repr,     /* reprfunc tp_repr; */
762
 
 
763
 
        /* Method suites for standard classes */
764
 
 
765
 
        NULL,                       /* PyNumberMethods *tp_as_number; */
766
 
        &BPy_IDGroup_Seq,                       /* PySequenceMethods *tp_as_sequence; */
767
 
        &BPy_IDGroup_Mapping,           /* PyMappingMethods *tp_as_mapping; */
768
 
 
769
 
        /* More standard operations (here for binary compatibility) */
770
 
 
771
 
        NULL,                       /* hashfunc tp_hash; */
772
 
        NULL,                       /* ternaryfunc tp_call; */
773
 
        NULL,                       /* reprfunc tp_str; */
774
 
        NULL,                       /* getattrofunc tp_getattro; */
775
 
        NULL,                       /* setattrofunc tp_setattro; */
776
 
 
777
 
        /* Functions to access object as input/output buffer */
778
 
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
779
 
 
780
 
  /*** Flags to define presence of optional/expanded features ***/
781
 
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
782
 
 
783
 
        NULL,                       /*  char *tp_doc;  Documentation string */
784
 
  /*** Assigned meaning in release 2.0 ***/
785
 
        /* call function for all accessible objects */
786
 
        NULL,                       /* traverseproc tp_traverse; */
787
 
 
788
 
        /* delete references to contained objects */
789
 
        NULL,                       /* inquiry tp_clear; */
790
 
 
791
 
  /***  Assigned meaning in release 2.1 ***/
792
 
  /*** rich comparisons ***/
793
 
        NULL,                       /* richcmpfunc tp_richcompare; */
794
 
 
795
 
  /***  weak reference enabler ***/
796
 
        0,                          /* long tp_weaklistoffset; */
797
 
 
798
 
  /*** Added in release 2.2 ***/
799
 
        /*   Iterators */
800
 
        (getiterfunc)BPy_IDGroup_SpawnIterator, /* getiterfunc tp_iter; */
801
 
        NULL,                       /* iternextfunc tp_iternext; */
802
 
  /*** Attribute descriptor and subclassing stuff ***/
803
 
        BPy_IDGroup_methods,        /* struct PyMethodDef *tp_methods; */
804
 
        NULL,                       /* struct PyMemberDef *tp_members; */
805
 
        BPy_IDGroup_getseters,       /* struct PyGetSetDef *tp_getset; */
806
 
};
807
 
 
808
 
/*********** Main external wrapping function *******/
809
 
PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent)
810
 
{
811
 
        BPy_IDProperty *wrap = PyObject_New(BPy_IDProperty, &IDGroup_Type);
812
 
        wrap->prop = prop;
813
 
        wrap->parent = parent;
814
 
        wrap->id = id;
815
 
        //wrap->destroy = 0;
816
 
        return (PyObject*) wrap;
817
 
}
818
 
 
819
 
 
820
 
/********Array Wrapper********/
821
 
 
822
 
static PyObject *IDArray_repr(BPy_IDArray *self)
823
 
{
824
 
        return PyUnicode_FromString("(ID Array)");
825
 
}
826
 
 
827
 
 
828
 
static PyObject *BPy_IDArray_GetType(BPy_IDArray *self)
829
 
{
830
 
        return PyLong_FromSsize_t( self->prop->subtype );
831
 
}
832
 
 
833
 
static PyObject *BPy_IDArray_GetLen(BPy_IDArray *self)
834
 
{
835
 
        return PyLong_FromSsize_t( self->prop->len );
836
 
}
837
 
 
838
 
static PyGetSetDef BPy_IDArray_getseters[] = {
839
 
        {"len",
840
 
         (getter)BPy_IDArray_GetLen, (setter)NULL,
841
 
         "The length of the array, can also be gotten with len(array).",
842
 
         NULL},
843
 
        {"type",
844
 
         (getter)BPy_IDArray_GetType, (setter)NULL,
845
 
         "The type of the data in the array, is an ant.",
846
 
         NULL},
847
 
        {NULL, NULL, NULL, NULL, NULL},
848
 
};
849
 
 
850
 
static PyObject *BPy_IDArray_ConvertToPy(BPy_IDArray *self)
851
 
{
852
 
        return BPy_IDGroup_MapDataToPy(self->prop);
853
 
}
854
 
 
855
 
static PyMethodDef BPy_IDArray_methods[] = {
856
 
        {"convert_to_pyobject", (PyCFunction)BPy_IDArray_ConvertToPy, METH_NOARGS,
857
 
                "return a purely python version of the group"},
858
 
        {0, NULL, 0, NULL}
859
 
};
860
 
 
861
 
static int BPy_IDArray_Len(BPy_IDArray *self)
862
 
{
863
 
        return self->prop->len;
864
 
}
865
 
 
866
 
static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index)
867
 
{
868
 
        if (index < 0 || index >= self->prop->len) {
869
 
                PyErr_SetString( PyExc_IndexError, "index out of range!");
870
 
                return NULL;
871
 
        }
872
 
 
873
 
        switch (self->prop->subtype) {
874
 
                case IDP_FLOAT:
875
 
                        return PyFloat_FromDouble( (double)(((float*)self->prop->data.pointer)[index]));
876
 
                        break;
877
 
                case IDP_DOUBLE:
878
 
                        return PyFloat_FromDouble( (((double*)self->prop->data.pointer)[index]));
879
 
                        break;
880
 
                case IDP_INT:
881
 
                        return PyLong_FromLong( (long)((int*)self->prop->data.pointer)[index] );
882
 
                        break;
883
 
        }
884
 
 
885
 
        PyErr_SetString( PyExc_RuntimeError, "invalid/corrupt array type!");
886
 
        return NULL;
887
 
}
888
 
 
889
 
static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value)
890
 
{
891
 
        int i;
892
 
        float f;
893
 
        double d;
894
 
 
895
 
        if (index < 0 || index >= self->prop->len) {
896
 
                PyErr_SetString( PyExc_RuntimeError, "index out of range!");
897
 
                return -1;
898
 
        }
899
 
 
900
 
        switch (self->prop->subtype) {
901
 
                case IDP_FLOAT:
902
 
                        f= (float)PyFloat_AsDouble(value);
903
 
                        if (f==-1 && PyErr_Occurred()) {
904
 
                                PyErr_SetString(PyExc_TypeError, "expected a float");
905
 
                                return -1;
906
 
                        }
907
 
                        ((float*)self->prop->data.pointer)[index] = f;
908
 
                        break;
909
 
                case IDP_DOUBLE:
910
 
                        d= PyFloat_AsDouble(value);
911
 
                        if (d==-1 && PyErr_Occurred()) {
912
 
                                PyErr_SetString(PyExc_TypeError, "expected a float");
913
 
                                return -1;
914
 
                        }
915
 
                        ((double*)self->prop->data.pointer)[index] = d;
916
 
                        break;
917
 
                case IDP_INT:
918
 
                        i= PyLong_AsSsize_t(value);
919
 
                        if (i==-1 && PyErr_Occurred()) {
920
 
                                PyErr_SetString(PyExc_TypeError, "expected an int type");
921
 
                                return -1;
922
 
                        }
923
 
 
924
 
                        ((int*)self->prop->data.pointer)[index] = i;
925
 
                        break;
926
 
        }
927
 
        return 0;
928
 
}
929
 
 
930
 
static PySequenceMethods BPy_IDArray_Seq = {
931
 
        (lenfunc) BPy_IDArray_Len,                      /* inquiry sq_length */
932
 
        0,                                                                      /* binaryfunc sq_concat */
933
 
        0,                                                                      /* intargfunc sq_repeat */
934
 
        (ssizeargfunc)BPy_IDArray_GetItem,      /* intargfunc sq_item */
935
 
        0,                                                                      /* intintargfunc sq_slice */
936
 
        (ssizeobjargproc)BPy_IDArray_SetItem,   /* intobjargproc sq_ass_item */
937
 
        0,                                                                      /* intintobjargproc sq_ass_slice */
938
 
        0,                                                                      /* objobjproc sq_contains */
939
 
                                /* Added in release 2.0 */
940
 
        0,                                                                      /* binaryfunc sq_inplace_concat */
941
 
        0,                                                                      /* intargfunc sq_inplace_repeat */
942
 
};
943
 
 
944
 
PyTypeObject IDArray_Type = {
945
 
        PyVarObject_HEAD_INIT(NULL, 0)
946
 
        /*  For printing, in format "<module>.<name>" */
947
 
        "Blender IDArray",           /* char *tp_name; */
948
 
        sizeof( BPy_IDArray ),       /* int tp_basicsize; */
949
 
        0,                          /* tp_itemsize;  For allocation */
950
 
 
951
 
        /* Methods to implement standard operations */
952
 
 
953
 
        NULL,                                           /* destructor tp_dealloc; */
954
 
        NULL,                       /* printfunc tp_print; */
955
 
        NULL,     /* getattrfunc tp_getattr; */
956
 
        NULL,     /* setattrfunc tp_setattr; */
957
 
        NULL,                       /* cmpfunc tp_compare; */
958
 
        ( reprfunc ) IDArray_repr,     /* reprfunc tp_repr; */
959
 
 
960
 
        /* Method suites for standard classes */
961
 
 
962
 
        NULL,                       /* PyNumberMethods *tp_as_number; */
963
 
        &BPy_IDArray_Seq,                       /* PySequenceMethods *tp_as_sequence; */
964
 
        NULL,                       /* PyMappingMethods *tp_as_mapping; */
965
 
 
966
 
        /* More standard operations (here for binary compatibility) */
967
 
 
968
 
        NULL,                       /* hashfunc tp_hash; */
969
 
        NULL,                       /* ternaryfunc tp_call; */
970
 
        NULL,                       /* reprfunc tp_str; */
971
 
        NULL,                       /* getattrofunc tp_getattro; */
972
 
        NULL,                       /* setattrofunc tp_setattro; */
973
 
 
974
 
        /* Functions to access object as input/output buffer */
975
 
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
976
 
 
977
 
  /*** Flags to define presence of optional/expanded features ***/
978
 
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
979
 
 
980
 
        NULL,                       /*  char *tp_doc;  Documentation string */
981
 
  /*** Assigned meaning in release 2.0 ***/
982
 
        /* call function for all accessible objects */
983
 
        NULL,                       /* traverseproc tp_traverse; */
984
 
 
985
 
        /* delete references to contained objects */
986
 
        NULL,                       /* inquiry tp_clear; */
987
 
 
988
 
  /***  Assigned meaning in release 2.1 ***/
989
 
  /*** rich comparisons ***/
990
 
        NULL,                       /* richcmpfunc tp_richcompare; */
991
 
 
992
 
  /***  weak reference enabler ***/
993
 
        0,                          /* long tp_weaklistoffset; */
994
 
 
995
 
  /*** Added in release 2.2 ***/
996
 
        /*   Iterators */
997
 
        NULL,                       /* getiterfunc tp_iter; */
998
 
        NULL,                       /* iternextfunc tp_iternext; */
999
 
 
1000
 
  /*** Attribute descriptor and subclassing stuff ***/
1001
 
        BPy_IDArray_methods,            /* struct PyMethodDef *tp_methods; */
1002
 
        NULL,                       /* struct PyMemberDef *tp_members; */
1003
 
        BPy_IDArray_getseters,       /* struct PyGetSetDef *tp_getset; */
1004
 
        NULL,                       /* struct _typeobject *tp_base; */
1005
 
        NULL,                       /* PyObject *tp_dict; */
1006
 
        NULL,                       /* descrgetfunc tp_descr_get; */
1007
 
        NULL,                       /* descrsetfunc tp_descr_set; */
1008
 
        0,                          /* long tp_dictoffset; */
1009
 
        NULL,                       /* initproc tp_init; */
1010
 
        NULL,                       /* allocfunc tp_alloc; */
1011
 
        NULL,                       /* newfunc tp_new; */
1012
 
        /*  Low-level free-memory routine */
1013
 
        NULL,                       /* freefunc tp_free;  */
1014
 
        /* For PyObject_IS_GC */
1015
 
        NULL,                       /* inquiry tp_is_gc;  */
1016
 
        NULL,                       /* PyObject *tp_bases; */
1017
 
        /* method resolution order */
1018
 
        NULL,                       /* PyObject *tp_mro;  */
1019
 
        NULL,                       /* PyObject *tp_cache; */
1020
 
        NULL,                       /* PyObject *tp_subclasses; */
1021
 
        NULL,                       /* PyObject *tp_weaklist; */
1022
 
        NULL
1023
 
};
1024
 
 
1025
 
/*********** ID Property Group iterator ********/
1026
 
 
1027
 
static PyObject *IDGroup_Iter_iterself(PyObject *self)
1028
 
{
1029
 
        Py_XINCREF(self);
1030
 
        return self;
1031
 
}
1032
 
 
1033
 
static PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self)
1034
 
{
1035
 
        return PyUnicode_FromString("(ID Property Group)");
1036
 
}
1037
 
 
1038
 
static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self)
1039
 
{
1040
 
        IDProperty *cur=NULL;
1041
 
        PyObject *ret;
1042
 
 
1043
 
        if (self->cur) {
1044
 
                cur = self->cur;
1045
 
                self->cur = self->cur->next;
1046
 
                if (self->mode == IDPROP_ITER_ITEMS) {
1047
 
                        ret = PyTuple_New(2);
1048
 
                        PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(cur->name));
1049
 
                        PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur));
1050
 
                        return ret;
1051
 
                } else {
1052
 
                        return PyUnicode_FromString(cur->name);
1053
 
                }
1054
 
        } else {
1055
 
                PyErr_SetString( PyExc_StopIteration, "iterator at end" );
1056
 
                return NULL;
1057
 
        }
1058
 
}
1059
 
 
1060
 
PyTypeObject IDGroup_Iter_Type = {
1061
 
        PyVarObject_HEAD_INIT(NULL, 0)
1062
 
        /*  For printing, in format "<module>.<name>" */
1063
 
        "Blender IDGroup_Iter",           /* char *tp_name; */
1064
 
        sizeof( BPy_IDGroup_Iter ),       /* int tp_basicsize; */
1065
 
        0,                          /* tp_itemsize;  For allocation */
1066
 
 
1067
 
        /* Methods to implement standard operations */
1068
 
 
1069
 
        NULL,                                           /* destructor tp_dealloc; */
1070
 
        NULL,                       /* printfunc tp_print; */
1071
 
        NULL,     /* getattrfunc tp_getattr; */
1072
 
        NULL,     /* setattrfunc tp_setattr; */
1073
 
        NULL,                       /* cmpfunc tp_compare; */
1074
 
        ( reprfunc ) IDGroup_Iter_repr,     /* reprfunc tp_repr; */
1075
 
 
1076
 
        /* Method suites for standard classes */
1077
 
 
1078
 
        NULL,                       /* PyNumberMethods *tp_as_number; */
1079
 
        NULL,                                           /* PySequenceMethods *tp_as_sequence; */
1080
 
        NULL,                       /* PyMappingMethods *tp_as_mapping; */
1081
 
 
1082
 
        /* More standard operations (here for binary compatibility) */
1083
 
 
1084
 
        NULL,                       /* hashfunc tp_hash; */
1085
 
        NULL,                       /* ternaryfunc tp_call; */
1086
 
        NULL,                       /* reprfunc tp_str; */
1087
 
        NULL,                       /* getattrofunc tp_getattro; */
1088
 
        NULL,                       /* setattrofunc tp_setattro; */
1089
 
 
1090
 
        /* Functions to access object as input/output buffer */
1091
 
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
1092
 
 
1093
 
  /*** Flags to define presence of optional/expanded features ***/
1094
 
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1095
 
 
1096
 
        NULL,                       /*  char *tp_doc;  Documentation string */
1097
 
  /*** Assigned meaning in release 2.0 ***/
1098
 
        /* call function for all accessible objects */
1099
 
        NULL,                       /* traverseproc tp_traverse; */
1100
 
 
1101
 
        /* delete references to contained objects */
1102
 
        NULL,                       /* inquiry tp_clear; */
1103
 
 
1104
 
  /***  Assigned meaning in release 2.1 ***/
1105
 
  /*** rich comparisons ***/
1106
 
        NULL,                       /* richcmpfunc tp_richcompare; */
1107
 
 
1108
 
  /***  weak reference enabler ***/
1109
 
        0,                          /* long tp_weaklistoffset; */
1110
 
 
1111
 
  /*** Added in release 2.2 ***/
1112
 
        /*   Iterators */
1113
 
        IDGroup_Iter_iterself,              /* getiterfunc tp_iter; */
1114
 
        (iternextfunc) BPy_Group_Iter_Next, /* iternextfunc tp_iternext; */
1115
 
};
1116
 
 
1117
 
void IDProp_Init_Types(void)
1118
 
{
1119
 
        PyType_Ready( &IDGroup_Type );
1120
 
        PyType_Ready( &IDGroup_Iter_Type );
1121
 
        PyType_Ready( &IDArray_Type );
1122
 
}