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