eda2511a1873d0bdc9047a4f85f89fd02d52119e
[blender.git] / source / blender / python / intern / bpy_rna_array.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Arystanbek Dyussenov
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/intern/bpy_rna_array.c
24  *  \ingroup pythonintern
25  */
26
27 #include <Python.h>
28
29 #include "RNA_types.h"
30
31 #include "bpy_rna.h"
32 #include "BKE_global.h"
33 #include "MEM_guardedalloc.h"
34
35 #include "RNA_access.h"
36
37 #define MAX_ARRAY_DIMENSION 10
38
39 typedef void (*ItemConvertFunc)(PyObject *, char *);
40 typedef int  (*ItemTypeCheckFunc)(PyObject *);
41 typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *);
42 typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *);
43
44 /*
45   arr[3][4][5]
46           0  1  2  <- dimension index
47 */
48
49 /*
50   arr[2]= x
51
52   py_to_array_index(arraydim=0, arrayoffset=0, index=2)
53         validate_array(lvalue_dim=0)
54         ... make real index ...
55 */
56
57 /* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */
58 /* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */
59 static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[],
60                                                            ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix)
61 {
62         Py_ssize_t i;
63
64         /* not the last dimension */
65         if (dim + 1 < totdim) {
66                 /* check that a sequence contains dimsize[dim] items */
67                 const Py_ssize_t seq_size= PySequence_Size(seq);
68                 if (seq_size == -1) {
69                         PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'",
70                                      error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name);
71                         return -1;
72                 }
73                 for (i= 0; i < seq_size; i++) {
74                         PyObject *item;
75                         int ok= 1;
76                         item= PySequence_GetItem(seq, i);
77
78                         if (item == NULL) {
79                                 PyErr_Format(PyExc_TypeError, "%s sequence type '%s' failed to retrieve index %d",
80                                              error_prefix, Py_TYPE(seq)->tp_name, i);
81                                 ok= 0;
82                         }
83                         else if (!PySequence_Check(item)) {
84                                 /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */
85                                 PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s, not %s",
86                                              error_prefix, item_type_str, Py_TYPE(item)->tp_name);
87                                 ok= 0;
88                         }
89                         /* arr[3][4][5]
90                            dimsize[1]=4
91                            dimsize[2]=5
92                    
93                            dim=0 */
94                         else if (PySequence_Size(item) != dimsize[dim + 1]) {
95                                 /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)dimsize[dim + 1]); */
96                                 PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items",
97                                              error_prefix, (int)dim + 1, (int)dimsize[dim + 1]);
98                                 ok= 0;
99                         }
100                         else if (validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) {
101                                 ok= 0;
102                         }
103
104                         Py_XDECREF(item);
105
106                         if (!ok)
107                                 return -1;
108                 }
109         }
110         else {
111                 /* check that items are of correct type */
112                 const int seq_size= PySequence_Size(seq);
113                 if (seq_size == -1) {
114                         PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'",
115                                      error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name);
116                         return -1;
117                 }
118                 for (i= 0; i < seq_size; i++) {
119                         PyObject *item= PySequence_GetItem(seq, i);
120
121                         if (item == NULL) {
122                                 PyErr_Format(PyExc_TypeError, "%s sequence type '%s' failed to retrieve index %d",
123                                              error_prefix, Py_TYPE(seq)->tp_name, i);
124                                 return -1;
125                         }
126                         else if (!check_item_type(item)) {
127                                 Py_DECREF(item);
128
129                                 /* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */
130                                 PyErr_Format(PyExc_TypeError, "%s expected sequence items of type %s, not %s",
131                                              error_prefix, item_type_str, Py_TYPE(item)->tp_name);
132                                 return -1;
133                         }
134
135                         Py_DECREF(item);
136                 }
137         }
138
139         return 0; /* ok */
140 }
141
142 /* Returns the number of items in a single- or multi-dimensional sequence. */
143 static int count_items(PyObject *seq, int dim)
144 {
145         int totitem= 0;
146
147         if (dim > 1) {
148                 const Py_ssize_t seq_size= PySequence_Size(seq);
149                 Py_ssize_t i;
150                 for (i= 0; i < seq_size; i++) {
151                         PyObject *item= PySequence_GetItem(seq, i);
152                         if (item) {
153                                 const int tot= count_items(item, dim - 1);
154                                 Py_DECREF(item);
155                                 if (tot != -1) {
156                                         totitem += tot;
157                                 }
158                                 else {
159                                         totitem= -1;
160                                         break;
161                                 }
162                         }
163                         else {
164                                 totitem= -1;
165                                 break;
166                         }
167                 }
168         }
169         else {
170                 totitem= PySequence_Size(seq);
171         }
172
173         return totitem;
174 }
175
176 /* Modifies property array length if needed and PROP_DYNAMIC flag is set. */
177 static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix)
178 {
179         int dimsize[MAX_ARRAY_DIMENSION];
180         int tot, totdim, len;
181
182         totdim= RNA_property_array_dimension(ptr, prop, dimsize);
183         tot= count_items(rvalue, totdim - lvalue_dim);
184
185         if (tot == -1) {
186                 PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, error validating the sequence length",
187                              error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
188                 return -1;
189         }
190         else if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
191                 if (RNA_property_array_length(ptr, prop) != tot) {
192 #if 0
193                         /* length is flexible */
194                         if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) {
195                                 /* BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */
196                                 PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d",
197                                              error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot);
198                                 return -1;
199                         }
200 #else
201                         *totitem= tot;
202                         return 0;
203
204 #endif
205                 }
206
207                 len= tot;
208         }
209         else {
210                 /* length is a constraint */
211                 if (!lvalue_dim) {
212                         len= RNA_property_array_length(ptr, prop);
213                 }
214                 /* array item assignment */
215                 else {
216                         int i;
217
218                         len= 1;
219
220                         /* arr[3][4][5]
221
222                            arr[2]= x
223                            dimsize={4, 5}
224                            dimsize[1]= 4
225                            dimsize[2]= 5
226                            lvalue_dim=0, totdim=3
227
228                            arr[2][3]= x
229                            lvalue_dim=1
230
231                            arr[2][3][4]= x
232                            lvalue_dim=2 */
233                         for (i= lvalue_dim; i < totdim; i++)
234                                 len *= dimsize[i];
235                 }
236
237                 if (tot != len) {
238                         /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */
239                         PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, sequence must have %d items total, not %d",
240                                      error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), len, tot);
241                         return -1;
242                 }
243         }
244
245         *totitem= len;
246
247         return 0;
248 }
249
250 static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix)
251 {
252         int dimsize[MAX_ARRAY_DIMENSION];
253         int totdim= RNA_property_array_dimension(ptr, prop, dimsize);
254
255         /* validate type first because length validation may modify property array length */
256
257         if (validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1)
258                 return -1;
259
260         return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix);
261 }
262
263 static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
264 {
265         if (!data) {
266                 char value[sizeof(int)];
267
268                 convert_item(item, value);
269                 rna_set_index(ptr, prop, *index, value);
270                 *index= *index + 1;
271         }
272         else {
273                 convert_item(item, data);
274                 data += item_size;
275         }
276
277         return data;
278 }
279
280 static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
281 {
282         int totdim= RNA_property_array_dimension(ptr, prop, NULL);
283         const Py_ssize_t seq_size= PySequence_Size(seq);
284         Py_ssize_t i;
285
286         /* Regarding PySequence_GetItem() failing.
287          *
288          * This should never be NULL since we validated it, _but_ some triky python
289          * developer could write their own sequence type which succeeds on
290          * validating but fails later somehow, so include checks for safety.
291          */
292
293         /* Note that 'data can be NULL' */
294
295         if (seq_size == -1) {
296                 return NULL;
297         }
298
299         for (i= 0; i < seq_size; i++) {
300                 PyObject *item= PySequence_GetItem(seq, i);
301                 if (item) {
302                         if (dim + 1 < totdim) {
303                                 data= copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index);
304                         }
305                         else {
306                                 data= copy_value_single(item, ptr, prop, data, item_size, index, convert_item, rna_set_index);
307                         }
308
309                         Py_DECREF(item);
310
311                         /* data may be NULL, but the for loop checks */
312                 }
313                 else {
314                         return NULL;
315                 }
316         }
317
318         return data;
319 }
320
321 static int py_to_array(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix)
322 {
323         /*int totdim, dim_size[MAX_ARRAY_DIMENSION];*/
324         int totitem;
325         char *data= NULL;
326
327         /*totdim= RNA_property_array_dimension(ptr, prop, dim_size);*/ /*UNUSED*/
328
329         if (validate_array(seq, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix) == -1) {
330                 return -1;
331         }
332
333         if (totitem) {
334                 /* note: this code is confusing */
335                 if (param_data && RNA_property_flag(prop) & PROP_DYNAMIC) {
336                         /* not freeing allocated mem, RNA_parameter_list_free() will do this */
337                         ParameterDynAlloc *param_alloc= (ParameterDynAlloc *)param_data;
338                         param_alloc->array_tot= (int)totitem;
339                         param_alloc->array= MEM_callocN(item_size * totitem, "py_to_array dyn"); /* freeing param list will free */
340
341                         data= param_alloc->array;
342                 }
343                 else if (param_data) {
344                         data= param_data;
345                 }
346                 else {
347                         data= PyMem_MALLOC(item_size * totitem);
348                 }
349
350                 /* will only fail in very rare cases since we already validated the
351                  * python data, the check here is mainly for completeness. */
352                 if (copy_values(seq, ptr, prop, 0, data, item_size, NULL, convert_item, NULL) != NULL) {
353                         if (param_data==NULL) {
354                                 /* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */
355                                 rna_set_array(ptr, prop, data);
356                                 PyMem_FREE(data);
357                         }
358                 }
359                 else {
360                         if (param_data==NULL) {
361                                 PyMem_FREE(data);
362                         }
363
364                         PyErr_Format(PyExc_TypeError, "%s internal error parsing sequence of type '%s' after successful validation",
365                                      error_prefix, Py_TYPE(seq)->tp_name);
366                         return -1;
367                 }
368         }
369
370         return 0;
371 }
372
373 static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix)
374 {
375         int totdim, dimsize[MAX_ARRAY_DIMENSION];
376         int totitem, i;
377
378         totdim= RNA_property_array_dimension(ptr, prop, dimsize);
379
380         /* convert index */
381
382         /* arr[3][4][5]
383
384            arr[2]= x
385            lvalue_dim=0, index= 0 + 2 * 4 * 5
386
387            arr[2][3]= x
388            lvalue_dim=1, index= 40 + 3 * 5 */
389
390         lvalue_dim++;
391
392         for (i= lvalue_dim; i < totdim; i++)
393                 index *= dimsize[i];
394
395         index += arrayoffset;
396
397         if (lvalue_dim == totdim) { /* single item, assign directly */
398                 if (!check_item_type(py)) {
399                         PyErr_Format(PyExc_TypeError, "%s %.200s.%.200s, expected a %s type, not %s",
400                                      error_prefix, RNA_struct_identifier(ptr->type),
401                                      RNA_property_identifier(prop), item_type_str,
402                                      Py_TYPE(py)->tp_name);
403                         return -1;
404                 }
405                 copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index);
406         }
407         else {
408                 if (validate_array(py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix) == -1) {
409                         return -1;
410                 }
411
412                 if (totitem) {
413                         copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index);
414                 }
415         }
416         return 0;
417 }
418
419 static void py_to_float(PyObject *py, char *data)
420 {
421         *(float*)data= (float)PyFloat_AsDouble(py);
422 }
423
424 static void py_to_int(PyObject *py, char *data)
425 {
426         *(int*)data= (int)PyLong_AsSsize_t(py);
427 }
428
429 static void py_to_bool(PyObject *py, char *data)
430 {
431         *(int*)data= (int)PyObject_IsTrue(py);
432 }
433
434 static int py_float_check(PyObject *py)
435 {
436         /* accept both floats and integers */
437         return PyNumber_Check(py);
438 }
439
440 static int py_int_check(PyObject *py)
441 {
442         /* accept only integers */
443         return PyLong_Check(py);
444 }
445
446 static int py_bool_check(PyObject *py)
447 {
448         return PyBool_Check(py);
449 }
450
451 static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
452 {
453         RNA_property_float_set_index(ptr, prop, index, *(float*)value);
454 }
455
456 static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
457 {
458         RNA_property_int_set_index(ptr, prop, index, *(int*)value);
459 }
460
461 static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
462 {
463         RNA_property_boolean_set_index(ptr, prop, index, *(int*)value);
464 }
465
466 int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix)
467 {
468         int ret;
469         switch (RNA_property_type(prop)) {
470         case PROP_FLOAT:
471                 ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix);
472                 break;
473         case PROP_INT:
474                 ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix);
475                 break;
476         case PROP_BOOLEAN:
477                 ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix);
478                 break;
479         default:
480                 PyErr_SetString(PyExc_TypeError, "not an array type");
481                 ret= -1;
482         }
483
484         return ret;
485 }
486
487 int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix)
488 {
489         int ret;
490         switch (RNA_property_type(prop)) {
491         case PROP_FLOAT:
492                 ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix);
493                 break;
494         case PROP_INT:
495                 ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix);
496                 break;
497         case PROP_BOOLEAN:
498                 ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix);
499                 break;
500         default:
501                 PyErr_SetString(PyExc_TypeError, "not an array type");
502                 ret= -1;
503         }
504
505         return ret;
506 }
507
508 PyObject *pyrna_array_index(PointerRNA *ptr, PropertyRNA *prop, int index)
509 {
510         PyObject *item;
511
512         switch (RNA_property_type(prop)) {
513         case PROP_FLOAT:
514                 item= PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index));
515                 break;
516         case PROP_BOOLEAN:
517                 item= PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index));
518                 break;
519         case PROP_INT:
520                 item= PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index));
521                 break;
522         default:
523                 PyErr_SetString(PyExc_TypeError, "not an array type");
524                 item= NULL;
525         }
526
527         return item;
528 }
529
530 #if 0
531 /* XXX this is not used (and never will?) */
532 /* Given an array property, creates an N-dimensional tuple of values. */
533 static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop, int dim, int *index)
534 {
535         PyObject *tuple;
536         int i, len;
537         int totdim= RNA_property_array_dimension(ptr, prop, NULL);
538
539         len= RNA_property_multi_array_length(ptr, prop, dim);
540
541         tuple= PyTuple_New(len);
542
543         for (i= 0; i < len; i++) {
544                 PyObject *item;
545
546                 if (dim + 1 < totdim)
547                         item= pyrna_py_from_array_internal(ptr, prop, dim + 1, index);
548                 else {
549                         item= pyrna_array_index(ptr, prop, *index);
550                         *index= *index + 1;
551                 }
552
553                 if (!item) {
554                         Py_DECREF(tuple);
555                         return NULL;
556                 }
557
558                 PyTuple_SET_ITEM(tuple, i, item);
559         }
560
561         return tuple;
562 }
563 #endif
564
565 PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int index)
566 {
567         int totdim, arraydim, arrayoffset, dimsize[MAX_ARRAY_DIMENSION], i, len;
568         BPy_PropertyArrayRNA *ret= NULL;
569
570         arraydim= self ? self->arraydim : 0;
571         arrayoffset= self ? self->arrayoffset : 0;
572
573         /* just in case check */
574         len= RNA_property_multi_array_length(ptr, prop, arraydim);
575         if (index >= len || index < 0) {
576                 /* this shouldn't happen because higher level funcs must check for invalid index */
577                 if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len);
578
579                 PyErr_SetString(PyExc_IndexError, "out of range");
580                 return NULL;
581         }
582
583         totdim= RNA_property_array_dimension(ptr, prop, dimsize);
584
585         if (arraydim + 1 < totdim) {
586                 ret= (BPy_PropertyArrayRNA*)pyrna_prop_CreatePyObject(ptr, prop);
587                 ret->arraydim= arraydim + 1;
588
589                 /* arr[3][4][5]
590
591                    x= arr[2]
592                    index= 0 + 2 * 4 * 5
593
594                    x= arr[2][3]
595                    index= offset + 3 * 5 */
596
597                 for (i= arraydim + 1; i < totdim; i++)
598                         index *= dimsize[i];
599
600                 ret->arrayoffset= arrayoffset + index;
601         }
602         else {
603                 index= arrayoffset + index;
604                 ret= (BPy_PropertyArrayRNA *)pyrna_array_index(ptr, prop, index);
605         }
606
607         return (PyObject*)ret;
608 }
609
610 PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop)
611 {
612         PyObject *ret;
613
614         ret= pyrna_math_object_from_array(ptr, prop);
615
616         /* is this a maths object? */
617         if (ret) return ret;
618
619         return pyrna_prop_CreatePyObject(ptr, prop);
620 }
621
622 /* TODO, multi-dimensional arrays */
623 int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
624 {
625         int len= RNA_property_array_length(ptr, prop);
626         int type;
627         int i;
628
629         if (len==0) /* possible with dynamic arrays */
630                 return 0;
631
632         if (RNA_property_array_dimension(ptr, prop, NULL) > 1) {
633                 PyErr_SetString(PyExc_TypeError, "PropertyRNA - multi dimensional arrays not supported yet");
634                 return -1;
635         }
636
637         type= RNA_property_type(prop);
638
639         switch (type) {
640                 case PROP_FLOAT:
641                 {
642                         float value_f= PyFloat_AsDouble(value);
643                         if (value_f==-1 && PyErr_Occurred()) {
644                                 PyErr_Clear();
645                                 return 0;
646                         }
647                         else {
648                                 float tmp[32];
649                                 float *tmp_arr;
650
651                                 if (len * sizeof(float) > sizeof(tmp)) {
652                                         tmp_arr= PyMem_MALLOC(len * sizeof(float));
653                                 }
654                                 else {
655                                         tmp_arr= tmp;
656                                 }
657
658                                 RNA_property_float_get_array(ptr, prop, tmp_arr);
659
660                                 for (i=0; i<len; i++) {
661                                         if (tmp_arr[i] == value_f) {
662                                                 break;
663                                         }
664                                 }
665
666                                 if (tmp_arr != tmp)
667                                         PyMem_FREE(tmp_arr);
668
669                                 return i<len ? 1 : 0;
670                         }
671                         break;
672                 }
673                 case PROP_BOOLEAN:
674                 case PROP_INT:
675                 {
676                         int value_i= PyLong_AsSsize_t(value);
677                         if (value_i==-1 && PyErr_Occurred()) {
678                                 PyErr_Clear();
679                                 return 0;
680                         }
681                         else {
682                                 int tmp[32];
683                                 int *tmp_arr;
684
685                                 if (len * sizeof(int) > sizeof(tmp)) {
686                                         tmp_arr= PyMem_MALLOC(len * sizeof(int));
687                                 }
688                                 else {
689                                         tmp_arr= tmp;
690                                 }
691
692                                 if (type==PROP_BOOLEAN)
693                                         RNA_property_boolean_get_array(ptr, prop, tmp_arr);
694                                 else
695                                         RNA_property_int_get_array(ptr, prop, tmp_arr);
696
697                                 for (i=0; i<len; i++) {
698                                         if (tmp_arr[i] == value_i) {
699                                                 break;
700                                         }
701                                 }
702
703                                 if (tmp_arr != tmp)
704                                         PyMem_FREE(tmp_arr);
705
706                                 return i<len ? 1 : 0;
707                         }
708                         break;
709                 }
710         }
711
712         /* should never reach this */
713         PyErr_SetString(PyExc_TypeError, "PropertyRNA - type not in float/bool/int");
714         return -1;
715 }