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