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