rename RNA_property_is_set() --> RNA_struct_property_is_set() in preperation to add...
[blender.git] / source / blender / python / intern / bpy_rna.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): Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/intern/bpy_rna.c
24  *  \ingroup pythonintern
25  *
26  * This file is the main interface between python and blenders data api (RNA),
27  * exposing RNA to python so blender data can be accessed in a python like way.
28  *
29  * The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base
30  * classes for most of the data python accesses in blender.
31  */
32
33 #include <Python.h>
34
35 #include <stddef.h>
36 #include <float.h> /* FLT_MIN/MAX */
37
38 #include "RNA_types.h"
39
40 #include "bpy_rna.h"
41 #include "bpy_rna_anim.h"
42 #include "bpy_props.h"
43 #include "bpy_util.h"
44 #include "bpy_rna_callback.h"
45 #include "bpy_intern_string.h"
46
47 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
48 #include "MEM_guardedalloc.h"
49 #endif
50
51 #include "BLI_dynstr.h"
52 #include "BLI_string.h"
53 #include "BLI_listbase.h"
54 #include "BLI_math_rotation.h"
55 #include "BLI_utildefines.h"
56
57 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
58 #include "BLI_ghash.h"
59 #endif
60
61 #include "RNA_enum_types.h"
62 #include "RNA_define.h" /* RNA_def_property_free_identifier */
63 #include "RNA_access.h"
64
65 #include "MEM_guardedalloc.h"
66
67 #include "BKE_main.h"
68 #include "BKE_idcode.h"
69 #include "BKE_context.h"
70 #include "BKE_global.h" /* evil G.* */
71 #include "BKE_report.h"
72 #include "BKE_idprop.h"
73
74 #include "BKE_animsys.h"
75 #include "BKE_fcurve.h"
76
77 #include "../generic/idprop_py_api.h" /* for IDprop lookups */
78 #include "../generic/py_capi_utils.h"
79
80 #ifdef WITH_INTERNATIONAL
81 #include "BLF_translation.h"
82 #endif
83
84 #define USE_PEDANTIC_WRITE
85 #define USE_MATHUTILS
86 #define USE_STRING_COERCE
87
88 static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
89 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
90
91 #define BPY_DOC_ID_PROP_TYPE_NOTE                                             \
92 "   .. note::\n"                                                              \
93 "\n"                                                                          \
94 "      Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n"            \
95 "      :class:`bpy.types.PoseBone` classes support custom properties.\n"
96
97
98 int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
99 {
100         if (pysrna->ptr.type) {
101                 return 0;
102         }
103         PyErr_Format(PyExc_ReferenceError,
104                      "StructRNA of type %.200s has been removed",
105                      Py_TYPE(pysrna)->tp_name);
106         return -1;
107 }
108
109 int pyrna_prop_validity_check(BPy_PropertyRNA *self)
110 {
111         if (self->ptr.type) {
112                 return 0;
113         }
114         PyErr_Format(PyExc_ReferenceError,
115                      "PropertyRNA of type %.200s.%.200s has been removed",
116                      Py_TYPE(self)->tp_name, RNA_property_identifier(self->prop));
117         return -1;
118 }
119
120 #if defined(USE_PYRNA_INVALIDATE_GC) || defined(USE_PYRNA_INVALIDATE_WEAKREF)
121 static void pyrna_invalidate(BPy_DummyPointerRNA *self)
122 {
123         self->ptr.type = NULL; /* this is checked for validity */
124         self->ptr.id.data = NULL; /* should not be needed but prevent bad pointer access, just incase */
125 }
126 #endif
127
128 #ifdef USE_PYRNA_INVALIDATE_GC
129 #define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1))
130
131 /* only for sizeof() */
132 struct gc_generation {
133         PyGC_Head head;
134         int threshold;
135         int count;
136 } gc_generation;
137
138 static void id_release_gc(struct ID *id)
139 {
140         unsigned int j;
141         // unsigned int i = 0;
142         for (j = 0; j < 3; j++) {
143                 /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */
144                 PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
145                 PyGC_Head *g = gen->gc.gc_next;
146                 while ((g = g->gc.gc_next) != gen) {
147                         PyObject *ob = FROM_GC(g);
148                         if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
149                                 BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob;
150                                 if (ob_ptr->ptr.id.data == id) {
151                                         pyrna_invalidate(ob_ptr);
152                                         // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
153                                         // i++;
154                                 }
155                         }
156                 }
157         }
158         // printf("id_release_gc freed '%s': %d\n", id->name, i);
159 }
160 #endif
161
162 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
163 //#define DEBUG_RNA_WEAKREF
164
165 struct GHash *id_weakref_pool = NULL;
166 static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
167 static PyMethodDef id_free_weakref_cb_def = {"id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL};
168
169 /* adds a reference to the list, remember to decref */
170 static GHash *id_weakref_pool_get(ID *id)
171 {
172         GHash *weakinfo_hash = NULL;
173
174         if (id_weakref_pool) {
175                 weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
176         }
177         else {
178                 /* first time, allocate pool */
179                 id_weakref_pool = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_global_pool");
180                 weakinfo_hash = NULL;
181         }
182
183         if (weakinfo_hash == NULL) {
184                 /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */
185                 weakinfo_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_id");
186                 BLI_ghash_insert(id_weakref_pool, (void *)id, weakinfo_hash);
187         }
188
189         return weakinfo_hash;
190 }
191
192 /* called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject() */
193 void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
194 {
195         PyObject *weakref;
196         PyObject *weakref_capsule;
197         PyObject *weakref_cb_py;
198
199         /* create a new function instance and insert the list as 'self' so we can remove ourself from it */
200         GHash *weakinfo_hash = id_weakref_pool_get(id); /* new or existing */
201
202         weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL);
203         weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
204         Py_DECREF(weakref_capsule);
205
206         /* add weakref to weakinfo_hash list */
207         weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
208
209         Py_DECREF(weakref_cb_py); /* function owned by the weakref now */
210
211         /* important to add at the end, since first removal looks at the end */
212         BLI_ghash_insert(weakinfo_hash, (void *)weakref, id); /* using a hash table as a set, all 'id's are the same */
213         /* weakinfo_hash owns the weakref */
214
215 }
216
217 /* workaround to get the last id without a lookup */
218 static ID *_id_tmp_ptr;
219 static void value_id_set(void *id)
220 {
221         _id_tmp_ptr = (ID *)id;
222 }
223
224 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
225 static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref)
226 {
227         /* important to search backwards */
228         GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL);
229
230
231         if (BLI_ghash_size(weakinfo_hash) > 1) {
232                 BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
233         }
234         else { /* get the last id and free it */
235                 BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set);
236                 id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
237         }
238
239         Py_DECREF(weakref);
240
241         Py_RETURN_NONE;
242 }
243
244 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
245 {
246         GHashIterator weakinfo_hash_iter;
247
248         BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
249
250 #ifdef DEBUG_RNA_WEAKREF
251         fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
252 #endif
253
254         while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) {
255                 PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
256                 PyObject *item = PyWeakref_GET_OBJECT(weakref);
257                 if (item != Py_None) {
258
259 #ifdef DEBUG_RNA_WEAKREF
260                         PyC_ObSpit("id_release_weakref item ", item);
261 #endif
262
263                         pyrna_invalidate((BPy_DummyPointerRNA *)item);
264                 }
265
266                 Py_DECREF(weakref);
267
268                 BLI_ghashIterator_step(&weakinfo_hash_iter);
269         }
270
271         BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
272         BLI_ghash_free(weakinfo_hash, NULL, NULL);
273
274         if (BLI_ghash_size(id_weakref_pool) == 0) {
275                 BLI_ghash_free(id_weakref_pool, NULL, NULL);
276                 id_weakref_pool = NULL;
277 #ifdef DEBUG_RNA_WEAKREF
278                 printf("id_release_weakref freeing pool\n");
279 #endif
280         }
281 }
282
283 static void id_release_weakref(struct ID *id)
284 {
285         GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
286         if (weakinfo_hash) {
287                 id_release_weakref_list(id, weakinfo_hash);
288         }
289 }
290
291 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
292
293 void BPY_id_release(struct ID *id)
294 {
295 #ifdef USE_PYRNA_INVALIDATE_GC
296         id_release_gc(id);
297 #endif
298
299 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
300         if (id_weakref_pool) {
301                 PyGILState_STATE gilstate = PyGILState_Ensure();
302
303                 id_release_weakref(id);
304
305                 PyGILState_Release(gilstate);
306         }
307 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
308
309         (void)id;
310 }
311
312 #ifdef USE_PEDANTIC_WRITE
313 static short rna_disallow_writes = FALSE;
314
315 static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
316 {
317         ID *id = ptr->id.data;
318         if (id) {
319                 const short idcode = GS(id->name);
320                 if (!ELEM(idcode, ID_WM, ID_SCR)) { /* may need more added here */
321                         const char *idtype = BKE_idcode_to_name(idcode);
322                         const char *pyname;
323                         if (key && PyUnicode_Check(key)) pyname = _PyUnicode_AsString(key);
324                         else                             pyname = "<UNKNOWN>";
325
326                         /* make a nice string error */
327                         BLI_assert(idtype != NULL);
328                         PyErr_Format(PyExc_AttributeError,
329                                      "Writing to ID classes in this context is not allowed: "
330                                      "%.200s, %.200s datablock, error setting %.200s.%.200s",
331                                      id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname);
332
333                         return TRUE;
334                 }
335         }
336         return FALSE;
337 }
338 #endif // USE_PEDANTIC_WRITE
339
340
341 #ifdef USE_PEDANTIC_WRITE
342 int pyrna_write_check(void)
343 {
344         return !rna_disallow_writes;
345 }
346
347 void pyrna_write_set(int val)
348 {
349         rna_disallow_writes = !val;
350 }
351 #else // USE_PEDANTIC_WRITE
352 int pyrna_write_check(void)
353 {
354         return TRUE;
355 }
356 void pyrna_write_set(int UNUSED(val))
357 {
358         /* nothing */
359 }
360 #endif // USE_PEDANTIC_WRITE
361
362 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
363 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
364 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
365 static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
366
367 #ifdef USE_MATHUTILS
368 #include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */
369
370 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
371                                                   Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
372 static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
373
374 /* bpyrna vector/euler/quat callbacks */
375 static int mathutils_rna_array_cb_index = -1; /* index for our callbacks */
376
377 /* subtype not used much yet */
378 #define MATHUTILS_CB_SUBTYPE_EUL 0
379 #define MATHUTILS_CB_SUBTYPE_VEC 1
380 #define MATHUTILS_CB_SUBTYPE_QUAT 2
381 #define MATHUTILS_CB_SUBTYPE_COLOR 3
382
383 static int mathutils_rna_generic_check(BaseMathObject *bmo)
384 {
385         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
386
387         PYRNA_PROP_CHECK_INT(self);
388
389         return self->prop ? 0 : -1;
390 }
391
392 static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
393 {
394         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
395
396         PYRNA_PROP_CHECK_INT(self);
397
398         if (self->prop == NULL)
399                 return -1;
400
401         RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
402
403         /* Euler order exception */
404         if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
405                 EulerObject *eul = (EulerObject *)bmo;
406                 PropertyRNA *prop_eul_order = NULL;
407                 eul->order = pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
408         }
409
410         return 0;
411 }
412
413 static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
414 {
415         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
416         float min, max;
417
418         PYRNA_PROP_CHECK_INT(self);
419
420         if (self->prop == NULL)
421                 return -1;
422
423 #ifdef USE_PEDANTIC_WRITE
424         if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
425                 return -1;
426         }
427 #endif // USE_PEDANTIC_WRITE
428
429         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
430                 PyErr_Format(PyExc_AttributeError,
431                              "bpy_prop \"%.200s.%.200s\" is read-only",
432                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
433                 return -1;
434         }
435
436         RNA_property_float_range(&self->ptr, self->prop, &min, &max);
437
438         if (min != FLT_MIN || max != FLT_MAX) {
439                 int i, len = RNA_property_array_length(&self->ptr, self->prop);
440                 for (i = 0; i < len; i++) {
441                         CLAMP(bmo->data[i], min, max);
442                 }
443         }
444
445         RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
446         if (RNA_property_update_check(self->prop)) {
447                 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
448         }
449
450         /* Euler order exception */
451         if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
452                 EulerObject *eul = (EulerObject *)bmo;
453                 PropertyRNA *prop_eul_order = NULL;
454                 short order = pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
455                 if (order != eul->order) {
456                         RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
457                         if (RNA_property_update_check(prop_eul_order)) {
458                                 RNA_property_update(BPy_GetContext(), &self->ptr, prop_eul_order);
459                         }
460                 }
461         }
462         return 0;
463 }
464
465 static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
466 {
467         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
468
469         PYRNA_PROP_CHECK_INT(self);
470
471         if (self->prop == NULL)
472                 return -1;
473
474         bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index);
475         return 0;
476 }
477
478 static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
479 {
480         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
481
482         PYRNA_PROP_CHECK_INT(self);
483
484         if (self->prop == NULL)
485                 return -1;
486
487 #ifdef USE_PEDANTIC_WRITE
488         if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
489                 return -1;
490         }
491 #endif // USE_PEDANTIC_WRITE
492
493         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
494                 PyErr_Format(PyExc_AttributeError,
495                              "bpy_prop \"%.200s.%.200s\" is read-only",
496                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
497                 return -1;
498         }
499
500         RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
501         RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
502
503         if (RNA_property_update_check(self->prop)) {
504                 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
505         }
506
507         return 0;
508 }
509
510 static Mathutils_Callback mathutils_rna_array_cb = {
511         (BaseMathCheckFunc)             mathutils_rna_generic_check,
512         (BaseMathGetFunc)               mathutils_rna_vector_get,
513         (BaseMathSetFunc)               mathutils_rna_vector_set,
514         (BaseMathGetIndexFunc)  mathutils_rna_vector_get_index,
515         (BaseMathSetIndexFunc)  mathutils_rna_vector_set_index
516 };
517
518
519 /* bpyrna matrix callbacks */
520 static int mathutils_rna_matrix_cb_index = -1; /* index for our callbacks */
521
522 static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
523 {
524         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
525
526         PYRNA_PROP_CHECK_INT(self);
527
528         if (self->prop == NULL)
529                 return -1;
530
531         RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
532         return 0;
533 }
534
535 static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
536 {
537         BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
538
539         PYRNA_PROP_CHECK_INT(self);
540
541         if (self->prop == NULL)
542                 return -1;
543
544 #ifdef USE_PEDANTIC_WRITE
545         if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
546                 return -1;
547         }
548 #endif // USE_PEDANTIC_WRITE
549
550         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
551                 PyErr_Format(PyExc_AttributeError,
552                              "bpy_prop \"%.200s.%.200s\" is read-only",
553                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
554                 return -1;
555         }
556
557         /* can ignore clamping here */
558         RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
559
560         if (RNA_property_update_check(self->prop)) {
561                 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
562         }
563         return 0;
564 }
565
566 static Mathutils_Callback mathutils_rna_matrix_cb = {
567         mathutils_rna_generic_check,
568         mathutils_rna_matrix_get,
569         mathutils_rna_matrix_set,
570         NULL,
571         NULL
572 };
573
574 static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback)
575 {
576         /* attempt to get order */
577         if (*prop_eul_order == NULL)
578                 *prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode");
579
580         if (*prop_eul_order) {
581                 short order = RNA_property_enum_get(ptr, *prop_eul_order);
582                 if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) /* could be quat or axisangle */
583                         return order;
584         }
585
586         return order_fallback;
587 }
588
589 #endif // USE_MATHUTILS
590
591 /* note that PROP_NONE is included as a vector subtype. this is because its handy to
592  * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */
593 #define PROP_ALL_VECTOR_SUBTYPES                                              \
594                  PROP_COORDS:                                                         \
595         case PROP_TRANSLATION:                                                    \
596         case PROP_DIRECTION:                                                      \
597         case PROP_VELOCITY:                                                       \
598         case PROP_ACCELERATION:                                                   \
599         case PROP_XYZ:                                                            \
600         case PROP_XYZ_LENGTH                                                      \
601
602
603 PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
604 {
605         PyObject *ret = NULL;
606
607 #ifdef USE_MATHUTILS
608         int subtype, totdim;
609         int len;
610         int is_thick;
611         const int flag = RNA_property_flag(prop);
612
613         /* disallow dynamic sized arrays to be wrapped since the size could change
614          * to a size mathutils does not support */
615         if ((RNA_property_type(prop) != PROP_FLOAT) || (flag & PROP_DYNAMIC))
616                 return NULL;
617
618         len = RNA_property_array_length(ptr, prop);
619         subtype = RNA_property_subtype(prop);
620         totdim = RNA_property_array_dimension(ptr, prop, NULL);
621         is_thick = (flag & PROP_THICK_WRAP);
622
623         if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
624                 if (!is_thick)
625                         ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
626
627                 switch (subtype) {
628                 case PROP_ALL_VECTOR_SUBTYPES:
629                         if (len >= 2 && len <= 4) {
630                                 if (is_thick) {
631                                         ret = Vector_CreatePyObject(NULL, len, Py_NEW, NULL);
632                                         RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
633                                 }
634                                 else {
635                                         PyObject *vec_cb = Vector_CreatePyObject_cb(ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC);
636                                         Py_DECREF(ret); /* the vector owns now */
637                                         ret = vec_cb; /* return the vector instead */
638                                 }
639                         }
640                         break;
641                 case PROP_MATRIX:
642                         if (len == 16) {
643                                 if (is_thick) {
644                                         ret = Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL);
645                                         RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
646                                 }
647                                 else {
648                                         PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
649                                         Py_DECREF(ret); /* the matrix owns now */
650                                         ret = mat_cb; /* return the matrix instead */
651                                 }
652                         }
653                         else if (len == 9) {
654                                 if (is_thick) {
655                                         ret = Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL);
656                                         RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
657                                 }
658                                 else {
659                                         PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
660                                         Py_DECREF(ret); /* the matrix owns now */
661                                         ret = mat_cb; /* return the matrix instead */
662                                 }
663                         }
664                         break;
665                 case PROP_EULER:
666                 case PROP_QUATERNION:
667                         if (len == 3) { /* euler */
668                                 if (is_thick) {
669                                         /* attempt to get order, only needed for thick types since wrapped with update via callbacks */
670                                         PropertyRNA *prop_eul_order = NULL;
671                                         short order = pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ);
672
673                                         ret = Euler_CreatePyObject(NULL, order, Py_NEW, NULL); // TODO, get order from RNA
674                                         RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
675                                 }
676                                 else {
677                                         /* order will be updated from callback on use */
678                                         PyObject *eul_cb = Euler_CreatePyObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
679                                         Py_DECREF(ret); /* the euler owns now */
680                                         ret = eul_cb; /* return the euler instead */
681                                 }
682                         }
683                         else if (len == 4) {
684                                 if (is_thick) {
685                                         ret = Quaternion_CreatePyObject(NULL, Py_NEW, NULL);
686                                         RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
687                                 }
688                                 else {
689                                         PyObject *quat_cb = Quaternion_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT);
690                                         Py_DECREF(ret); /* the quat owns now */
691                                         ret = quat_cb; /* return the quat instead */
692                                 }
693                         }
694                         break;
695                 case PROP_COLOR:
696                 case PROP_COLOR_GAMMA:
697                         if (len == 3) { /* color */
698                                 if (is_thick) {
699                                         ret = Color_CreatePyObject(NULL, Py_NEW, NULL); // TODO, get order from RNA
700                                         RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col);
701                                 }
702                                 else {
703                                         PyObject *col_cb = Color_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR);
704                                         Py_DECREF(ret); /* the color owns now */
705                                         ret = col_cb; /* return the color instead */
706                                 }
707                         }
708                 default:
709                         break;
710                 }
711         }
712
713         if (ret == NULL) {
714                 if (is_thick) {
715                         /* this is an array we cant reference (since its not thin wrappable)
716                          * and cannot be coerced into a mathutils type, so return as a list */
717                         ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
718                 }
719                 else {
720                         ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
721                 }
722         }
723 #else // USE_MATHUTILS
724         (void)ptr;
725         (void)prop;
726 #endif // USE_MATHUTILS
727
728         return ret;
729 }
730
731 /* same as RNA_enum_value_from_id but raises an exception */
732 int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
733 {
734         if (RNA_enum_value_from_id(item, identifier, value) == 0) {
735                 const char *enum_str = BPy_enum_as_string(item);
736                 PyErr_Format(PyExc_TypeError,
737                              "%s: '%.200s' not found in (%s)",
738                              error_prefix, identifier, enum_str);
739                 MEM_freeN((void *)enum_str);
740                 return -1;
741         }
742
743         return 0;
744 }
745
746 static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
747 {
748         return (a->ptr.data == b->ptr.data) ? 0 : -1;
749 }
750
751 static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
752 {
753         return (a->prop == b->prop && a->ptr.data == b->ptr.data) ? 0 : -1;
754 }
755
756 static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
757 {
758         PyObject *res;
759         int ok = -1; /* zero is true */
760
761         if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b))
762                 ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
763
764         switch (op) {
765         case Py_NE:
766                 ok = !ok; /* pass through */
767         case Py_EQ:
768                 res = ok ? Py_False : Py_True;
769                 break;
770
771         case Py_LT:
772         case Py_LE:
773         case Py_GT:
774         case Py_GE:
775                 res = Py_NotImplemented;
776                 break;
777         default:
778                 PyErr_BadArgument();
779                 return NULL;
780         }
781
782         return Py_INCREF(res), res;
783 }
784
785 static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
786 {
787         PyObject *res;
788         int ok = -1; /* zero is true */
789
790         if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b))
791                 ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
792
793         switch (op) {
794         case Py_NE:
795                 ok = !ok; /* pass through */
796         case Py_EQ:
797                 res = ok ? Py_False : Py_True;
798                 break;
799
800         case Py_LT:
801         case Py_LE:
802         case Py_GT:
803         case Py_GE:
804                 res = Py_NotImplemented;
805                 break;
806         default:
807                 PyErr_BadArgument();
808                 return NULL;
809         }
810
811         return Py_INCREF(res), res;
812 }
813
814 /*----------------------repr--------------------------------------------*/
815 static PyObject *pyrna_struct_str(BPy_StructRNA *self)
816 {
817         PyObject *ret;
818         const char *name;
819
820         if (!PYRNA_STRUCT_IS_VALID(self)) {
821                 return PyUnicode_FromFormat("<bpy_struct, %.200s dead>",
822                                             Py_TYPE(self)->tp_name);
823         }
824
825         /* print name if available */
826         name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
827         if (name) {
828                 ret = PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>",
829                                           RNA_struct_identifier(self->ptr.type),
830                                           name);
831                 MEM_freeN((void *)name);
832                 return ret;
833         }
834
835         return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>",
836                                     RNA_struct_identifier(self->ptr.type),
837                                     self->ptr.data);
838 }
839
840 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
841 {
842         ID *id = self->ptr.id.data;
843         PyObject *tmp_str;
844         PyObject *ret;
845
846         if (id == NULL || !PYRNA_STRUCT_IS_VALID(self))
847                 return pyrna_struct_str(self); /* fallback */
848
849         tmp_str = PyUnicode_FromString(id->name + 2);
850
851         if (RNA_struct_is_ID(self->ptr.type)) {
852                 ret = PyUnicode_FromFormat("bpy.data.%s[%R]",
853                                             BKE_idcode_to_name_plural(GS(id->name)),
854                                             tmp_str);
855         }
856         else {
857                 const char *path;
858                 path = RNA_path_from_ID_to_struct(&self->ptr);
859                 if (path) {
860                         ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
861                                                   BKE_idcode_to_name_plural(GS(id->name)),
862                                                   tmp_str,
863                                                   path);
864                         MEM_freeN((void *)path);
865                 }
866                 else { /* cant find, print something sane */
867                         ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
868                                                   BKE_idcode_to_name_plural(GS(id->name)),
869                                                   tmp_str,
870                                                   RNA_struct_identifier(self->ptr.type));
871                 }
872         }
873
874         Py_DECREF(tmp_str);
875
876         return ret;
877 }
878
879 static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
880 {
881         PyObject *ret;
882         PointerRNA ptr;
883         const char *name;
884         const char *type_id = NULL;
885         char type_fmt[64] = "";
886         int type;
887
888         PYRNA_PROP_CHECK_OBJ(self);
889
890         type = RNA_property_type(self->prop);
891
892         if (RNA_enum_id_from_value(property_type_items, type, &type_id) == 0) {
893                 PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */
894                 return NULL;
895         }
896         else {
897                 /* this should never fail */
898                 int len = -1;
899                 char *c = type_fmt;
900
901                 while ((*c++= tolower(*type_id++))) {} ;
902
903                 if (type == PROP_COLLECTION) {
904                         len = pyrna_prop_collection_length(self);
905                 }
906                 else if (RNA_property_array_check(self->prop)) {
907                         len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
908                 }
909
910                 if (len != -1)
911                         sprintf(--c, "[%d]", len);
912         }
913
914         /* if a pointer, try to print name of pointer target too */
915         if (type == PROP_POINTER) {
916                 ptr = RNA_property_pointer_get(&self->ptr, self->prop);
917                 name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
918
919                 if (name) {
920                         ret = PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
921                                                   type_fmt,
922                                                   RNA_struct_identifier(self->ptr.type),
923                                                   RNA_property_identifier(self->prop),
924                                                   name);
925                         MEM_freeN((void *)name);
926                         return ret;
927                 }
928         }
929         if (type == PROP_COLLECTION) {
930                 PointerRNA r_ptr;
931                 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
932                         return PyUnicode_FromFormat("<bpy_%.200s, %.200s>",
933                                                     type_fmt,
934                                                     RNA_struct_identifier(r_ptr.type));
935                 }
936         }
937
938         return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>",
939                                     type_fmt,
940                                     RNA_struct_identifier(self->ptr.type),
941                                     RNA_property_identifier(self->prop));
942 }
943
944 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
945 {
946         ID *id = self->ptr.id.data;
947         PyObject *tmp_str;
948         PyObject *ret;
949         const char *path;
950
951         PYRNA_PROP_CHECK_OBJ(self);
952
953         if (id == NULL)
954                 return pyrna_prop_str(self); /* fallback */
955
956         tmp_str = PyUnicode_FromString(id->name + 2);
957
958         path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
959         if (path) {
960                 ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
961                                           BKE_idcode_to_name_plural(GS(id->name)),
962                                           tmp_str,
963                                           path);
964                 MEM_freeN((void *)path);
965         }
966         else { /* cant find, print something sane */
967                 ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
968                                           BKE_idcode_to_name_plural(GS(id->name)),
969                                           tmp_str,
970                                           RNA_property_identifier(self->prop));
971         }
972
973         Py_DECREF(tmp_str);
974
975         return ret;
976 }
977
978
979 static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
980 {
981         return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
982                                     Py_TYPE(self)->tp_name,
983                                     RNA_struct_identifier(self->ptr.type),
984                                     RNA_function_identifier(self->func));
985 }
986
987
988 static long pyrna_struct_hash(BPy_StructRNA *self)
989 {
990         return _Py_HashPointer(self->ptr.data);
991 }
992
993 /* from python's meth_hash v3.1.2 */
994 static long pyrna_prop_hash(BPy_PropertyRNA *self)
995 {
996         long x, y;
997         if (self->ptr.data == NULL)
998                 x = 0;
999         else {
1000                 x = _Py_HashPointer(self->ptr.data);
1001                 if (x == -1)
1002                         return -1;
1003         }
1004         y = _Py_HashPointer((void *)(self->prop));
1005         if (y == -1)
1006                 return -1;
1007         x ^= y;
1008         if (x == -1)
1009                 x = -2;
1010         return x;
1011 }
1012
1013 #ifdef USE_PYRNA_STRUCT_REFERENCE
1014 static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1015 {
1016         Py_VISIT(self->reference);
1017         return 0;
1018 }
1019
1020 static int pyrna_struct_clear(BPy_StructRNA *self)
1021 {
1022         Py_CLEAR(self->reference);
1023         return 0;
1024 }
1025 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1026
1027 /* use our own dealloc so we can free a property if we use one */
1028 static void pyrna_struct_dealloc(BPy_StructRNA *self)
1029 {
1030 #ifdef PYRNA_FREE_SUPPORT
1031         if (self->freeptr && self->ptr.data) {
1032                 IDP_FreeProperty(self->ptr.data);
1033                 MEM_freeN(self->ptr.data);
1034                 self->ptr.data = NULL;
1035         }
1036 #endif /* PYRNA_FREE_SUPPORT */
1037
1038 #ifdef USE_WEAKREFS
1039         if (self->in_weakreflist != NULL) {
1040                 PyObject_ClearWeakRefs((PyObject *)self);
1041         }
1042 #endif
1043
1044 #ifdef USE_PYRNA_STRUCT_REFERENCE
1045         if (self->reference) {
1046                 PyObject_GC_UnTrack(self);
1047                 pyrna_struct_clear(self);
1048         }
1049 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1050
1051         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1052         Py_TYPE(self)->tp_free(self);
1053 }
1054
1055 #ifdef USE_PYRNA_STRUCT_REFERENCE
1056 static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1057 {
1058         if (self->reference) {
1059 //              PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
1060                 pyrna_struct_clear(self);
1061         }
1062         /* reference is now NULL */
1063
1064         if (reference) {
1065                 self->reference = reference;
1066                 Py_INCREF(reference);
1067 //              PyObject_GC_Track(self);  /* INITIALIZED TRACKED ? */
1068         }
1069 }
1070 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1071
1072 /* use our own dealloc so we can free a property if we use one */
1073 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
1074 {
1075 #ifdef USE_WEAKREFS
1076         if (self->in_weakreflist != NULL) {
1077                 PyObject_ClearWeakRefs((PyObject *)self);
1078         }
1079 #endif
1080         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1081         Py_TYPE(self)->tp_free(self);
1082 }
1083
1084 static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
1085 {
1086 #ifdef USE_WEAKREFS
1087         if (self->in_weakreflist != NULL) {
1088                 PyObject_ClearWeakRefs((PyObject *)self);
1089         }
1090 #endif
1091         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1092         Py_TYPE(self)->tp_free(self);
1093 }
1094
1095 static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
1096 {
1097         EnumPropertyItem *item;
1098         const char *result;
1099         int free = FALSE;
1100
1101         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1102         if (item) {
1103                 result = BPy_enum_as_string(item);
1104         }
1105         else {
1106                 result = "";
1107         }
1108
1109         if (free)
1110                 MEM_freeN(item);
1111
1112         return result;
1113 }
1114
1115
1116 static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
1117 {
1118         const char *param = _PyUnicode_AsString(item);
1119
1120         if (param == NULL) {
1121                 PyErr_Format(PyExc_TypeError,
1122                              "%.200s expected a string enum, not %.200s",
1123                              error_prefix, Py_TYPE(item)->tp_name);
1124                 return -1;
1125         }
1126         else {
1127                 /* hack so that dynamic enums used for operator properties will be able to be built (i.e. context will be supplied to itemf)
1128                  * and thus running defining operator buttons for such operators in UI will work */
1129                 RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
1130
1131                 if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
1132                         const char *enum_str = pyrna_enum_as_string(ptr, prop);
1133                         PyErr_Format(PyExc_TypeError,
1134                                      "%.200s enum \"%.200s\" not found in (%.200s)",
1135                                      error_prefix, param, enum_str);
1136                         MEM_freeN((void *)enum_str);
1137                         return -1;
1138                 }
1139         }
1140
1141         return 0;
1142 }
1143
1144 /* 'value' _must_ be a set type, error check before calling */
1145 int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
1146 {
1147         /* set of enum items, concatenate all values with OR */
1148         int ret, flag = 0;
1149
1150         /* set looping */
1151         Py_ssize_t pos = 0;
1152         Py_ssize_t hash = 0;
1153         PyObject *key;
1154
1155         *r_value = 0;
1156
1157         while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1158                 const char *param = _PyUnicode_AsString(key);
1159
1160                 if (param == NULL) {
1161                         PyErr_Format(PyExc_TypeError,
1162                                      "%.200s expected a string, not %.200s",
1163                                      error_prefix, Py_TYPE(key)->tp_name);
1164                         return -1;
1165                 }
1166
1167                 if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
1168                         return -1;
1169                 }
1170
1171                 flag |= ret;
1172         }
1173
1174         *r_value = flag;
1175         return 0;
1176 }
1177
1178 static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1179 {
1180         EnumPropertyItem *item;
1181         int ret;
1182         int free = FALSE;
1183
1184         *r_value = 0;
1185
1186         if (!PyAnySet_Check(value)) {
1187                 PyErr_Format(PyExc_TypeError,
1188                              "%.200s, %.200s.%.200s expected a set, not a %.200s",
1189                              error_prefix, RNA_struct_identifier(ptr->type),
1190                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1191                 return -1;
1192         }
1193
1194         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1195
1196         if (item) {
1197                 ret = pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix);
1198         }
1199         else {
1200                 if (PySet_GET_SIZE(value)) {
1201                         PyErr_Format(PyExc_TypeError,
1202                                      "%.200s: empty enum \"%.200s\" could not have any values assigned",
1203                                      error_prefix, RNA_property_identifier(prop));
1204                         ret = -1;
1205                 }
1206                 else {
1207                         ret = 0;
1208                 }
1209         }
1210
1211         if (free)
1212                 MEM_freeN(item);
1213
1214         return ret;
1215 }
1216
1217 PyObject *pyrna_enum_bitfield_to_py(EnumPropertyItem *items, int value)
1218 {
1219         PyObject *ret = PySet_New(NULL);
1220         const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1221
1222         if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
1223                 PyObject *item;
1224                 int index;
1225                 for (index = 0; identifier[index]; index++) {
1226                         item = PyUnicode_FromString(identifier[index]);
1227                         PySet_Add(ret, item);
1228                         Py_DECREF(item);
1229                 }
1230         }
1231
1232         return ret;
1233 }
1234
1235 static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1236 {
1237         PyObject *item, *ret = NULL;
1238
1239         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1240                 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1241
1242                 ret = PySet_New(NULL);
1243
1244                 if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) {
1245                         int index;
1246
1247                         for (index = 0; identifier[index]; index++) {
1248                                 item = PyUnicode_FromString(identifier[index]);
1249                                 PySet_Add(ret, item);
1250                                 Py_DECREF(item);
1251                         }
1252
1253                 }
1254         }
1255         else {
1256                 const char *identifier;
1257                 if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) {
1258                         ret = PyUnicode_FromString(identifier);
1259                 }
1260                 else {
1261                         EnumPropertyItem *enum_item;
1262                         int free = FALSE;
1263
1264                         /* don't throw error here, can't trust blender 100% to give the
1265                          * right values, python code should not generate error for that */
1266                         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &enum_item, NULL, &free);
1267                         if (enum_item && enum_item->identifier) {
1268                                 ret = PyUnicode_FromString(enum_item->identifier);
1269                         }
1270                         else {
1271                                 const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
1272
1273                                 /* prefer not fail silently incase of api errors, maybe disable it later */
1274                                 printf("RNA Warning: Current value \"%d\" "
1275                                            "matches no enum in '%s', '%s', '%s'\n",
1276                                            val, RNA_struct_identifier(ptr->type),
1277                                            ptr_name, RNA_property_identifier(prop));
1278
1279 #if 0                   // gives python decoding errors while generating docs :(
1280                                 char error_str[256];
1281                                 BLI_snprintf(error_str, sizeof(error_str),
1282                                                          "RNA Warning: Current value \"%d\" "
1283                                                          "matches no enum in '%s', '%s', '%s'",
1284                                                          val, RNA_struct_identifier(ptr->type),
1285                                                          ptr_name, RNA_property_identifier(prop));
1286
1287                                 PyErr_Warn(PyExc_RuntimeWarning, error_str);
1288 #endif
1289
1290                                 if (ptr_name)
1291                                         MEM_freeN((void *)ptr_name);
1292
1293                                 ret = PyUnicode_FromString("");
1294                         }
1295
1296                         if (free)
1297                                 MEM_freeN(enum_item);
1298                         /*
1299                         PyErr_Format(PyExc_AttributeError,
1300                                      "RNA Error: Current value \"%d\" matches no enum", val);
1301                         ret = NULL;
1302                         */
1303                 }
1304         }
1305
1306         return ret;
1307 }
1308
1309 PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
1310 {
1311         PyObject *ret;
1312         const int type = RNA_property_type(prop);
1313
1314         if (RNA_property_array_check(prop)) {
1315                 return pyrna_py_from_array(ptr, prop);
1316         }
1317
1318         /* see if we can coorce into a python type - PropertyType */
1319         switch (type) {
1320         case PROP_BOOLEAN:
1321                 ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1322                 break;
1323         case PROP_INT:
1324                 ret = PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop));
1325                 break;
1326         case PROP_FLOAT:
1327                 ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1328                 break;
1329         case PROP_STRING:
1330         {
1331                 const int subtype = RNA_property_subtype(prop);
1332                 const char *buf;
1333                 int buf_len;
1334                 char buf_fixed[32];
1335
1336                 buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1337 #ifdef USE_STRING_COERCE
1338                 /* only file paths get special treatment, they may contain non utf-8 chars */
1339                 if (subtype == PROP_BYTESTRING) {
1340                         ret = PyBytes_FromStringAndSize(buf, buf_len);
1341                 }
1342                 else if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1343                         ret = PyC_UnicodeFromByteAndSize(buf, buf_len);
1344                 }
1345                 else {
1346                         ret = PyUnicode_FromStringAndSize(buf, buf_len);
1347                 }
1348 #else // USE_STRING_COERCE
1349                 if (subtype == PROP_BYTESTRING) {
1350                         ret = PyBytes_FromStringAndSize(buf, buf_len);
1351                 }
1352                 else {
1353                         ret = PyUnicode_FromStringAndSize(buf, buf_len);
1354                 }
1355 #endif // USE_STRING_COERCE
1356                 if (buf_fixed != buf) {
1357                         MEM_freeN((void *)buf);
1358                 }
1359                 break;
1360         }
1361         case PROP_ENUM:
1362         {
1363                 ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop));
1364                 break;
1365         }
1366         case PROP_POINTER:
1367         {
1368                 PointerRNA newptr;
1369                 newptr = RNA_property_pointer_get(ptr, prop);
1370                 if (newptr.data) {
1371                         ret = pyrna_struct_CreatePyObject(&newptr);
1372                 }
1373                 else {
1374                         ret = Py_None;
1375                         Py_INCREF(ret);
1376                 }
1377                 break;
1378         }
1379         case PROP_COLLECTION:
1380                 ret = pyrna_prop_CreatePyObject(ptr, prop);
1381                 break;
1382         default:
1383                 PyErr_Format(PyExc_TypeError,
1384                              "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", type);
1385                 ret = NULL;
1386                 break;
1387         }
1388
1389         return ret;
1390 }
1391
1392 /* This function is used by operators and converting dicts into collections.
1393  * Its takes keyword args and fills them with property values */
1394 int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix)
1395 {
1396         int error_val = 0;
1397         int totkw;
1398         const char *arg_name = NULL;
1399         PyObject *item;
1400
1401         totkw = kw ? PyDict_Size(kw):0;
1402
1403         RNA_STRUCT_BEGIN(ptr, prop) {
1404                 arg_name = RNA_property_identifier(prop);
1405
1406                 if (strcmp(arg_name, "rna_type") == 0) continue;
1407
1408                 if (kw == NULL) {
1409                         PyErr_Format(PyExc_TypeError,
1410                                      "%.200s: no keywords, expected \"%.200s\"",
1411                                      error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1412                         error_val = -1;
1413                         break;
1414                 }
1415
1416                 item = PyDict_GetItemString(kw, arg_name); /* wont set an error */
1417
1418                 if (item == NULL) {
1419                         if (all_args) {
1420                                 PyErr_Format(PyExc_TypeError,
1421                                              "%.200s: keyword \"%.200s\" missing",
1422                                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1423                                 error_val = -1; /* pyrna_py_to_prop sets the error */
1424                                 break;
1425                         }
1426                 }
1427                 else {
1428                         if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1429                                 error_val = -1;
1430                                 break;
1431                         }
1432                         totkw--;
1433                 }
1434         }
1435         RNA_STRUCT_END;
1436
1437         if (error_val == 0 && totkw > 0) { /* some keywords were given that were not used :/ */
1438                 PyObject *key, *value;
1439                 Py_ssize_t pos = 0;
1440
1441                 while (PyDict_Next(kw, &pos, &key, &value)) {
1442                         arg_name = _PyUnicode_AsString(key);
1443                         if (RNA_struct_find_property(ptr, arg_name) == NULL) break;
1444                         arg_name = NULL;
1445                 }
1446
1447                 PyErr_Format(PyExc_TypeError,
1448                              "%.200s: keyword \"%.200s\" unrecognized",
1449                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1450                 error_val = -1;
1451         }
1452
1453         return error_val;
1454 }
1455
1456
1457 static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
1458 {
1459         BPy_FunctionRNA* pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1460         pyfunc->ptr = *ptr;
1461         pyfunc->func = func;
1462         return (PyObject *)pyfunc;
1463 }
1464
1465
1466 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1467 {
1468         /* XXX hard limits should be checked here */
1469         const int type = RNA_property_type(prop);
1470
1471
1472         if (RNA_property_array_check(prop)) {
1473                 /* done getting the length */
1474                 if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1475                         return -1;
1476                 }
1477         }
1478         else {
1479                 /* Normal Property (not an array) */
1480
1481                 /* see if we can coorce into a python type - PropertyType */
1482                 switch (type) {
1483                 case PROP_BOOLEAN:
1484                 {
1485                         int param;
1486                         /* prefer not to have an exception here
1487                          * however so many poll functions return None or a valid Object.
1488                          * its a hassle to convert these into a bool before returning, */
1489                         if (RNA_property_flag(prop) & PROP_OUTPUT)
1490                                 param = PyObject_IsTrue(value);
1491                         else
1492                                 param = PyLong_AsLong(value);
1493
1494                         if (param < 0) {
1495                                 PyErr_Format(PyExc_TypeError,
1496                                              "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1497                                              error_prefix, RNA_struct_identifier(ptr->type),
1498                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1499                                 return -1;
1500                         }
1501                         else {
1502                                 if (data)  *((int *)data)= param;
1503                                 else       RNA_property_boolean_set(ptr, prop, param);
1504                         }
1505                         break;
1506                 }
1507                 case PROP_INT:
1508                 {
1509                         int overflow;
1510                         long param = PyLong_AsLongAndOverflow(value, &overflow);
1511                         if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1512                                 PyErr_Format(PyExc_ValueError,
1513                                              "%.200s %.200s.%.200s value not in 'int' range "
1514                                              "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1515                                              error_prefix, RNA_struct_identifier(ptr->type),
1516                                              RNA_property_identifier(prop));
1517                                 return -1;
1518                         }
1519                         else if (param == -1 && PyErr_Occurred()) {
1520                                 PyErr_Format(PyExc_TypeError,
1521                                              "%.200s %.200s.%.200s expected an int type, not %.200s",
1522                                              error_prefix, RNA_struct_identifier(ptr->type),
1523                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1524                                 return -1;
1525                         }
1526                         else {
1527                                 int param_i = (int)param;
1528                                 RNA_property_int_clamp(ptr, prop, &param_i);
1529                                 if (data)  *((int *)data)= param_i;
1530                                 else       RNA_property_int_set(ptr, prop, param_i);
1531                         }
1532                         break;
1533                 }
1534                 case PROP_FLOAT:
1535                 {
1536                         float param = PyFloat_AsDouble(value);
1537                         if (PyErr_Occurred()) {
1538                                 PyErr_Format(PyExc_TypeError,
1539                                              "%.200s %.200s.%.200s expected a float type, not %.200s",
1540                                              error_prefix, RNA_struct_identifier(ptr->type),
1541                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1542                                 return -1;
1543                         }
1544                         else {
1545                                 RNA_property_float_clamp(ptr, prop, (float *)&param);
1546                                 if (data)   *((float *)data)= param;
1547                                 else        RNA_property_float_set(ptr, prop, param);
1548                         }
1549                         break;
1550                 }
1551                 case PROP_STRING:
1552                 {
1553                         const int subtype = RNA_property_subtype(prop);
1554                         const char *param;
1555
1556                         if (subtype == PROP_BYTESTRING) {
1557
1558                                 /* Byte String */
1559
1560                                 param = PyBytes_AsString(value);
1561
1562                                 if (param == NULL) {
1563                                         if (PyBytes_Check(value)) {
1564                                                 /* there was an error assigning a string type,
1565                                                  * rather than setting a new error, prefix the existing one
1566                                                  */
1567                                                 PyC_Err_Format_Prefix(PyExc_TypeError,
1568                                                                       "%.200s %.200s.%.200s error assigning bytes",
1569                                                                       error_prefix, RNA_struct_identifier(ptr->type),
1570                                                                       RNA_property_identifier(prop));
1571                                         }
1572                                         else {
1573                                                 PyErr_Format(PyExc_TypeError,
1574                                                              "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1575                                                              error_prefix, RNA_struct_identifier(ptr->type),
1576                                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1577                                         }
1578
1579                                         return -1;
1580                                 }
1581                                 else {
1582                                         /* same as unicode */
1583                                         if (data)   *((char **)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1584                                         else        RNA_property_string_set(ptr, prop, param);
1585                                 }
1586                         }
1587                         else {
1588
1589                                 /* Unicode String */
1590
1591 #ifdef USE_STRING_COERCE
1592                                 PyObject *value_coerce = NULL;
1593                                 if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1594                                         /* TODO, get size */
1595                                         param = PyC_UnicodeAsByte(value, &value_coerce);
1596                                 }
1597                                 else {
1598                                         param = _PyUnicode_AsString(value);
1599 #ifdef WITH_INTERNATIONAL
1600                                         if (subtype == PROP_TRANSLATE) {
1601                                                 param = IFACE_(param);
1602                                         }
1603 #endif // WITH_INTERNATIONAL
1604
1605                                 }
1606 #else // USE_STRING_COERCE
1607                                 param = _PyUnicode_AsString(value);
1608 #endif // USE_STRING_COERCE
1609
1610                                 if (param == NULL) {
1611                                         if (PyUnicode_Check(value)) {
1612                                                 /* there was an error assigning a string type,
1613                                                  * rather than setting a new error, prefix the existing one
1614                                                  */
1615                                                 PyC_Err_Format_Prefix(PyExc_TypeError,
1616                                                                       "%.200s %.200s.%.200s error assigning string",
1617                                                                       error_prefix, RNA_struct_identifier(ptr->type),
1618                                                                       RNA_property_identifier(prop));
1619                                         }
1620                                         else {
1621                                                 PyErr_Format(PyExc_TypeError,
1622                                                              "%.200s %.200s.%.200s expected a string type, not %.200s",
1623                                                              error_prefix, RNA_struct_identifier(ptr->type),
1624                                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1625                                         }
1626
1627                                         return -1;
1628                                 }
1629                                 else {
1630                                         /* same as bytes */
1631                                         if (data)   *((char **)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1632                                         else        RNA_property_string_set(ptr, prop, param);
1633                                 }
1634 #ifdef USE_STRING_COERCE
1635                                 Py_XDECREF(value_coerce);
1636 #endif // USE_STRING_COERCE
1637                         }
1638                         break;
1639                 }
1640                 case PROP_ENUM:
1641                 {
1642                         int val = 0;
1643
1644                         /* type checkins is done by each function */
1645                         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1646                                 /* set of enum items, concatenate all values with OR */
1647                                 if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
1648                                         return -1;
1649                                 }
1650                         }
1651                         else {
1652                                 /* simple enum string */
1653                                 if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
1654                                         return -1;
1655                                 }
1656                         }
1657
1658                         if (data)  *((int *)data)= val;
1659                         else       RNA_property_enum_set(ptr, prop, val);
1660
1661                         break;
1662                 }
1663                 case PROP_POINTER:
1664                 {
1665                         PyObject *value_new = NULL;
1666
1667                         StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
1668                         int flag = RNA_property_flag(prop);
1669
1670                         /* this is really nasty!, so we can fake the operator having direct properties eg:
1671                          * layout.prop(self, "filepath")
1672                          * ... which infact should be
1673                          * layout.prop(self.properties, "filepath")
1674                          *
1675                          * we need to do this trick.
1676                          * if the prop is not an operator type and the pyobject is an operator,
1677                          * use its properties in place of its self.
1678                          *
1679                          * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing
1680                          * if this causes problems in the future it should be removed.
1681                          */
1682                         if ((ptr_type == &RNA_AnyType) &&
1683                                 (BPy_StructRNA_Check(value)) &&
1684                                 (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator))
1685                         ) {
1686                                 value = PyObject_GetAttrString(value, "properties");
1687                                 value_new = value;
1688                         }
1689
1690
1691                         /* if property is an OperatorProperties pointer and value is a map,
1692                          * forward back to pyrna_pydict_to_props */
1693                         if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) {
1694                                 PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1695                                 return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
1696                         }
1697
1698                         /* another exception, allow to pass a collection as an RNA property */
1699                         if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* ok to ignore idprop collections */
1700                                 PointerRNA c_ptr;
1701                                 BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
1702                                 if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1703                                         value = pyrna_struct_CreatePyObject(&c_ptr);
1704                                         value_new = value;
1705                                 }
1706                                 else {
1707                                         PyErr_Format(PyExc_TypeError,
1708                                                      "%.200s %.200s.%.200s collection has no type, "
1709                                                      "cant be used as a %.200s type",
1710                                                      error_prefix, RNA_struct_identifier(ptr->type),
1711                                                      RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1712                                         return -1;
1713                                 }
1714                         }
1715
1716                         if (!BPy_StructRNA_Check(value) && value != Py_None) {
1717                                 PyErr_Format(PyExc_TypeError,
1718                                              "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1719                                              error_prefix, RNA_struct_identifier(ptr->type),
1720                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type),
1721                                              Py_TYPE(value)->tp_name);
1722                                 Py_XDECREF(value_new); return -1;
1723                         }
1724                         else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
1725                                 PyErr_Format(PyExc_TypeError,
1726                                              "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1727                                              error_prefix, RNA_struct_identifier(ptr->type),
1728                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1729                                 Py_XDECREF(value_new); return -1;
1730                         }
1731                         else if ((value != Py_None) &&
1732                                  ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA *)value)->ptr.id.data))
1733                         {
1734                                 PyErr_Format(PyExc_TypeError,
1735                                              "%.200s %.200s.%.200s ID type does not support assignment to its self",
1736                                              error_prefix, RNA_struct_identifier(ptr->type),
1737                                              RNA_property_identifier(prop));
1738                                 Py_XDECREF(value_new); return -1;
1739                         }
1740                         else {
1741                                 BPy_StructRNA *param = (BPy_StructRNA *)value;
1742                                 int raise_error = FALSE;
1743                                 if (data) {
1744
1745                                         if (flag & PROP_RNAPTR) {
1746                                                 if (value == Py_None)
1747                                                         memset(data, 0, sizeof(PointerRNA));
1748                                                 else
1749                                                         *((PointerRNA *)data)= param->ptr;
1750                                         }
1751                                         else if (value == Py_None) {
1752                                                 *((void **)data)= NULL;
1753                                         }
1754                                         else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1755                                                 *((void **)data)= param->ptr.data;
1756                                         }
1757                                         else {
1758                                                 raise_error = TRUE;
1759                                         }
1760                                 }
1761                                 else {
1762                                         /* data == NULL, assign to RNA */
1763                                         if (value == Py_None) {
1764                                                 PointerRNA valueptr = {{NULL}};
1765                                                 RNA_property_pointer_set(ptr, prop, valueptr);
1766                                         }
1767                                         else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1768                                                 RNA_property_pointer_set(ptr, prop, param->ptr);
1769                                         }
1770                                         else {
1771                                                 PointerRNA tmp;
1772                                                 RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1773                                                 PyErr_Format(PyExc_TypeError,
1774                                                              "%.200s %.200s.%.200s expected a %.200s type. not %.200s",
1775                                                              error_prefix, RNA_struct_identifier(ptr->type),
1776                                                              RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1777                                                              RNA_struct_identifier(param->ptr.type));
1778                                                 Py_XDECREF(value_new); return -1;
1779                                         }
1780                                 }
1781
1782                                 if (raise_error) {
1783                                         PointerRNA tmp;
1784                                         RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1785                                         PyErr_Format(PyExc_TypeError,
1786                                                      "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1787                                                      error_prefix, RNA_struct_identifier(ptr->type),
1788                                                      RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1789                                                      RNA_struct_identifier(param->ptr.type));
1790                                         Py_XDECREF(value_new); return -1;
1791                                 }
1792                         }
1793
1794                         Py_XDECREF(value_new);
1795
1796                         break;
1797                 }
1798                 case PROP_COLLECTION:
1799                 {
1800                         Py_ssize_t seq_len, i;
1801                         PyObject *item;
1802                         PointerRNA itemptr;
1803                         ListBase *lb;
1804                         CollectionPointerLink *link;
1805
1806                         lb = (data) ? (ListBase *)data : NULL;
1807
1808                         /* convert a sequence of dict's into a collection */
1809                         if (!PySequence_Check(value)) {
1810                                 PyErr_Format(PyExc_TypeError,
1811                                              "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
1812                                              error_prefix, RNA_struct_identifier(ptr->type),
1813                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1814                                 return -1;
1815                         }
1816
1817                         seq_len = PySequence_Size(value);
1818                         for (i = 0; i < seq_len; i++) {
1819                                 item = PySequence_GetItem(value, i);
1820
1821                                 if (item == NULL) {
1822                                         PyErr_Format(PyExc_TypeError,
1823                                                      "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
1824                                                      error_prefix, RNA_struct_identifier(ptr->type),
1825                                                      RNA_property_identifier(prop), i);
1826                                         Py_XDECREF(item);
1827                                         return -1;
1828                                 }
1829
1830                                 if (PyDict_Check(item) == 0) {
1831                                         PyErr_Format(PyExc_TypeError,
1832                                                      "%.200s %.200s.%.200s expected a each sequence "
1833                                                      "member to be a dict for an RNA collection, not %.200s",
1834                                                      error_prefix, RNA_struct_identifier(ptr->type),
1835                                                      RNA_property_identifier(prop), Py_TYPE(item)->tp_name);
1836                                         Py_XDECREF(item);
1837                                         return -1;
1838                                 }
1839
1840                                 if (lb) {
1841                                         link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
1842                                         link->ptr = itemptr;
1843                                         BLI_addtail(lb, link);
1844                                 }
1845                                 else
1846                                         RNA_property_collection_add(ptr, prop, &itemptr);
1847
1848                                 if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection") == -1) {
1849                                         PyObject *msg = PyC_ExceptionBuffer();
1850                                         const char *msg_char = _PyUnicode_AsString(msg);
1851
1852                                         PyErr_Format(PyExc_TypeError,
1853                                                      "%.200s %.200s.%.200s error converting a member of a collection "
1854                                                      "from a dicts into an RNA collection, failed with: %s",
1855                                                      error_prefix, RNA_struct_identifier(ptr->type),
1856                                                      RNA_property_identifier(prop), msg_char);
1857
1858                                         Py_DECREF(item);
1859                                         Py_DECREF(msg);
1860                                         return -1;
1861                                 }
1862                                 Py_DECREF(item);
1863                         }
1864
1865                         break;
1866                 }
1867                 default:
1868                         PyErr_Format(PyExc_AttributeError,
1869                                      "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
1870                                      error_prefix, RNA_struct_identifier(ptr->type),
1871                                      RNA_property_identifier(prop));
1872                         return -1;
1873                         break;
1874                 }
1875         }
1876
1877         /* Run rna property functions */
1878         if (RNA_property_update_check(prop)) {
1879                 RNA_property_update(BPy_GetContext(), ptr, prop);
1880         }
1881
1882         return 0;
1883 }
1884
1885 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
1886 {
1887         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
1888         return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
1889 }
1890
1891 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
1892 {
1893         int ret = 0;
1894         PointerRNA *ptr = &self->ptr;
1895         PropertyRNA *prop = self->prop;
1896
1897         const int totdim = RNA_property_array_dimension(ptr, prop, NULL);
1898
1899         if (totdim > 1) {
1900                 /* char error_str[512]; */
1901                 if (pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
1902                         /* error is set */
1903                         ret = -1;
1904                 }
1905         }
1906         else {
1907                 /* see if we can coerce into a python type - PropertyType */
1908                 switch (RNA_property_type(prop)) {
1909                 case PROP_BOOLEAN:
1910                         {
1911                                 int param = PyLong_AsLong(value);
1912
1913                                 if (param < 0 || param > 1) {
1914                                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1915                                         ret = -1;
1916                                 }
1917                                 else {
1918                                         RNA_property_boolean_set_index(ptr, prop, index, param);
1919                                 }
1920                                 break;
1921                         }
1922                 case PROP_INT:
1923                         {
1924                                 int param = PyLong_AsLong(value);
1925                                 if (param == -1 && PyErr_Occurred()) {
1926                                         PyErr_SetString(PyExc_TypeError, "expected an int type");
1927                                         ret = -1;
1928                                 }
1929                                 else {
1930                                         RNA_property_int_clamp(ptr, prop, &param);
1931                                         RNA_property_int_set_index(ptr, prop, index, param);
1932                                 }
1933                                 break;
1934                         }
1935                 case PROP_FLOAT:
1936                         {
1937                                 float param = PyFloat_AsDouble(value);
1938                                 if (PyErr_Occurred()) {
1939                                         PyErr_SetString(PyExc_TypeError, "expected a float type");
1940                                         ret = -1;
1941                                 }
1942                                 else {
1943                                         RNA_property_float_clamp(ptr, prop, &param);
1944                                         RNA_property_float_set_index(ptr, prop, index, param);
1945                                 }
1946                                 break;
1947                         }
1948                 default:
1949                         PyErr_SetString(PyExc_AttributeError, "not an array type");
1950                         ret = -1;
1951                         break;
1952                 }
1953         }
1954
1955         /* Run rna property functions */
1956         if (RNA_property_update_check(prop)) {
1957                 RNA_property_update(BPy_GetContext(), ptr, prop);
1958         }
1959
1960         return ret;
1961 }
1962
1963 //---------------sequence-------------------------------------------
1964 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
1965 {
1966         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
1967
1968         if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
1969                 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
1970         else
1971                 return RNA_property_array_length(&self->ptr, self->prop);
1972 }
1973
1974 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
1975 {
1976         PYRNA_PROP_CHECK_INT(self);
1977
1978         return RNA_property_collection_length(&self->ptr, self->prop);
1979 }
1980
1981 /* bool functions are for speed, so we can avoid getting the length
1982  * of 1000's of items in a linked list for eg. */
1983 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
1984 {
1985         PYRNA_PROP_CHECK_INT(self);
1986
1987         return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
1988 }
1989
1990 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
1991 {
1992         /* no callback defined, just iterate and find the nth item */
1993         CollectionPropertyIterator iter;
1994         int test;
1995
1996         PYRNA_PROP_CHECK_INT(self);
1997
1998         RNA_property_collection_begin(&self->ptr, self->prop, &iter);
1999         test = iter.valid;
2000         RNA_property_collection_end(&iter);
2001         return test;
2002 }
2003
2004
2005 /* notice getting the length of the collection is avoided unless negative
2006  * index is used or to detect internal error with a valid index.
2007  * This is done for faster lookups. */
2008 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err)                              \
2009         if (keynum < 0) {                                                         \
2010                 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2011                 if (keynum_abs < 0) {                                                 \
2012                         PyErr_Format(PyExc_IndexError,                                    \
2013                                      "bpy_prop_collection[%d]: out of range.", keynum);   \
2014                         return ret_err;                                                   \
2015                 }                                                                     \
2016         }                                                                         \
2017
2018
2019 /* internal use only */
2020 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2021 {
2022         PointerRNA newptr;
2023         Py_ssize_t keynum_abs = keynum;
2024
2025         PYRNA_PROP_CHECK_OBJ(self);
2026
2027         PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
2028
2029         if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2030                 return pyrna_struct_CreatePyObject(&newptr);
2031         }
2032         else {
2033                 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2034                 if (keynum_abs >= len) {
2035                         PyErr_Format(PyExc_IndexError,
2036                                      "bpy_prop_collection[index]: "
2037                                      "index %d out of range, size %d", keynum, len);
2038                 }
2039                 else {
2040                         PyErr_Format(PyExc_RuntimeError,
2041                                      "bpy_prop_collection[index]: internal error, "
2042                                      "valid index %d given in %d sized collection but value not found",
2043                                      keynum_abs, len);
2044                 }
2045
2046                 return NULL;
2047         }
2048 }
2049
2050 /* values type must have been already checked */
2051 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
2052 {
2053         Py_ssize_t keynum_abs = keynum;
2054         const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2055
2056         PYRNA_PROP_CHECK_INT(self);
2057
2058         PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
2059
2060         if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2061                 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2062                 if (keynum_abs >= len) {
2063                         PyErr_Format(PyExc_IndexError,
2064                                      "bpy_prop_collection[index] = value: "
2065                                      "index %d out of range, size %d", keynum, len);
2066                 }
2067                 else {
2068
2069                         PyErr_Format(PyExc_IndexError,
2070                                      "bpy_prop_collection[index] = value: "
2071                                      "failed assignment (unknown reason)", keynum);
2072                 }
2073                 return -1;
2074         }
2075
2076         return 0;
2077 }
2078
2079 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2080 {
2081         int len;
2082
2083         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2084
2085         len = pyrna_prop_array_length(self);
2086
2087         if (keynum < 0) keynum += len;
2088
2089         if (keynum >= 0 && keynum < len)
2090                 return pyrna_prop_array_to_py_index(self, keynum);
2091
2092         PyErr_Format(PyExc_IndexError,
2093                      "bpy_prop_array[index]: index %d out of range", keynum);
2094         return NULL;
2095 }
2096
2097 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2098 {
2099         PointerRNA newptr;
2100
2101         PYRNA_PROP_CHECK_OBJ(self);
2102
2103         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2104                 return pyrna_struct_CreatePyObject(&newptr);
2105
2106         PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2107         return NULL;
2108 }
2109 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
2110
2111 /* special case: bpy.data.objects["some_id_name", "//some_lib_name.blend"]
2112  * also for:     bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)
2113  *
2114  * note:
2115  * error codes since this is not to be called directly from python,
2116  * this matches pythons __contains__ values capi.
2117  * -1: exception set
2118  *  0: not found
2119  *  1: found */
2120 int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, PyObject *key,
2121                                                      const char *err_prefix, const short err_not_found,
2122                                                      PointerRNA *r_ptr
2123                                                      )
2124 {
2125         char *keyname;
2126
2127         /* first validate the args, all we know is that they are a tuple */
2128         if (PyTuple_GET_SIZE(key) != 2) {
2129                 PyErr_Format(PyExc_KeyError,
2130                              "%s: tuple key must be a pair, not size %d",
2131                              err_prefix, PyTuple_GET_SIZE(key));
2132                 return -1;
2133         }
2134         else if (self->ptr.type != &RNA_BlendData) {
2135                 PyErr_Format(PyExc_KeyError,
2136                              "%s: is only valid for bpy.data collections, not %.200s",
2137                              err_prefix, RNA_struct_identifier(self->ptr.type));
2138                 return -1;
2139         }
2140         else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
2141                 PyErr_Format(PyExc_KeyError,
2142                              "%s: id must be a string, not %.200s",
2143                              err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2144                 return -1;
2145         }
2146         else {
2147                 PyObject *keylib = PyTuple_GET_ITEM(key, 1);
2148                 Library *lib;
2149                 int found = FALSE;
2150
2151                 if (keylib == Py_None) {
2152                         lib = NULL;
2153                 }
2154                 else if (PyUnicode_Check(keylib)) {
2155                         Main *bmain = self->ptr.data;
2156                         const char *keylib_str = _PyUnicode_AsString(keylib);
2157                         lib = BLI_findstring(&bmain->library, keylib_str, offsetof(Library, name));
2158                         if (lib == NULL) {
2159                                 if (err_not_found) {
2160                                         PyErr_Format(PyExc_KeyError,
2161                                                                  "%s: lib name '%.240s' "
2162                                                                  "does not reference a valid library",
2163                                                                  err_prefix, keylib_str);
2164                                         return -1;
2165                                 }
2166                                 else {
2167                                         return 0;
2168                                 }
2169
2170                         }
2171                 }
2172                 else {
2173                         PyErr_Format(PyExc_KeyError,
2174                                      "%s: lib must be a sting or None, not %.200s",
2175                                      err_prefix, Py_TYPE(keylib)->tp_name);
2176                         return -1;
2177                 }
2178
2179                 /* lib is either a valid poniter or NULL,
2180                  * either way can do direct comparison with id.lib */
2181
2182                 RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
2183                         ID *id = itemptr.data; /* always an ID */
2184                         if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
2185                                 found = TRUE;
2186                                 if (r_ptr) {
2187                                         *r_ptr = itemptr;
2188                                 }
2189                                 break;
2190                         }
2191                 }
2192                 RNA_PROP_END;
2193
2194                 /* we may want to fail silently as with collection.get() */
2195                 if ((found == FALSE) && err_not_found) {
2196                         /* only runs for getitem access so use fixed string */
2197                         PyErr_SetString(PyExc_KeyError,
2198                                         "bpy_prop_collection[key, lib]: not found");
2199                         return -1;
2200                 }
2201                 else {
2202                         return found; /* 1 / 0, no exception */
2203                 }
2204         }
2205 }
2206
2207 static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
2208                                                               const char *err_prefix, const short err_not_found)
2209 {
2210         PointerRNA ptr;
2211         const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
2212
2213         if (contains == 1) {
2214                 return pyrna_struct_CreatePyObject(&ptr);
2215         }
2216         else {
2217                 return NULL;
2218         }
2219 }
2220
2221
2222 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
2223 {
2224         CollectionPropertyIterator rna_macro_iter;
2225         int count = 0;
2226
2227         PyObject *list;
2228         PyObject *item;
2229
2230         PYRNA_PROP_CHECK_OBJ(self);
2231
2232         list = PyList_New(0);
2233
2234         /* first loop up-until the start */
2235         for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2236              rna_macro_iter.valid;
2237              RNA_property_collection_next(&rna_macro_iter))
2238         {
2239                 /* PointerRNA itemptr = rna_macro_iter.ptr; */
2240                 if (count == start) {
2241                         break;
2242                 }
2243                 count++;
2244         }
2245
2246         /* add items until stop */
2247         for (; rna_macro_iter.valid;
2248              RNA_property_collection_next(&rna_macro_iter))
2249         {
2250                 item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2251                 PyList_Append(list, item);
2252                 Py_DECREF(item);
2253
2254                 count++;
2255                 if (count == stop) {
2256                         break;
2257                 }
2258         }
2259
2260         RNA_property_collection_end(&rna_macro_iter);
2261
2262         return list;
2263 }
2264
2265 /* TODO - dimensions
2266  * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
2267  * since at the moment it reads (and even allocates) the entire array for each index.
2268  */
2269 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
2270                                                   Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
2271 {
2272         int count, totdim;
2273         PyObject *tuple;
2274
2275         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2276
2277         tuple = PyTuple_New(stop - start);
2278
2279         /* PYRNA_PROP_CHECK_OBJ(self); isn't needed, internal use only */
2280
2281         totdim = RNA_property_array_dimension(ptr, prop, NULL);
2282
2283         if (totdim > 1) {
2284                 for (count = start; count < stop; count++)
2285                         PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2286         }
2287         else {
2288                 switch (RNA_property_type(prop)) {
2289                 case PROP_FLOAT:
2290                         {
2291                                 float values_stack[PYRNA_STACK_ARRAY];
2292                                 float *values;
2293                                 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(float) * length); }
2294                                 else                            { values = values_stack; }
2295                                 RNA_property_float_get_array(ptr, prop, values);
2296
2297                                 for (count = start; count < stop; count++)
2298                                         PyTuple_SET_ITEM(tuple, count-start, PyFloat_FromDouble(values[count]));
2299
2300                                 if (values != values_stack) {
2301                                         PyMem_FREE(values);
2302                                 }
2303                                 break;
2304                         }
2305                 case PROP_BOOLEAN:
2306                         {
2307                                 int values_stack[PYRNA_STACK_ARRAY];
2308                                 int *values;
2309                                 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); }
2310                                 else                            { values = values_stack; }
2311
2312                                 RNA_property_boolean_get_array(ptr, prop, values);
2313                                 for (count = start; count < stop; count++)
2314                                         PyTuple_SET_ITEM(tuple, count-start, PyBool_FromLong(values[count]));
2315
2316                                 if (values != values_stack) {
2317                                         PyMem_FREE(values);
2318                                 }
2319                                 break;
2320                         }
2321                 case PROP_INT:
2322                         {
2323                                 int values_stack[PYRNA_STACK_ARRAY];
2324                                 int *values;
2325                                 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); }
2326                                 else                            { values = values_stack; }
2327
2328                                 RNA_property_int_get_array(ptr, prop, values);
2329                                 for (count = start; count < stop; count++)
2330                                         PyTuple_SET_ITEM(tuple, count-start, PyLong_FromSsize_t(values[count]));
2331
2332                                 if (values != values_stack) {
2333                                         PyMem_FREE(values);
2334                                 }
2335                                 break;
2336                         }
2337                 default:
2338                         BLI_assert(!"Invalid array type");
2339
2340                         PyErr_SetString(PyExc_TypeError, "not an array type");
2341                         Py_DECREF(tuple);
2342                         tuple = NULL;
2343                 }
2344         }
2345         return tuple;
2346 }
2347
2348 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2349 {
2350         PYRNA_PROP_CHECK_OBJ(self);
2351
2352         if (PyUnicode_Check(key)) {
2353                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2354         }
2355         else if (PyIndex_Check(key)) {
2356                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2357                 if (i == -1 && PyErr_Occurred())
2358                         return NULL;
2359
2360                 return pyrna_prop_collection_subscript_int(self, i);
2361         }
2362         else if (PySlice_Check(key)) {
2363                 PySliceObject *key_slice = (PySliceObject *)key;
2364                 Py_ssize_t step = 1;
2365
2366                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2367                         return NULL;
2368                 }
2369                 else if (step != 1) {
2370                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2371                         return NULL;
2372                 }
2373                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2374                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2375                 }
2376                 else {
2377                         Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2378
2379                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2380                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2381                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
2382
2383                         if (start < 0 || stop < 0) {
2384                                 /* only get the length for negative values */
2385                                 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2386                                 if (start < 0) start += len;
2387                                 if (stop < 0) start += len;
2388                         }
2389
2390                         if (stop - start <= 0) {
2391                                 return PyList_New(0);
2392                         }
2393                         else {
2394                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2395                         }
2396                 }
2397         }
2398         else if (PyTuple_Check(key)) {
2399                 /* special case, for ID datablocks we */
2400                 return pyrna_prop_collection_subscript_str_lib_pair(self, key,
2401                                                                     "bpy_prop_collection[id, lib]", TRUE);
2402         }
2403         else {
2404                 PyErr_Format(PyExc_TypeError,
2405                              "bpy_prop_collection[key]: invalid key, "
2406                              "must be a string or an int, not %.200s",
2407                              Py_TYPE(key)->tp_name);
2408                 return NULL;
2409         }
2410 }
2411
2412 /* generic check to see if a PyObject is compatible with a collection
2413  * -1 on failure, 0 on success, sets the error */
2414 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2415 {
2416         StructRNA *prop_srna;
2417
2418         if (value == Py_None) {
2419                 if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2420                         PyErr_Format(PyExc_TypeError,
2421                                      "bpy_prop_collection[key] = value: invalid, "
2422                                      "this collection doesnt support None assignment");
2423                         return -1;
2424                 }
2425                 else {
2426                         return 0; /* None is OK */
2427                 }
2428         }
2429         else if (BPy_StructRNA_Check(value) == 0) {
2430                 PyErr_Format(PyExc_TypeError,
2431                              "bpy_prop_collection[key] = value: invalid, "
2432                              "expected a StructRNA type or None, not a %.200s",
2433                              Py_TYPE(value)->tp_name);
2434                 return -1;
2435         }
2436         else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
2437                 StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
2438                 if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2439                         PyErr_Format(PyExc_TypeError,
2440                                      "bpy_prop_collection[key] = value: invalid, "
2441                                      "expected a '%.200s' type or None, not a '%.200s'",
2442                                      RNA_struct_identifier(prop_srna),
2443                                      RNA_struct_identifier(value_srna)
2444                                      );
2445                         return -1;
2446                 }
2447                 else {
2448                         return 0; /* OK, this is the correct type!*/
2449                 }
2450         }
2451
2452         PyErr_Format(PyExc_TypeError,
2453                      "bpy_prop_collection[key] = value: internal error, "
2454                      "failed to get the collection type");
2455         return -1;
2456 }
2457
2458 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2459  * large blocks commented, we may support slice/key indicies later */
2460 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
2461 {
2462         PYRNA_PROP_CHECK_INT(self);
2463
2464         /* validate the assigned value */
2465         if (value == NULL) {
2466                 PyErr_SetString(PyExc_TypeError,
2467                                 "del bpy_prop_collection[key]: not supported");
2468                 return -1;
2469         }
2470         else if (pyrna_prop_collection_type_check(self, value) == -1) {
2471                 return -1; /* exception is set */
2472         }
2473
2474 #if 0
2475         if (PyUnicode_Check(key)) {
2476                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2477         }
2478         else
2479 #endif
2480         if (PyIndex_Check(key)) {
2481                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2482                 if (i == -1 && PyErr_Occurred())
2483                         return -1;
2484
2485                 return pyrna_prop_collection_ass_subscript_int(self, i, value);
2486         }
2487 #if 0 /* TODO, fake slice assignment */
2488         else if (PySlice_Check(key)) {
2489                 PySliceObject *key_slice = (PySliceObject *)key;
2490                 Py_ssize_t step = 1;
2491
2492                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2493                         return NULL;
2494                 }
2495                 else if (step != 1) {
2496                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2497                         return NULL;
2498                 }
2499                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2500                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2501                 }
2502                 else {
2503                         Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2504
2505                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2506                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start))       return NULL;
2507                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))          return NULL;
2508
2509                         if (start < 0 || stop < 0) {
2510                                 /* only get the length for negative values */
2511                                 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2512                                 if (start < 0) start += len;
2513                                 if (stop < 0) start += len;
2514                         }
2515
2516                         if (stop - start <= 0) {
2517                                 return PyList_New(0);
2518                         }
2519                         else {
2520                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2521                         }
2522                 }
2523         }
2524 #endif
2525         else {
2526                 PyErr_Format(PyExc_TypeError,
2527                              "bpy_prop_collection[key]: invalid key, "
2528                              "must be a string or an int, not %.200s",
2529                              Py_TYPE(key)->tp_name);
2530                 return -1;
2531         }
2532 }
2533
2534 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2535 {
2536         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2537
2538         /*if (PyUnicode_Check(key)) {
2539                 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2540         }
2541         else */
2542         if (PyIndex_Check(key)) {
2543                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2544                 if (i == -1 && PyErr_Occurred())
2545                         return NULL;
2546                 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
2547         }
2548         else if (PySlice_Check(key)) {
2549                 Py_ssize_t step = 1;
2550                 PySliceObject *key_slice = (PySliceObject *)key;
2551
2552                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2553                         return NULL;
2554                 }
2555                 else if (step != 1) {
2556                         PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2557                         return NULL;
2558                 }
2559                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2560                         /* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
2561                         Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
2562                         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2563                 }
2564                 else {
2565                         int len = pyrna_prop_array_length(self);
2566                         Py_ssize_t start, stop, slicelength;
2567
2568                         if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0)
2569                                 return NULL;
2570
2571                         if (slicelength <= 0) {
2572                                 return PyTuple_New(0);
2573                         }
2574                         else {
2575                                 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2576                         }
2577                 }
2578         }
2579         else {
2580                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2581                 return NULL;
2582         }
2583 }
2584
2585 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
2586 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
2587                                           int start, int stop, int length, PyObject *value_orig)
2588 {
2589         PyObject *value;
2590         int count;
2591         void *values_alloc = NULL;
2592         int ret = 0;
2593
2594         if (value_orig == NULL) {
2595                 PyErr_SetString(PyExc_TypeError,
2596                                 "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
2597                 return -1;
2598         }
2599
2600         if (!(value = PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
2601                 return -1;
2602         }
2603
2604         if (PySequence_Fast_GET_SIZE(value) != stop-start) {
2605                 Py_DECREF(value);
2606                 PyErr_SetString(PyExc_TypeError,
2607                                 "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported");
2608                 return -1;
2609         }
2610
2611         switch (RNA_property_type(prop)) {
2612                 case PROP_FLOAT:
2613                 {
2614                         float values_stack[PYRNA_STACK_ARRAY];
2615                         float *values, fval;
2616
2617                         float min, max;
2618                         RNA_property_float_range(ptr, prop, &min, &max);
2619
2620                         if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(float) * length); }
2621                         else                            { values = values_stack; }
2622                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2623                                 RNA_property_float_get_array(ptr, prop, values);
2624
2625                         for (count = start; count < stop; count++) {
2626                                 fval = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
2627                                 CLAMP(fval, min, max);
2628                                 values[count] = fval;
2629                         }
2630
2631                         if (PyErr_Occurred()) ret = -1;
2632                         else                  RNA_property_float_set_array(ptr, prop, values);
2633                         break;
2634                 }
2635                 case PROP_BOOLEAN:
2636                 {
2637                         int values_stack[PYRNA_STACK_ARRAY];
2638                         int *values;
2639                         if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); }
2640                         else                            { values = values_stack; }
2641
2642                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2643                                 RNA_property_boolean_get_array(ptr, prop, values);
2644
2645                         for (count = start; count < stop; count++)
2646                                 values[count] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
2647
2648                         if (PyErr_Occurred()) ret = -1;
2649                         else                  RNA_property_boolean_set_array(ptr, prop, values);
2650                         break;
2651                 }
2652                 case PROP_INT:
2653                 {
2654                         int values_stack[PYRNA_STACK_ARRAY];
2655                         int *values, ival;
2656
2657                         int min, max;
2658                         RNA_property_int_range(ptr, prop, &min, &max);
2659
2660                         if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); }
2661                         else                            { values = values_stack; }
2662
2663                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2664                                 RNA_property_int_get_array(ptr, prop, values);
2665
2666                         for (count = start; count < stop; count++) {
2667                                 ival = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
2668                                 CLAMP(ival, min, max);
2669                                 values[count] = ival;
2670                         }
2671
2672                         if (PyErr_Occurred()) ret = -1;
2673                         else                  RNA_property_int_set_array(ptr, prop, values);
2674                         break;
2675                 }
2676                 default:
2677                         PyErr_SetString(PyExc_TypeError, "not an array type");
2678                         ret = -1;
2679         }
2680
2681         Py_DECREF(value);
2682
2683         if (values_alloc) {
2684                 PyMem_FREE(values_alloc);
2685         }
2686
2687         return ret;
2688
2689 }
2690
2691 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
2692 {
2693         int len;
2694
2695         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2696
2697         len = pyrna_prop_array_length(self);
2698
2699         if (keynum < 0) keynum += len;
2700
2701         if (keynum >= 0 && keynum < len)
2702                 return pyrna_py_to_prop_array_index(self, keynum, value);
2703
2704         PyErr_SetString(PyExc_IndexError,
2705                         "bpy_prop_array[index] = value: index out of range");
2706         return -1;
2707 }
2708
2709 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
2710 {
2711         /* char *keyname = NULL; */ /* not supported yet */
2712         int ret = -1;
2713
2714         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2715
2716         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
2717                 PyErr_Format(PyExc_AttributeError,
2718                              "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
2719                              RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type));
2720                 ret = -1;
2721         }
2722
2723         else if (PyIndex_Check(key)) {
2724                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2725                 if (i == -1 && PyErr_Occurred()) {
2726                         ret = -1;
2727                 }
2728                 else {
2729                         ret = prop_subscript_ass_array_int(self, i, value);
2730                 }
2731         }
2732         else if (PySlice_Check(key)) {
2733                 int len = RNA_property_array_length(&self->ptr, self->prop);
2734                 Py_ssize_t start, stop, step, slicelength;
2735
2736                 if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) {
2737                         ret = -1;
2738                 }
2739                 else if (slicelength <= 0) {
2740                         ret = 0; /* do nothing */
2741                 }
2742                 else if (step == 1) {
2743                         ret = prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
2744                 }
2745                 else {
2746                         PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
2747                         ret = -1;
2748                 }
2749         }
2750         else {
2751                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
2752                 ret = -1;
2753         }
2754
2755         if (ret != -1) {
2756                 if (RNA_property_update_check(self->prop)) {
2757                         RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
2758                 }
2759         }
2760
2761         return ret;
2762 }
2763
2764 /* for slice only */
2765 static PyMappingMethods pyrna_prop_array_as_mapping = {
2766         (lenfunc) pyrna_prop_array_length,      /* mp_length */
2767         (binaryfunc) pyrna_prop_array_subscript,        /* mp_subscript */
2768         (objobjargproc) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
2769 };
2770
2771 static PyMappingMethods pyrna_prop_collection_as_mapping = {
2772         (lenfunc) pyrna_prop_collection_length, /* mp_length */
2773         (binaryfunc) pyrna_prop_collection_subscript,   /* mp_subscript */
2774         (objobjargproc) pyrna_prop_collection_ass_subscript,    /* mp_ass_subscript */
2775 };
2776
2777 /* only for fast bool's, large structs, assign nb_bool on init */
2778 static PyNumberMethods pyrna_prop_array_as_number = {
2779         NULL, /* nb_add */
2780         NULL, /* nb_subtract */
2781         NULL, /* nb_multiply */
2782         NULL, /* nb_remainder */
2783         NULL, /* nb_divmod */
2784         NULL, /* nb_power */
2785         NULL, /* nb_negative */
2786         NULL, /* nb_positive */
2787         NULL, /* nb_absolute */
2788         (inquiry) pyrna_prop_array_bool, /* nb_bool */
2789 };
2790 static PyNumberMethods pyrna_prop_collection_as_number = {
2791         NULL, /* nb_add */
2792         NULL, /* nb_subtract */
2793         NULL, /* nb_multiply */
2794         NULL, /* nb_remainder */
2795         NULL, /* nb_divmod */
2796         NULL, /* nb_power */
2797         NULL, /* nb_negative */
2798         NULL, /* nb_positive */
2799         NULL, /* nb_absolute */
2800         (inquiry) pyrna_prop_collection_bool, /* nb_bool */
2801 };
2802
2803 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
2804 {
2805         return pyrna_array_contains_py(&self->ptr, self->prop, value);
2806 }
2807
2808 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
2809 {
2810         PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
2811
2812         if (PyTuple_Check(key)) {
2813                 /* special case, for ID datablocks we */
2814                 return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
2815                                                                         "(id, lib) in bpy_prop_collection", FALSE, NULL);
2816         }
2817         else {
2818
2819                 /* key in dict style check */
2820                 const char *keyname = _PyUnicode_AsString(key);
2821
2822                 if (keyname == NULL) {
2823                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string or a typle of strings");
2824                         return -1;
2825                 }
2826
2827                 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2828                         return 1;
2829
2830                 return 0;
2831         }
2832 }
2833
2834 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
2835 {
2836         IDProperty *group;
2837         const char *name = _PyUnicode_AsString(value);
2838
2839         PYRNA_STRUCT_CHECK_INT(self);
2840
2841         if (!name) {
2842                 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
2843                 return -1;
2844         }
2845
2846         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2847                 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
2848                 return -1;
2849         }
2850
2851         group = RNA_struct_idprops(&self->ptr, 0);
2852
2853         if (!group)
2854                 return 0;
2855
2856         return IDP_GetPropertyFromGroup(group, name) ? 1:0;
2857 }
2858
2859 static PySequenceMethods pyrna_prop_array_as_sequence = {
2860         (lenfunc)pyrna_prop_array_length,               /* Cant set the len otherwise it can evaluate as false */
2861         NULL,           /* sq_concat */
2862         NULL,           /* sq_repeat */
2863         (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2864         NULL,           /* sq_slice */
2865         (ssizeobjargproc)prop_subscript_ass_array_int,          /* sq_ass_item */
2866         NULL,           /* *was* sq_ass_slice */
2867         (objobjproc)pyrna_prop_array_contains,  /* sq_contains */
2868         (binaryfunc) NULL, /* sq_inplace_concat */
2869         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2870 };
2871
2872 static PySequenceMethods pyrna_prop_collection_as_sequence = {
2873         (lenfunc)pyrna_prop_collection_length,          /* Cant set the len otherwise it can evaluate as false */
2874         NULL,           /* sq_concat */
2875         NULL,           /* sq_repeat */
2876         (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2877         NULL,           /* *was* sq_slice */
2878         (ssizeobjargproc)/* pyrna_prop_collection_ass_subscript_int */ NULL /* let mapping take this one */, /* sq_ass_item */
2879         NULL,           /* *was* sq_ass_slice */
2880         (objobjproc)pyrna_prop_collection_contains,     /* sq_contains */
2881         (binaryfunc) NULL, /* sq_inplace_concat */
2882         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2883 };
2884
2885 static PySequenceMethods pyrna_struct_as_sequence = {
2886         NULL,           /* Cant set the len otherwise it can evaluate as false */
2887         NULL,           /* sq_concat */
2888         NULL,           /* sq_repeat */
2889         NULL,           /* sq_item */ /* Only set this so PySequence_Check() returns True */
2890         NULL,           /* *was* sq_slice */
2891         NULL,           /* sq_ass_item */
2892         NULL,           /* *was* sq_ass_slice */
2893         (objobjproc)pyrna_struct_contains,      /* sq_contains */
2894         (binaryfunc) NULL, /* sq_inplace_concat */
2895         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2896 };
2897
2898 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
2899 {
2900         /* mostly copied from BPy_IDGroup_Map_GetItem */
2901         IDProperty *group, *idprop;
2902         const char *name = _PyUnicode_AsString(key);
2903
2904         PYRNA_STRUCT_CHECK_OBJ(self);
2905
2906         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2907                 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
2908                 return NULL;
2909         }
2910
2911         if (name == NULL) {
2912                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
2913                 return NULL;
2914         }
2915
2916         group = RNA_struct_idprops(&self->ptr, 0);
2917
2918         if (group == NULL) {
2919                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2920                 return NULL;
2921         }
2922
2923         idprop = IDP_GetPropertyFromGroup(group, name);
2924
2925         if (idprop == NULL) {
2926                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2927                 return NULL;
2928         }
2929
2930         return BPy_IDGroup_WrapData(self->ptr.id.data, idprop, group);
2931 }
2932
2933 static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
2934 {
2935         IDProperty *group;
2936
2937         PYRNA_STRUCT_CHECK_INT(self);
2938
2939         group = RNA_struct_idprops(&self->ptr, 1);
2940
2941 #ifdef USE_PEDANTIC_WRITE
2942         if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
2943                 return -1;
2944         }
2945 #endif // USE_PEDANTIC_WRITE
2946
2947         if (group == NULL) {
2948                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
2949                 return -1;
2950         }
2951
2952         return BPy_Wrap_SetMapItem(group, key, value);
2953 }
2954
2955 static PyMappingMethods pyrna_struct_as_mapping = {
2956         (lenfunc) NULL, /* mp_length */
2957         (binaryfunc) pyrna_struct_subscript,    /* mp_subscript */
2958         (objobjargproc) pyrna_struct_ass_subscript,     /* mp_ass_subscript */
2959 };
2960
2961 PyDoc_STRVAR(pyrna_struct_keys_doc,
2962 ".. method:: keys()\n"
2963 "\n"
2964 "   Returns the keys of this objects custom properties (matches pythons\n"
2965 "   dictionary function of the same name).\n"
2966 "\n"
2967 "   :return: custom property keys.\n"
2968 "   :rtype: list of strings\n"
2969 "\n"
2970 BPY_DOC_ID_PROP_TYPE_NOTE
2971 );
2972 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
2973 {
2974         IDProperty *group;
2975
2976         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2977                 PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
2978                 return NULL;
2979         }
2980
2981         group = RNA_struct_idprops(&self->ptr, 0);
2982
2983         if (group == NULL)
2984                 return PyList_New(0);
2985
2986         return BPy_Wrap_GetKeys(group);
2987 }
2988
2989 PyDoc_STRVAR(pyrna_struct_items_doc,
2990 ".. method:: items()\n"
2991 "\n"
2992 "   Returns the items of this objects custom properties (matches pythons\n"
2993 "   dictionary function of the same name).\n"
2994 "\n"
2995 "   :return: custom property key, value pairs.\n"
2996 "   :rtype: list of key, value tuples\n"
2997 "\n"
2998 BPY_DOC_ID_PROP_TYPE_NOTE
2999 );
3000 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
3001 {
3002         IDProperty *group;
3003
3004         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3005                 PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
3006                 return NULL;
3007         }
3008
3009         group = RNA_struct_idprops(&self->ptr, 0);
3010
3011         if (group == NULL)
3012                 return PyList_New(0);
3013
3014         return BPy_Wrap_GetItems(self->ptr.id.data, group);
3015 }
3016
3017 PyDoc_STRVAR(pyrna_struct_values_doc,
3018 ".. method:: values()\n"
3019 "\n"
3020 "   Returns the values of this objects custom properties (matches pythons\n"
3021 "   dictionary function of the same name).\n"
3022 "\n"
3023 "   :return: custom property values.\n"
3024 "   :rtype: list\n"
3025 "\n"
3026 BPY_DOC_ID_PROP_TYPE_NOTE
3027 );
3028 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
3029 {
3030         IDProperty *group;
3031
3032         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3033                 PyErr_SetString(PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
3034                 return NULL;
3035         }
3036
3037         group = RNA_struct_idprops(&self->ptr, 0);
3038
3039         if (group == NULL)
3040                 return PyList_New(0);
3041
3042         return BPy_Wrap_GetValues(self->ptr.id.data, group);
3043 }
3044
3045
3046 PyDoc_STRVAR(pyrna_struct_is_property_set_doc,
3047 ".. method:: is_property_set(property)\n"
3048 "\n"
3049 "   Check if a property is set, use for testing operator properties.\n"
3050 "\n"
3051 "   :return: True when the property has been set.\n"
3052 "   :rtype: boolean\n"
3053 );
3054 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
3055 {
3056         PropertyRNA *prop;
3057         const char *name;
3058         int ret;
3059
3060         PYRNA_STRUCT_CHECK_OBJ(self);
3061
3062         if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
3063                 return NULL;
3064
3065         if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3066                 PyErr_Format(PyExc_TypeError,
3067                              "%.200s.is_property_set(\"%.200s\") not found",
3068                              RNA_struct_identifier(self->ptr.type), name);
3069                 return NULL;
3070         }
3071
3072         /* double property lookup, could speed up */
3073         /* return PyBool_FromLong(RNA_struct_property_is_set(&self->ptr, name)); */
3074         if (RNA_property_flag(prop) & PROP_IDPROPERTY) {
3075                 IDProperty *group = RNA_struct_idprops(&self->ptr, 0);
3076                 if (group) {
3077                         ret = IDP_GetPropertyFromGroup(group, name) ? 1:0;
3078                 }
3079                 else {
3080                         ret = 0;
3081                 }
3082         }
3083         else {