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