7259ea8e2f57a436021d5d49ea34c0f5e8d64f78
[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_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "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_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "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                 arg_name = RNA_property_identifier(prop);
1429
1430                 if (strcmp(arg_name, "rna_type") == 0) continue;
1431
1432                 if (kw == NULL) {
1433                         PyErr_Format(PyExc_TypeError,
1434                                      "%.200s: no keywords, expected \"%.200s\"",
1435                                      error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1436                         error_val = -1;
1437                         break;
1438                 }
1439
1440                 item = PyDict_GetItemString(kw, arg_name); /* wont set an error */
1441
1442                 if (item == NULL) {
1443                         if (all_args) {
1444                                 PyErr_Format(PyExc_TypeError,
1445                                              "%.200s: keyword \"%.200s\" missing",
1446                                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1447                                 error_val = -1; /* pyrna_py_to_prop sets the error */
1448                                 break;
1449                         }
1450                 }
1451                 else {
1452                         if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1453                                 error_val = -1;
1454                                 break;
1455                         }
1456                         totkw--;
1457                 }
1458         }
1459         RNA_STRUCT_END;
1460
1461         if (error_val == 0 && totkw > 0) { /* some keywords were given that were not used :/ */
1462                 PyObject *key, *value;
1463                 Py_ssize_t pos = 0;
1464
1465                 while (PyDict_Next(kw, &pos, &key, &value)) {
1466                         arg_name = _PyUnicode_AsString(key);
1467                         if (RNA_struct_find_property(ptr, arg_name) == NULL) break;
1468                         arg_name = NULL;
1469                 }
1470
1471                 PyErr_Format(PyExc_TypeError,
1472                              "%.200s: keyword \"%.200s\" unrecognized",
1473                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1474                 error_val = -1;
1475         }
1476
1477         return error_val;
1478 }
1479
1480
1481 static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
1482 {
1483         BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1484         pyfunc->ptr = *ptr;
1485         pyfunc->func = func;
1486         return (PyObject *)pyfunc;
1487 }
1488
1489
1490 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1491 {
1492         /* XXX hard limits should be checked here */
1493         const int type = RNA_property_type(prop);
1494
1495
1496         if (RNA_property_array_check(prop)) {
1497                 /* done getting the length */
1498                 if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1499                         return -1;
1500                 }
1501         }
1502         else {
1503                 /* Normal Property (not an array) */
1504
1505                 /* see if we can coorce into a python type - PropertyType */
1506                 switch (type) {
1507                         case PROP_BOOLEAN:
1508                         {
1509                                 int param;
1510                                 /* prefer not to have an exception here
1511                                  * however so many poll functions return None or a valid Object.
1512                                  * its a hassle to convert these into a bool before returning, */
1513                                 if (RNA_property_flag(prop) & PROP_OUTPUT)
1514                                         param = PyObject_IsTrue(value);
1515                                 else
1516                                         param = PyLong_AsLong(value);
1517
1518                                 if (param < 0) {
1519                                         PyErr_Format(PyExc_TypeError,
1520                                                      "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1521                                                      error_prefix, RNA_struct_identifier(ptr->type),
1522                                                      RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1523                                         return -1;
1524                                 }
1525                                 else {
1526                                         if (data) *((int *)data) = param;
1527                                         else RNA_property_boolean_set(ptr, prop, param);
1528                                 }
1529                                 break;
1530                         }
1531                         case PROP_INT:
1532                         {
1533                                 int overflow;
1534                                 long param = PyLong_AsLongAndOverflow(value, &overflow);
1535                                 if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1536                                         PyErr_Format(PyExc_ValueError,
1537                                                      "%.200s %.200s.%.200s value not in 'int' range "
1538                                                      "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1539                                                      error_prefix, RNA_struct_identifier(ptr->type),
1540                                                      RNA_property_identifier(prop));
1541                                         return -1;
1542                                 }
1543                                 else if (param == -1 && PyErr_Occurred()) {
1544                                         PyErr_Format(PyExc_TypeError,
1545                                                      "%.200s %.200s.%.200s expected an int type, not %.200s",
1546                                                      error_prefix, RNA_struct_identifier(ptr->type),
1547                                                      RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1548                                         return -1;
1549                                 }
1550                                 else {
1551                                         int param_i = (int)param;
1552                                         RNA_property_int_clamp(ptr, prop, &param_i);
1553                                         if (data) *((int *)data) = param_i;
1554                                         else RNA_property_int_set(ptr, prop, param_i);
1555                                 }
1556                                 break;
1557                         }
1558                         case PROP_FLOAT:
1559                         {
1560                                 float param = PyFloat_AsDouble(value);
1561                                 if (PyErr_Occurred()) {
1562                                         PyErr_Format(PyExc_TypeError,
1563                                                      "%.200s %.200s.%.200s expected a float type, not %.200s",
1564                                                      error_prefix, RNA_struct_identifier(ptr->type),
1565                                                      RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1566                                         return -1;
1567                                 }
1568                                 else {
1569                                         RNA_property_float_clamp(ptr, prop, (float *)&param);
1570                                         if (data) *((float *)data) = param;
1571                                         else RNA_property_float_set(ptr, prop, param);
1572                                 }
1573                                 break;
1574                         }
1575                         case PROP_STRING:
1576                         {
1577                                 const int subtype = RNA_property_subtype(prop);
1578                                 const char *param;
1579
1580                                 if (subtype == PROP_BYTESTRING) {
1581
1582                                         /* Byte String */
1583
1584                                         param = PyBytes_AsString(value);
1585
1586                                         if (param == NULL) {
1587                                                 if (PyBytes_Check(value)) {
1588                                                         /* there was an error assigning a string type,
1589                                                          * rather than setting a new error, prefix the existing one
1590                                                          */
1591                                                         PyC_Err_Format_Prefix(PyExc_TypeError,
1592                                                                               "%.200s %.200s.%.200s error assigning bytes",
1593                                                                               error_prefix, RNA_struct_identifier(ptr->type),
1594                                                                               RNA_property_identifier(prop));
1595                                                 }
1596                                                 else {
1597                                                         PyErr_Format(PyExc_TypeError,
1598                                                                      "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1599                                                                      error_prefix, RNA_struct_identifier(ptr->type),
1600                                                                      RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1601                                                 }
1602
1603                                                 return -1;
1604                                         }
1605                                         else {
1606                                                 /* same as unicode */
1607                                                 if (data) *((char **)data) = (char *)param;  /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1608                                                 else RNA_property_string_set(ptr, prop, param);
1609                                         }
1610                                 }
1611                                 else {
1612
1613                                         /* Unicode String */
1614
1615 #ifdef USE_STRING_COERCE
1616                                         PyObject *value_coerce = NULL;
1617                                         if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1618                                                 /* TODO, get size */
1619                                                 param = PyC_UnicodeAsByte(value, &value_coerce);
1620                                         }
1621                                         else {
1622                                                 param = _PyUnicode_AsString(value);
1623 #ifdef WITH_INTERNATIONAL
1624                                                 if (subtype == PROP_TRANSLATE) {
1625                                                         param = IFACE_(param);
1626                                                 }
1627 #endif // WITH_INTERNATIONAL
1628
1629                                         }
1630 #else // USE_STRING_COERCE
1631                                         param = _PyUnicode_AsString(value);
1632 #endif // USE_STRING_COERCE
1633
1634                                         if (param == NULL) {
1635                                                 if (PyUnicode_Check(value)) {
1636                                                         /* there was an error assigning a string type,
1637                                                          * rather than setting a new error, prefix the existing one
1638                                                          */
1639                                                         PyC_Err_Format_Prefix(PyExc_TypeError,
1640                                                                               "%.200s %.200s.%.200s error assigning string",
1641                                                                               error_prefix, RNA_struct_identifier(ptr->type),
1642                                                                               RNA_property_identifier(prop));
1643                                                 }
1644                                                 else {
1645                                                         PyErr_Format(PyExc_TypeError,
1646                                                                      "%.200s %.200s.%.200s expected a string type, not %.200s",
1647                                                                      error_prefix, RNA_struct_identifier(ptr->type),
1648                                                                      RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1649                                                 }
1650
1651                                                 return -1;
1652                                         }
1653                                         else {
1654                                                 /* same as bytes */
1655                                                 if (data) *((char **)data) = (char *)param;  /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1656                                                 else RNA_property_string_set(ptr, prop, param);
1657                                         }
1658 #ifdef USE_STRING_COERCE
1659                                         Py_XDECREF(value_coerce);
1660 #endif // USE_STRING_COERCE
1661                                 }
1662                                 break;
1663                         }
1664                         case PROP_ENUM:
1665                         {
1666                                 int val = 0;
1667
1668                                 /* type checkins is done by each function */
1669                                 if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1670                                         /* set of enum items, concatenate all values with OR */
1671                                         if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
1672                                                 return -1;
1673                                         }
1674                                 }
1675                                 else {
1676                                         /* simple enum string */
1677                                         if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
1678                                                 return -1;
1679                                         }
1680                                 }
1681
1682                                 if (data) *((int *)data) = val;
1683                                 else RNA_property_enum_set(ptr, prop, val);
1684
1685                                 break;
1686                         }
1687                         case PROP_POINTER:
1688                         {
1689                                 PyObject *value_new = NULL;
1690
1691                                 StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
1692                                 int flag = RNA_property_flag(prop);
1693
1694                                 /* this is really nasty!, so we can fake the operator having direct properties eg:
1695                                  * layout.prop(self, "filepath")
1696                                  * ... which infact should be
1697                                  * layout.prop(self.properties, "filepath")
1698                                  *
1699                                  * we need to do this trick.
1700                                  * if the prop is not an operator type and the pyobject is an operator,
1701                                  * use its properties in place of its self.
1702                                  *
1703                                  * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing
1704                                  * if this causes problems in the future it should be removed.
1705                                  */
1706                                 if ((ptr_type == &RNA_AnyType) &&
1707                                     (BPy_StructRNA_Check(value)) &&
1708                                     (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator)))
1709                                 {
1710                                         value = PyObject_GetAttrString(value, "properties");
1711                                         value_new = value;
1712                                 }
1713
1714
1715                                 /* if property is an OperatorProperties pointer and value is a map,
1716                                  * forward back to pyrna_pydict_to_props */
1717                                 if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) {
1718                                         PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1719                                         return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
1720                                 }
1721
1722                                 /* another exception, allow to pass a collection as an RNA property */
1723                                 if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* ok to ignore idprop collections */
1724                                         PointerRNA c_ptr;
1725                                         BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
1726                                         if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1727                                                 value = pyrna_struct_CreatePyObject(&c_ptr);
1728                                                 value_new = value;
1729                                         }
1730                                         else {
1731                                                 PyErr_Format(PyExc_TypeError,
1732                                                              "%.200s %.200s.%.200s collection has no type, "
1733                                                              "cant be used as a %.200s type",
1734                                                              error_prefix, RNA_struct_identifier(ptr->type),
1735                                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1736                                                 return -1;
1737                                         }
1738                                 }
1739
1740                                 if (!BPy_StructRNA_Check(value) && value != Py_None) {
1741                                         PyErr_Format(PyExc_TypeError,
1742                                                      "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1743                                                      error_prefix, RNA_struct_identifier(ptr->type),
1744                                                      RNA_property_identifier(prop), RNA_struct_identifier(ptr_type),
1745                                                      Py_TYPE(value)->tp_name);
1746                                         Py_XDECREF(value_new); return -1;
1747                                 }
1748                                 else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
1749                                         PyErr_Format(PyExc_TypeError,
1750                                                      "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1751                                                      error_prefix, RNA_struct_identifier(ptr->type),
1752                                                      RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1753                                         Py_XDECREF(value_new); return -1;
1754                                 }
1755                                 else if ((value != Py_None) &&
1756                                          ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA *)value)->ptr.id.data))
1757                                 {
1758                                         PyErr_Format(PyExc_TypeError,
1759                                                      "%.200s %.200s.%.200s ID type does not support assignment to its self",
1760                                                      error_prefix, RNA_struct_identifier(ptr->type),
1761                                                      RNA_property_identifier(prop));
1762                                         Py_XDECREF(value_new); return -1;
1763                                 }
1764                                 else {
1765                                         BPy_StructRNA *param = (BPy_StructRNA *)value;
1766                                         int raise_error = FALSE;
1767                                         if (data) {
1768
1769                                                 if (flag & PROP_RNAPTR) {
1770                                                         if (value == Py_None)
1771                                                                 memset(data, 0, sizeof(PointerRNA));
1772                                                         else
1773                                                                 *((PointerRNA *)data) = param->ptr;
1774                                                 }
1775                                                 else if (value == Py_None) {
1776                                                         *((void **)data) = NULL;
1777                                                 }
1778                                                 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1779                                                         *((void **)data) = param->ptr.data;
1780                                                 }
1781                                                 else {
1782                                                         raise_error = TRUE;
1783                                                 }
1784                                         }
1785                                         else {
1786                                                 /* data == NULL, assign to RNA */
1787                                                 if (value == Py_None) {
1788                                                         PointerRNA valueptr = {{NULL}};
1789                                                         RNA_property_pointer_set(ptr, prop, valueptr);
1790                                                 }
1791                                                 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1792                                                         RNA_property_pointer_set(ptr, prop, param->ptr);
1793                                                 }
1794                                                 else {
1795                                                         PointerRNA tmp;
1796                                                         RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1797                                                         PyErr_Format(PyExc_TypeError,
1798                                                                      "%.200s %.200s.%.200s expected a %.200s type. not %.200s",
1799                                                                      error_prefix, RNA_struct_identifier(ptr->type),
1800                                                                      RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1801                                                                      RNA_struct_identifier(param->ptr.type));
1802                                                         Py_XDECREF(value_new); return -1;
1803                                                 }
1804                                         }
1805
1806                                         if (raise_error) {
1807                                                 PointerRNA tmp;
1808                                                 RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1809                                                 PyErr_Format(PyExc_TypeError,
1810                                                              "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1811                                                              error_prefix, RNA_struct_identifier(ptr->type),
1812                                                              RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1813                                                              RNA_struct_identifier(param->ptr.type));
1814                                                 Py_XDECREF(value_new); return -1;
1815                                         }
1816                                 }
1817
1818                                 Py_XDECREF(value_new);
1819
1820                                 break;
1821                         }
1822                         case PROP_COLLECTION:
1823                         {
1824                                 Py_ssize_t seq_len, i;
1825                                 PyObject *item;
1826                                 PointerRNA itemptr;
1827                                 ListBase *lb;
1828                                 CollectionPointerLink *link;
1829
1830                                 lb = (data) ? (ListBase *)data : NULL;
1831
1832                                 /* convert a sequence of dict's into a collection */
1833                                 if (!PySequence_Check(value)) {
1834                                         PyErr_Format(PyExc_TypeError,
1835                                                      "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
1836                                                      error_prefix, RNA_struct_identifier(ptr->type),
1837                                                      RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1838                                         return -1;
1839                                 }
1840
1841                                 seq_len = PySequence_Size(value);
1842                                 for (i = 0; i < seq_len; i++) {
1843                                         item = PySequence_GetItem(value, i);
1844
1845                                         if (item == NULL) {
1846                                                 PyErr_Format(PyExc_TypeError,
1847                                                              "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
1848                                                              error_prefix, RNA_struct_identifier(ptr->type),
1849                                                              RNA_property_identifier(prop), i);
1850                                                 Py_XDECREF(item);
1851                                                 return -1;
1852                                         }
1853
1854                                         if (PyDict_Check(item) == 0) {
1855                                                 PyErr_Format(PyExc_TypeError,
1856                                                              "%.200s %.200s.%.200s expected a each sequence "
1857                                                              "member to be a dict for an RNA collection, not %.200s",
1858                                                              error_prefix, RNA_struct_identifier(ptr->type),
1859                                                              RNA_property_identifier(prop), Py_TYPE(item)->tp_name);
1860                                                 Py_XDECREF(item);
1861                                                 return -1;
1862                                         }
1863
1864                                         if (lb) {
1865                                                 link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
1866                                                 link->ptr = itemptr;
1867                                                 BLI_addtail(lb, link);
1868                                         }
1869                                         else
1870                                                 RNA_property_collection_add(ptr, prop, &itemptr);
1871
1872                                         if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection") == -1) {
1873                                                 PyObject *msg = PyC_ExceptionBuffer();
1874                                                 const char *msg_char = _PyUnicode_AsString(msg);
1875
1876                                                 PyErr_Format(PyExc_TypeError,
1877                                                              "%.200s %.200s.%.200s error converting a member of a collection "
1878                                                              "from a dicts into an RNA collection, failed with: %s",
1879                                                              error_prefix, RNA_struct_identifier(ptr->type),
1880                                                              RNA_property_identifier(prop), msg_char);
1881
1882                                                 Py_DECREF(item);
1883                                                 Py_DECREF(msg);
1884                                                 return -1;
1885                                         }
1886                                         Py_DECREF(item);
1887                                 }
1888
1889                                 break;
1890                         }
1891                         default:
1892                                 PyErr_Format(PyExc_AttributeError,
1893                                              "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
1894                                              error_prefix, RNA_struct_identifier(ptr->type),
1895                                              RNA_property_identifier(prop));
1896                                 return -1;
1897                                 break;
1898                 }
1899         }
1900
1901         /* Run rna property functions */
1902         if (RNA_property_update_check(prop)) {
1903                 RNA_property_update(BPy_GetContext(), ptr, prop);
1904         }
1905
1906         return 0;
1907 }
1908
1909 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
1910 {
1911         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
1912         return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
1913 }
1914
1915 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
1916 {
1917         int ret = 0;
1918         PointerRNA *ptr = &self->ptr;
1919         PropertyRNA *prop = self->prop;
1920
1921         const int totdim = RNA_property_array_dimension(ptr, prop, NULL);
1922
1923         if (totdim > 1) {
1924                 /* char error_str[512]; */
1925                 if (pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
1926                         /* error is set */
1927                         ret = -1;
1928                 }
1929         }
1930         else {
1931                 /* see if we can coerce into a python type - PropertyType */
1932                 switch (RNA_property_type(prop)) {
1933                         case PROP_BOOLEAN:
1934                         {
1935                                 int param = PyLong_AsLong(value);
1936
1937                                 if (param < 0 || param > 1) {
1938                                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1939                                         ret = -1;
1940                                 }
1941                                 else {
1942                                         RNA_property_boolean_set_index(ptr, prop, index, param);
1943                                 }
1944                                 break;
1945                         }
1946                         case PROP_INT:
1947                         {
1948                                 int param = PyLong_AsLong(value);
1949                                 if (param == -1 && PyErr_Occurred()) {
1950                                         PyErr_SetString(PyExc_TypeError, "expected an int type");
1951                                         ret = -1;
1952                                 }
1953                                 else {
1954                                         RNA_property_int_clamp(ptr, prop, &param);
1955                                         RNA_property_int_set_index(ptr, prop, index, param);
1956                                 }
1957                                 break;
1958                         }
1959                         case PROP_FLOAT:
1960                         {
1961                                 float param = PyFloat_AsDouble(value);
1962                                 if (PyErr_Occurred()) {
1963                                         PyErr_SetString(PyExc_TypeError, "expected a float type");
1964                                         ret = -1;
1965                                 }
1966                                 else {
1967                                         RNA_property_float_clamp(ptr, prop, &param);
1968                                         RNA_property_float_set_index(ptr, prop, index, param);
1969                                 }
1970                                 break;
1971                         }
1972                         default:
1973                                 PyErr_SetString(PyExc_AttributeError, "not an array type");
1974                                 ret = -1;
1975                                 break;
1976                 }
1977         }
1978
1979         /* Run rna property functions */
1980         if (RNA_property_update_check(prop)) {
1981                 RNA_property_update(BPy_GetContext(), ptr, prop);
1982         }
1983
1984         return ret;
1985 }
1986
1987 //---------------sequence-------------------------------------------
1988 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
1989 {
1990         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
1991
1992         if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
1993                 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
1994         else
1995                 return RNA_property_array_length(&self->ptr, self->prop);
1996 }
1997
1998 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
1999 {
2000         PYRNA_PROP_CHECK_INT(self);
2001
2002         return RNA_property_collection_length(&self->ptr, self->prop);
2003 }
2004
2005 /* bool functions are for speed, so we can avoid getting the length
2006  * of 1000's of items in a linked list for eg. */
2007 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
2008 {
2009         PYRNA_PROP_CHECK_INT(self);
2010
2011         return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
2012 }
2013
2014 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
2015 {
2016         /* no callback defined, just iterate and find the nth item */
2017         CollectionPropertyIterator iter;
2018         int test;
2019
2020         PYRNA_PROP_CHECK_INT(self);
2021
2022         RNA_property_collection_begin(&self->ptr, self->prop, &iter);
2023         test = iter.valid;
2024         RNA_property_collection_end(&iter);
2025         return test;
2026 }
2027
2028
2029 /* notice getting the length of the collection is avoided unless negative
2030  * index is used or to detect internal error with a valid index.
2031  * This is done for faster lookups. */
2032 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err)                              \
2033         if (keynum < 0) {                                                         \
2034                 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2035                 if (keynum_abs < 0) {                                                 \
2036                         PyErr_Format(PyExc_IndexError,                                    \
2037                                      "bpy_prop_collection[%d]: out of range.", keynum);   \
2038                         return ret_err;                                                   \
2039                 }                                                                     \
2040         }                                                                         \
2041
2042
2043 /* internal use only */
2044 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2045 {
2046         PointerRNA newptr;
2047         Py_ssize_t keynum_abs = keynum;
2048
2049         PYRNA_PROP_CHECK_OBJ(self);
2050
2051         PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
2052
2053         if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2054                 return pyrna_struct_CreatePyObject(&newptr);
2055         }
2056         else {
2057                 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2058                 if (keynum_abs >= len) {
2059                         PyErr_Format(PyExc_IndexError,
2060                                      "bpy_prop_collection[index]: "
2061                                      "index %d out of range, size %d", keynum, len);
2062                 }
2063                 else {
2064                         PyErr_Format(PyExc_RuntimeError,
2065                                      "bpy_prop_collection[index]: internal error, "
2066                                      "valid index %d given in %d sized collection but value not found",
2067                                      keynum_abs, len);
2068                 }
2069
2070                 return NULL;
2071         }
2072 }
2073
2074 /* values type must have been already checked */
2075 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
2076 {
2077         Py_ssize_t keynum_abs = keynum;
2078         const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2079
2080         PYRNA_PROP_CHECK_INT(self);
2081
2082         PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
2083
2084         if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2085                 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2086                 if (keynum_abs >= len) {
2087                         PyErr_Format(PyExc_IndexError,
2088                                      "bpy_prop_collection[index] = value: "
2089                                      "index %d out of range, size %d", keynum, len);
2090                 }
2091                 else {
2092
2093                         PyErr_Format(PyExc_IndexError,
2094                                      "bpy_prop_collection[index] = value: "
2095                                      "failed assignment (unknown reason)", keynum);
2096                 }
2097                 return -1;
2098         }
2099
2100         return 0;
2101 }
2102
2103 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2104 {
2105         int len;
2106
2107         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2108
2109         len = pyrna_prop_array_length(self);
2110
2111         if (keynum < 0) keynum += len;
2112
2113         if (keynum >= 0 && keynum < len)
2114                 return pyrna_prop_array_to_py_index(self, keynum);
2115
2116         PyErr_Format(PyExc_IndexError,
2117                      "bpy_prop_array[index]: index %d out of range", keynum);
2118         return NULL;
2119 }
2120
2121 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2122 {
2123         PointerRNA newptr;
2124
2125         PYRNA_PROP_CHECK_OBJ(self);
2126
2127         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2128                 return pyrna_struct_CreatePyObject(&newptr);
2129
2130         PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2131         return NULL;
2132 }
2133 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
2134
2135 /* special case: bpy.data.objects["some_id_name", "//some_lib_name.blend"]
2136  * also for:     bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)
2137  *
2138  * note:
2139  * error codes since this is not to be called directly from python,
2140  * this matches pythons __contains__ values capi.
2141  * -1: exception set
2142  *  0: not found
2143  *  1: found */
2144 int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, PyObject *key,
2145                                                      const char *err_prefix, const short err_not_found,
2146                                                      PointerRNA *r_ptr
2147                                                      )
2148 {
2149         char *keyname;
2150
2151         /* first validate the args, all we know is that they are a tuple */
2152         if (PyTuple_GET_SIZE(key) != 2) {
2153                 PyErr_Format(PyExc_KeyError,
2154                              "%s: tuple key must be a pair, not size %d",
2155                              err_prefix, PyTuple_GET_SIZE(key));
2156                 return -1;
2157         }
2158         else if (self->ptr.type != &RNA_BlendData) {
2159                 PyErr_Format(PyExc_KeyError,
2160                              "%s: is only valid for bpy.data collections, not %.200s",
2161                              err_prefix, RNA_struct_identifier(self->ptr.type));
2162                 return -1;
2163         }
2164         else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
2165                 PyErr_Format(PyExc_KeyError,
2166                              "%s: id must be a string, not %.200s",
2167                              err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2168                 return -1;
2169         }
2170         else {
2171                 PyObject *keylib = PyTuple_GET_ITEM(key, 1);
2172                 Library *lib;
2173                 int found = FALSE;
2174
2175                 if (keylib == Py_None) {
2176                         lib = NULL;
2177                 }
2178                 else if (PyUnicode_Check(keylib)) {
2179                         Main *bmain = self->ptr.data;
2180                         const char *keylib_str = _PyUnicode_AsString(keylib);
2181                         lib = BLI_findstring(&bmain->library, keylib_str, offsetof(Library, name));
2182                         if (lib == NULL) {
2183                                 if (err_not_found) {
2184                                         PyErr_Format(PyExc_KeyError,
2185                                                      "%s: lib name '%.240s' "
2186                                                      "does not reference a valid library",
2187                                                      err_prefix, keylib_str);
2188                                         return -1;
2189                                 }
2190                                 else {
2191                                         return 0;
2192                                 }
2193
2194                         }
2195                 }
2196                 else {
2197                         PyErr_Format(PyExc_KeyError,
2198                                      "%s: lib must be a sting or None, not %.200s",
2199                                      err_prefix, Py_TYPE(keylib)->tp_name);
2200                         return -1;
2201                 }
2202
2203                 /* lib is either a valid poniter or NULL,
2204                  * either way can do direct comparison with id.lib */
2205
2206                 RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
2207                         ID *id = itemptr.data; /* always an ID */
2208                         if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
2209                                 found = TRUE;
2210                                 if (r_ptr) {
2211                                         *r_ptr = itemptr;
2212                                 }
2213                                 break;
2214                         }
2215                 }
2216                 RNA_PROP_END;
2217
2218                 /* we may want to fail silently as with collection.get() */
2219                 if ((found == FALSE) && err_not_found) {
2220                         /* only runs for getitem access so use fixed string */
2221                         PyErr_SetString(PyExc_KeyError,
2222                                         "bpy_prop_collection[key, lib]: not found");
2223                         return -1;
2224                 }
2225                 else {
2226                         return found; /* 1 / 0, no exception */
2227                 }
2228         }
2229 }
2230
2231 static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
2232                                                               const char *err_prefix, const short err_not_found)
2233 {
2234         PointerRNA ptr;
2235         const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
2236
2237         if (contains == 1) {
2238                 return pyrna_struct_CreatePyObject(&ptr);
2239         }
2240         else {
2241                 return NULL;
2242         }
2243 }
2244
2245
2246 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
2247 {
2248         CollectionPropertyIterator rna_macro_iter;
2249         int count = 0;
2250
2251         PyObject *list;
2252         PyObject *item;
2253
2254         PYRNA_PROP_CHECK_OBJ(self);
2255
2256         list = PyList_New(0);
2257
2258         /* first loop up-until the start */
2259         for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2260              rna_macro_iter.valid;
2261              RNA_property_collection_next(&rna_macro_iter))
2262         {
2263                 /* PointerRNA itemptr = rna_macro_iter.ptr; */
2264                 if (count == start) {
2265                         break;
2266                 }
2267                 count++;
2268         }
2269
2270         /* add items until stop */
2271         for (; rna_macro_iter.valid;
2272              RNA_property_collection_next(&rna_macro_iter))
2273         {
2274                 item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2275                 PyList_Append(list, item);
2276                 Py_DECREF(item);
2277
2278                 count++;
2279                 if (count == stop) {
2280                         break;
2281                 }
2282         }
2283
2284         RNA_property_collection_end(&rna_macro_iter);
2285
2286         return list;
2287 }
2288
2289 /* TODO - dimensions
2290  * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
2291  * since at the moment it reads (and even allocates) the entire array for each index.
2292  */
2293 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
2294                                                   Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
2295 {
2296         int count, totdim;
2297         PyObject *tuple;
2298
2299         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2300
2301         tuple = PyTuple_New(stop - start);
2302
2303         /* PYRNA_PROP_CHECK_OBJ(self); isn't needed, internal use only */
2304
2305         totdim = RNA_property_array_dimension(ptr, prop, NULL);
2306
2307         if (totdim > 1) {
2308                 for (count = start; count < stop; count++)
2309                         PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2310         }
2311         else {
2312                 switch (RNA_property_type(prop)) {
2313                         case PROP_FLOAT:
2314                         {
2315                                 float values_stack[PYRNA_STACK_ARRAY];
2316                                 float *values;
2317                                 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(float) * length); }
2318                                 else                            { values = values_stack; }
2319                                 RNA_property_float_get_array(ptr, prop, values);
2320
2321                                 for (count = start; count < stop; count++)
2322                                         PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count]));
2323
2324                                 if (values != values_stack) {
2325                                         PyMem_FREE(values);
2326                                 }
2327                                 break;
2328                         }
2329                         case PROP_BOOLEAN:
2330                         {
2331                                 int values_stack[PYRNA_STACK_ARRAY];
2332                                 int *values;
2333                                 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); }
2334                                 else                            { values = values_stack; }
2335
2336                                 RNA_property_boolean_get_array(ptr, prop, values);
2337                                 for (count = start; count < stop; count++)
2338                                         PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count]));
2339
2340                                 if (values != values_stack) {
2341                                         PyMem_FREE(values);
2342                                 }
2343                                 break;
2344                         }
2345                         case PROP_INT:
2346                         {
2347                                 int values_stack[PYRNA_STACK_ARRAY];
2348                                 int *values;
2349                                 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); }
2350                                 else                            { values = values_stack; }
2351
2352                                 RNA_property_int_get_array(ptr, prop, values);
2353                                 for (count = start; count < stop; count++)
2354                                         PyTuple_SET_ITEM(tuple, count - start, PyLong_FromSsize_t(values[count]));
2355
2356                                 if (values != values_stack) {
2357                                         PyMem_FREE(values);
2358                                 }
2359                                 break;
2360                         }
2361                         default:
2362                                 BLI_assert(!"Invalid array type");
2363
2364                                 PyErr_SetString(PyExc_TypeError, "not an array type");
2365                                 Py_DECREF(tuple);
2366                                 tuple = NULL;
2367                 }
2368         }
2369         return tuple;
2370 }
2371
2372 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2373 {
2374         PYRNA_PROP_CHECK_OBJ(self);
2375
2376         if (PyUnicode_Check(key)) {
2377                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2378         }
2379         else if (PyIndex_Check(key)) {
2380                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2381                 if (i == -1 && PyErr_Occurred())
2382                         return NULL;
2383
2384                 return pyrna_prop_collection_subscript_int(self, i);
2385         }
2386         else if (PySlice_Check(key)) {
2387                 PySliceObject *key_slice = (PySliceObject *)key;
2388                 Py_ssize_t step = 1;
2389
2390                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2391                         return NULL;
2392                 }
2393                 else if (step != 1) {
2394                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2395                         return NULL;
2396                 }
2397                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2398                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2399                 }
2400                 else {
2401                         Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2402
2403                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2404                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2405                         if (key_slice->stop  != Py_None && !_PyEval_SliceIndex(key_slice->stop,  &stop))  return NULL;
2406
2407                         if (start < 0 || stop < 0) {
2408                                 /* only get the length for negative values */
2409                                 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2410                                 if (start < 0) start += len;
2411                                 if (stop < 0) start += len;
2412                         }
2413
2414                         if (stop - start <= 0) {
2415                                 return PyList_New(0);
2416                         }
2417                         else {
2418                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2419                         }
2420                 }
2421         }
2422         else if (PyTuple_Check(key)) {
2423                 /* special case, for ID datablocks we */
2424                 return pyrna_prop_collection_subscript_str_lib_pair(self, key,
2425                                                                     "bpy_prop_collection[id, lib]", TRUE);
2426         }
2427         else {
2428                 PyErr_Format(PyExc_TypeError,
2429                              "bpy_prop_collection[key]: invalid key, "
2430                              "must be a string or an int, not %.200s",
2431                              Py_TYPE(key)->tp_name);
2432                 return NULL;
2433         }
2434 }
2435
2436 /* generic check to see if a PyObject is compatible with a collection
2437  * -1 on failure, 0 on success, sets the error */
2438 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2439 {
2440         StructRNA *prop_srna;
2441
2442         if (value == Py_None) {
2443                 if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2444                         PyErr_Format(PyExc_TypeError,
2445                                      "bpy_prop_collection[key] = value: invalid, "
2446                                      "this collection doesn't support None assignment");
2447                         return -1;
2448                 }
2449                 else {
2450                         return 0; /* None is OK */
2451                 }
2452         }
2453         else if (BPy_StructRNA_Check(value) == 0) {
2454                 PyErr_Format(PyExc_TypeError,
2455                              "bpy_prop_collection[key] = value: invalid, "
2456                              "expected a StructRNA type or None, not a %.200s",
2457                              Py_TYPE(value)->tp_name);
2458                 return -1;
2459         }
2460         else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
2461                 StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
2462                 if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2463                         PyErr_Format(PyExc_TypeError,
2464                                      "bpy_prop_collection[key] = value: invalid, "
2465                                      "expected a '%.200s' type or None, not a '%.200s'",
2466                                      RNA_struct_identifier(prop_srna),
2467                                      RNA_struct_identifier(value_srna)
2468                                      );
2469                         return -1;
2470                 }
2471                 else {
2472                         return 0; /* OK, this is the correct type!*/
2473                 }
2474         }
2475
2476         PyErr_Format(PyExc_TypeError,
2477                      "bpy_prop_collection[key] = value: internal error, "
2478                      "failed to get the collection type");
2479         return -1;
2480 }
2481
2482 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2483  * large blocks commented, we may support slice/key indices later */
2484 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
2485 {
2486         PYRNA_PROP_CHECK_INT(self);
2487
2488         /* validate the assigned value */
2489         if (value == NULL) {
2490                 PyErr_SetString(PyExc_TypeError,
2491                                 "del bpy_prop_collection[key]: not supported");
2492                 return -1;
2493         }
2494         else if (pyrna_prop_collection_type_check(self, value) == -1) {
2495                 return -1; /* exception is set */
2496         }
2497
2498 #if 0
2499         if (PyUnicode_Check(key)) {
2500                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2501         }
2502         else
2503 #endif
2504         if (PyIndex_Check(key)) {
2505                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2506                 if (i == -1 && PyErr_Occurred())
2507                         return -1;
2508
2509                 return pyrna_prop_collection_ass_subscript_int(self, i, value);
2510         }
2511 #if 0 /* TODO, fake slice assignment */
2512         else if (PySlice_Check(key)) {
2513                 PySliceObject *key_slice = (PySliceObject *)key;
2514                 Py_ssize_t step = 1;
2515
2516                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2517                         return NULL;
2518                 }
2519                 else if (step != 1) {
2520                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2521                         return NULL;
2522                 }
2523                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2524                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2525                 }
2526                 else {
2527                         Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2528
2529                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2530                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2531                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
2532
2533                         if (start < 0 || stop < 0) {
2534                                 /* only get the length for negative values */
2535                                 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2536                                 if (start < 0) start += len;
2537                                 if (stop < 0) start += len;
2538                         }
2539
2540                         if (stop - start <= 0) {
2541                                 return PyList_New(0);
2542                         }
2543                         else {
2544                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2545                         }
2546                 }
2547         }
2548 #endif
2549         else {
2550                 PyErr_Format(PyExc_TypeError,
2551                              "bpy_prop_collection[key]: invalid key, "
2552                              "must be a string or an int, not %.200s",
2553                              Py_TYPE(key)->tp_name);
2554                 return -1;
2555         }
2556 }
2557
2558 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2559 {
2560         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2561
2562 #if 0
2563         if (PyUnicode_Check(key)) {
2564                 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2565         }
2566         else
2567 #endif
2568         if (PyIndex_Check(key)) {
2569                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2570                 if (i == -1 && PyErr_Occurred())
2571                         return NULL;
2572                 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
2573         }
2574         else if (PySlice_Check(key)) {
2575                 Py_ssize_t step = 1;
2576                 PySliceObject *key_slice = (PySliceObject *)key;
2577
2578                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2579                         return NULL;
2580                 }
2581                 else if (step != 1) {
2582                         PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2583                         return NULL;
2584                 }
2585                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2586                         /* note, no significant advantage with optimizing [:] slice as with collections
2587                          * but include here for consistency with collection slice func */
2588                         Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
2589                         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2590                 }
2591                 else {
2592                         int len = pyrna_prop_array_length(self);
2593                         Py_ssize_t start, stop, slicelength;
2594
2595                         if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0)
2596                                 return NULL;
2597
2598                         if (slicelength <= 0) {
2599                                 return PyTuple_New(0);
2600                         }
2601                         else {
2602                                 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2603                         }
2604                 }
2605         }
2606         else {
2607                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2608                 return NULL;
2609         }
2610 }
2611
2612 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
2613 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
2614                                           int start, int stop, int length, PyObject *value_orig)
2615 {
2616         PyObject *value;
2617         int count;
2618         void *values_alloc = NULL;
2619         int ret = 0;
2620
2621         if (value_orig == NULL) {
2622                 PyErr_SetString(PyExc_TypeError,
2623                                 "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
2624                 return -1;
2625         }
2626
2627         if (!(value = PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
2628                 return -1;
2629         }
2630
2631         if (PySequence_Fast_GET_SIZE(value) != stop - start) {
2632                 Py_DECREF(value);
2633                 PyErr_SetString(PyExc_TypeError,
2634                                 "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported");
2635                 return -1;
2636         }
2637
2638         switch (RNA_property_type(prop)) {
2639                 case PROP_FLOAT:
2640                 {
2641                         float values_stack[PYRNA_STACK_ARRAY];
2642                         float *values, fval;
2643
2644                         float min, max;
2645                         RNA_property_float_range(ptr, prop, &min, &max);
2646
2647                         if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(float) * length); }
2648                         else                            { values = values_stack; }
2649                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2650                                 RNA_property_float_get_array(ptr, prop, values);
2651
2652                         for (count = start; count < stop; count++) {
2653                                 fval = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count - start));
2654                                 CLAMP(fval, min, max);
2655                                 values[count] = fval;
2656                         }
2657
2658                         if (PyErr_Occurred()) ret = -1;
2659                         else                  RNA_property_float_set_array(ptr, prop, values);
2660                         break;
2661                 }
2662                 case PROP_BOOLEAN:
2663                 {
2664                         int values_stack[PYRNA_STACK_ARRAY];
2665                         int *values;
2666                         if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); }
2667                         else                            { values = values_stack; }
2668
2669                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2670                                 RNA_property_boolean_get_array(ptr, prop, values);
2671
2672                         for (count = start; count < stop; count++)
2673                                 values[count] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count - start));
2674
2675                         if (PyErr_Occurred()) ret = -1;
2676                         else                  RNA_property_boolean_set_array(ptr, prop, values);
2677                         break;
2678                 }
2679                 case PROP_INT:
2680                 {
2681                         int values_stack[PYRNA_STACK_ARRAY];
2682                         int *values, ival;
2683
2684                         int min, max;
2685                         RNA_property_int_range(ptr, prop, &min, &max);
2686
2687                         if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); }
2688                         else                            { values = values_stack; }
2689
2690                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2691                                 RNA_property_int_get_array(ptr, prop, values);
2692
2693                         for (count = start; count < stop; count++) {
2694                                 ival = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count - start));
2695                                 CLAMP(ival, min, max);
2696                                 values[count] = ival;
2697                         }
2698
2699                         if (PyErr_Occurred()) ret = -1;
2700                         else                  RNA_property_int_set_array(ptr, prop, values);
2701                         break;
2702                 }
2703                 default:
2704                         PyErr_SetString(PyExc_TypeError, "not an array type");
2705                         ret = -1;
2706         }
2707
2708         Py_DECREF(value);
2709
2710         if (values_alloc) {
2711                 PyMem_FREE(values_alloc);
2712         }
2713
2714         return ret;
2715
2716 }
2717
2718 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
2719 {
2720         int len;
2721
2722         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2723
2724         len = pyrna_prop_array_length(self);
2725
2726         if (keynum < 0) keynum += len;
2727
2728         if (keynum >= 0 && keynum < len)
2729                 return pyrna_py_to_prop_array_index(self, keynum, value);
2730
2731         PyErr_SetString(PyExc_IndexError,
2732                         "bpy_prop_array[index] = value: index out of range");
2733         return -1;
2734 }
2735
2736 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
2737 {
2738         /* char *keyname = NULL; */ /* not supported yet */
2739         int ret = -1;
2740
2741         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2742
2743         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
2744                 PyErr_Format(PyExc_AttributeError,
2745                              "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
2746                              RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type));
2747                 ret = -1;
2748         }
2749
2750         else if (PyIndex_Check(key)) {
2751                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2752                 if (i == -1 && PyErr_Occurred()) {
2753                         ret = -1;
2754                 }
2755                 else {
2756                         ret = prop_subscript_ass_array_int(self, i, value);
2757                 }
2758         }
2759         else if (PySlice_Check(key)) {
2760                 int len = RNA_property_array_length(&self->ptr, self->prop);
2761                 Py_ssize_t start, stop, step, slicelength;
2762
2763                 if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) {
2764                         ret = -1;
2765                 }
2766                 else if (slicelength <= 0) {
2767                         ret = 0; /* do nothing */
2768                 }
2769                 else if (step == 1) {
2770                         ret = prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
2771                 }
2772                 else {
2773                         PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
2774                         ret = -1;
2775                 }
2776         }
2777         else {
2778                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
2779                 ret = -1;
2780         }
2781
2782         if (ret != -1) {
2783                 if (RNA_property_update_check(self->prop)) {
2784                         RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
2785                 }
2786         }
2787
2788         return ret;
2789 }
2790
2791 /* for slice only */
2792 static PyMappingMethods pyrna_prop_array_as_mapping = {
2793         (lenfunc) pyrna_prop_array_length,               /* mp_length */
2794         (binaryfunc) pyrna_prop_array_subscript,         /* mp_subscript */
2795         (objobjargproc) pyrna_prop_array_ass_subscript,  /* mp_ass_subscript */
2796 };
2797
2798 static PyMappingMethods pyrna_prop_collection_as_mapping = {
2799         (lenfunc) pyrna_prop_collection_length,               /* mp_length */
2800         (binaryfunc) pyrna_prop_collection_subscript,         /* mp_subscript */
2801         (objobjargproc) pyrna_prop_collection_ass_subscript,  /* mp_ass_subscript */
2802 };
2803
2804 /* only for fast bool's, large structs, assign nb_bool on init */
2805 static PyNumberMethods pyrna_prop_array_as_number = {
2806         NULL, /* nb_add */
2807         NULL, /* nb_subtract */
2808         NULL, /* nb_multiply */
2809         NULL, /* nb_remainder */
2810         NULL, /* nb_divmod */
2811         NULL, /* nb_power */
2812         NULL, /* nb_negative */
2813         NULL, /* nb_positive */
2814         NULL, /* nb_absolute */
2815         (inquiry) pyrna_prop_array_bool, /* nb_bool */
2816 };
2817 static PyNumberMethods pyrna_prop_collection_as_number = {
2818         NULL, /* nb_add */
2819         NULL, /* nb_subtract */
2820         NULL, /* nb_multiply */
2821         NULL, /* nb_remainder */
2822         NULL, /* nb_divmod */
2823         NULL, /* nb_power */
2824         NULL, /* nb_negative */
2825         NULL, /* nb_positive */
2826         NULL, /* nb_absolute */
2827         (inquiry) pyrna_prop_collection_bool, /* nb_bool */
2828 };
2829
2830 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
2831 {
2832         return pyrna_array_contains_py(&self->ptr, self->prop, value);
2833 }
2834
2835 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
2836 {
2837         PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
2838
2839         if (PyTuple_Check(key)) {
2840                 /* special case, for ID datablocks we */
2841                 return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
2842                                                                         "(id, lib) in bpy_prop_collection", FALSE, NULL);
2843         }
2844         else {
2845
2846                 /* key in dict style check */
2847                 const char *keyname = _PyUnicode_AsString(key);
2848
2849                 if (keyname == NULL) {
2850                         PyErr_SetString(PyExc_TypeError,
2851                                         "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
2852                         return -1;
2853                 }
2854
2855                 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2856                         return 1;
2857
2858                 return 0;
2859         }
2860 }
2861
2862 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
2863 {
2864         IDProperty *group;
2865         const char *name = _PyUnicode_AsString(value);
2866
2867         PYRNA_STRUCT_CHECK_INT(self);
2868
2869         if (!name) {
2870                 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
2871                 return -1;
2872         }
2873
2874         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2875                 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
2876                 return -1;
2877         }
2878
2879         group = RNA_struct_idprops(&self->ptr, 0);
2880
2881         if (!group)
2882                 return 0;
2883
2884         return IDP_GetPropertyFromGroup(group, name) ? 1 : 0;
2885 }
2886
2887 static PySequenceMethods pyrna_prop_array_as_sequence = {
2888         (lenfunc)pyrna_prop_array_length,       /* Cant set the len otherwise it can evaluate as false */
2889         NULL,       /* sq_concat */
2890         NULL,       /* sq_repeat */
2891         (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2892         NULL,       /* sq_slice */
2893         (ssizeobjargproc)prop_subscript_ass_array_int,      /* sq_ass_item */
2894         NULL,       /* *was* sq_ass_slice */
2895         (objobjproc)pyrna_prop_array_contains,  /* sq_contains */
2896         (binaryfunc) NULL, /* sq_inplace_concat */
2897         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2898 };
2899
2900 static PySequenceMethods pyrna_prop_collection_as_sequence = {
2901         (lenfunc)pyrna_prop_collection_length,      /* Cant set the len otherwise it can evaluate as false */
2902         NULL,       /* sq_concat */
2903         NULL,       /* sq_repeat */
2904         (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2905         NULL,       /* *was* sq_slice */
2906         (ssizeobjargproc)/* pyrna_prop_collection_ass_subscript_int */ NULL /* let mapping take this one */, /* sq_ass_item */
2907         NULL,       /* *was* sq_ass_slice */
2908         (objobjproc)pyrna_prop_collection_contains, /* sq_contains */
2909         (binaryfunc) NULL, /* sq_inplace_concat */
2910         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2911 };
2912
2913 static PySequenceMethods pyrna_struct_as_sequence = {
2914         NULL,       /* Cant set the len otherwise it can evaluate as false */
2915         NULL,       /* sq_concat */
2916         NULL,       /* sq_repeat */
2917         NULL,       /* sq_item */ /* Only set this so PySequence_Check() returns True */
2918         NULL,       /* *was* sq_slice */
2919         NULL,       /* sq_ass_item */
2920         NULL,       /* *was* sq_ass_slice */
2921         (objobjproc)pyrna_struct_contains,  /* sq_contains */
2922         (binaryfunc) NULL, /* sq_inplace_concat */
2923         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2924 };
2925
2926 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
2927 {
2928         /* mostly copied from BPy_IDGroup_Map_GetItem */
2929         IDProperty *group, *idprop;
2930         const char *name = _PyUnicode_AsString(key);
2931
2932         PYRNA_STRUCT_CHECK_OBJ(self);
2933
2934         if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2935                 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
2936                 return NULL;
2937         }
2938
2939         if (name == NULL) {
2940                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
2941                 return NULL;
2942         }
2943
2944         group = RNA_struct_idprops(&self->ptr, 0);
2945
2946         if (group == NULL) {
2947                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2948                 return NULL;
2949         }
2950
2951         idprop = IDP_GetPropertyFromGroup(group, name);
2952
2953         if (idprop == NULL) {
2954                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2955                 return NULL;
2956         }
2957
2958         return BPy_IDGroup_WrapData(self->ptr.id.data, idprop, group);
2959 }
2960
2961 static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
2962 {
2963         IDProperty *group;
2964
2965         PYRNA_STRUCT_CHECK_INT(self);
2966
2967         group = RNA_struct_idprops(&self->ptr, 1);
2968
2969 #ifdef USE_PEDANTIC_WRITE
2970         if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
2971                 return -1;
2972         }
2973 #endif // USE_PEDANTIC_WRITE
2974
2975         if (group == NULL) {
2976                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
2977                 return -1;
2978         }
2979
2980         return BPy_Wrap_SetMapItem(group, key, value);
2981 }
2982
2983 static PyMappingMethods pyrna_struct_as_mapping = {
2984         (lenfunc) NULL,                             /* mp_length */