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