fix for py/rna mesh.materials[:] where empty materials exist, would raise a runtime...
[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 {
1426                         PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection");
1427                         return NULL;
1428                 }
1429         }
1430         PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
1431         return NULL;
1432 }
1433
1434 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
1435 {
1436         int len= pyrna_prop_array_length(self);
1437
1438         if(keynum < 0) keynum += len;
1439
1440         if(keynum >= 0 && keynum < len)
1441                 return pyrna_prop_array_to_py_index(self, keynum);
1442
1443         PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
1444         return NULL;
1445 }
1446
1447 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
1448 {
1449         PointerRNA newptr;
1450         if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
1451                 return pyrna_struct_CreatePyObject(&newptr);
1452
1453         PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
1454         return NULL;
1455 }
1456 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
1457
1458 static PyObject *pyrna_prop_collection_subscript_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop)
1459 {
1460         PointerRNA newptr;
1461         PyObject *list = PyList_New(stop - start);
1462         int count;
1463
1464         start = MIN2(start,stop); /* values are clamped from  */
1465
1466         for(count = start; count < stop; count++) {
1467                 if(RNA_property_collection_lookup_int(ptr, prop, count - start, &newptr)) {
1468                         PyList_SET_ITEM(list, count - start, pyrna_struct_CreatePyObject(&newptr));
1469                 }
1470                 else {
1471                         Py_DECREF(list);
1472
1473                         PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection");
1474                         return NULL;
1475                 }
1476         }
1477
1478         return list;
1479 }
1480
1481 /* TODO - dimensions
1482  * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
1483  * since at the moment it reads (and even allocates) the entire array for each index.
1484  */
1485 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
1486 {
1487         int count, totdim;
1488
1489         PyObject *tuple= PyTuple_New(stop - start);
1490
1491         totdim = RNA_property_array_dimension(ptr, prop, NULL);
1492
1493         if (totdim > 1) {
1494                 for (count = start; count < stop; count++)
1495                         PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
1496         }
1497         else {
1498                 switch (RNA_property_type(prop)) {
1499                 case PROP_FLOAT:
1500                         {
1501                                 float values_stack[PYRNA_STACK_ARRAY];
1502                                 float *values;
1503                                 if(length > PYRNA_STACK_ARRAY)  {       values= PyMem_MALLOC(sizeof(float) * length); }
1504                                 else                                                    {       values= values_stack; }
1505                                 RNA_property_float_get_array(ptr, prop, values);
1506                         
1507                                 for(count=start; count<stop; count++)
1508                                         PyTuple_SET_ITEM(tuple, count-start, PyFloat_FromDouble(values[count]));
1509
1510                                 if(values != values_stack) {
1511                                         PyMem_FREE(values);
1512                                 }
1513                                 break;
1514                         }
1515                 case PROP_BOOLEAN:
1516                         {
1517                                 int values_stack[PYRNA_STACK_ARRAY];
1518                                 int *values;
1519                                 if(length > PYRNA_STACK_ARRAY)  {       values= PyMem_MALLOC(sizeof(int) * length); }
1520                                 else                                                    {       values= values_stack; }
1521
1522                                 RNA_property_boolean_get_array(ptr, prop, values);
1523                                 for(count=start; count<stop; count++)
1524                                         PyTuple_SET_ITEM(tuple, count-start, PyBool_FromLong(values[count]));
1525
1526                                 if(values != values_stack) {
1527                                         PyMem_FREE(values);
1528                                 }
1529                                 break;
1530                         }
1531                 case PROP_INT:
1532                         {
1533                                 int values_stack[PYRNA_STACK_ARRAY];
1534                                 int *values;
1535                                 if(length > PYRNA_STACK_ARRAY)  {       values= PyMem_MALLOC(sizeof(int) * length); }
1536                                 else                                                    {       values= values_stack; }
1537
1538                                 RNA_property_int_get_array(ptr, prop, values);
1539                                 for(count=start; count<stop; count++)
1540                                         PyTuple_SET_ITEM(tuple, count-start, PyLong_FromSsize_t(values[count]));
1541
1542                                 if(values != values_stack) {
1543                                         PyMem_FREE(values);
1544                                 }
1545                                 break;
1546                         }
1547                 default:
1548                         BKE_assert(!"Invalid array type");
1549
1550                         PyErr_SetString(PyExc_TypeError, "not an array type");
1551                         Py_DECREF(tuple);
1552                         tuple= NULL;
1553                 }
1554         }
1555         return tuple;
1556 }
1557
1558 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
1559 {
1560         if (PyUnicode_Check(key)) {
1561                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
1562         }
1563         else if (PyIndex_Check(key)) {
1564                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1565                 if (i == -1 && PyErr_Occurred())
1566                         return NULL;
1567
1568                 return pyrna_prop_collection_subscript_int(self, i);
1569         }
1570         else if (PySlice_Check(key)) {
1571                 int len= RNA_property_collection_length(&self->ptr, self->prop);
1572                 Py_ssize_t start, stop, step, slicelength;
1573
1574                 if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
1575                         return NULL;
1576
1577                 if (slicelength <= 0) {
1578                         return PyList_New(0);
1579                 }
1580                 else if (step == 1) {
1581                         return pyrna_prop_collection_subscript_slice(&self->ptr, self->prop, start, stop);
1582                 }
1583                 else {
1584                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported with rna");
1585                         return NULL;
1586                 }
1587         }
1588         else {
1589                 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);
1590                 return NULL;
1591         }
1592 }
1593
1594 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
1595 {
1596         /*if (PyUnicode_Check(key)) {
1597                 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
1598         } else*/
1599         if (PyIndex_Check(key)) {
1600                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1601                 if (i == -1 && PyErr_Occurred())
1602                         return NULL;
1603                 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
1604         }
1605         else if (PySlice_Check(key)) {
1606                 Py_ssize_t start, stop, step, slicelength;
1607                 int len = pyrna_prop_array_length(self);
1608
1609                 if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
1610                         return NULL;
1611
1612                 if (slicelength <= 0) {
1613                         return PyList_New(0);
1614                 }
1615                 else if (step == 1) {
1616                         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
1617                 }
1618                 else {
1619                         PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported with rna");
1620                         return NULL;
1621                 }
1622         }
1623         else {
1624                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
1625                 return NULL;
1626         }
1627 }
1628
1629 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
1630 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length, PyObject *value_orig)
1631 {
1632         PyObject *value;
1633         int count;
1634         void *values_alloc= NULL;
1635         int ret= 0;
1636
1637         if(value_orig == NULL) {
1638                 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
1639                 return -1;
1640         }
1641
1642         if(!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
1643                 return -1;
1644         }
1645
1646         if(PySequence_Fast_GET_SIZE(value) != stop-start) {
1647                 Py_DECREF(value);
1648                 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported");
1649                 return -1;
1650         }
1651
1652         switch (RNA_property_type(prop)) {
1653                 case PROP_FLOAT:
1654                 {
1655                         float values_stack[PYRNA_STACK_ARRAY];
1656                         float *values, fval;
1657
1658                         float min, max;
1659                         RNA_property_float_range(ptr, prop, &min, &max);
1660
1661                         if(length > PYRNA_STACK_ARRAY)  {       values= values_alloc= PyMem_MALLOC(sizeof(float) * length); }
1662                         else                                                    {       values= values_stack; }
1663                         if(start != 0 || stop != length) /* partial assignment? - need to get the array */
1664                                 RNA_property_float_get_array(ptr, prop, values);
1665                         
1666                         for(count=start; count<stop; count++) {
1667                                 fval = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
1668                                 CLAMP(fval, min, max);
1669                                 values[count] = fval;
1670                         }
1671
1672                         if(PyErr_Occurred())    ret= -1;
1673                         else                                    RNA_property_float_set_array(ptr, prop, values);
1674                         break;
1675                 }
1676                 case PROP_BOOLEAN:
1677                 {
1678                         int values_stack[PYRNA_STACK_ARRAY];
1679                         int *values;
1680                         if(length > PYRNA_STACK_ARRAY)  {       values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
1681                         else                                                    {       values= values_stack; }
1682
1683                         if(start != 0 || stop != length) /* partial assignment? - need to get the array */
1684                                 RNA_property_boolean_get_array(ptr, prop, values);
1685         
1686                         for(count=start; count<stop; count++)
1687                                 values[count] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
1688
1689                         if(PyErr_Occurred())    ret= -1;
1690                         else                                    RNA_property_boolean_set_array(ptr, prop, values);
1691                         break;
1692                 }
1693                 case PROP_INT:
1694                 {
1695                         int values_stack[PYRNA_STACK_ARRAY];
1696                         int *values, ival;
1697
1698                         int min, max;
1699                         RNA_property_int_range(ptr, prop, &min, &max);
1700
1701                         if(length > PYRNA_STACK_ARRAY)  {       values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
1702                         else                                                    {       values= values_stack; }
1703
1704                         if(start != 0 || stop != length) /* partial assignment? - need to get the array */
1705                                 RNA_property_int_get_array(ptr, prop, values);
1706
1707                         for(count=start; count<stop; count++) {
1708                                 ival = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
1709                                 CLAMP(ival, min, max);
1710                                 values[count] = ival;
1711                         }
1712
1713                         if(PyErr_Occurred())    ret= -1;
1714                         else                                    RNA_property_int_set_array(ptr, prop, values);
1715                         break;
1716                 }
1717                 default:
1718                         PyErr_SetString(PyExc_TypeError, "not an array type");
1719                         ret= -1;
1720         }
1721
1722         Py_DECREF(value);
1723         
1724         if(values_alloc) {
1725                 PyMem_FREE(values_alloc);
1726         }
1727         
1728         return ret;
1729
1730 }
1731
1732 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
1733 {
1734         int len= pyrna_prop_array_length(self);
1735
1736         if(keynum < 0) keynum += len;
1737
1738         if(keynum >= 0 && keynum < len)
1739                 return pyrna_py_to_prop_array_index(self, keynum, value);
1740
1741         PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
1742         return -1;
1743 }
1744
1745 static int pyrna_prop_array_ass_subscript( BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value )
1746 {
1747         /* char *keyname = NULL; */ /* not supported yet */
1748         int ret= -1;
1749
1750         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
1751                 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) );
1752                 ret= -1;
1753         }
1754
1755         else if (PyIndex_Check(key)) {
1756                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1757                 if (i == -1 && PyErr_Occurred()) {
1758                         ret= -1;
1759                 }
1760                 else {
1761                         ret= prop_subscript_ass_array_int(self, i, value);
1762                 }
1763         }
1764         else if (PySlice_Check(key)) {
1765                 int len= RNA_property_array_length(&self->ptr, self->prop);
1766                 Py_ssize_t start, stop, step, slicelength;
1767
1768                 if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) {
1769                         ret= -1;
1770                 }
1771                 else if (slicelength <= 0) {
1772                         ret= 0; /* do nothing */
1773                 }
1774                 else if (step == 1) {
1775                         ret= prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
1776                 }
1777                 else {
1778                         PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
1779                         ret= -1;
1780                 }
1781         }
1782         else {
1783                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
1784                 ret= -1;
1785         }
1786
1787         if(ret != -1) {
1788                 if(RNA_property_update_check(self->prop)) {
1789                         RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
1790                 }
1791         }
1792
1793         return ret;
1794 }
1795
1796 /* for slice only */
1797 static PyMappingMethods pyrna_prop_array_as_mapping = {
1798         ( lenfunc ) pyrna_prop_array_length,    /* mp_length */
1799         ( binaryfunc ) pyrna_prop_array_subscript,      /* mp_subscript */
1800         ( objobjargproc ) pyrna_prop_array_ass_subscript,       /* mp_ass_subscript */
1801 };
1802
1803 static PyMappingMethods pyrna_prop_collection_as_mapping = {
1804         ( lenfunc ) pyrna_prop_collection_length,       /* mp_length */
1805         ( binaryfunc ) pyrna_prop_collection_subscript, /* mp_subscript */
1806         ( objobjargproc ) NULL, /* mp_ass_subscript */
1807 };
1808
1809 /* only for fast bool's, large structs, assign nb_bool on init */
1810 static PyNumberMethods pyrna_prop_array_as_number = {
1811         NULL, /* nb_add */
1812         NULL, /* nb_subtract */
1813         NULL, /* nb_multiply */
1814         NULL, /* nb_remainder */
1815         NULL, /* nb_divmod */
1816         NULL, /* nb_power */
1817         NULL, /* nb_negative */
1818         NULL, /* nb_positive */
1819         NULL, /* nb_absolute */
1820         (inquiry) pyrna_prop_array_bool, /* nb_bool */
1821 };
1822 static PyNumberMethods pyrna_prop_collection_as_number = {
1823         NULL, /* nb_add */
1824         NULL, /* nb_subtract */
1825         NULL, /* nb_multiply */
1826         NULL, /* nb_remainder */
1827         NULL, /* nb_divmod */
1828         NULL, /* nb_power */
1829         NULL, /* nb_negative */
1830         NULL, /* nb_positive */
1831         NULL, /* nb_absolute */
1832         (inquiry) pyrna_prop_collection_bool, /* nb_bool */
1833 };
1834
1835 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
1836 {
1837         return pyrna_array_contains_py(&self->ptr, self->prop, value);
1838 }
1839
1840 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value)
1841 {
1842         PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
1843
1844         /* key in dict style check */
1845         char *keyname = _PyUnicode_AsString(value);
1846
1847         if(keyname==NULL) {
1848                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
1849                 return -1;
1850         }
1851
1852         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
1853                 return 1;
1854
1855         return 0;
1856 }
1857
1858 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
1859 {
1860         IDProperty *group;
1861         char *name = _PyUnicode_AsString(value);
1862
1863         if (!name) {
1864                 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
1865                 return -1;
1866         }
1867
1868         if(RNA_struct_idprops_check(self->ptr.type)==0) {
1869                 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesnt support IDProperties");
1870                 return -1;
1871         }
1872
1873         group= RNA_struct_idprops(&self->ptr, 0);
1874         
1875         if(!group)
1876                 return 0;
1877         
1878         return IDP_GetPropertyFromGroup(group, name) ? 1:0;
1879 }
1880
1881 static PySequenceMethods pyrna_prop_array_as_sequence = {
1882         (lenfunc)pyrna_prop_array_length,               /* Cant set the len otherwise it can evaluate as false */
1883         NULL,           /* sq_concat */
1884         NULL,           /* sq_repeat */
1885         (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
1886         NULL,           /* sq_slice */
1887         (ssizeobjargproc)prop_subscript_ass_array_int,          /* sq_ass_item */
1888         NULL,           /* *was* sq_ass_slice */
1889         (objobjproc)pyrna_prop_array_contains,  /* sq_contains */
1890         (binaryfunc) NULL, /* sq_inplace_concat */
1891         (ssizeargfunc) NULL, /* sq_inplace_repeat */
1892 };
1893
1894 static PySequenceMethods pyrna_prop_collection_as_sequence = {
1895         (lenfunc)pyrna_prop_collection_length,          /* Cant set the len otherwise it can evaluate as false */
1896         NULL,           /* sq_concat */
1897         NULL,           /* sq_repeat */
1898         (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
1899         NULL,           /* *was* sq_slice */
1900         NULL,           /* sq_ass_item */
1901         NULL,           /* *was* sq_ass_slice */
1902         (objobjproc)pyrna_prop_collection_contains,     /* sq_contains */
1903         (binaryfunc) NULL, /* sq_inplace_concat */
1904         (ssizeargfunc) NULL, /* sq_inplace_repeat */
1905 };
1906
1907 static PySequenceMethods pyrna_struct_as_sequence = {
1908         NULL,           /* Cant set the len otherwise it can evaluate as false */
1909         NULL,           /* sq_concat */
1910         NULL,           /* sq_repeat */
1911         NULL,           /* sq_item */ /* Only set this so PySequence_Check() returns True */
1912         NULL,           /* *was* sq_slice */
1913         NULL,           /* sq_ass_item */
1914         NULL,           /* *was* sq_ass_slice */
1915         (objobjproc)pyrna_struct_contains,      /* sq_contains */
1916         (binaryfunc) NULL, /* sq_inplace_concat */
1917         (ssizeargfunc) NULL, /* sq_inplace_repeat */
1918 };
1919
1920 static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
1921 {
1922         /* mostly copied from BPy_IDGroup_Map_GetItem */
1923         IDProperty *group, *idprop;
1924         char *name= _PyUnicode_AsString(key);
1925
1926         if(RNA_struct_idprops_check(self->ptr.type)==0) {
1927                 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
1928                 return NULL;
1929         }
1930
1931         if(name==NULL) {
1932                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
1933                 return NULL;
1934         }
1935
1936         group= RNA_struct_idprops(&self->ptr, 0);
1937
1938         if(group==NULL) {
1939                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
1940                 return NULL;
1941         }
1942
1943         idprop= IDP_GetPropertyFromGroup(group, name);
1944
1945         if(idprop==NULL) {
1946                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
1947                 return NULL;
1948         }
1949
1950         return BPy_IDGroup_WrapData(self->ptr.id.data, idprop);
1951 }
1952
1953 static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObject *value )
1954 {
1955         IDProperty *group= RNA_struct_idprops(&self->ptr, 1);
1956
1957 #ifdef USE_PEDANTIC_WRITE
1958         if(rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
1959                 return -1;
1960         }
1961 #endif // USE_STRING_COERCE
1962
1963         if(group==NULL) {
1964                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
1965                 return -1;
1966         }
1967
1968         return BPy_Wrap_SetMapItem(group, key, value);
1969 }
1970
1971 static PyMappingMethods pyrna_struct_as_mapping = {
1972         ( lenfunc ) NULL,       /* mp_length */
1973         ( binaryfunc ) pyrna_struct_subscript,  /* mp_subscript */
1974         ( objobjargproc ) pyrna_struct_ass_subscript,   /* mp_ass_subscript */
1975 };
1976
1977 static char pyrna_struct_keys_doc[] =
1978 ".. method:: keys()\n"
1979 "\n"
1980 "   Returns the keys of this objects custom properties (matches pythons dictionary function of the same name).\n"
1981 "\n"
1982 "   :return: custom property keys.\n"
1983 "   :rtype: list of strings\n"
1984 "\n"
1985 "   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
1986
1987 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
1988 {
1989         IDProperty *group;
1990
1991         if(RNA_struct_idprops_check(self->ptr.type)==0) {
1992                 PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
1993                 return NULL;
1994         }
1995
1996         group= RNA_struct_idprops(&self->ptr, 0);
1997
1998         if(group==NULL)
1999                 return PyList_New(0);
2000
2001         return BPy_Wrap_GetKeys(group);
2002 }
2003
2004 static char pyrna_struct_items_doc[] =
2005 ".. method:: items()\n"
2006 "\n"
2007 "   Returns the items of this objects custom properties (matches pythons dictionary function of the same name).\n"
2008 "\n"
2009 "   :return: custom property key, value pairs.\n"
2010 "   :rtype: list of key, value tuples\n"
2011 "\n"
2012 "   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
2013
2014 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
2015 {
2016         IDProperty *group;
2017
2018         if(RNA_struct_idprops_check(self->ptr.type)==0) {
2019                 PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
2020                 return NULL;
2021         }
2022
2023         group= RNA_struct_idprops(&self->ptr, 0);
2024
2025         if(group==NULL)
2026                 return PyList_New(0);
2027
2028         return BPy_Wrap_GetItems(self->ptr.id.data, group);
2029 }
2030
2031 static char pyrna_struct_values_doc[] =
2032 ".. method:: values()\n"
2033 "\n"
2034 "   Returns the values of this objects custom properties (matches pythons dictionary function of the same name).\n"
2035 "\n"
2036 "   :return: custom property values.\n"
2037 "   :rtype: list\n"
2038 "\n"
2039 "   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
2040
2041 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
2042 {
2043         IDProperty *group;
2044
2045         if(RNA_struct_idprops_check(self->ptr.type)==0) {
2046                 PyErr_SetString(PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
2047                 return NULL;
2048         }
2049
2050         group= RNA_struct_idprops(&self->ptr, 0);
2051
2052         if(group==NULL)
2053                 return PyList_New(0);
2054
2055         return BPy_Wrap_GetValues(self->ptr.id.data, group);
2056 }
2057
2058 /* for keyframes and drivers */
2059 static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
2060         char **path_full, int *index)
2061 {
2062         const int is_idbase= RNA_struct_is_ID(ptr->type);
2063         PropertyRNA *prop;
2064         PointerRNA r_ptr;
2065         
2066         if (ptr->data==NULL) {
2067                 PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
2068                 return -1;
2069         }
2070         
2071         /* full paths can only be given from ID base */
2072         if(is_idbase) {
2073                 int r_index= -1;
2074                 if(RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) {
2075                         prop= NULL;
2076                 }
2077                 else if(r_index != -1) {
2078                         PyErr_Format(PyExc_ValueError, "%.200s path includes index, must be a separate argument", error_prefix, path);
2079                         return -1;
2080                 }
2081                 else if(ptr->id.data != r_ptr.id.data) {
2082                         PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
2083                         return -1;
2084                 }
2085         }
2086     else {
2087                 prop = RNA_struct_find_property(ptr, path);
2088                 r_ptr= *ptr;
2089     }
2090
2091         if (prop==NULL) {
2092                 PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
2093                 return -1;
2094         }
2095
2096         if (!RNA_property_animateable(&r_ptr, prop)) {
2097                 PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
2098                 return -1;
2099         }
2100
2101         if(RNA_property_array_check(&r_ptr, prop) == 0) {
2102                 if((*index) == -1) {
2103                         *index= 0;
2104                 }
2105                 else {
2106                         PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
2107                         return -1;
2108                 }
2109         }
2110         else {
2111                 int array_len= RNA_property_array_length(&r_ptr, prop);
2112                 if((*index) < -1 || (*index) >= array_len) {
2113                         PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
2114                         return -1;
2115                 }
2116         }
2117         
2118         if(is_idbase) {
2119                 *path_full= BLI_strdup(path);
2120         }
2121         else {
2122                 *path_full= RNA_path_from_ID_to_property(&r_ptr, prop);
2123         
2124                 if (*path_full==NULL) {
2125                         PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
2126                         return -1;
2127                 }
2128         }
2129
2130         return 0;
2131 }
2132
2133 /* internal use for insert and delete */
2134 static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw,  const char *parse_str, const char *error_prefix,
2135         char **path_full, int *index, float *cfra, char **group_name) /* return values */
2136 {
2137         static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
2138         char *path;
2139
2140         /* note, parse_str MUST start with 's|ifs' */
2141         if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
2142                 return -1;
2143
2144         if(pyrna_struct_anim_args_parse(ptr, error_prefix, path,  path_full, index) < 0) 
2145                 return -1;
2146         
2147         if(*cfra==FLT_MAX)
2148                 *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
2149
2150         return 0; /* success */
2151 }
2152
2153 static char pyrna_struct_keyframe_insert_doc[] =
2154 ".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
2155 "\n"
2156 "   Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
2157 "\n"
2158 "   :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
2159 "   :type data_path: string\n"
2160 "   :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"
2161 "   :type index: int\n"
2162 "   :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
2163 "   :type frame: float\n"
2164 "   :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
2165 "   :type group: str\n"
2166 "   :return: Success of keyframe insertion.\n"
2167 "   :rtype: boolean";
2168
2169 static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
2170 {
2171         /* args, pyrna_struct_keyframe_parse handles these */
2172         char *path_full= NULL;
2173         int index= -1;
2174         float cfra= FLT_MAX;
2175         char *group_name= NULL;
2176
2177         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) {
2178                 return NULL;
2179         }
2180         else {
2181                 short result;
2182                 ReportList reports;
2183
2184                 BKE_reports_init(&reports, RPT_STORE);
2185
2186                 result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
2187                 MEM_freeN(path_full);
2188
2189                 if(BPy_reports_to_error(&reports, TRUE))
2190                         return NULL;
2191
2192                 return PyBool_FromLong(result);
2193         }
2194 }
2195
2196 static char pyrna_struct_keyframe_delete_doc[] =
2197 ".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
2198 "\n"
2199 "   Remove a keyframe from this properties fcurve.\n"
2200 "\n"
2201 "   :arg data_path: path to the property to remove a key, analogous to the fcurve's data path.\n"
2202 "   :type data_path: string\n"
2203 "   :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"
2204 "   :type index: int\n"
2205 "   :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
2206 "   :type frame: float\n"
2207 "   :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
2208 "   :type group: str\n"
2209 "   :return: Success of keyframe deleation.\n"
2210 "   :rtype: boolean";
2211
2212 static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
2213 {
2214         /* args, pyrna_struct_keyframe_parse handles these */
2215         char *path_full= NULL;
2216         int index= -1;
2217         float cfra= FLT_MAX;
2218         char *group_name= NULL;
2219
2220         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) {
2221                 return NULL;
2222         }
2223         else {
2224                 short result;
2225                 ReportList reports;
2226
2227                 BKE_reports_init(&reports, RPT_STORE);
2228
2229                 result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
2230                 MEM_freeN(path_full);
2231
2232                 if(BPy_reports_to_error(&reports, TRUE))
2233                         return NULL;
2234
2235                 return PyBool_FromLong(result);
2236         }
2237
2238 }
2239
2240 static char pyrna_struct_driver_add_doc[] =
2241 ".. method:: driver_add(path, index=-1)\n"
2242 "\n"
2243 "   Adds driver(s) to the given property\n"
2244 "\n"
2245 "   :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
2246 "   :type path: string\n"
2247 "   :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"
2248 "   :type index: int\n"
2249 "   :return: The driver(s) added.\n"
2250 "   :rtype: :class:`FCurve` or list if index is -1 with an array property.";
2251
2252 static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
2253 {
2254         char *path, *path_full;
2255         int index= -1;
2256
2257         if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
2258                 return NULL;
2259
2260         if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path,  &path_full, &index) < 0) {
2261                 return NULL;
2262         }
2263         else {
2264                 PyObject *ret= NULL;
2265                 ReportList reports;
2266                 int result;
2267
2268                 BKE_reports_init(&reports, RPT_STORE);
2269
2270                 result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
2271
2272                 if(BPy_reports_to_error(&reports, TRUE))
2273                         return NULL;
2274
2275                 if(result) {
2276                         ID *id= self->ptr.id.data;
2277                         AnimData *adt= BKE_animdata_from_id(id);
2278                         FCurve *fcu;
2279
2280                         PointerRNA tptr;
2281                         PyObject *item;
2282
2283                         if(index == -1) { /* all, use a list */
2284                                 int i= 0;
2285                                 ret= PyList_New(0);
2286                                 while((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) {
2287                                         RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
2288                                         item= pyrna_struct_CreatePyObject(&tptr);
2289                                         PyList_Append(ret, item);
2290                                         Py_DECREF(item);
2291                                 }
2292                         }
2293                         else {
2294                                 fcu= list_find_fcurve(&adt->drivers, path_full, index);
2295                                 RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
2296                                 ret= pyrna_struct_CreatePyObject(&tptr);
2297                         }
2298                 }
2299                 else {
2300                         /* XXX, should be handled by reports, */
2301                         PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
2302                         return NULL;
2303                 }
2304
2305                 MEM_freeN(path_full);
2306
2307                 return ret;
2308         }
2309 }
2310
2311
2312 static char pyrna_struct_driver_remove_doc[] =
2313 ".. method:: driver_remove(path, index=-1)\n"
2314 "\n"
2315 "   Remove driver(s) from the given property\n"
2316 "\n"
2317 "   :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
2318 "   :type path: string\n"
2319 "   :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"
2320 "   :type index: int\n"
2321 "   :return: Success of driver removal.\n"
2322 "   :rtype: boolean";
2323
2324 static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
2325 {
2326         char *path, *path_full;
2327         int index= -1;
2328
2329         if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
2330                 return NULL;
2331
2332         if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path,  &path_full, &index) < 0) {
2333                 return NULL;
2334         }
2335         else {
2336                 short result;
2337                 ReportList reports;
2338
2339                 BKE_reports_init(&reports, RPT_STORE);
2340
2341                 result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
2342
2343                 MEM_freeN(path_full);
2344
2345                 if(BPy_reports_to_error(&reports, TRUE))
2346                         return NULL;
2347
2348                 return PyBool_FromLong(result);
2349         }
2350 }
2351
2352
2353 static char pyrna_struct_is_property_set_doc[] =
2354 ".. method:: is_property_set(property)\n"
2355 "\n"
2356 "   Check if a property is set, use for testing operator properties.\n"
2357 "\n"
2358 "   :return: True when the property has been set.\n"
2359 "   :rtype: boolean";
2360
2361 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
2362 {
2363         PropertyRNA *prop;
2364         char *name;
2365         int ret;
2366
2367         if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
2368                 return NULL;
2369
2370         if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
2371                 PyErr_Format(PyExc_TypeError, "%.200s.is_property_set(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
2372                 return NULL;
2373         }
2374
2375         /* double property lookup, could speed up */
2376         /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */
2377         if(RNA_property_flag(prop) & PROP_IDPROPERTY) {
2378                 IDProperty *group= RNA_struct_idprops(&self->ptr, 0);           
2379                 if(group) {
2380                         ret= IDP_GetPropertyFromGroup(group, name) ? 1:0;
2381                 }
2382                 else {
2383                         ret= 0;
2384                 }
2385         }
2386         else {
2387                 ret= 1;
2388         }
2389         
2390         return PyBool_FromLong(ret);
2391 }
2392
2393 static char pyrna_struct_is_property_hidden_doc[] =
2394 ".. method:: is_property_hidden(property)\n"
2395 "\n"
2396 "   Check if a property is hidden.\n"
2397 "\n"
2398 "   :return: True when the property is hidden.\n"
2399 "   :rtype: boolean";
2400
2401 static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
2402 {
2403         PropertyRNA *prop;
2404         char *name;
2405
2406         if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
2407                 return NULL;
2408
2409         if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
2410                 PyErr_Format(PyExc_TypeError, "%.200s.is_property_hidden(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
2411                 return NULL;
2412         }
2413
2414         return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
2415 }
2416
2417 static char pyrna_struct_path_resolve_doc[] =
2418 ".. method:: path_resolve(path, coerce=True)\n"
2419 "\n"
2420 "   Returns the property from the path, raise an exception when not found.\n"
2421 "\n"
2422 "   :arg path: path which this property resolves.\n"
2423 "   :type path: string\n"
2424 "   :arg coerce: optional argument, when True, the property will be converted into its python representation.\n"
2425 "   :type coerce: boolean\n";
2426
2427 static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
2428 {
2429         char *path;
2430         PyObject *coerce= Py_True;
2431         PointerRNA r_ptr;
2432         PropertyRNA *r_prop;
2433         int index= -1;
2434
2435         if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce))
2436                 return NULL;
2437
2438         if (RNA_path_resolve_full(&self->ptr, path, &r_ptr, &r_prop, &index)) {
2439                 if(r_prop) {
2440                         if(index != -1) {
2441                                 if(index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
2442                                         PyErr_Format(PyExc_TypeError, "%.200s.path_resolve(\"%.200s\") index out of range", RNA_struct_identifier(self->ptr.type), path);
2443                                         return NULL;
2444                                 }
2445                                 else {
2446                                         return pyrna_array_index(&r_ptr, r_prop, index);
2447                                 }
2448                         }
2449                         else {
2450                                 if(coerce == Py_False) {
2451                                         return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
2452                                 }
2453                                 else {
2454                                         return pyrna_prop_to_py(&r_ptr, r_prop);
2455                                 }
2456                         }
2457                 }
2458                 else {
2459                         return pyrna_struct_CreatePyObject(&r_ptr);
2460                 }
2461         }
2462         else {
2463                 PyErr_Format(PyExc_TypeError, "%.200s.path_resolve(\"%.200s\") could not be resolved", RNA_struct_identifier(self->ptr.type), path);
2464                 return NULL;
2465         }
2466 }
2467
2468 static char pyrna_struct_path_from_id_doc[] =
2469 ".. method:: path_from_id(property=\"\")\n"
2470 "\n"
2471 "   Returns the data path from the ID to this object (string).\n"
2472 "\n"
2473 "   :arg property: Optional property name which can be used if the path is to a property of this object.\n"
2474 "   :type property: string\n"
2475 "   :return: The path from :class:`bpy_struct.id_data` to this struct and property (when given).\n"
2476 "   :rtype: str";
2477
2478 static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
2479 {
2480         char *name= NULL;
2481         char *path;
2482         PropertyRNA *prop;
2483         PyObject *ret;
2484
2485         if (!PyArg_ParseTuple(args, "|s:path_from_id", &name))
2486                 return NULL;
2487
2488         if(name) {
2489                 prop= RNA_struct_find_property(&self->ptr, name);
2490                 if(prop==NULL) {
2491                         PyErr_Format(PyExc_TypeError, "%.200s.path_from_id(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
2492                         return NULL;
2493                 }
2494
2495                 path= RNA_path_from_ID_to_property(&self->ptr, prop);
2496         }
2497         else {
2498                 path= RNA_path_from_ID_to_struct(&self->ptr);
2499         }
2500
2501         if(path==NULL) {
2502                 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);
2503                 else            PyErr_Format(PyExc_TypeError, "%.200s.path_from_id() does not support path creation for this type", RNA_struct_identifier(self->ptr.type));
2504                 return NULL;
2505         }
2506
2507         ret= PyUnicode_FromString(path);
2508         MEM_freeN(path);
2509
2510         return ret;
2511 }
2512
2513 static char pyrna_prop_path_from_id_doc[] =
2514 ".. method:: path_from_id()\n"
2515 "\n"
2516 "   Returns the data path from the ID to this property (string).\n"
2517 "\n"
2518 "   :return: The path from :class:`bpy_struct.id_data` to this property.\n"
2519 "   :rtype: str";
2520
2521 static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
2522 {
2523         char *path;
2524         PropertyRNA *prop = self->prop;
2525         PyObject *ret;
2526
2527         path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
2528
2529         if(path==NULL) {
2530                 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));
2531                 return NULL;
2532         }
2533
2534         ret= PyUnicode_FromString(path);
2535         MEM_freeN(path);
2536
2537         return ret;
2538 }
2539
2540 static char pyrna_struct_type_recast_doc[] =
2541 ".. method:: type_recast()\n"
2542 "\n"
2543 "   Return a new instance, this is needed because types such as textures can be changed at runtime.\n"
2544 "\n"
2545 "   :return: a new instance of this object with the type initialized again.\n"
2546 "   :rtype: subclass of :class:`bpy_struct`";
2547
2548 static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
2549 {
2550         PointerRNA r_ptr;
2551         RNA_pointer_recast(&self->ptr, &r_ptr);
2552         return pyrna_struct_CreatePyObject(&r_ptr);
2553 }
2554
2555 static void pyrna_dir_members_py(PyObject *list, PyObject *self)
2556 {
2557         PyObject *dict;
2558         PyObject **dict_ptr;
2559         PyObject *list_tmp;
2560
2561         dict_ptr= _PyObject_GetDictPtr((PyObject *)self);
2562
2563         if(dict_ptr && (dict=*dict_ptr)) {
2564                 list_tmp = PyDict_Keys(dict);
2565                 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
2566                 Py_DECREF(list_tmp);
2567         }
2568
2569         dict= ((PyTypeObject *)Py_TYPE(self))->tp_dict;
2570         if(dict) {
2571                 list_tmp = PyDict_Keys(dict);
2572                 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
2573                 Py_DECREF(list_tmp);
2574         }
2575 }
2576
2577 static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
2578 {
2579         PyObject *pystring;
2580         const char *idname;
2581
2582         /* for looping over attrs and funcs */
2583         PointerRNA tptr;
2584         PropertyRNA *iterprop;
2585
2586         {
2587                 RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
2588                 iterprop= RNA_struct_find_property(&tptr, "functions");
2589
2590                 RNA_PROP_BEGIN(&tptr, itemptr, iterprop) {
2591                         idname= RNA_function_identifier(itemptr.data);
2592
2593                         pystring = PyUnicode_FromString(idname);
2594                         PyList_Append(list, pystring);
2595                         Py_DECREF(pystring);
2596                 }
2597                 RNA_PROP_END;
2598         }
2599
2600         {
2601                 /*
2602                  * Collect RNA attributes
2603                  */
2604                 char name[256], *nameptr;
2605
2606                 iterprop= RNA_struct_iterator_property(ptr->type);
2607
2608                 RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
2609                         nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
2610
2611                         if(nameptr) {
2612                                 pystring = PyUnicode_FromString(nameptr);
2613                                 PyList_Append(list, pystring);
2614                                 Py_DECREF(pystring);
2615
2616                                 if(name != nameptr)
2617                                         MEM_freeN(nameptr);
2618                         }
2619                 }
2620                 RNA_PROP_END;
2621         }
2622 }
2623
2624
2625 static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
2626 {
2627         PyObject *ret;
2628         PyObject *pystring;
2629
2630         /* Include this incase this instance is a subtype of a python class
2631          * In these instances we may want to return a function or variable provided by the subtype
2632          * */
2633         ret = PyList_New(0);
2634
2635         if (!BPy_StructRNA_CheckExact(self))
2636                 pyrna_dir_members_py(ret, (PyObject *)self);
2637
2638         pyrna_dir_members_rna(ret, &self->ptr);
2639
2640         if(self->ptr.type == &RNA_Context) {
2641                 ListBase lb = CTX_data_dir_get(self->ptr.data);
2642                 LinkData *link;
2643
2644                 for(link=lb.first; link; link=link->next) {
2645                         pystring = PyUnicode_FromString(link->data);
2646                         PyList_Append(ret, pystring);
2647                         Py_DECREF(pystring);
2648                 }
2649
2650                 BLI_freelistN(&lb);
2651         }
2652         return ret;
2653 }
2654
2655 //---------------getattr--------------------------------------------
2656 static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
2657 {
2658         char *name = _PyUnicode_AsString(pyname);
2659         PyObject *ret;
2660         PropertyRNA *prop;
2661         FunctionRNA *func;
2662         
2663         if(name == NULL) {
2664                 PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
2665                 ret = NULL;
2666         }
2667         else if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
2668                 /* annoying exception, maybe we need to have different types for this... */
2669                 if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idprops_check(self->ptr.type)) {
2670                         PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
2671                         ret = NULL;
2672                 }
2673                 else {
2674                         ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
2675                 }
2676         }
2677         else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
2678                   ret = pyrna_prop_to_py(&self->ptr, prop);
2679         }
2680         /* RNA function only if callback is declared (no optional functions) */
2681         else if ((func = RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) {
2682                 ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
2683         }
2684         else if (self->ptr.type == &RNA_Context) {
2685                 bContext *C = self->ptr.data;
2686                 if(C==NULL) {
2687                         PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name);
2688                         ret= NULL;
2689                 }
2690                 else {
2691                         PointerRNA newptr;
2692                         ListBase newlb;
2693                         short newtype;
2694
2695                         int done= CTX_data_get(C, name, &newptr, &newlb, &newtype);
2696
2697                         if(done==1) { /* found */
2698                                 switch(newtype) {
2699                                 case CTX_DATA_TYPE_POINTER:
2700                                         if(newptr.data == NULL) {
2701                                                 ret= Py_None;
2702                                                 Py_INCREF(ret);
2703                                         }
2704                                         else {
2705                                                 ret= pyrna_struct_CreatePyObject(&newptr);
2706                                         }
2707                                         break;
2708                                 case CTX_DATA_TYPE_COLLECTION:
2709                                         {
2710                                                 CollectionPointerLink *link;
2711                                                 PyObject *linkptr;
2712         
2713                                                 ret = PyList_New(0);
2714         
2715                                                 for(link=newlb.first; link; link=link->next) {
2716                                                         linkptr= pyrna_struct_CreatePyObject(&link->ptr);
2717                                                         PyList_Append(ret, linkptr);
2718                                                         Py_DECREF(linkptr);
2719                                                 }
2720                                         }
2721                                         break;
2722                                 default:
2723                                         /* should never happen */
2724                                         BKE_assert(!"Invalid context type");
2725
2726                                         PyErr_Format(PyExc_AttributeError, "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context", newtype, name);
2727                                         ret= NULL;
2728                                 }
2729                         }
2730                         else if (done==-1) { /* found but not set */
2731                                 ret = Py_None;
2732                                 Py_INCREF(ret);
2733                         }
2734                         else { /* not found in the context */
2735                                 /* lookup the subclass. raise an error if its not found */
2736                                 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
2737                         }
2738
2739                         BLI_freelistN(&newlb);
2740                 }
2741         }
2742         else {
2743 #if 0
2744                 PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
2745                 ret = NULL;
2746 #endif
2747                 /* Include this incase this instance is a subtype of a python class
2748                  * In these instances we may want to return a function or variable provided by the subtype
2749                  *
2750                  * Also needed to return methods when its not a subtype
2751                  * */
2752
2753                 /* The error raised here will be displayed */
2754                 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
2755         }
2756         
2757         return ret;
2758 }
2759
2760 #if 0
2761 static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname)
2762 {
2763          PyObject *dict= *(_PyObject_GetDictPtr((PyObject *)self));
2764          if (dict==NULL) /* unlikely */
2765                  return 0;
2766
2767         return PyDict_Contains(dict, pyname);
2768 }
2769 #endif
2770
2771 //--------------- setattr-------------------------------------------
2772 static int pyrna_is_deferred_prop(PyObject *value)
2773 {
2774         return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value)==2 && PyCallable_Check(PyTuple_GET_ITEM(value, 0)) && PyDict_CheckExact(PyTuple_GET_ITEM(value, 1));
2775 }
2776
2777 static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *pyname)
2778 {
2779         return PyType_Type.tp_getattro(cls, pyname);    
2780 }
2781
2782 static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
2783 {
2784         StructRNA *srna= srna_from_self(cls, "");
2785
2786         if(srna == NULL) {
2787                 if(value && pyrna_is_deferred_prop(value)) {
2788                         PyErr_Format(PyExc_AttributeError, "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'", ((PyTypeObject *)cls)->tp_name);
2789                         return -1;
2790                 }
2791
2792                 /* srna_from_self may set an error */
2793                 PyErr_Clear(); 
2794                 return PyType_Type.tp_setattro(cls, attr, value);
2795         }
2796
2797         if(value) {
2798                 /* check if the value is a property */
2799                 if(pyrna_is_deferred_prop(value)) {
2800                         int ret= deferred_register_prop(srna, attr, value);
2801                         if(ret < 0)
2802                                 return ret;
2803                         /* pass through, when the value isn't assigned it still works but gets confusing from script writers POV */
2804                 }
2805                 else {
2806                         /* remove existing property if its set or we also end up with confusement */
2807                         char *attr_str= _PyUnicode_AsString(attr);
2808                         RNA_def_property_free_identifier(srna, attr_str); /* ignore on failier */
2809                 }
2810         }
2811         else { /* __delattr__ */
2812                 /* first find if this is a registered property */
2813                 char *attr_str= _PyUnicode_AsString(attr);
2814                 int ret= RNA_def_property_free_identifier(srna, attr_str);
2815                 if (ret == -1) {
2816                         PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str);
2817                         return -1;
2818                 }
2819         }
2820         
2821         /* fallback to standard py, delattr/setattr */
2822         return PyType_Type.tp_setattro(cls, attr, value);
2823 }
2824                 
2825 static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObject *value )
2826 {
2827         char *name = _PyUnicode_AsString(pyname);
2828         PropertyRNA *prop= NULL;
2829
2830 #ifdef USE_PEDANTIC_WRITE
2831         if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
2832                 return -1;
2833         }
2834 #endif // USE_STRING_COERCE
2835
2836         if(name == NULL) {
2837                 PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
2838                 return -1;
2839         }
2840         else if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) {
2841                 if (!RNA_property_editable_flag(&self->ptr, prop)) {
2842                         PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
2843                         return -1;
2844                 }
2845         }
2846         else if (self->ptr.type == &RNA_Context) {
2847                 /* code just raises correct error, context prop's cant be set, unless its apart of the py class */
2848                 bContext *C = self->ptr.data;
2849                 if(C==NULL) {
2850                         PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", name);
2851                         return -1;
2852                 }
2853                 else {
2854                         PointerRNA newptr;
2855                         ListBase newlb;
2856                         short newtype;
2857
2858                         int done= CTX_data_get(C, name, &newptr, &newlb, &newtype);
2859
2860                         if(done==1) {
2861                                 PyErr_Format(PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name);
2862                                 BLI_freelistN(&newlb);
2863                                 return -1;
2864                         }
2865
2866                         BLI_freelistN(&newlb);
2867                 }
2868         }
2869
2870         /* pyrna_py_to_prop sets its own exceptions */
2871         if(prop) {
2872                 if(value == NULL) {
2873                         PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
2874                         return -1;
2875                 }
2876                 return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:");
2877         }
2878         else {
2879                 return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
2880         }
2881 }
2882
2883 static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
2884 {
2885         PyObject *ret;
2886         PointerRNA r_ptr;
2887
2888         /* Include this incase this instance is a subtype of a python class
2889          * In these instances we may want to return a function or variable provided by the subtype
2890          * */
2891         ret = PyList_New(0);
2892
2893         if (!BPy_PropertyRNA_CheckExact(self))
2894                 pyrna_dir_members_py(ret, (PyObject *)self);
2895
2896         if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr))
2897                 pyrna_dir_members_rna(ret, &r_ptr);
2898
2899         return ret;
2900 }
2901
2902
2903 static PyObject *pyrna_prop_array_getattro( BPy_PropertyRNA *self, PyObject *pyname )
2904 {
2905         return PyObject_GenericGetAttr((PyObject *)self, pyname);
2906 }
2907
2908 static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject *pyname )
2909 {
2910         char *name = _PyUnicode_AsString(pyname);
2911
2912         if(name == NULL) {
2913                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
2914                 return NULL;
2915         }
2916         else if(name[0] != '_') {
2917                 PyObject *ret;
2918                 PropertyRNA *prop;
2919                 FunctionRNA *func;
2920
2921                 PointerRNA r_ptr;
2922                 if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
2923                         if ((prop = RNA_struct_find_property(&r_ptr, name))) {
2924                                 ret = pyrna_prop_to_py(&r_ptr, prop);
2925
2926                                 return ret;
2927                         }
2928                         else if ((func = RNA_struct_find_function(&r_ptr, name))) {
2929                                 PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr);
2930                                 ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
2931                                 Py_DECREF(self_collection);
2932
2933                                 return ret;
2934                         }
2935                 }
2936         }
2937
2938         /* The error raised here will be displayed */
2939         return PyObject_GenericGetAttr((PyObject *)self, pyname);
2940 }
2941
2942 //--------------- setattr-------------------------------------------
2943 static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObject *value )
2944 {
2945         char *name = _PyUnicode_AsString(pyname);
2946         PropertyRNA *prop;
2947         PointerRNA r_ptr;
2948
2949 #ifdef USE_PEDANTIC_WRITE
2950         if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
2951                 return -1;
2952         }
2953 #endif // USE_STRING_COERCE
2954
2955         if(name == NULL) {
2956                 PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
2957                 return -1;
2958         }
2959         else if(value == NULL) {
2960                 PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
2961                 return -1;
2962         }
2963         else if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
2964                 if ((prop = RNA_struct_find_property(&r_ptr, name))) {
2965                         /* pyrna_py_to_prop sets its own exceptions */
2966                         return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
2967                 }
2968         }
2969
2970         PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
2971         return -1;
2972 }
2973
2974 /* odd case, we need to be able return a python method from a tp_getset */
2975 static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
2976 {
2977         PointerRNA r_ptr;
2978
2979         RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
2980         if(!r_ptr.data) {
2981                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.add(): not supported for this collection");
2982                 return NULL;
2983         }
2984         else {
2985                 return pyrna_struct_CreatePyObject(&r_ptr);
2986         }
2987 }
2988
2989 static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
2990 {
2991         int key= PyLong_AsLong(value);
2992
2993         if (key==-1 && PyErr_Occurred()) {
2994                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument");
2995                 return NULL;
2996         }
2997
2998         if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
2999                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove() not supported for this collection");
3000                 return NULL;
3001         }
3002
3003         Py_RETURN_NONE;
3004 }
3005
3006 static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args)
3007 {
3008         int key=0, pos=0;
3009
3010         if (!PyArg_ParseTuple(args, "ii", &key, &pos)) {
3011                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments");
3012                 return NULL;
3013         }
3014
3015         if(!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) {
3016                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move() not supported for this collection");
3017                 return NULL;
3018         }
3019
3020         Py_RETURN_NONE;
3021 }
3022
3023 static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
3024 {
3025         /* used for struct and pointer since both have a ptr */
3026         if(self->ptr.id.data) {
3027                 PointerRNA id_ptr;
3028                 RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr);
3029                 return pyrna_struct_CreatePyObject(&id_ptr);
3030         }
3031
3032         Py_RETURN_NONE;
3033 }
3034
3035 /*****************************************************************************/
3036 /* Python attributes get/set structure:                                      */
3037 /*****************************************************************************/
3038
3039 static PyGetSetDef pyrna_prop_getseters[] = {
3040         {(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},
3041         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
3042 };
3043
3044
3045 static PyGetSetDef pyrna_struct_getseters[] = {
3046         {(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},
3047         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
3048 };
3049
3050 static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
3051 {
3052         PyObject *ret= PyList_New(0);
3053         PyObject *item;
3054         char name[256], *nameptr;
3055
3056         RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
3057                 nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
3058
3059                 if(nameptr) {
3060                         /* add to python list */
3061                         item = PyUnicode_FromString( nameptr );
3062                         PyList_Append(ret, item);
3063                         Py_DECREF(item);
3064                         /* done */
3065
3066                         if(name != nameptr)
3067                                 MEM_freeN(nameptr);
3068                 }
3069         }
3070         RNA_PROP_END;
3071         
3072         return ret;
3073 }
3074
3075 static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
3076 {
3077         PyObject *ret= PyList_New(0);
3078         PyObject *item;
3079         char name[256], *nameptr;
3080         int i= 0;
3081
3082         RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
3083                 if(itemptr.data) {
3084                         /* add to python list */
3085                         item= PyTuple_New(2);
3086                         nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
3087                         if(nameptr) {
3088                                 PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));