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