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