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