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