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