formatting edits in py api, no functional changes
[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)->contigPtr);
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)->contigPtr);
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_TypeError,
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 static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
747 {
748         return (a->ptr.data==b->ptr.data) ? 0 : -1;
749 }
750
751 static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
752 {
753         return (a->prop==b->prop && a->ptr.data==b->ptr.data) ? 0 : -1;
754 }
755
756 static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
757 {
758         PyObject *res;
759         int ok= -1; /* zero is true */
760
761         if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b))
762                 ok= pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
763
764         switch (op) {
765         case Py_NE:
766                 ok= !ok; /* pass through */
767         case Py_EQ:
768                 res= ok ? Py_False : Py_True;
769                 break;
770
771         case Py_LT:
772         case Py_LE:
773         case Py_GT:
774         case Py_GE:
775                 res= Py_NotImplemented;
776                 break;
777         default:
778                 PyErr_BadArgument();
779                 return NULL;
780         }
781
782         return Py_INCREF(res), res;
783 }
784
785 static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
786 {
787         PyObject *res;
788         int ok= -1; /* zero is true */
789
790         if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b))
791                 ok= pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
792
793         switch (op) {
794         case Py_NE:
795                 ok= !ok; /* pass through */
796         case Py_EQ:
797                 res= ok ? Py_False : Py_True;
798                 break;
799
800         case Py_LT:
801         case Py_LE:
802         case Py_GT:
803         case Py_GE:
804                 res= Py_NotImplemented;
805                 break;
806         default:
807                 PyErr_BadArgument();
808                 return NULL;
809         }
810
811         return Py_INCREF(res), res;
812 }
813
814 /*----------------------repr--------------------------------------------*/
815 static PyObject *pyrna_struct_str(BPy_StructRNA *self)
816 {
817         PyObject *ret;
818         const char *name;
819
820         if (!PYRNA_STRUCT_IS_VALID(self)) {
821                 return PyUnicode_FromFormat("<bpy_struct, %.200s dead>",
822                                             Py_TYPE(self)->tp_name);
823         }
824
825         /* print name if available */
826         name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
827         if (name) {
828                 ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>",
829                                           RNA_struct_identifier(self->ptr.type),
830                                           name);
831                 MEM_freeN((void *)name);
832                 return ret;
833         }
834
835         return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>",
836                                     RNA_struct_identifier(self->ptr.type),
837                                     self->ptr.data);
838 }
839
840 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
841 {
842         ID *id= self->ptr.id.data;
843         PyObject *tmp_str;
844         PyObject *ret;
845
846         if (id == NULL || !PYRNA_STRUCT_IS_VALID(self))
847                 return pyrna_struct_str(self); /* fallback */
848
849         tmp_str= PyUnicode_FromString(id->name+2);
850
851         if (RNA_struct_is_ID(self->ptr.type)) {
852                 ret= PyUnicode_FromFormat("bpy.data.%s[%R]",
853                                             BKE_idcode_to_name_plural(GS(id->name)),
854                                             tmp_str);
855         }
856         else {
857                 const char *path;
858                 path= RNA_path_from_ID_to_struct(&self->ptr);
859                 if (path) {
860                         ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s",
861                                                   BKE_idcode_to_name_plural(GS(id->name)),
862                                                   tmp_str,
863                                                   path);
864                         MEM_freeN((void *)path);
865                 }
866                 else { /* cant find, print something sane */
867                         ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
868                                                   BKE_idcode_to_name_plural(GS(id->name)),
869                                                   tmp_str,
870                                                   RNA_struct_identifier(self->ptr.type));
871                 }
872         }
873
874         Py_DECREF(tmp_str);
875
876         return ret;
877 }
878
879 static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
880 {
881         PyObject *ret;
882         PointerRNA ptr;
883         const char *name;
884         const char *type_id= NULL;
885         char type_fmt[64]= "";
886         int type;
887
888         PYRNA_PROP_CHECK_OBJ(self);
889
890         type= RNA_property_type(self->prop);
891
892         if (RNA_enum_id_from_value(property_type_items, type, &type_id)==0) {
893                 PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */
894                 return NULL;
895         }
896         else {
897                 /* this should never fail */
898                 int len= -1;
899                 char *c= type_fmt;
900
901                 while ((*c++= tolower(*type_id++))) {} ;
902
903                 if (type==PROP_COLLECTION) {
904                         len= pyrna_prop_collection_length(self);
905                 }
906                 else if (RNA_property_array_check(self->prop)) {
907                         len= pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
908                 }
909
910                 if (len != -1)
911                         sprintf(--c, "[%d]", len);
912         }
913
914         /* if a pointer, try to print name of pointer target too */
915         if (type == PROP_POINTER) {
916                 ptr= RNA_property_pointer_get(&self->ptr, self->prop);
917                 name= RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
918
919                 if (name) {
920                         ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
921                                                   type_fmt,
922                                                   RNA_struct_identifier(self->ptr.type),
923                                                   RNA_property_identifier(self->prop),
924                                                   name);
925                         MEM_freeN((void *)name);
926                         return ret;
927                 }
928         }
929         if (type == PROP_COLLECTION) {
930                 PointerRNA r_ptr;
931                 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
932                         return PyUnicode_FromFormat("<bpy_%.200s, %.200s>",
933                                                     type_fmt,
934                                                     RNA_struct_identifier(r_ptr.type));
935                 }
936         }
937
938         return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>",
939                                     type_fmt,
940                                     RNA_struct_identifier(self->ptr.type),
941                                     RNA_property_identifier(self->prop));
942 }
943
944 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
945 {
946         ID *id= self->ptr.id.data;
947         PyObject *tmp_str;
948         PyObject *ret;
949         const char *path;
950
951         PYRNA_PROP_CHECK_OBJ(self);
952
953         if (id == NULL)
954                 return pyrna_prop_str(self); /* fallback */
955
956         tmp_str= PyUnicode_FromString(id->name+2);
957
958         path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
959         if (path) {
960                 ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s",
961                                           BKE_idcode_to_name_plural(GS(id->name)),
962                                           tmp_str,
963                                           path);
964                 MEM_freeN((void *)path);
965         }
966         else { /* cant find, print something sane */
967                 ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
968                                           BKE_idcode_to_name_plural(GS(id->name)),
969                                           tmp_str,
970                                           RNA_property_identifier(self->prop));
971         }
972
973         Py_DECREF(tmp_str);
974
975         return ret;
976 }
977
978
979 static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
980 {
981         return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
982                                     Py_TYPE(self)->tp_name,
983                                     RNA_struct_identifier(self->ptr.type),
984                                     RNA_function_identifier(self->func));
985 }
986
987
988 static long pyrna_struct_hash(BPy_StructRNA *self)
989 {
990         return _Py_HashPointer(self->ptr.data);
991 }
992
993 /* from python's meth_hash v3.1.2 */
994 static long pyrna_prop_hash(BPy_PropertyRNA *self)
995 {
996         long x, y;
997         if (self->ptr.data == NULL)
998                 x= 0;
999         else {
1000                 x= _Py_HashPointer(self->ptr.data);
1001                 if (x == -1)
1002                         return -1;
1003         }
1004         y= _Py_HashPointer((void*)(self->prop));
1005         if (y == -1)
1006                 return -1;
1007         x ^= y;
1008         if (x == -1)
1009                 x= -2;
1010         return x;
1011 }
1012
1013 #ifdef USE_PYRNA_STRUCT_REFERENCE
1014 static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1015 {
1016         Py_VISIT(self->reference);
1017         return 0;
1018 }
1019
1020 static int pyrna_struct_clear(BPy_StructRNA *self)
1021 {
1022         Py_CLEAR(self->reference);
1023         return 0;
1024 }
1025 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1026
1027 /* use our own dealloc so we can free a property if we use one */
1028 static void pyrna_struct_dealloc(BPy_StructRNA *self)
1029 {
1030 #ifdef PYRNA_FREE_SUPPORT
1031         if (self->freeptr && self->ptr.data) {
1032                 IDP_FreeProperty(self->ptr.data);
1033                 MEM_freeN(self->ptr.data);
1034                 self->ptr.data= NULL;
1035         }
1036 #endif /* PYRNA_FREE_SUPPORT */
1037
1038 #ifdef USE_WEAKREFS
1039         if (self->in_weakreflist != NULL) {
1040                 PyObject_ClearWeakRefs((PyObject *)self);
1041         }
1042 #endif
1043
1044 #ifdef USE_PYRNA_STRUCT_REFERENCE
1045         if (self->reference) {
1046                 PyObject_GC_UnTrack(self);
1047                 pyrna_struct_clear(self);
1048         }
1049 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1050
1051         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1052         Py_TYPE(self)->tp_free(self);
1053 }
1054
1055 #ifdef USE_PYRNA_STRUCT_REFERENCE
1056 static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1057 {
1058         if (self->reference) {
1059 //              PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED? */
1060                 pyrna_struct_clear(self);
1061         }
1062         /* reference is now NULL */
1063
1064         if (reference) {
1065                 self->reference= reference;
1066                 Py_INCREF(reference);
1067 //              PyObject_GC_Track(self);  /* INITIALIZED TRACKED? */
1068         }
1069 }
1070 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1071
1072 /* use our own dealloc so we can free a property if we use one */
1073 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
1074 {
1075 #ifdef USE_WEAKREFS
1076         if (self->in_weakreflist != NULL) {
1077                 PyObject_ClearWeakRefs((PyObject *)self);
1078         }
1079 #endif
1080         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1081         Py_TYPE(self)->tp_free(self);
1082 }
1083
1084 static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
1085 {
1086 #ifdef USE_WEAKREFS
1087         if (self->in_weakreflist != NULL) {
1088                 PyObject_ClearWeakRefs((PyObject *)self);
1089         }
1090 #endif
1091         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1092         Py_TYPE(self)->tp_free(self);
1093 }
1094
1095 static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
1096 {
1097         EnumPropertyItem *item;
1098         const char *result;
1099         int free= FALSE;
1100
1101         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1102         if (item) {
1103                 result= BPy_enum_as_string(item);
1104         }
1105         else {
1106                 result= "";
1107         }
1108
1109         if (free)
1110                 MEM_freeN(item);
1111
1112         return result;
1113 }
1114
1115
1116 static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
1117 {
1118         const char *param= _PyUnicode_AsString(item);
1119
1120         if (param==NULL) {
1121                 const char *enum_str= pyrna_enum_as_string(ptr, prop);
1122                 PyErr_Format(PyExc_TypeError,
1123                              "%.200s expected a string enum type in (%.200s)",
1124                              error_prefix, enum_str);
1125                 MEM_freeN((void *)enum_str);
1126                 return 0;
1127         }
1128         else {
1129                 /* hack so that dynamic enums used for operator properties will be able to be built (i.e. context will be supplied to itemf)
1130                  * and thus running defining operator buttons for such operators in UI will work */
1131                 RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
1132
1133                 if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
1134                         const char *enum_str= pyrna_enum_as_string(ptr, prop);
1135                         PyErr_Format(PyExc_TypeError,
1136                                      "%.200s enum \"%.200s\" not found in (%.200s)",
1137                                      error_prefix, param, enum_str);
1138                         MEM_freeN((void *)enum_str);
1139                         return 0;
1140                 }
1141         }
1142
1143         return 1;
1144 }
1145
1146 /* 'value' _must_ be a set type, error check before calling */
1147 int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
1148 {
1149         /* set of enum items, concatenate all values with OR */
1150         int ret, flag= 0;
1151
1152         /* set looping */
1153         Py_ssize_t pos= 0;
1154         Py_ssize_t hash= 0;
1155         PyObject *key;
1156
1157         *r_value= 0;
1158
1159         while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1160                 const char *param= _PyUnicode_AsString(key);
1161
1162                 if (param==NULL) {
1163                         PyErr_Format(PyExc_TypeError,
1164                                      "%.200s expected a string, not %.200s",
1165                                      error_prefix, Py_TYPE(key)->tp_name);
1166                         return -1;
1167                 }
1168
1169                 if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
1170                         return -1;
1171                 }
1172
1173                 flag |= ret;
1174         }
1175
1176         *r_value= flag;
1177         return 0;
1178 }
1179
1180 static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1181 {
1182         EnumPropertyItem *item;
1183         int ret;
1184         int free= FALSE;
1185
1186         *r_value= 0;
1187
1188         if (!PyAnySet_Check(value)) {
1189                 PyErr_Format(PyExc_TypeError,
1190                              "%.200s, %.200s.%.200s expected a set, not a %.200s",
1191                              error_prefix, RNA_struct_identifier(ptr->type),
1192                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1193                 return -1;
1194         }
1195
1196         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1197
1198         if (item) {
1199                 ret= pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix);
1200         }
1201         else {
1202                 if (PySet_GET_SIZE(value)) {
1203                         PyErr_Format(PyExc_TypeError,
1204                                      "%.200s: empty enum \"%.200s\" could not have any values assigned",
1205                                      error_prefix, RNA_property_identifier(prop));
1206                         ret= -1;
1207                 }
1208                 else {
1209                         ret= 0;
1210                 }
1211         }
1212
1213         if (free)
1214                 MEM_freeN(item);
1215
1216         return ret;
1217 }
1218
1219 PyObject *pyrna_enum_bitfield_to_py(EnumPropertyItem *items, int value)
1220 {
1221         PyObject *ret= PySet_New(NULL);
1222         const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1223
1224         if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
1225                 PyObject *item;
1226                 int index;
1227                 for (index=0; identifier[index]; index++) {
1228                         item= PyUnicode_FromString(identifier[index]);
1229                         PySet_Add(ret, item);
1230                         Py_DECREF(item);
1231                 }
1232         }
1233
1234         return ret;
1235 }
1236
1237 static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1238 {
1239         PyObject *item, *ret= NULL;
1240
1241         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1242                 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1243
1244                 ret= PySet_New(NULL);
1245
1246                 if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) {
1247                         int index;
1248
1249                         for (index=0; identifier[index]; index++) {
1250                                 item= PyUnicode_FromString(identifier[index]);
1251                                 PySet_Add(ret, item);
1252                                 Py_DECREF(item);
1253                         }
1254
1255                 }
1256         }
1257         else {
1258                 const char *identifier;
1259                 if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) {
1260                         ret= PyUnicode_FromString(identifier);
1261                 }
1262                 else {
1263                         EnumPropertyItem *enum_item;
1264                         int free= FALSE;
1265
1266                         /* don't throw error here, can't trust blender 100% to give the
1267                          * right values, python code should not generate error for that */
1268                         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &enum_item, NULL, &free);
1269                         if (enum_item && enum_item->identifier) {
1270                                 ret= PyUnicode_FromString(enum_item->identifier);
1271                         }
1272                         else {
1273                                 const char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
1274
1275                                 /* prefer not fail silently incase of api errors, maybe disable it later */
1276                                 printf("RNA Warning: Current value \"%d\" "
1277                                            "matches no enum in '%s', '%s', '%s'\n",
1278                                            val, RNA_struct_identifier(ptr->type),
1279                                            ptr_name, RNA_property_identifier(prop));
1280
1281 #if 0                   // gives python decoding errors while generating docs :(
1282                                 char error_str[256];
1283                                 BLI_snprintf(error_str, sizeof(error_str),
1284                                                          "RNA Warning: Current value \"%d\" "
1285                                                          "matches no enum in '%s', '%s', '%s'",
1286                                                          val, RNA_struct_identifier(ptr->type),
1287                                                          ptr_name, RNA_property_identifier(prop));
1288
1289                                 PyErr_Warn(PyExc_RuntimeWarning, error_str);
1290 #endif
1291
1292                                 if (ptr_name)
1293                                         MEM_freeN((void *)ptr_name);
1294
1295                                 ret= PyUnicode_FromString("");
1296                         }
1297
1298                         if (free)
1299                                 MEM_freeN(enum_item);
1300                         /*
1301                         PyErr_Format(PyExc_AttributeError,
1302                                      "RNA Error: Current value \"%d\" matches no enum", val);
1303                         ret= NULL;
1304                         */
1305                 }
1306         }
1307
1308         return ret;
1309 }
1310
1311 PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
1312 {
1313         PyObject *ret;
1314         const int type= RNA_property_type(prop);
1315
1316         if (RNA_property_array_check(prop)) {
1317                 return pyrna_py_from_array(ptr, prop);
1318         }
1319
1320         /* see if we can coorce into a python type - PropertyType */
1321         switch (type) {
1322         case PROP_BOOLEAN:
1323                 ret= PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1324                 break;
1325         case PROP_INT:
1326                 ret= PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop));
1327                 break;
1328         case PROP_FLOAT:
1329                 ret= PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1330                 break;
1331         case PROP_STRING:
1332         {
1333                 const int subtype= RNA_property_subtype(prop);
1334                 const char *buf;
1335                 int buf_len;
1336                 char buf_fixed[32];
1337
1338                 buf= RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1339 #ifdef USE_STRING_COERCE
1340                 /* only file paths get special treatment, they may contain non utf-8 chars */
1341                 if (subtype == PROP_BYTESTRING) {
1342                         ret= PyBytes_FromStringAndSize(buf, buf_len);
1343                 }
1344                 else if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1345                         ret= PyC_UnicodeFromByteAndSize(buf, buf_len);
1346                 }
1347                 else {
1348                         ret= PyUnicode_FromStringAndSize(buf, buf_len);
1349                 }
1350 #else // USE_STRING_COERCE
1351                 if (subtype == PROP_BYTESTRING) {
1352                         ret= PyBytes_FromStringAndSize(buf, buf_len);
1353                 }
1354                 else {
1355                         ret= PyUnicode_FromStringAndSize(buf, buf_len);
1356                 }
1357 #endif // USE_STRING_COERCE
1358                 if (buf_fixed != buf) {
1359                         MEM_freeN((void *)buf);
1360                 }
1361                 break;
1362         }
1363         case PROP_ENUM:
1364         {
1365                 ret= pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop));
1366                 break;
1367         }
1368         case PROP_POINTER:
1369         {
1370                 PointerRNA newptr;
1371                 newptr= RNA_property_pointer_get(ptr, prop);
1372                 if (newptr.data) {
1373                         ret= pyrna_struct_CreatePyObject(&newptr);
1374                 }
1375                 else {
1376                         ret= Py_None;
1377                         Py_INCREF(ret);
1378                 }
1379                 break;
1380         }
1381         case PROP_COLLECTION:
1382                 ret= pyrna_prop_CreatePyObject(ptr, prop);
1383                 break;
1384         default:
1385                 PyErr_Format(PyExc_TypeError,
1386                              "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", type);
1387                 ret= NULL;
1388                 break;
1389         }
1390
1391         return ret;
1392 }
1393
1394 /* This function is used by operators and converting dicts into collections.
1395  * Its takes keyword args and fills them with property values */
1396 int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix)
1397 {
1398         int error_val= 0;
1399         int totkw;
1400         const char *arg_name= NULL;
1401         PyObject *item;
1402
1403         totkw= kw ? PyDict_Size(kw):0;
1404
1405         RNA_STRUCT_BEGIN(ptr, prop) {
1406                 arg_name= RNA_property_identifier(prop);
1407
1408                 if (strcmp(arg_name, "rna_type")==0) continue;
1409
1410                 if (kw==NULL) {
1411                         PyErr_Format(PyExc_TypeError,
1412                                      "%.200s: no keywords, expected \"%.200s\"",
1413                                      error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1414                         error_val= -1;
1415                         break;
1416                 }
1417
1418                 item= PyDict_GetItemString(kw, arg_name); /* wont set an error */
1419
1420                 if (item == NULL) {
1421                         if (all_args) {
1422                                 PyErr_Format(PyExc_TypeError,
1423                                              "%.200s: keyword \"%.200s\" missing",
1424                                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1425                                 error_val= -1; /* pyrna_py_to_prop sets the error */
1426                                 break;
1427                         }
1428                 }
1429                 else {
1430                         if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1431                                 error_val= -1;
1432                                 break;
1433                         }
1434                         totkw--;
1435                 }
1436         }
1437         RNA_STRUCT_END;
1438
1439         if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */
1440                 PyObject *key, *value;
1441                 Py_ssize_t pos= 0;
1442
1443                 while (PyDict_Next(kw, &pos, &key, &value)) {
1444                         arg_name= _PyUnicode_AsString(key);
1445                         if (RNA_struct_find_property(ptr, arg_name) == NULL) break;
1446                         arg_name= NULL;
1447                 }
1448
1449                 PyErr_Format(PyExc_TypeError,
1450                              "%.200s: keyword \"%.200s\" unrecognized",
1451                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1452                 error_val= -1;
1453         }
1454
1455         return error_val;
1456 }
1457
1458
1459 static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
1460 {
1461         BPy_FunctionRNA* pyfunc= (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1462         pyfunc->ptr= *ptr;
1463         pyfunc->func= func;
1464         return (PyObject *)pyfunc;
1465 }
1466
1467
1468 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1469 {
1470         /* XXX hard limits should be checked here */
1471         const int type= RNA_property_type(prop);
1472
1473
1474         if (RNA_property_array_check(prop)) {
1475                 /* done getting the length */
1476                 if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1477                         return -1;
1478                 }
1479         }
1480         else {
1481                 /* Normal Property (not an array) */
1482
1483                 /* see if we can coorce into a python type - PropertyType */
1484                 switch (type) {
1485                 case PROP_BOOLEAN:
1486                 {
1487                         int param;
1488                         /* prefer not to have an exception here
1489                          * however so many poll functions return None or a valid Object.
1490                          * its a hassle to convert these into a bool before returning, */
1491                         if (RNA_property_flag(prop) & PROP_OUTPUT)
1492                                 param= PyObject_IsTrue(value);
1493                         else
1494                                 param= PyLong_AsLong(value);
1495
1496                         if (param < 0) {
1497                                 PyErr_Format(PyExc_TypeError,
1498                                              "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1499                                              error_prefix, RNA_struct_identifier(ptr->type),
1500                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1501                                 return -1;
1502                         }
1503                         else {
1504                                 if (data)  *((int*)data)= param;
1505                                 else       RNA_property_boolean_set(ptr, prop, param);
1506                         }
1507                         break;
1508                 }
1509                 case PROP_INT:
1510                 {
1511                         int overflow;
1512                         long param= PyLong_AsLongAndOverflow(value, &overflow);
1513                         if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1514                                 PyErr_Format(PyExc_ValueError,
1515                                              "%.200s %.200s.%.200s value not in 'int' range "
1516                                              "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1517                                              error_prefix, RNA_struct_identifier(ptr->type),
1518                                              RNA_property_identifier(prop));
1519                                 return -1;
1520                         }
1521                         else if (param==-1 && PyErr_Occurred()) {
1522                                 PyErr_Format(PyExc_TypeError,
1523                                              "%.200s %.200s.%.200s expected an int type, not %.200s",
1524                                              error_prefix, RNA_struct_identifier(ptr->type),
1525                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1526                                 return -1;
1527                         }
1528                         else {
1529                                 int param_i= (int)param;
1530                                 RNA_property_int_clamp(ptr, prop, &param_i);
1531                                 if (data)  *((int*)data)= param_i;
1532                                 else       RNA_property_int_set(ptr, prop, param_i);
1533                         }
1534                         break;
1535                 }
1536                 case PROP_FLOAT:
1537                 {
1538                         float param= PyFloat_AsDouble(value);
1539                         if (PyErr_Occurred()) {
1540                                 PyErr_Format(PyExc_TypeError,
1541                                              "%.200s %.200s.%.200s expected a float type, not %.200s",
1542                                              error_prefix, RNA_struct_identifier(ptr->type),
1543                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1544                                 return -1;
1545                         }
1546                         else {
1547                                 RNA_property_float_clamp(ptr, prop, (float *)&param);
1548                                 if (data)   *((float*)data)= param;
1549                                 else        RNA_property_float_set(ptr, prop, param);
1550                         }
1551                         break;
1552                 }
1553                 case PROP_STRING:
1554                 {
1555                         const int subtype= RNA_property_subtype(prop);
1556                         const char *param;
1557
1558                         if (subtype == PROP_BYTESTRING) {
1559
1560                                 /* Byte String */
1561
1562                                 param= PyBytes_AsString(value);
1563
1564                                 if (param==NULL) {
1565                                         if (PyBytes_Check(value)) {
1566                                                 /* there was an error assigning a string type,
1567                                                  * rather than setting a new error, prefix the existing one
1568                                                  */
1569                                                 PyC_Err_Format_Prefix(PyExc_TypeError,
1570                                                                       "%.200s %.200s.%.200s error assigning bytes",
1571                                                                       error_prefix, RNA_struct_identifier(ptr->type),
1572                                                                       RNA_property_identifier(prop));
1573                                         }
1574                                         else {
1575                                                 PyErr_Format(PyExc_TypeError,
1576                                                              "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1577                                                              error_prefix, RNA_struct_identifier(ptr->type),
1578                                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1579                                         }
1580
1581                                         return -1;
1582                                 }
1583                                 else {
1584                                         /* same as unicode */
1585                                         if (data)   *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1586                                         else        RNA_property_string_set(ptr, prop, param);
1587                                 }
1588                         }
1589                         else {
1590
1591                                 /* Unicode String */
1592
1593 #ifdef USE_STRING_COERCE
1594                                 PyObject *value_coerce= NULL;
1595                                 if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1596                                         /* TODO, get size */
1597                                         param= PyC_UnicodeAsByte(value, &value_coerce);
1598                                 }
1599                                 else {
1600                                         param= _PyUnicode_AsString(value);
1601 #ifdef WITH_INTERNATIONAL
1602                                         if (subtype == PROP_TRANSLATE) {
1603                                                 param= IFACE_(param);
1604                                         }
1605 #endif // WITH_INTERNATIONAL
1606
1607                                 }
1608 #else // USE_STRING_COERCE
1609                                 param= _PyUnicode_AsString(value);
1610 #endif // USE_STRING_COERCE
1611
1612                                 if (param==NULL) {
1613                                         if (PyUnicode_Check(value)) {
1614                                                 /* there was an error assigning a string type,
1615                                                  * rather than setting a new error, prefix the existing one
1616                                                  */
1617                                                 PyC_Err_Format_Prefix(PyExc_TypeError,
1618                                                                       "%.200s %.200s.%.200s error assigning string",
1619                                                                       error_prefix, RNA_struct_identifier(ptr->type),
1620                                                                       RNA_property_identifier(prop));
1621                                         }
1622                                         else {
1623                                                 PyErr_Format(PyExc_TypeError,
1624                                                              "%.200s %.200s.%.200s expected a string type, not %.200s",
1625                                                              error_prefix, RNA_struct_identifier(ptr->type),
1626                                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1627                                         }
1628
1629                                         return -1;
1630                                 }
1631                                 else {
1632                                         /* same as bytes */
1633                                         if (data)   *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1634                                         else        RNA_property_string_set(ptr, prop, param);
1635                                 }
1636 #ifdef USE_STRING_COERCE
1637                                 Py_XDECREF(value_coerce);
1638 #endif // USE_STRING_COERCE
1639                         }
1640                         break;
1641                 }
1642                 case PROP_ENUM:
1643                 {
1644                         int val= 0;
1645
1646                         /* type checkins is done by each function */
1647                         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1648                                 /* set of enum items, concatenate all values with OR */
1649                                 if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
1650                                         return -1;
1651                                 }
1652                         }
1653                         else {
1654                                 /* simple enum string */
1655                                 if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
1656                                         return -1;
1657                                 }
1658                         }
1659
1660                         if (data)  *((int*)data)= val;
1661                         else       RNA_property_enum_set(ptr, prop, val);
1662
1663                         break;
1664                 }
1665                 case PROP_POINTER:
1666                 {
1667                         PyObject *value_new= NULL;
1668
1669                         StructRNA *ptr_type= RNA_property_pointer_type(ptr, prop);
1670                         int flag= RNA_property_flag(prop);
1671
1672                         /* this is really nasty!, so we can fake the operator having direct properties eg:
1673                          * layout.prop(self, "filepath")
1674                          * ... which infact should be
1675                          * layout.prop(self.properties, "filepath")
1676                          *
1677                          * we need to do this trick.
1678                          * if the prop is not an operator type and the pyobject is an operator, use its properties in place of its self.
1679                          *
1680                          * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing
1681                          * if this causes problems in the future it should be removed.
1682                          */
1683                         if ((ptr_type == &RNA_AnyType) &&
1684                                 (BPy_StructRNA_Check(value)) &&
1685                                 (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator))
1686                         ) {
1687                                 value= PyObject_GetAttrString(value, "properties");
1688                                 value_new= value;
1689                         }
1690
1691
1692                         /* if property is an OperatorProperties pointer and value is a map, forward back to pyrna_pydict_to_props */
1693                         if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) {
1694                                 PointerRNA opptr= RNA_property_pointer_get(ptr, prop);
1695                                 return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
1696                         }
1697
1698                         /* another exception, allow to pass a collection as an RNA property */
1699                         if (Py_TYPE(value)==&pyrna_prop_collection_Type) { /* ok to ignore idprop collections */
1700                                 PointerRNA c_ptr;
1701                                 BPy_PropertyRNA *value_prop= (BPy_PropertyRNA *)value;
1702                                 if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1703                                         value= pyrna_struct_CreatePyObject(&c_ptr);
1704                                         value_new= value;
1705                                 }
1706                                 else {
1707                                         PyErr_Format(PyExc_TypeError,
1708                                                      "%.200s %.200s.%.200s collection has no type, "
1709                                                      "cant be used as a %.200s type",
1710                                                      error_prefix, RNA_struct_identifier(ptr->type),
1711                                                      RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1712                                         return -1;
1713                                 }
1714                         }
1715
1716                         if (!BPy_StructRNA_Check(value) && value != Py_None) {
1717                                 PyErr_Format(PyExc_TypeError,
1718                                              "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1719                                              error_prefix, RNA_struct_identifier(ptr->type),
1720                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type),
1721                                              Py_TYPE(value)->tp_name);
1722                                 Py_XDECREF(value_new); return -1;
1723                         }
1724                         else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
1725                                 PyErr_Format(PyExc_TypeError,
1726                                              "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1727                                              error_prefix, RNA_struct_identifier(ptr->type),
1728                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1729                                 Py_XDECREF(value_new); return -1;
1730                         }
1731                         else if (value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
1732                                 PyErr_Format(PyExc_TypeError,
1733                                              "%.200s %.200s.%.200s ID type does not support assignment to its self",
1734                                              error_prefix, RNA_struct_identifier(ptr->type),
1735                                              RNA_property_identifier(prop));
1736                                 Py_XDECREF(value_new); return -1;
1737                         }
1738                         else {
1739                                 BPy_StructRNA *param= (BPy_StructRNA*)value;
1740                                 int raise_error= FALSE;
1741                                 if (data) {
1742
1743                                         if (flag & PROP_RNAPTR) {
1744                                                 if (value == Py_None)
1745                                                         memset(data, 0, sizeof(PointerRNA));
1746                                                 else
1747                                                         *((PointerRNA*)data)= param->ptr;
1748                                         }
1749                                         else if (value == Py_None) {
1750                                                 *((void**)data)= NULL;
1751                                         }
1752                                         else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1753                                                 *((void**)data)= param->ptr.data;
1754                                         }
1755                                         else {
1756                                                 raise_error= TRUE;
1757                                         }
1758                                 }
1759                                 else {
1760                                         /* data==NULL, assign to RNA */
1761                                         if (value == Py_None) {
1762                                                 PointerRNA valueptr= {{NULL}};
1763                                                 RNA_property_pointer_set(ptr, prop, valueptr);
1764                                         }
1765                                         else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1766                                                 RNA_property_pointer_set(ptr, prop, param->ptr);
1767                                         }
1768                                         else {
1769                                                 PointerRNA tmp;
1770                                                 RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1771                                                 PyErr_Format(PyExc_TypeError,
1772                                                              "%.200s %.200s.%.200s expected a %.200s type. not %.200s",
1773                                                              error_prefix, RNA_struct_identifier(ptr->type),
1774                                                              RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1775                                                              RNA_struct_identifier(param->ptr.type));
1776                                                 Py_XDECREF(value_new); return -1;
1777                                         }
1778                                 }
1779
1780                                 if (raise_error) {
1781                                         PointerRNA tmp;
1782                                         RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1783                                         PyErr_Format(PyExc_TypeError,
1784                                                      "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1785                                                      error_prefix, RNA_struct_identifier(ptr->type),
1786                                                      RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1787                                                      RNA_struct_identifier(param->ptr.type));
1788                                         Py_XDECREF(value_new); return -1;
1789                                 }
1790                         }
1791
1792                         Py_XDECREF(value_new);
1793
1794                         break;
1795                 }
1796                 case PROP_COLLECTION:
1797                 {
1798                         Py_ssize_t seq_len, i;
1799                         PyObject *item;
1800                         PointerRNA itemptr;
1801                         ListBase *lb;
1802                         CollectionPointerLink *link;
1803
1804                         lb= (data)? (ListBase*)data: NULL;
1805
1806                         /* convert a sequence of dict's into a collection */
1807                         if (!PySequence_Check(value)) {
1808                                 PyErr_Format(PyExc_TypeError,
1809                                              "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
1810                                              error_prefix, RNA_struct_identifier(ptr->type),
1811                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1812                                 return -1;
1813                         }
1814
1815                         seq_len= PySequence_Size(value);
1816                         for (i=0; i < seq_len; i++) {
1817                                 item= PySequence_GetItem(value, i);
1818
1819                                 if (item==NULL) {
1820                                         PyErr_Format(PyExc_TypeError,
1821                                                      "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
1822                                                      error_prefix, RNA_struct_identifier(ptr->type),
1823                                                      RNA_property_identifier(prop), i);
1824                                         Py_XDECREF(item);
1825                                         return -1;
1826                                 }
1827
1828                                 if (PyDict_Check(item)==0) {
1829                                         PyErr_Format(PyExc_TypeError,
1830                                                      "%.200s %.200s.%.200s expected a each sequence "
1831                                                      "member to be a dict for an RNA collection, not %.200s",
1832                                                      error_prefix, RNA_struct_identifier(ptr->type),
1833                                                      RNA_property_identifier(prop), Py_TYPE(item)->tp_name);
1834                                         Py_XDECREF(item);
1835                                         return -1;
1836                                 }
1837
1838                                 if (lb) {
1839                                         link= MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
1840                                         link->ptr= itemptr;
1841                                         BLI_addtail(lb, link);
1842                                 }
1843                                 else
1844                                         RNA_property_collection_add(ptr, prop, &itemptr);
1845
1846                                 if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection")==-1) {
1847                                         PyObject *msg= PyC_ExceptionBuffer();
1848                                         const char *msg_char= _PyUnicode_AsString(msg);
1849
1850                                         PyErr_Format(PyExc_TypeError,
1851                                                      "%.200s %.200s.%.200s error converting a member of a collection "
1852                                                      "from a dicts into an RNA collection, failed with: %s",
1853                                                      error_prefix, RNA_struct_identifier(ptr->type),
1854                                                      RNA_property_identifier(prop), msg_char);
1855
1856                                         Py_DECREF(item);
1857                                         Py_DECREF(msg);
1858                                         return -1;
1859                                 }
1860                                 Py_DECREF(item);
1861                         }
1862
1863                         break;
1864                 }
1865                 default:
1866                         PyErr_Format(PyExc_AttributeError,
1867                                      "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
1868                                      error_prefix, RNA_struct_identifier(ptr->type),
1869                                      RNA_property_identifier(prop));
1870                         return -1;
1871                         break;
1872                 }
1873         }
1874
1875         /* Run rna property functions */
1876         if (RNA_property_update_check(prop)) {
1877                 RNA_property_update(BPy_GetContext(), ptr, prop);
1878         }
1879
1880         return 0;
1881 }
1882
1883 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
1884 {
1885         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
1886         return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
1887 }
1888
1889 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
1890 {
1891         int ret= 0;
1892         PointerRNA *ptr= &self->ptr;
1893         PropertyRNA *prop= self->prop;
1894
1895         const int totdim= RNA_property_array_dimension(ptr, prop, NULL);
1896
1897         if (totdim > 1) {
1898                 /* char error_str[512]; */
1899                 if (pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
1900                         /* error is set */
1901                         ret= -1;
1902                 }
1903         }
1904         else {
1905                 /* see if we can coerce into a python type - PropertyType */
1906                 switch (RNA_property_type(prop)) {
1907                 case PROP_BOOLEAN:
1908                         {
1909                                 int param= PyLong_AsLong(value);
1910
1911                                 if (param < 0 || param > 1) {
1912                                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1913                                         ret= -1;
1914                                 }
1915                                 else {
1916                                         RNA_property_boolean_set_index(ptr, prop, index, param);
1917                                 }
1918                                 break;
1919                         }
1920                 case PROP_INT:
1921                         {
1922                                 int param= PyLong_AsLong(value);
1923                                 if (param==-1 && PyErr_Occurred()) {
1924                                         PyErr_SetString(PyExc_TypeError, "expected an int type");
1925                                         ret= -1;
1926                                 }
1927                                 else {
1928                                         RNA_property_int_clamp(ptr, prop, &param);
1929                                         RNA_property_int_set_index(ptr, prop, index, param);
1930                                 }
1931                                 break;
1932                         }
1933                 case PROP_FLOAT:
1934                         {
1935                                 float param= PyFloat_AsDouble(value);
1936                                 if (PyErr_Occurred()) {
1937                                         PyErr_SetString(PyExc_TypeError, "expected a float type");
1938                                         ret= -1;
1939                                 }
1940                                 else {
1941                                         RNA_property_float_clamp(ptr, prop, &param);
1942                                         RNA_property_float_set_index(ptr, prop, index, param);
1943                                 }
1944                                 break;
1945                         }
1946                 default:
1947                         PyErr_SetString(PyExc_AttributeError, "not an array type");
1948                         ret= -1;
1949                         break;
1950                 }
1951         }
1952
1953         /* Run rna property functions */
1954         if (RNA_property_update_check(prop)) {
1955                 RNA_property_update(BPy_GetContext(), ptr, prop);
1956         }
1957
1958         return ret;
1959 }
1960
1961 //---------------sequence-------------------------------------------
1962 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
1963 {
1964         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
1965
1966         if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
1967                 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
1968         else
1969                 return RNA_property_array_length(&self->ptr, self->prop);
1970 }
1971
1972 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
1973 {
1974         PYRNA_PROP_CHECK_INT(self);
1975
1976         return RNA_property_collection_length(&self->ptr, self->prop);
1977 }
1978
1979 /* bool functions are for speed, so we can avoid getting the length
1980  * of 1000's of items in a linked list for eg. */
1981 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
1982 {
1983         PYRNA_PROP_CHECK_INT(self);
1984
1985         return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
1986 }
1987
1988 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
1989 {
1990         /* no callback defined, just iterate and find the nth item */
1991         CollectionPropertyIterator iter;
1992         int test;
1993
1994         PYRNA_PROP_CHECK_INT(self);
1995
1996         RNA_property_collection_begin(&self->ptr, self->prop, &iter);
1997         test= iter.valid;
1998         RNA_property_collection_end(&iter);
1999         return test;
2000 }
2001
2002
2003 /* notice getting the length of the collection is avoided unless negative
2004  * index is used or to detect internal error with a valid index.
2005  * This is done for faster lookups. */
2006 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err)                              \
2007         if (keynum < 0) {                                                         \
2008                 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2009                 if (keynum_abs < 0) {                                                 \
2010                         PyErr_Format(PyExc_IndexError,                                    \
2011                                      "bpy_prop_collection[%d]: out of range.", keynum);   \
2012                         return ret_err;                                                   \
2013                 }                                                                     \
2014         }                                                                         \
2015
2016
2017 /* internal use only */
2018 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2019 {
2020         PointerRNA newptr;
2021         Py_ssize_t keynum_abs= keynum;
2022
2023         PYRNA_PROP_CHECK_OBJ(self);
2024
2025         PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
2026
2027         if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2028                 return pyrna_struct_CreatePyObject(&newptr);
2029         }
2030         else {
2031                 const int len= RNA_property_collection_length(&self->ptr, self->prop);
2032                 if (keynum_abs >= len) {
2033                         PyErr_Format(PyExc_IndexError,
2034                                      "bpy_prop_collection[index]: "
2035                                      "index %d out of range, size %d", keynum, len);
2036                 }
2037                 else {
2038                         PyErr_Format(PyExc_RuntimeError,
2039                                      "bpy_prop_collection[index]: internal error, "
2040                                      "valid index %d given in %d sized collection but value not found",
2041                                      keynum_abs, len);
2042                 }
2043
2044                 return NULL;
2045         }
2046 }
2047
2048 /* values type must have been already checked */
2049 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
2050 {
2051         Py_ssize_t keynum_abs= keynum;
2052         const PointerRNA *ptr= (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2053
2054         PYRNA_PROP_CHECK_INT(self);
2055
2056         PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
2057
2058         if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2059                 const int len= RNA_property_collection_length(&self->ptr, self->prop);
2060                 if (keynum_abs >= len) {
2061                         PyErr_Format(PyExc_IndexError,
2062                                      "bpy_prop_collection[index] = value: "
2063                                      "index %d out of range, size %d", keynum, len);
2064                 }
2065                 else {
2066
2067                         PyErr_Format(PyExc_IndexError,
2068                                      "bpy_prop_collection[index] = value: "
2069                                      "failed assignment (unknown reason)", keynum);
2070                 }
2071                 return -1;
2072         }
2073
2074         return 0;
2075 }
2076
2077 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2078 {
2079         int len;
2080
2081         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2082
2083         len= pyrna_prop_array_length(self);
2084
2085         if (keynum < 0) keynum += len;
2086
2087         if (keynum >= 0 && keynum < len)
2088                 return pyrna_prop_array_to_py_index(self, keynum);
2089
2090         PyErr_Format(PyExc_IndexError,
2091                      "bpy_prop_array[index]: index %d out of range", keynum);
2092         return NULL;
2093 }
2094
2095 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2096 {
2097         PointerRNA newptr;
2098
2099         PYRNA_PROP_CHECK_OBJ(self);
2100
2101         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2102                 return pyrna_struct_CreatePyObject(&newptr);
2103
2104         PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2105         return NULL;
2106 }
2107 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
2108
2109 /* special case: bpy.data.objects["some_id_name", "//some_lib_name.blend"]
2110  * also for:     bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)
2111  *
2112  * note:
2113  * error codes since this is not to be called directly from python,
2114  * this matches pythons __contains__ values capi.
2115  * -1: exception set
2116  *  0: not found
2117  *  1: found */
2118 int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, PyObject *key,
2119                                                      const char *err_prefix, const short err_not_found,
2120                                                      PointerRNA *r_ptr
2121                                                      )
2122 {
2123         char *keyname;
2124
2125         /* first validate the args, all we know is that they are a tuple */
2126         if (PyTuple_GET_SIZE(key) != 2) {
2127                 PyErr_Format(PyExc_KeyError,
2128                              "%s: tuple key must be a pair, not size %d",
2129                              err_prefix, PyTuple_GET_SIZE(key));
2130                 return -1;
2131         }
2132         else if (self->ptr.type != &RNA_BlendData) {
2133                 PyErr_Format(PyExc_KeyError,
2134                              "%s: is only valid for bpy.data collections, not %.200s",
2135                              err_prefix, RNA_struct_identifier(self->ptr.type));
2136                 return -1;
2137         }
2138         else if ((keyname= _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
2139                 PyErr_Format(PyExc_KeyError,
2140                              "%s: id must be a string, not %.200s",
2141                              err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2142                 return -1;
2143         }
2144         else {
2145                 PyObject *keylib= PyTuple_GET_ITEM(key, 1);
2146                 Library *lib;
2147                 int found= FALSE;
2148
2149                 if (keylib == Py_None) {
2150                         lib= NULL;
2151                 }
2152                 else if (PyUnicode_Check(keylib)) {
2153                         Main *bmain= self->ptr.data;
2154                         const char *keylib_str= _PyUnicode_AsString(keylib);
2155                         lib= BLI_findstring(&bmain->library, keylib_str, offsetof(Library, name));
2156                         if (lib == NULL) {
2157                                 if (err_not_found) {
2158                                         PyErr_Format(PyExc_KeyError,
2159                                                                  "%s: lib name '%.240s' "
2160                                                                  "does not reference a valid library",
2161                                                                  err_prefix, keylib_str);
2162                                         return -1;
2163                                 }
2164                                 else {
2165                                         return 0;
2166                                 }
2167
2168                         }
2169                 }
2170                 else {
2171                         PyErr_Format(PyExc_KeyError,
2172                                      "%s: lib must be a sting or None, not %.200s",
2173                                      err_prefix, Py_TYPE(keylib)->tp_name);
2174                         return -1;
2175                 }
2176
2177                 /* lib is either a valid poniter or NULL,
2178                  * either way can do direct comparison with id.lib */
2179
2180                 RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
2181                         ID *id= itemptr.data; /* always an ID */
2182                         if (id->lib == lib && (strncmp(keyname, id->name+2, sizeof(id->name)-2) == 0)) {
2183                                 found= TRUE;
2184                                 if (r_ptr) {
2185                                         *r_ptr= itemptr;
2186                                 }
2187                                 break;
2188                         }
2189                 }
2190                 RNA_PROP_END;
2191
2192                 /* we may want to fail silently as with collection.get() */
2193                 if ((found == FALSE) && err_not_found) {
2194                         /* only runs for getitem access so use fixed string */
2195                         PyErr_SetString(PyExc_KeyError,
2196                                         "bpy_prop_collection[key, lib]: not found");
2197                         return -1;
2198                 }
2199                 else {
2200                         return found; /* 1 / 0, no exception */
2201                 }
2202         }
2203 }
2204
2205 static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
2206                                                               const char *err_prefix, const short err_not_found)
2207 {
2208         PointerRNA ptr;
2209         const int contains= pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
2210
2211         if (contains == 1) {
2212                 return pyrna_struct_CreatePyObject(&ptr);
2213         }
2214         else {
2215                 return NULL;
2216         }
2217 }
2218
2219
2220 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
2221 {
2222         CollectionPropertyIterator rna_macro_iter;
2223         int count= 0;
2224
2225         PyObject *list;
2226         PyObject *item;
2227
2228         PYRNA_PROP_CHECK_OBJ(self);
2229
2230         list= PyList_New(0);
2231
2232         /* first loop up-until the start */
2233         for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2234              rna_macro_iter.valid;
2235              RNA_property_collection_next(&rna_macro_iter))
2236         {
2237                 /* PointerRNA itemptr= rna_macro_iter.ptr; */
2238                 if (count == start) {
2239                         break;
2240                 }
2241                 count++;
2242         }
2243
2244         /* add items until stop */
2245         for (; rna_macro_iter.valid;
2246              RNA_property_collection_next(&rna_macro_iter))
2247         {
2248                 item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2249                 PyList_Append(list, item);
2250                 Py_DECREF(item);
2251
2252                 count++;
2253                 if (count == stop) {
2254                         break;
2255                 }
2256         }
2257
2258         RNA_property_collection_end(&rna_macro_iter);
2259
2260         return list;
2261 }
2262
2263 /* TODO - dimensions
2264  * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
2265  * since at the moment it reads (and even allocates) the entire array for each index.
2266  */
2267 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
2268                                                   Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
2269 {
2270         int count, totdim;
2271         PyObject *tuple;
2272
2273         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2274
2275         tuple= PyTuple_New(stop - start);
2276
2277         /* PYRNA_PROP_CHECK_OBJ(self); isn't needed, internal use only */
2278
2279         totdim= RNA_property_array_dimension(ptr, prop, NULL);
2280
2281         if (totdim > 1) {
2282                 for (count= start; count < stop; count++)
2283                         PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2284         }
2285         else {
2286                 switch (RNA_property_type(prop)) {
2287                 case PROP_FLOAT:
2288                         {
2289                                 float values_stack[PYRNA_STACK_ARRAY];
2290                                 float *values;
2291                                 if (length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(float) * length); }
2292                                 else                            { values= values_stack; }
2293                                 RNA_property_float_get_array(ptr, prop, values);
2294
2295                                 for (count=start; count<stop; count++)
2296                                         PyTuple_SET_ITEM(tuple, count-start, PyFloat_FromDouble(values[count]));
2297
2298                                 if (values != values_stack) {
2299                                         PyMem_FREE(values);
2300                                 }
2301                                 break;
2302                         }
2303                 case PROP_BOOLEAN:
2304                         {
2305                                 int values_stack[PYRNA_STACK_ARRAY];
2306                                 int *values;
2307                                 if (length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); }
2308                                 else                            { values= values_stack; }
2309
2310                                 RNA_property_boolean_get_array(ptr, prop, values);
2311                                 for (count=start; count<stop; count++)
2312                                         PyTuple_SET_ITEM(tuple, count-start, PyBool_FromLong(values[count]));
2313
2314                                 if (values != values_stack) {
2315                                         PyMem_FREE(values);
2316                                 }
2317                                 break;
2318                         }
2319                 case PROP_INT:
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_int_get_array(ptr, prop, values);
2327                                 for (count=start; count<stop; count++)
2328                                         PyTuple_SET_ITEM(tuple, count-start, PyLong_FromSsize_t(values[count]));
2329
2330                                 if (values != values_stack) {
2331                                         PyMem_FREE(values);
2332                                 }
2333                                 break;
2334                         }
2335                 default:
2336                         BLI_assert(!"Invalid array type");
2337
2338                         PyErr_SetString(PyExc_TypeError, "not an array type");
2339                         Py_DECREF(tuple);
2340                         tuple= NULL;
2341                 }
2342         }
2343         return tuple;
2344 }
2345
2346 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2347 {
2348         PYRNA_PROP_CHECK_OBJ(self);
2349
2350         if (PyUnicode_Check(key)) {
2351                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2352         }
2353         else if (PyIndex_Check(key)) {
2354                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2355                 if (i == -1 && PyErr_Occurred())
2356                         return NULL;
2357
2358                 return pyrna_prop_collection_subscript_int(self, i);
2359         }
2360         else if (PySlice_Check(key)) {
2361                 PySliceObject *key_slice= (PySliceObject *)key;
2362                 Py_ssize_t step= 1;
2363
2364                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2365                         return NULL;
2366                 }
2367                 else if (step != 1) {
2368                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2369                         return NULL;
2370                 }
2371                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2372                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2373                 }
2374                 else {
2375                         Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
2376
2377                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2378                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2379                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
2380
2381                         if (start < 0 || stop < 0) {
2382                                 /* only get the length for negative values */
2383                                 Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2384                                 if (start < 0) start += len;
2385                                 if (stop < 0) start += len;
2386                         }
2387
2388                         if (stop - start <= 0) {
2389                                 return PyList_New(0);
2390                         }
2391                         else {
2392                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2393                         }
2394                 }
2395         }
2396         else if (PyTuple_Check(key)) {
2397                 /* special case, for ID datablocks we */
2398                 return pyrna_prop_collection_subscript_str_lib_pair(self, key,
2399                                                                     "bpy_prop_collection[id, lib]", TRUE);
2400         }
2401         else {
2402                 PyErr_Format(PyExc_TypeError,
2403                              "bpy_prop_collection[key]: invalid key, "
2404                              "must be a string or an int, not %.200s",
2405                              Py_TYPE(key)->tp_name);
2406                 return NULL;
2407         }
2408 }
2409
2410 /* generic check to see if a PyObject is compatible with a collection
2411  * -1 on failure, 0 on success, sets the error */
2412 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2413 {
2414         StructRNA *prop_srna;
2415
2416         if (value == Py_None) {
2417                 if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2418                         PyErr_Format(PyExc_TypeError,
2419                                      "bpy_prop_collection[key] = value: invalid, "
2420                                      "this collection doesnt support None assignment");
2421                         return -1;
2422                 }
2423                 else {
2424                         return 0; /* None is OK */
2425                 }
2426         }
2427         else if (BPy_StructRNA_Check(value) == 0) {
2428                 PyErr_Format(PyExc_TypeError,
2429                              "bpy_prop_collection[key] = value: invalid, "
2430                              "expected a StructRNA type or None, not a %.200s",
2431                              Py_TYPE(value)->tp_name);
2432                 return -1;
2433         }
2434         else if ((prop_srna= RNA_property_pointer_type(&self->ptr, self->prop))) {
2435                 StructRNA *value_srna= ((BPy_StructRNA *)value)->ptr.type;
2436                 if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2437                         PyErr_Format(PyExc_TypeError,
2438                                      "bpy_prop_collection[key] = value: invalid, "
2439                                      "expected a '%.200s' type or None, not a '%.200s'",
2440                                      RNA_struct_identifier(prop_srna),
2441                                      RNA_struct_identifier(value_srna)
2442                                      );
2443                         return -1;
2444                 }
2445                 else {
2446                         return 0; /* OK, this is the correct type!*/
2447                 }
2448         }
2449
2450         PyErr_Format(PyExc_TypeError,
2451                      "bpy_prop_collection[key] = value: internal error, "
2452                      "failed to get the collection type");
2453         return -1;
2454 }
2455
2456 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2457  * large blocks commented, we may support slice/key indicies later */
2458 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
2459 {
2460         PYRNA_PROP_CHECK_INT(self);
2461
2462         /* validate the assigned value */
2463         if (value == NULL) {
2464                 PyErr_SetString(PyExc_TypeError,
2465                                 "del bpy_prop_collection[key]: not supported");
2466                 return -1;
2467         }
2468         else if (pyrna_prop_collection_type_check(self, value) == -1) {
2469                 return -1; /* exception is set */
2470         }
2471
2472 #if 0
2473         if (PyUnicode_Check(key)) {
2474                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2475         }
2476         else
2477 #endif
2478         if (PyIndex_Check(key)) {
2479                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2480                 if (i == -1 && PyErr_Occurred())
2481                         return -1;
2482
2483                 return pyrna_prop_collection_ass_subscript_int(self, i, value);
2484         }
2485 #if 0 /* TODO, fake slice assignment */
2486         else if (PySlice_Check(key)) {
2487                 PySliceObject *key_slice= (PySliceObject *)key;
2488                 Py_ssize_t step= 1;
2489
2490                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2491                         return NULL;
2492                 }
2493                 else if (step != 1) {
2494                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2495                         return NULL;
2496                 }
2497                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2498                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2499                 }
2500                 else {
2501                         Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
2502
2503                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2504                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start))       return NULL;
2505                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))          return NULL;
2506
2507                         if (start < 0 || stop < 0) {
2508                                 /* only get the length for negative values */
2509                                 Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2510                                 if (start < 0) start += len;
2511                                 if (stop < 0) start += len;
2512                         }
2513
2514                         if (stop - start <= 0) {
2515                                 return PyList_New(0);
2516                         }
2517                         else {
2518                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2519                         }
2520                 }
2521         }
2522 #endif
2523         else {
2524                 PyErr_Format(PyExc_TypeError,
2525                              "bpy_prop_collection[key]: invalid key, "
2526                              "must be a string or an int, not %.200s",
2527                              Py_TYPE(key)->tp_name);
2528                 return -1;
2529         }
2530 }
2531
2532 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2533 {
2534         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2535
2536         /*if (PyUnicode_Check(key)) {
2537                 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2538         }
2539         else */
2540         if (PyIndex_Check(key)) {
2541                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2542                 if (i == -1 && PyErr_Occurred())
2543                         return NULL;
2544                 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
2545         }
2546         else if (PySlice_Check(key)) {
2547                 Py_ssize_t step= 1;
2548                 PySliceObject *key_slice= (PySliceObject *)key;
2549
2550                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2551                         return NULL;
2552                 }
2553                 else if (step != 1) {
2554                         PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2555                         return NULL;
2556                 }
2557                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2558                         /* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
2559                         Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self);
2560                         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2561                 }
2562                 else {
2563                         int len= pyrna_prop_array_length(self);
2564                         Py_ssize_t start, stop, slicelength;
2565
2566                         if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0)
2567                                 return NULL;
2568
2569                         if (slicelength <= 0) {
2570                                 return PyTuple_New(0);
2571                         }
2572                         else {
2573                                 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2574                         }
2575                 }
2576         }
2577         else {
2578                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2579                 return NULL;
2580         }
2581 }
2582
2583 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
2584 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
2585                                           int start, int stop, int length, PyObject *value_orig)
2586 {
2587         PyObject *value;
2588         int count;
2589         void *values_alloc= NULL;
2590         int ret= 0;
2591
2592         if (value_orig == NULL) {
2593                 PyErr_SetString(PyExc_TypeError,
2594                                 "bpy_prop_array[slice]= value: deleting with list types is not supported by bpy_struct");
2595                 return -1;
2596         }
2597
2598         if (!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice]= value: assignment is not a sequence type"))) {
2599                 return -1;
2600         }
2601
2602         if (PySequence_Fast_GET_SIZE(value) != stop-start) {
2603                 Py_DECREF(value);
2604                 PyErr_SetString(PyExc_TypeError,
2605                                 "bpy_prop_array[slice]= value: resizing bpy_struct arrays isn't supported");
2606                 return -1;
2607         }
2608
2609         switch (RNA_property_type(prop)) {
2610                 case PROP_FLOAT:
2611                 {
2612                         float values_stack[PYRNA_STACK_ARRAY];
2613                         float *values, fval;
2614
2615                         float min, max;
2616                         RNA_property_float_range(ptr, prop, &min, &max);
2617
2618                         if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(float) * length); }
2619                         else                            { values= values_stack; }
2620                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2621                                 RNA_property_float_get_array(ptr, prop, values);
2622
2623                         for (count=start; count<stop; count++) {
2624                                 fval= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
2625                                 CLAMP(fval, min, max);
2626                                 values[count]= fval;
2627                         }
2628
2629                         if (PyErr_Occurred()) ret= -1;
2630                         else                  RNA_property_float_set_array(ptr, prop, values);
2631                         break;
2632                 }
2633                 case PROP_BOOLEAN:
2634                 {
2635                         int values_stack[PYRNA_STACK_ARRAY];
2636                         int *values;
2637                         if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
2638                         else                            { values= values_stack; }
2639
2640                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2641                                 RNA_property_boolean_get_array(ptr, prop, values);
2642
2643                         for (count=start; count<stop; count++)
2644                                 values[count]= PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
2645
2646                         if (PyErr_Occurred()) ret= -1;
2647                         else                  RNA_property_boolean_set_array(ptr, prop, values);
2648                         break;
2649                 }
2650                 case PROP_INT:
2651                 {
2652                         int values_stack[PYRNA_STACK_ARRAY];
2653                         int *values, ival;
2654
2655                         int min, max;
2656                         RNA_property_int_range(ptr, prop, &min, &max);
2657
2658                         if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
2659                         else                            { values= values_stack; }
2660
2661                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2662                                 RNA_property_int_get_array(ptr, prop, values);
2663
2664                         for (count=start; count<stop; count++) {
2665                                 ival= PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
2666                                 CLAMP(ival, min, max);
2667                                 values[count]= ival;
2668                         }
2669
2670                         if (PyErr_Occurred()) ret= -1;
2671                         else                  RNA_property_int_set_array(ptr, prop, values);
2672                         break;
2673                 }
2674                 default:
2675                         PyErr_SetString(PyExc_TypeError, "not an array type");
2676                         ret= -1;
2677         }
2678
2679         Py_DECREF(value);
2680
2681         if (values_alloc) {
2682                 PyMem_FREE(values_alloc);
2683         }
2684
2685         return ret;
2686
2687 }
2688
2689 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
2690 {
2691         int len;
2692
2693         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2694
2695         len= pyrna_prop_array_length(self);
2696
2697         if (keynum < 0) keynum += len;
2698
2699         if (keynum >= 0 && keynum < len)
2700                 return pyrna_py_to_prop_array_index(self, keynum, value);
2701
2702         PyErr_SetString(PyExc_IndexError,
2703                         "bpy_prop_array[index] = value: index out of range");
2704         return -1;
2705 }
2706
2707 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
2708 {
2709         /* char *keyname= NULL; */ /* not supported yet */
2710         int ret= -1;
2711
2712         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2713
2714         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
2715                 PyErr_Format(PyExc_AttributeError,
2716                              "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
2717                              RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type));
2718                 ret= -1;
2719         }
2720
2721         else if (PyIndex_Check(key)) {
2722                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2723                 if (i == -1 && PyErr_Occurred()) {
2724                         ret= -1;
2725                 }
2726                 else {
2727                         ret= prop_subscript_ass_array_int(self, i, value);
2728                 }
2729         }
2730         else if (PySlice_Check(key)) {
2731                 int len= RNA_property_array_length(&self->ptr, self->prop);
2732                 Py_ssize_t start, stop, step, slicelength;
2733
2734                 if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) {
2735                         ret= -1;
2736                 }
2737                 else if (slicelength <= 0) {
2738                         ret= 0; /* do nothing */
2739                 }
2740                 else if (step == 1) {
2741                         ret= prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
2742                 }
2743                 else {
2744                         PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
2745                         ret= -1;
2746                 }
2747         }
2748         else {
2749                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
2750                 ret= -1;
2751         }
2752
2753         if (ret != -1) {
2754                 if (RNA_property_update_check(self->prop)) {
2755                         RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
2756                 }
2757         }
2758
2759         return ret;
2760 }
2761
2762 /* for slice only */
2763 static PyMappingMethods pyrna_prop_array_as_mapping= {
2764         (lenfunc) pyrna_prop_array_length,      /* mp_length */
2765         (binaryfunc) pyrna_prop_array_subscript,        /* mp_subscript */
2766         (objobjargproc) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
2767 };
2768
2769 static PyMappingMethods pyrna_prop_collection_as_mapping= {
2770         (lenfunc) pyrna_prop_collection_length, /* mp_length */
2771         (binaryfunc) pyrna_prop_collection_subscript,   /* mp_subscript */
2772         (objobjargproc) pyrna_prop_collection_ass_subscript,    /* mp_ass_subscript */
2773 };
2774
2775 /* only for fast bool's, large structs, assign nb_bool on init */
2776 static PyNumberMethods pyrna_prop_array_as_number= {
2777         NULL, /* nb_add */
2778         NULL, /* nb_subtract */
2779         NULL, /* nb_multiply */
2780         NULL, /* nb_remainder */
2781         NULL, /* nb_divmod */
2782         NULL, /* nb_power */
2783         NULL, /* nb_negative */
2784         NULL, /* nb_positive */
2785         NULL, /* nb_absolute */
2786         (inquiry) pyrna_prop_array_bool, /* nb_bool */
2787 };
2788 static PyNumberMethods pyrna_prop_collection_as_number= {
2789         NULL, /* nb_add */
2790         NULL, /* nb_subtract */
2791         NULL, /* nb_multiply */
2792         NULL, /* nb_remainder */
2793         NULL, /* nb_divmod */
2794         NULL, /* nb_power */
2795         NULL, /* nb_negative */
2796         NULL, /* nb_positive */
2797         NULL, /* nb_absolute */
2798         (inquiry) pyrna_prop_collection_bool, /* nb_bool */
2799 };
2800
2801 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
2802 {
2803         return pyrna_array_contains_py(&self->ptr, self->prop, value);
2804 }
2805
2806 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
2807 {
2808         PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
2809
2810         if (PyTuple_Check(key)) {
2811                 /* special case, for ID datablocks we */
2812                 return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
2813                                                                         "(id, lib) in bpy_prop_collection", FALSE, NULL);
2814         }
2815         else {
2816
2817                 /* key in dict style check */
2818                 const char *keyname= _PyUnicode_AsString(key);
2819
2820                 if (keyname==NULL) {
2821                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string or a typle of strings");
2822                         return -1;
2823                 }
2824
2825                 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2826                         return 1;
2827
2828                 return 0;
2829         }
2830 }
2831
2832 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
2833 {
2834         IDProperty *group;
2835         const char *name= _PyUnicode_AsString(value);
2836
2837         PYRNA_STRUCT_CHECK_INT(self);
2838
2839         if (!name) {
2840                 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
2841                 return -1;
2842         }
2843
2844         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2845                 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
2846                 return -1;
2847         }
2848
2849         group= RNA_struct_idprops(&self->ptr, 0);
2850
2851         if (!group)
2852                 return 0;
2853
2854         return IDP_GetPropertyFromGroup(group, name) ? 1:0;
2855 }
2856
2857 static PySequenceMethods pyrna_prop_array_as_sequence= {
2858         (lenfunc)pyrna_prop_array_length,               /* Cant set the len otherwise it can evaluate as false */
2859         NULL,           /* sq_concat */
2860         NULL,           /* sq_repeat */
2861         (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2862         NULL,           /* sq_slice */
2863         (ssizeobjargproc)prop_subscript_ass_array_int,          /* sq_ass_item */
2864         NULL,           /* *was* sq_ass_slice */
2865         (objobjproc)pyrna_prop_array_contains,  /* sq_contains */
2866         (binaryfunc) NULL, /* sq_inplace_concat */
2867         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2868 };
2869
2870 static PySequenceMethods pyrna_prop_collection_as_sequence= {
2871         (lenfunc)pyrna_prop_collection_length,          /* Cant set the len otherwise it can evaluate as false */
2872         NULL,           /* sq_concat */
2873         NULL,           /* sq_repeat */
2874         (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2875         NULL,           /* *was* sq_slice */
2876         (ssizeobjargproc)/* pyrna_prop_collection_ass_subscript_int */ NULL /* let mapping take this one */, /* sq_ass_item */
2877         NULL,           /* *was* sq_ass_slice */
2878         (objobjproc)pyrna_prop_collection_contains,     /* sq_contains */
2879         (binaryfunc) NULL, /* sq_inplace_concat */
2880         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2881 };
2882
2883 static PySequenceMethods pyrna_struct_as_sequence= {
2884         NULL,           /* Cant set the len otherwise it can evaluate as false */
2885         NULL,           /* sq_concat */
2886         NULL,           /* sq_repeat */
2887         NULL,           /* sq_item */ /* Only set this so PySequence_Check() returns True */
2888         NULL,           /* *was* sq_slice */
2889         NULL,           /* sq_ass_item */
2890         NULL,           /* *was* sq_ass_slice */
2891         (objobjproc)pyrna_struct_contains,      /* sq_contains */
2892         (binaryfunc) NULL, /* sq_inplace_concat */
2893         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2894 };
2895
2896 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
2897 {
2898         /* mostly copied from BPy_IDGroup_Map_GetItem */
2899         IDProperty *group, *idprop;
2900         const char *name= _PyUnicode_AsString(key);
2901
2902         PYRNA_STRUCT_CHECK_OBJ(self);
2903
2904         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2905                 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
2906                 return NULL;
2907         }
2908
2909         if (name==NULL) {
2910                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
2911                 return NULL;
2912         }
2913
2914         group= RNA_struct_idprops(&self->ptr, 0);
2915
2916         if (group==NULL) {
2917                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2918                 return NULL;
2919         }
2920
2921         idprop= IDP_GetPropertyFromGroup(group, name);
2922
2923         if (idprop==NULL) {
2924                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2925                 return NULL;
2926         }
2927
2928         return BPy_IDGroup_WrapData(self->ptr.id.data, idprop, group);
2929 }
2930
2931 static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
2932 {
2933         IDProperty *group;
2934
2935         PYRNA_STRUCT_CHECK_INT(self);
2936
2937         group= RNA_struct_idprops(&self->ptr, 1);
2938
2939 #ifdef USE_PEDANTIC_WRITE
2940         if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
2941                 return -1;
2942         }
2943 #endif // USE_PEDANTIC_WRITE
2944
2945         if (group==NULL) {
2946                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]= val: id properties not supported for this type");
2947                 return -1;
2948         }
2949
2950         return BPy_Wrap_SetMapItem(group, key, value);
2951 }
2952
2953 static PyMappingMethods pyrna_struct_as_mapping= {
2954         (lenfunc) NULL, /* mp_length */
2955         (binaryfunc) pyrna_struct_subscript,    /* mp_subscript */
2956         (objobjargproc) pyrna_struct_ass_subscript,     /* mp_ass_subscript */
2957 };
2958
2959 PyDoc_STRVAR(pyrna_struct_keys_doc,
2960 ".. method:: keys()\n"
2961 "\n"
2962 "   Returns the keys of this objects custom properties (matches pythons\n"
2963 "   dictionary function of the same name).\n"
2964 "\n"
2965 "   :return: custom property keys.\n"
2966 "   :rtype: list of strings\n"
2967 "\n"
2968 BPY_DOC_ID_PROP_TYPE_NOTE
2969 );
2970 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
2971 {
2972         IDProperty *group;
2973
2974         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2975                 PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
2976                 return NULL;
2977         }
2978
2979         group= RNA_struct_idprops(&self->ptr, 0);
2980
2981         if (group==NULL)
2982                 return PyList_New(0);
2983
2984         return BPy_Wrap_GetKeys(group);
2985 }
2986
2987 PyDoc_STRVAR(pyrna_struct_items_doc,
2988 ".. method:: items()\n"
2989 "\n"
2990 "   Returns the items of this objects custom properties (matches pythons\n"
2991 "   dictionary function of the same name).\n"
2992 "\n"
2993 "   :return: custom property key, value pairs.\n"
2994 "   :rtype: list of key, value tuples\n"
2995 "\n"
2996 BPY_DOC_ID_PROP_TYPE_NOTE
2997 );
2998 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
2999 {
3000         IDProperty *group;
3001
3002         if (RNA_struct_idprops_check(self->ptr.type)==0) {
3003                 PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
3004                 return NULL;
3005         }
3006
3007         group= RNA_struct_idprops(&self->ptr, 0);
3008
3009         if (group==NULL)
3010                 return PyList_New(0);
3011
3012         return BPy_Wrap_GetItems(self->ptr.id.data, group);
3013 }
3014
3015 PyDoc_STRVAR(pyrna_struct_values_doc,
3016 ".. method:: values()\n"
3017 "\n"
3018 "   Returns the values of this objects custom properties (matches pythons\n"
3019 "   dictionary function of the same name).\n"
3020 "\n"
3021 "   :return: custom property values.\n"
3022 "   :rtype: list\n"
3023 "\n"
3024 BPY_DOC_ID_PROP_TYPE_NOTE
3025 );
3026 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
3027 {
3028         IDProperty *group;
3029
3030         if (RNA_struct_idprops_check(self->ptr.type)==0) {
3031                 PyErr_SetString(PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
3032                 return NULL;
3033         }
3034
3035         group= RNA_struct_idprops(&self->ptr, 0);
3036
3037         if (group==NULL)
3038                 return PyList_New(0);
3039
3040         return BPy_Wrap_GetValues(self->ptr.id.data, group);
3041 }
3042
3043
3044 PyDoc_STRVAR(pyrna_struct_is_property_set_doc,
3045 ".. method:: is_property_set(property)\n"
3046 "\n"
3047 "   Check if a property is set, use for testing operator properties.\n"
3048 "\n"
3049 "   :return: True when the property has been set.\n"
3050 "   :rtype: boolean\n"
3051 );
3052 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
3053 {
3054         PropertyRNA *prop;
3055         const char *name;
3056         int ret;
3057
3058         PYRNA_STRUCT_CHECK_OBJ(self);
3059
3060         if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
3061                 return NULL;
3062
3063         if ((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
3064                 PyErr_Format(PyExc_TypeError,
3065                              "%.200s.is_property_set(\"%.200s\") not found",
3066                              RNA_struct_identifier(self->ptr.type), name);
3067                 return NULL;
3068         }
3069
3070         /* double property lookup, could speed up */
3071         /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */
3072         if (RNA_property_flag(prop) & PROP_IDPROPERTY) {
3073                 IDProperty *group= RNA_struct_idprops(&self->ptr, 0);
3074                 if (group) {
3075                         ret= IDP_GetPropertyFromGroup(group, name) ? 1:0;
3076                 }
3077                 else {
3078                         ret= 0;
3079                 }
3080         }
3081         else {
3082                 ret= 1;
3083         }
3084
3085         return PyBool_FromLong(ret);
3086 }
3087
3088 PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc,
3089 ".. method:: is_property_hidden(property)\n"
3090 "\n"
3091 "   Check if a property is hidden.\n"
3092 "\n"
3093 "   :return: True when the property is hidden.\n"
3094 "   :rtype: boolean\n"
3095 );
3096 static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)