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