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