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