8f745bc2756fc6faa3a4a779037795970a013745
[blender-staging.git] / source / blender / python / intern / bpy_rna.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24 #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                                 param= PyC_UnicodeAsByte(value, &value_coerce);
1079                         }
1080                         else {
1081                                 param= _PyUnicode_AsString(value);
1082                         }
1083 #else // USE_STRING_COERCE
1084                         param= _PyUnicode_AsString(value);
1085 #endif // USE_STRING_COERCE
1086
1087                         if (param==NULL) {
1088                                 PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a string type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
1089                                 return -1;
1090                         }
1091                         else {
1092                                 if(data)        *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1093                                 else            RNA_property_string_set(ptr, prop, param);
1094                         }
1095 #ifdef USE_STRING_COERCE
1096                         Py_XDECREF(value_coerce);
1097 #endif // USE_STRING_COERCE
1098                         break;
1099                 }
1100                 case PROP_ENUM:
1101                 {
1102                         int val= 0;
1103
1104                         if (PyUnicode_Check(value)) {
1105                                 if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix))
1106                                         return -1;
1107                         }
1108                         else if (PyAnySet_Check(value)) {
1109                                 if(RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1110                                         /* set of enum items, concatenate all values with OR */
1111                                         if(pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0)
1112                                                 return -1;
1113                                 }
1114                                 else {
1115                                         PyErr_Format(PyExc_TypeError, "%.200s, %.200s.%.200s is not a bitflag enum type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
1116                                         return -1;
1117                                 }
1118                         }
1119                         else {
1120                                 const char *enum_str= pyrna_enum_as_string(ptr, prop);
1121                                 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);
1122                                 MEM_freeN((void *)enum_str);
1123                                 return -1;
1124                         }
1125
1126                         if(data)        *((int*)data)= val;
1127                         else            RNA_property_enum_set(ptr, prop, val);
1128                         
1129                         break;
1130                 }
1131                 case PROP_POINTER:
1132                 {
1133                         PyObject *value_new= NULL;
1134                                         
1135                         StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
1136                         int flag = RNA_property_flag(prop);
1137
1138                         /* this is really nasty!, so we can fake the operator having direct properties eg:
1139                          * layout.prop(self, "filepath")
1140                          * ... which infact should be
1141                          * layout.prop(self.properties, "filepath")
1142                          * 
1143                          * we need to do this trick.
1144                          * if the prop is not an operator type and the pyobject is an operator, use its properties in place of its self.
1145                          * 
1146                          * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing
1147                          * if this causes problems in the future it should be removed.
1148                          */
1149                         if(     (ptype == &RNA_AnyType) &&
1150                                 (BPy_StructRNA_Check(value)) &&
1151                                 (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator))
1152                         ) {
1153                                 value= PyObject_GetAttrString(value, "properties");
1154                                 value_new= value;
1155                         }
1156
1157
1158                         /* if property is an OperatorProperties pointer and value is a map, forward back to pyrna_pydict_to_props */
1159                         if (RNA_struct_is_a(ptype, &RNA_OperatorProperties) && PyDict_Check(value)) {
1160                                 PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1161                                 return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
1162                         }
1163
1164                         /* another exception, allow to pass a collection as an RNA property */
1165                         if(Py_TYPE(value)==&pyrna_prop_collection_Type) { /* ok to ignore idprop collections */
1166                                 PointerRNA c_ptr;
1167                                 BPy_PropertyRNA *value_prop= (BPy_PropertyRNA *)value;
1168                                 if(RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1169                                         value= pyrna_struct_CreatePyObject(&c_ptr);
1170                                         value_new= value;
1171                                 }
1172                                 else {
1173                                         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));
1174                                         return -1;
1175                                 }
1176                         }
1177
1178                         if(!BPy_StructRNA_Check(value) && value != Py_None) {
1179                                 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));
1180                                 Py_XDECREF(value_new); return -1;
1181                         } else if((flag & PROP_NEVER_NULL) && value == Py_None) {
1182                                 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));
1183                                 Py_XDECREF(value_new); return -1;
1184                         } else if(value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
1185                                 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));
1186                                 Py_XDECREF(value_new); return -1;
1187                         } else {
1188                                 BPy_StructRNA *param= (BPy_StructRNA*)value;
1189                                 int raise_error= FALSE;
1190                                 if(data) {
1191
1192                                         if(flag & PROP_RNAPTR) {
1193                                                 if(value == Py_None)
1194                                                         memset(data, 0, sizeof(PointerRNA));
1195                                                 else
1196                                                         *((PointerRNA*)data)= param->ptr;
1197                                         }
1198                                         else if(value == Py_None) {
1199                                                 *((void**)data)= NULL;
1200                                         }
1201                                         else if(RNA_struct_is_a(param->ptr.type, ptype)) {
1202                                                 *((void**)data)= param->ptr.data;
1203                                         }
1204                                         else {
1205                                                 raise_error= TRUE;
1206                                         }
1207                                 }
1208                                 else {
1209                                         /* data==NULL, assign to RNA */
1210                                         if(value == Py_None) {
1211                                                 PointerRNA valueptr= {{0}};
1212                                                 RNA_property_pointer_set(ptr, prop, valueptr);
1213                                         }
1214                                         else if(RNA_struct_is_a(param->ptr.type, ptype)) {
1215                                                 RNA_property_pointer_set(ptr, prop, param->ptr);
1216                                         }
1217                                         else {
1218                                                 PointerRNA tmp;
1219                                                 RNA_pointer_create(NULL, ptype, NULL, &tmp);
1220                                                 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));
1221                                                 Py_XDECREF(value_new); return -1;
1222                                         }
1223                                 }
1224                                 
1225                                 if(raise_error) {
1226                                         PointerRNA tmp;
1227                                         RNA_pointer_create(NULL, ptype, NULL, &tmp);
1228                                         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));
1229                                         Py_XDECREF(value_new); return -1;
1230                                 }
1231                         }
1232                         
1233                         Py_XDECREF(value_new);
1234
1235                         break;
1236                 }
1237                 case PROP_COLLECTION:
1238                 {
1239                         int seq_len, i;
1240                         PyObject *item;
1241                         PointerRNA itemptr;
1242                         ListBase *lb;
1243                         CollectionPointerLink *link;
1244
1245                         lb= (data)? (ListBase*)data: NULL;
1246                         
1247                         /* convert a sequence of dict's into a collection */
1248                         if(!PySequence_Check(value)) {
1249                                 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);
1250                                 return -1;
1251                         }
1252
1253                         seq_len = PySequence_Size(value);
1254                         for(i=0; i<seq_len; i++) {
1255                                 item= PySequence_GetItem(value, i);
1256
1257                                 if(item==NULL) {
1258                                         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);
1259                                         Py_XDECREF(item);
1260                                         return -1;
1261                                 }
1262
1263                                 if(PyDict_Check(item)==0) {
1264                                         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);
1265                                         Py_XDECREF(item);
1266                                         return -1;
1267                                 }
1268
1269                                 if(lb) {
1270                                         link= MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
1271                                         link->ptr= itemptr;
1272                                         BLI_addtail(lb, link);
1273                                 }
1274                                 else
1275                                         RNA_property_collection_add(ptr, prop, &itemptr);
1276
1277                                 if(pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection")==-1) {
1278                                         PyObject *msg= PyC_ExceptionBuffer();
1279                                         char *msg_char= _PyUnicode_AsString(msg);
1280
1281                                         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);
1282
1283                                         Py_DECREF(item);
1284                                         Py_DECREF(msg);
1285                                         return -1;
1286                                 }
1287                                 Py_DECREF(item);
1288                         }
1289                         
1290                         break;
1291                 }
1292                 default:
1293                         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));
1294                         return -1;
1295                         break;
1296                 }
1297         }
1298
1299         /* Run rna property functions */
1300         if(RNA_property_update_check(prop)) {
1301                 RNA_property_update(BPy_GetContext(), ptr, prop);
1302         }
1303
1304         return 0;
1305 }
1306
1307 static PyObject * pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
1308 {
1309         return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
1310 }
1311
1312 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
1313 {
1314         int ret = 0;
1315         PointerRNA *ptr= &self->ptr;
1316         PropertyRNA *prop= self->prop;
1317
1318         const int totdim= RNA_property_array_dimension(ptr, prop, NULL);
1319
1320         if (totdim > 1) {
1321                 /* char error_str[512]; */
1322                 if (!pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "")) {
1323                         /* PyErr_SetString(PyExc_AttributeError, error_str); */
1324                         ret= -1;
1325                 }
1326         }
1327         else {
1328                 /* see if we can coorce into a python type - PropertyType */
1329                 switch (RNA_property_type(prop)) {
1330                 case PROP_BOOLEAN:
1331                         {
1332                                 int param = PyLong_AsLong( value );
1333                 
1334                                 if( param < 0 || param > 1) {
1335                                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1336                                         ret = -1;
1337                                 } else {
1338                                         RNA_property_boolean_set_index(ptr, prop, index, param);
1339                                 }
1340                                 break;
1341                         }
1342                 case PROP_INT:
1343                         {
1344                                 int param = PyLong_AsLong(value);
1345                                 if (param==-1 && PyErr_Occurred()) {
1346                                         PyErr_SetString(PyExc_TypeError, "expected an int type");
1347                                         ret = -1;
1348                                 } else {
1349                                         RNA_property_int_clamp(ptr, prop, &param);
1350                                         RNA_property_int_set_index(ptr, prop, index, param);
1351                                 }
1352                                 break;
1353                         }
1354                 case PROP_FLOAT:
1355                         {
1356                                 float param = PyFloat_AsDouble(value);
1357                                 if (PyErr_Occurred()) {
1358                                         PyErr_SetString(PyExc_TypeError, "expected a float type");
1359                                         ret = -1;
1360                                 } else {
1361                                         RNA_property_float_clamp(ptr, prop, &param);
1362                                         RNA_property_float_set_index(ptr, prop, index, param);
1363                                 }
1364                                 break;
1365                         }
1366                 default:
1367                         PyErr_SetString(PyExc_AttributeError, "not an array type");
1368                         ret = -1;
1369                         break;
1370                 }
1371         }
1372
1373         /* Run rna property functions */
1374         if(RNA_property_update_check(prop)) {
1375                 RNA_property_update(BPy_GetContext(), ptr, prop);
1376         }
1377
1378         return ret;
1379 }
1380
1381 //---------------sequence-------------------------------------------
1382 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
1383 {
1384         if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
1385                 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
1386         else
1387                 return RNA_property_array_length(&self->ptr, self->prop);
1388 }
1389
1390 static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self )
1391 {
1392         return RNA_property_collection_length(&self->ptr, self->prop);
1393 }
1394
1395 /* bool funcs are for speed, so we can avoid getting the length
1396  * of 1000's of items in a linked list for eg. */
1397 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
1398 {
1399         return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
1400 }
1401
1402 static int pyrna_prop_collection_bool( BPy_PropertyRNA *self )
1403 {
1404         /* no callback defined, just iterate and find the nth item */
1405         CollectionPropertyIterator iter;
1406         int test;
1407
1408         RNA_property_collection_begin(&self->ptr, self->prop, &iter);
1409         test = iter.valid;
1410         RNA_property_collection_end(&iter);
1411         return test;
1412 }
1413
1414 /* internal use only */
1415 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
1416 {
1417         PointerRNA newptr;
1418         Py_ssize_t keynum_abs= keynum;
1419
1420         /* notice getting the length of the collection is avoided unless negative index is used
1421          * or to detect internal error with a valid index.
1422          * This is done for faster lookups. */
1423         if(keynum < 0) {
1424                 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop);
1425
1426                 if(keynum_abs < 0) {
1427                         PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum);
1428                         return NULL;
1429                 }
1430         }
1431
1432         if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
1433                 return pyrna_struct_CreatePyObject(&newptr);
1434         }
1435         else {
1436                 const int len= RNA_property_collection_length(&self->ptr, self->prop);
1437                 if(keynum_abs >= len) {
1438                         PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
1439                 }
1440                 else {
1441                         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);
1442                 }
1443
1444                 return NULL;
1445         }
1446 }
1447
1448 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
1449 {
1450         int len= pyrna_prop_array_length(self);
1451
1452         if(keynum < 0) keynum += len;
1453
1454         if(keynum >= 0 && keynum < len)
1455                 return pyrna_prop_array_to_py_index(self, keynum);
1456
1457         PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
1458         return NULL;
1459 }
1460
1461 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
1462 {
1463         PointerRNA newptr;
1464         if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
1465                 return pyrna_struct_CreatePyObject(&newptr);
1466
1467         PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
1468         return NULL;
1469 }
1470 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
1471
1472 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
1473 {
1474         int count= 0;
1475
1476         PyObject *list= PyList_New(0);
1477         PyObject *item;
1478
1479         /* first loop up-until the start */
1480         CollectionPropertyIterator rna_macro_iter;
1481         for(RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
1482                 /* PointerRNA itemptr= rna_macro_iter.ptr; */
1483                 if(count == start) {
1484                         break;
1485                 }
1486                 count++;
1487         }
1488
1489         /* add items until stop */
1490         for(; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
1491                 item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
1492                 PyList_Append(list, item);
1493                 Py_DECREF(item);
1494
1495                 count++;
1496                 if(count == stop) {
1497                         break;
1498                 }
1499         }
1500
1501         RNA_property_collection_end(&rna_macro_iter);
1502
1503         return list;
1504 }
1505
1506 /* TODO - dimensions
1507  * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
1508  * since at the moment it reads (and even allocates) the entire array for each index.
1509  */
1510 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)
1511 {
1512         int count, totdim;
1513
1514         PyObject *tuple= PyTuple_New(stop - start);
1515
1516         totdim = RNA_property_array_dimension(ptr, prop, NULL);
1517
1518         if (totdim > 1) {
1519                 for (count = start; count < stop; count++)
1520                         PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
1521         }
1522         else {
1523                 switch (RNA_property_type(prop)) {
1524                 case PROP_FLOAT:
1525                         {
1526                                 float values_stack[PYRNA_STACK_ARRAY];
1527                                 float *values;
1528                                 if(length > PYRNA_STACK_ARRAY)  {       values= PyMem_MALLOC(sizeof(float) * length); }
1529                                 else                                                    {       values= values_stack; }
1530                                 RNA_property_float_get_array(ptr, prop, values);
1531                         
1532                                 for(count=start; count<stop; count++)
1533                                         PyTuple_SET_ITEM(tuple, count-start, PyFloat_FromDouble(values[count]));
1534
1535                                 if(values != values_stack) {
1536                                         PyMem_FREE(values);
1537                                 }
1538                                 break;
1539                         }
1540                 case PROP_BOOLEAN:
1541                         {
1542                                 int values_stack[PYRNA_STACK_ARRAY];
1543                                 int *values;
1544                                 if(length > PYRNA_STACK_ARRAY)  {       values= PyMem_MALLOC(sizeof(int) * length); }
1545                                 else                                                    {       values= values_stack; }
1546
1547                                 RNA_property_boolean_get_array(ptr, prop, values);
1548                                 for(count=start; count<stop; count++)
1549                                         PyTuple_SET_ITEM(tuple, count-start, PyBool_FromLong(values[count]));
1550
1551                                 if(values != values_stack) {
1552                                         PyMem_FREE(values);
1553                                 }
1554                                 break;
1555                         }
1556                 case PROP_INT:
1557                         {
1558                                 int values_stack[PYRNA_STACK_ARRAY];
1559                                 int *values;
1560                                 if(length > PYRNA_STACK_ARRAY)  {       values= PyMem_MALLOC(sizeof(int) * length); }
1561                                 else                                                    {       values= values_stack; }
1562
1563                                 RNA_property_int_get_array(ptr, prop, values);
1564                                 for(count=start; count<stop; count++)
1565                                         PyTuple_SET_ITEM(tuple, count-start, PyLong_FromSsize_t(values[count]));
1566
1567                                 if(values != values_stack) {
1568                                         PyMem_FREE(values);
1569                                 }
1570                                 break;
1571                         }
1572                 default:
1573                         BLI_assert(!"Invalid array type");
1574
1575                         PyErr_SetString(PyExc_TypeError, "not an array type");
1576                         Py_DECREF(tuple);
1577                         tuple= NULL;
1578                 }
1579         }
1580         return tuple;
1581 }
1582
1583 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
1584 {
1585         if (PyUnicode_Check(key)) {
1586                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
1587         }
1588         else if (PyIndex_Check(key)) {
1589                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1590                 if (i == -1 && PyErr_Occurred())
1591                         return NULL;
1592
1593                 return pyrna_prop_collection_subscript_int(self, i);
1594         }
1595         else if (PySlice_Check(key)) {
1596                 PySliceObject *key_slice= (PySliceObject *)key;
1597                 Py_ssize_t step= 1;
1598
1599                 if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
1600                         return NULL;
1601                 }
1602                 else if (step != 1) {
1603                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
1604                         return NULL;
1605                 }
1606                 else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
1607                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
1608                 }
1609                 else {
1610                         Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
1611
1612                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
1613                         if(key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start))        return NULL;
1614                         if(key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))           return NULL;
1615
1616                         if(start < 0 || stop < 0) {
1617                                 /* only get the length for negative values */
1618                                 Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
1619                                 if(start < 0) start += len;
1620                                 if(stop < 0) start += len;
1621                         }
1622
1623                         if (stop - start <= 0) {
1624                                 return PyList_New(0);
1625                         }
1626                         else {
1627                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
1628                         }
1629                 }
1630         }
1631         else {
1632                 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);
1633                 return NULL;
1634         }
1635 }
1636
1637 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
1638 {
1639         /*if (PyUnicode_Check(key)) {
1640                 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
1641         } else*/
1642         if (PyIndex_Check(key)) {
1643                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1644                 if (i == -1 && PyErr_Occurred())
1645                         return NULL;
1646                 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
1647         }
1648         else if (PySlice_Check(key)) {
1649                 Py_ssize_t step= 1;
1650                 PySliceObject *key_slice= (PySliceObject *)key;
1651
1652                 if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
1653                         return NULL;
1654                 }
1655                 else if (step != 1) {
1656                         PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
1657                         return NULL;
1658                 }
1659                 else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
1660                         /* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
1661                         Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self);
1662                         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
1663                 }
1664                 else {
1665                         int len= pyrna_prop_array_length(self);
1666                         Py_ssize_t start, stop, slicelength;
1667
1668                         if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0)
1669                                 return NULL;
1670
1671                         if (slicelength <= 0) {
1672                                 return PyTuple_New(0);
1673                         }
1674                         else {
1675                                 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
1676                         }
1677                 }
1678         }
1679         else {
1680                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
1681                 return NULL;
1682         }
1683 }
1684
1685 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
1686 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length, PyObject *value_orig)
1687 {
1688         PyObject *value;
1689         int count;
1690         void *values_alloc= NULL;
1691         int ret= 0;
1692
1693         if(value_orig == NULL) {
1694                 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
1695                 return -1;
1696         }
1697
1698         if(!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
1699                 return -1;
1700         }
1701
1702         if(PySequence_Fast_GET_SIZE(value) != stop-start) {
1703                 Py_DECREF(value);
1704                 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported");
1705                 return -1;
1706         }
1707
1708         switch (RNA_property_type(prop)) {
1709                 case PROP_FLOAT:
1710                 {
1711                         float values_stack[PYRNA_STACK_ARRAY];
1712                         float *values, fval;
1713
1714                         float min, max;
1715                         RNA_property_float_range(ptr, prop, &min, &max);
1716
1717                         if(length > PYRNA_STACK_ARRAY)  {       values= values_alloc= PyMem_MALLOC(sizeof(float) * length); }
1718                         else                                                    {       values= values_stack; }
1719                         if(start != 0 || stop != length) /* partial assignment? - need to get the array */
1720                                 RNA_property_float_get_array(ptr, prop, values);
1721                         
1722                         for(count=start; count<stop; count++) {
1723                                 fval = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
1724                                 CLAMP(fval, min, max);
1725                                 values[count] = fval;
1726                         }
1727
1728                         if(PyErr_Occurred())    ret= -1;
1729                         else                                    RNA_property_float_set_array(ptr, prop, values);
1730                         break;
1731                 }
1732                 case PROP_BOOLEAN:
1733                 {
1734                         int values_stack[PYRNA_STACK_ARRAY];
1735                         int *values;
1736                         if(length > PYRNA_STACK_ARRAY)  {       values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
1737                         else                                                    {       values= values_stack; }
1738
1739                         if(start != 0 || stop != length) /* partial assignment? - need to get the array */
1740                                 RNA_property_boolean_get_array(ptr, prop, values);
1741         
1742                         for(count=start; count<stop; count++)
1743                                 values[count] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
1744
1745                         if(PyErr_Occurred())    ret= -1;
1746                         else                                    RNA_property_boolean_set_array(ptr, prop, values);
1747                         break;
1748                 }
1749                 case PROP_INT:
1750                 {
1751                         int values_stack[PYRNA_STACK_ARRAY];
1752                         int *values, ival;
1753
1754                         int min, max;
1755                         RNA_property_int_range(ptr, prop, &min, &max);
1756
1757                         if(length > PYRNA_STACK_ARRAY)  {       values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
1758                         else                                                    {       values= values_stack; }
1759
1760                         if(start != 0 || stop != length) /* partial assignment? - need to get the array */
1761                                 RNA_property_int_get_array(ptr, prop, values);
1762
1763                         for(count=start; count<stop; count++) {
1764                                 ival = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
1765                                 CLAMP(ival, min, max);
1766                                 values[count] = ival;
1767                         }
1768
1769                         if(PyErr_Occurred())    ret= -1;
1770                         else                                    RNA_property_int_set_array(ptr, prop, values);
1771                         break;
1772                 }
1773                 default:
1774                         PyErr_SetString(PyExc_TypeError, "not an array type");
1775                         ret= -1;
1776         }
1777
1778         Py_DECREF(value);
1779         
1780         if(values_alloc) {
1781                 PyMem_FREE(values_alloc);
1782         }
1783         
1784         return ret;
1785
1786 }
1787
1788 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
1789 {
1790         int len= pyrna_prop_array_length(self);
1791
1792         if(keynum < 0) keynum += len;
1793
1794         if(keynum >= 0 && keynum < len)
1795                 return pyrna_py_to_prop_array_index(self, keynum, value);
1796
1797         PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
1798         return -1;
1799 }
1800
1801 static int pyrna_prop_array_ass_subscript( BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value )
1802 {
1803         /* char *keyname = NULL; */ /* not supported yet */
1804         int ret= -1;
1805
1806         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
1807                 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) );
1808                 ret= -1;
1809         }
1810
1811         else if (PyIndex_Check(key)) {
1812                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1813                 if (i == -1 && PyErr_Occurred()) {
1814                         ret= -1;
1815                 }
1816                 else {
1817                         ret= prop_subscript_ass_array_int(self, i, value);
1818                 }
1819         }
1820         else if (PySlice_Check(key)) {
1821                 int len= RNA_property_array_length(&self->ptr, self->prop);
1822                 Py_ssize_t start, stop, step, slicelength;
1823
1824                 if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) {
1825                         ret= -1;
1826                 }
1827                 else if (slicelength <= 0) {
1828                         ret= 0; /* do nothing */
1829                 }
1830                 else if (step == 1) {
1831                         ret= prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
1832                 }
1833                 else {
1834                         PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
1835                         ret= -1;
1836                 }
1837         }
1838         else {
1839                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
1840                 ret= -1;
1841         }
1842
1843         if(ret != -1) {
1844                 if(RNA_property_update_check(self->prop)) {
1845                         RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
1846                 }
1847         }
1848
1849         return ret;
1850 }
1851
1852 /* for slice only */
1853 static PyMappingMethods pyrna_prop_array_as_mapping = {
1854         ( lenfunc ) pyrna_prop_array_length,    /* mp_length */
1855         ( binaryfunc ) pyrna_prop_array_subscript,      /* mp_subscript */
1856         ( objobjargproc ) pyrna_prop_array_ass_subscript,       /* mp_ass_subscript */
1857 };
1858
1859 static PyMappingMethods pyrna_prop_collection_as_mapping = {
1860         ( lenfunc ) pyrna_prop_collection_length,       /* mp_length */
1861         ( binaryfunc ) pyrna_prop_collection_subscript, /* mp_subscript */
1862         ( objobjargproc ) NULL, /* mp_ass_subscript */
1863 };
1864
1865 /* only for fast bool's, large structs, assign nb_bool on init */
1866 static PyNumberMethods pyrna_prop_array_as_number = {
1867         NULL, /* nb_add */
1868         NULL, /* nb_subtract */
1869         NULL, /* nb_multiply */
1870         NULL, /* nb_remainder */
1871         NULL, /* nb_divmod */
1872         NULL, /* nb_power */
1873         NULL, /* nb_negative */
1874         NULL, /* nb_positive */
1875         NULL, /* nb_absolute */
1876         (inquiry) pyrna_prop_array_bool, /* nb_bool */
1877 };
1878 static PyNumberMethods pyrna_prop_collection_as_number = {
1879         NULL, /* nb_add */
1880         NULL, /* nb_subtract */
1881         NULL, /* nb_multiply */
1882         NULL, /* nb_remainder */
1883         NULL, /* nb_divmod */
1884         NULL, /* nb_power */
1885         NULL, /* nb_negative */
1886         NULL, /* nb_positive */
1887         NULL, /* nb_absolute */
1888         (inquiry) pyrna_prop_collection_bool, /* nb_bool */
1889 };
1890
1891 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
1892 {
1893         return pyrna_array_contains_py(&self->ptr, self->prop, value);
1894 }
1895
1896 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value)
1897 {
1898         PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
1899
1900         /* key in dict style check */
1901         char *keyname = _PyUnicode_AsString(value);
1902
1903         if(keyname==NULL) {
1904                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
1905                 return -1;
1906         }
1907
1908         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
1909                 return 1;
1910
1911         return 0;
1912 }
1913
1914 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
1915 {
1916         IDProperty *group;
1917         char *name = _PyUnicode_AsString(value);
1918
1919         if (!name) {
1920                 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
1921                 return -1;
1922         }
1923
1924         if(RNA_struct_idprops_check(self->ptr.type)==0) {
1925                 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesnt support IDProperties");
1926                 return -1;
1927         }
1928
1929         group= RNA_struct_idprops(&self->ptr, 0);
1930         
1931         if(!group)
1932                 return 0;
1933         
1934         return IDP_GetPropertyFromGroup(group, name) ? 1:0;
1935 }
1936
1937 static PySequenceMethods pyrna_prop_array_as_sequence = {
1938         (lenfunc)pyrna_prop_array_length,               /* Cant set the len otherwise it can evaluate as false */
1939         NULL,           /* sq_concat */
1940         NULL,           /* sq_repeat */
1941         (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
1942         NULL,           /* sq_slice */
1943         (ssizeobjargproc)prop_subscript_ass_array_int,          /* sq_ass_item */
1944         NULL,           /* *was* sq_ass_slice */
1945         (objobjproc)pyrna_prop_array_contains,  /* sq_contains */
1946         (binaryfunc) NULL, /* sq_inplace_concat */
1947         (ssizeargfunc) NULL, /* sq_inplace_repeat */
1948 };
1949
1950 static PySequenceMethods pyrna_prop_collection_as_sequence = {
1951         (lenfunc)pyrna_prop_collection_length,          /* Cant set the len otherwise it can evaluate as false */
1952         NULL,           /* sq_concat */
1953         NULL,           /* sq_repeat */
1954         (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
1955         NULL,           /* *was* sq_slice */
1956         NULL,           /* sq_ass_item */
1957         NULL,           /* *was* sq_ass_slice */
1958         (objobjproc)pyrna_prop_collection_contains,     /* sq_contains */
1959         (binaryfunc) NULL, /* sq_inplace_concat */
1960         (ssizeargfunc) NULL, /* sq_inplace_repeat */
1961 };
1962
1963 static PySequenceMethods pyrna_struct_as_sequence = {
1964         NULL,           /* Cant set the len otherwise it can evaluate as false */
1965         NULL,           /* sq_concat */
1966         NULL,           /* sq_repeat */
1967         NULL,           /* sq_item */ /* Only set this so PySequence_Check() returns True */
1968         NULL,           /* *was* sq_slice */
1969         NULL,           /* sq_ass_item */
1970         NULL,           /* *was* sq_ass_slice */
1971         (objobjproc)pyrna_struct_contains,      /* sq_contains */
1972         (binaryfunc) NULL, /* sq_inplace_concat */
1973         (ssizeargfunc) NULL, /* sq_inplace_repeat */
1974 };
1975
1976 static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
1977 {
1978         /* mostly copied from BPy_IDGroup_Map_GetItem */
1979         IDProperty *group, *idprop;
1980         char *name= _PyUnicode_AsString(key);
1981
1982         if(RNA_struct_idprops_check(self->ptr.type)==0) {
1983                 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
1984                 return NULL;
1985         }
1986
1987         if(name==NULL) {
1988                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
1989                 return NULL;
1990         }
1991
1992         group= RNA_struct_idprops(&self->ptr, 0);
1993
1994         if(group==NULL) {
1995                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
1996                 return NULL;
1997         }
1998
1999         idprop= IDP_GetPropertyFromGroup(group, name);
2000
2001         if(idprop==NULL) {
2002                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2003                 return NULL;
2004         }
2005
2006         return BPy_IDGroup_WrapData(self->ptr.id.data, idprop);
2007 }
2008
2009 static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObject *value )
2010 {
2011         IDProperty *group= RNA_struct_idprops(&self->ptr, 1);
2012
2013 #ifdef USE_PEDANTIC_WRITE
2014         if(rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
2015                 return -1;
2016         }
2017 #endif // USE_STRING_COERCE
2018
2019         if(group==NULL) {
2020                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
2021                 return -1;
2022         }
2023
2024         return BPy_Wrap_SetMapItem(group, key, value);
2025 }
2026
2027 static PyMappingMethods pyrna_struct_as_mapping = {
2028         ( lenfunc ) NULL,       /* mp_length */
2029         ( binaryfunc ) pyrna_struct_subscript,  /* mp_subscript */
2030         ( objobjargproc ) pyrna_struct_ass_subscript,   /* mp_ass_subscript */
2031 };
2032
2033 static char pyrna_struct_keys_doc[] =
2034 ".. method:: keys()\n"
2035 "\n"
2036 "   Returns the keys of this objects custom properties (matches pythons dictionary function of the same name).\n"
2037 "\n"
2038 "   :return: custom property keys.\n"
2039 "   :rtype: list of strings\n"
2040 "\n"
2041 "   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
2042
2043 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
2044 {
2045         IDProperty *group;
2046
2047         if(RNA_struct_idprops_check(self->ptr.type)==0) {
2048                 PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
2049                 return NULL;
2050         }
2051
2052         group= RNA_struct_idprops(&self->ptr, 0);
2053
2054         if(group==NULL)
2055                 return PyList_New(0);
2056
2057         return BPy_Wrap_GetKeys(group);
2058 }
2059
2060 static char pyrna_struct_items_doc[] =
2061 ".. method:: items()\n"
2062 "\n"
2063 "   Returns the items of this objects custom properties (matches pythons dictionary function of the same name).\n"
2064 "\n"
2065 "   :return: custom property key, value pairs.\n"
2066 "   :rtype: list of key, value tuples\n"
2067 "\n"
2068 "   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
2069
2070 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
2071 {
2072         IDProperty *group;
2073
2074         if(RNA_struct_idprops_check(self->ptr.type)==0) {
2075                 PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
2076                 return NULL;
2077         }
2078
2079         group= RNA_struct_idprops(&self->ptr, 0);
2080
2081         if(group==NULL)
2082                 return PyList_New(0);
2083
2084         return BPy_Wrap_GetItems(self->ptr.id.data, group);
2085 }
2086
2087 static char pyrna_struct_values_doc[] =
2088 ".. method:: values()\n"
2089 "\n"
2090 "   Returns the values of this objects custom properties (matches pythons dictionary function of the same name).\n"
2091 "\n"
2092 "   :return: custom property values.\n"
2093 "   :rtype: list\n"
2094 "\n"
2095 "   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
2096
2097 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
2098 {
2099         IDProperty *group;
2100
2101         if(RNA_struct_idprops_check(self->ptr.type)==0) {
2102                 PyErr_SetString(PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
2103                 return NULL;
2104         }
2105
2106         group= RNA_struct_idprops(&self->ptr, 0);
2107
2108         if(group==NULL)
2109                 return PyList_New(0);
2110
2111         return BPy_Wrap_GetValues(self->ptr.id.data, group);
2112 }
2113
2114 /* for keyframes and drivers */
2115 static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
2116         char **path_full, int *index)
2117 {
2118         const int is_idbase= RNA_struct_is_ID(ptr->type);
2119         PropertyRNA *prop;
2120         PointerRNA r_ptr;
2121         
2122         if (ptr->data==NULL) {
2123                 PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
2124                 return -1;
2125         }
2126         
2127         /* full paths can only be given from ID base */
2128         if(is_idbase) {
2129                 int r_index= -1;
2130                 if(RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) {
2131                         prop= NULL;
2132                 }
2133                 else if(r_index != -1) {
2134                         PyErr_Format(PyExc_ValueError, "%.200s path includes index, must be a separate argument", error_prefix, path);
2135                         return -1;
2136                 }
2137                 else if(ptr->id.data != r_ptr.id.data) {
2138                         PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
2139                         return -1;
2140                 }
2141         }
2142     else {
2143                 prop = RNA_struct_find_property(ptr, path);
2144                 r_ptr= *ptr;
2145     }
2146
2147         if (prop==NULL) {
2148                 PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
2149                 return -1;
2150         }
2151
2152         if (!RNA_property_animateable(&r_ptr, prop)) {
2153                 PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
2154                 return -1;
2155         }
2156
2157         if(RNA_property_array_check(&r_ptr, prop) == 0) {
2158                 if((*index) == -1) {
2159                         *index= 0;
2160                 }
2161                 else {
2162                         PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
2163                         return -1;
2164                 }
2165         }
2166         else {
2167                 int array_len= RNA_property_array_length(&r_ptr, prop);
2168                 if((*index) < -1 || (*index) >= array_len) {
2169                         PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
2170                         return -1;
2171                 }
2172         }
2173         
2174         if(is_idbase) {
2175                 *path_full= BLI_strdup(path);
2176         }
2177         else {
2178                 *path_full= RNA_path_from_ID_to_property(&r_ptr, prop);
2179         
2180                 if (*path_full==NULL) {
2181                         PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
2182                         return -1;
2183                 }
2184         }
2185
2186         return 0;
2187 }
2188
2189 /* internal use for insert and delete */
2190 static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw,  const char *parse_str, const char *error_prefix,
2191         char **path_full, int *index, float *cfra, char **group_name) /* return values */
2192 {
2193         static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
2194         char *path;
2195
2196         /* note, parse_str MUST start with 's|ifs' */
2197         if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
2198                 return -1;
2199
2200         if(pyrna_struct_anim_args_parse(ptr, error_prefix, path,  path_full, index) < 0) 
2201                 return -1;
2202         
2203         if(*cfra==FLT_MAX)
2204                 *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
2205
2206         return 0; /* success */
2207 }
2208
2209 static char pyrna_struct_keyframe_insert_doc[] =
2210 ".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
2211 "\n"
2212 "   Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
2213 "\n"
2214 "   :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
2215 "   :type data_path: string\n"
2216 "   :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"
2217 "   :type index: int\n"
2218 "   :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
2219 "   :type frame: float\n"
2220 "   :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
2221 "   :type group: str\n"
2222 "   :return: Success of keyframe insertion.\n"
2223 "   :rtype: boolean";
2224
2225 static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
2226 {
2227         /* args, pyrna_struct_keyframe_parse handles these */
2228         char *path_full= NULL;
2229         int index= -1;
2230         float cfra= FLT_MAX;
2231         char *group_name= NULL;
2232
2233         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) {
2234                 return NULL;
2235         }
2236         else {
2237                 short result;
2238                 ReportList reports;
2239
2240                 BKE_reports_init(&reports, RPT_STORE);
2241
2242                 result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
2243                 MEM_freeN(path_full);
2244
2245                 if(BPy_reports_to_error(&reports, TRUE))
2246                         return NULL;
2247
2248                 return PyBool_FromLong(result);
2249         }
2250 }
2251
2252 static char pyrna_struct_keyframe_delete_doc[] =
2253 ".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
2254 "\n"
2255 "   Remove a keyframe from this properties fcurve.\n"
2256 "\n"
2257 "   :arg data_path: path to the property to remove a key, analogous to the fcurve's data path.\n"
2258 "   :type data_path: string\n"
2259 "   :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"
2260 "   :type index: int\n"
2261 "   :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
2262 "   :type frame: float\n"
2263 "   :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
2264 "   :type group: str\n"
2265 "   :return: Success of keyframe deleation.\n"
2266 "   :rtype: boolean";
2267
2268 static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
2269 {
2270         /* args, pyrna_struct_keyframe_parse handles these */
2271         char *path_full= NULL;
2272         int index= -1;
2273         float cfra= FLT_MAX;
2274         char *group_name= NULL;
2275
2276         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) {
2277                 return NULL;
2278         }
2279         else {
2280                 short result;
2281                 ReportList reports;
2282
2283                 BKE_reports_init(&reports, RPT_STORE);
2284
2285                 result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
2286                 MEM_freeN(path_full);
2287
2288                 if(BPy_reports_to_error(&reports, TRUE))
2289                         return NULL;
2290
2291                 return PyBool_FromLong(result);
2292         }
2293
2294 }
2295
2296 static char pyrna_struct_driver_add_doc[] =
2297 ".. method:: driver_add(path, index=-1)\n"
2298 "\n"
2299 "   Adds driver(s) to the given property\n"
2300 "\n"
2301 "   :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
2302 "   :type path: string\n"
2303 "   :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"
2304 "   :type index: int\n"
2305 "   :return: The driver(s) added.\n"
2306 "   :rtype: :class:`FCurve` or list if index is -1 with an array property.";
2307
2308 static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
2309 {
2310         char *path, *path_full;
2311         int index= -1;
2312
2313         if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
2314                 return NULL;
2315
2316         if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path,  &path_full, &index) < 0) {
2317                 return NULL;
2318         }
2319         else {
2320                 PyObject *ret= NULL;
2321                 ReportList reports;
2322                 int result;
2323
2324                 BKE_reports_init(&reports, RPT_STORE);
2325
2326                 result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
2327
2328                 if(BPy_reports_to_error(&reports, TRUE))
2329                         return NULL;
2330
2331                 if(result) {
2332                         ID *id= self->ptr.id.data;
2333                         AnimData *adt= BKE_animdata_from_id(id);
2334                         FCurve *fcu;
2335
2336                         PointerRNA tptr;
2337                         PyObject *item;
2338
2339                         if(index == -1) { /* all, use a list */
2340                                 int i= 0;
2341                                 ret= PyList_New(0);
2342                                 while((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) {
2343                                         RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
2344                                         item= pyrna_struct_CreatePyObject(&tptr);
2345                                         PyList_Append(ret, item);
2346                                         Py_DECREF(item);
2347                                 }
2348                         }
2349                         else {
2350                                 fcu= list_find_fcurve(&adt->drivers, path_full, index);
2351                                 RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
2352                                 ret= pyrna_struct_CreatePyObject(&tptr);
2353                         }
2354                 }
2355                 else {
2356                         /* XXX, should be handled by reports, */
2357                         PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
2358                         return NULL;
2359                 }
2360
2361                 MEM_freeN(path_full);
2362
2363                 return ret;
2364         }
2365 }
2366
2367
2368 static char pyrna_struct_driver_remove_doc[] =
2369 ".. method:: driver_remove(path, index=-1)\n"
2370 "\n"
2371 "   Remove driver(s) from the given property\n"
2372 "\n"
2373 "   :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
2374 "   :type path: string\n"
2375 "   :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"
2376 "   :type index: int\n"
2377 "   :return: Success of driver removal.\n"
2378 "   :rtype: boolean";
2379
2380 static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
2381 {
2382         char *path, *path_full;
2383         int index= -1;
2384
2385         if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
2386                 return NULL;
2387
2388         if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path,  &path_full, &index) < 0) {
2389                 return NULL;
2390         }
2391         else {
2392                 short result;
2393                 ReportList reports;
2394
2395                 BKE_reports_init(&reports, RPT_STORE);
2396
2397                 result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
2398
2399                 MEM_freeN(path_full);
2400
2401                 if(BPy_reports_to_error(&reports, TRUE))
2402                         return NULL;
2403
2404                 return PyBool_FromLong(result);
2405         }
2406 }
2407
2408
2409 static char pyrna_struct_is_property_set_doc[] =
2410 ".. method:: is_property_set(property)\n"
2411 "\n"
2412 "   Check if a property is set, use for testing operator properties.\n"
2413 "\n"
2414 "   :return: True when the property has been set.\n"
2415 "   :rtype: boolean";
2416
2417 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
2418 {
2419         PropertyRNA *prop;
2420         char *name;
2421         int ret;
2422
2423         if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
2424                 return NULL;
2425
2426         if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
2427                 PyErr_Format(PyExc_TypeError, "%.200s.is_property_set(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
2428                 return NULL;
2429         }
2430
2431         /* double property lookup, could speed up */
2432         /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */
2433         if(RNA_property_flag(prop) & PROP_IDPROPERTY) {
2434                 IDProperty *group= RNA_struct_idprops(&self->ptr, 0);           
2435                 if(group) {
2436                         ret= IDP_GetPropertyFromGroup(group, name) ? 1:0;
2437                 }
2438                 else {
2439                         ret= 0;
2440                 }
2441         }
2442         else {
2443                 ret= 1;
2444         }
2445         
2446         return PyBool_FromLong(ret);
2447 }
2448
2449 static char pyrna_struct_is_property_hidden_doc[] =
2450 ".. method:: is_property_hidden(property)\n"
2451 "\n"
2452 "   Check if a property is hidden.\n"
2453 "\n"
2454 "   :return: True when the property is hidden.\n"
2455 "   :rtype: boolean";
2456
2457 static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
2458 {
2459         PropertyRNA *prop;
2460         char *name;
2461
2462         if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
2463                 return NULL;
2464
2465         if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
2466                 PyErr_Format(PyExc_TypeError, "%.200s.is_property_hidden(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
2467                 return NULL;
2468         }
2469
2470         return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
2471 }
2472
2473 static char pyrna_struct_path_resolve_doc[] =
2474 ".. method:: path_resolve(path, coerce=True)\n"
2475 "\n"
2476 "   Returns the property from the path, raise an exception when not found.\n"
2477 "\n"
2478 "   :arg path: path which this property resolves.\n"
2479 "   :type path: string\n"
2480 "   :arg coerce: optional argument, when True, the property will be converted into its python representation.\n"
2481 "   :type coerce: boolean\n";
2482
2483 static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
2484 {
2485         char *path;
2486         PyObject *coerce= Py_True;
2487         PointerRNA r_ptr;
2488         PropertyRNA *r_prop;
2489         int index= -1;
2490
2491         if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce))
2492                 return NULL;
2493
2494         if (RNA_path_resolve_full(&self->ptr, path, &r_ptr, &r_prop, &index)) {
2495                 if(r_prop) {
2496                         if(index != -1) {
2497                                 if(index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
2498                                         PyErr_Format(PyExc_TypeError, "%.200s.path_resolve(\"%.200s\") index out of range", RNA_struct_identifier(self->ptr.type), path);
2499                                         return NULL;
2500                                 }
2501                                 else {
2502                                         return pyrna_array_index(&r_ptr, r_prop, index);
2503                                 }
2504                         }
2505                         else {
2506                                 if(coerce == Py_False) {
2507                                         return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
2508                                 }
2509                                 else {
2510                                         return pyrna_prop_to_py(&r_ptr, r_prop);
2511                                 }
2512                         }
2513                 }
2514                 else {
2515                         return pyrna_struct_CreatePyObject(&r_ptr);
2516                 }
2517         }
2518         else {
2519                 PyErr_Format(PyExc_TypeError, "%.200s.path_resolve(\"%.200s\") could not be resolved", RNA_struct_identifier(self->ptr.type), path);
2520                 return NULL;
2521         }
2522 }
2523
2524 static char pyrna_struct_path_from_id_doc[] =
2525 ".. method:: path_from_id(property=\"\")\n"
2526 "\n"
2527 "   Returns the data path from the ID to this object (string).\n"
2528 "\n"
2529 "   :arg property: Optional property name which can be used if the path is to a property of this object.\n"
2530 "   :type property: string\n"
2531 "   :return: The path from :class:`bpy_struct.id_data` to this struct and property (when given).\n"
2532 "   :rtype: str";
2533
2534 static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
2535 {
2536         char *name= NULL;
2537         char *path;
2538         PropertyRNA *prop;
2539         PyObject *ret;
2540
2541         if (!PyArg_ParseTuple(args, "|s:path_from_id", &name))
2542                 return NULL;
2543
2544         if(name) {
2545                 prop= RNA_struct_find_property(&self->ptr, name);
2546                 if(prop==NULL) {
2547                         PyErr_Format(PyExc_TypeError, "%.200s.path_from_id(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
2548                         return NULL;
2549                 }
2550
2551                 path= RNA_path_from_ID_to_property(&self->ptr, prop);
2552         }
2553         else {
2554                 path= RNA_path_from_ID_to_struct(&self->ptr);
2555         }
2556
2557         if(path==NULL) {
2558                 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);
2559                 else            PyErr_Format(PyExc_TypeError, "%.200s.path_from_id() does not support path creation for this type", RNA_struct_identifier(self->ptr.type));
2560                 return NULL;
2561         }
2562
2563         ret= PyUnicode_FromString(path);
2564         MEM_freeN(path);
2565
2566         return ret;
2567 }
2568
2569 static char pyrna_prop_path_from_id_doc[] =
2570 ".. method:: path_from_id()\n"
2571 "\n"
2572 "   Returns the data path from the ID to this property (string).\n"
2573 "\n"
2574 "   :return: The path from :class:`bpy_struct.id_data` to this property.\n"
2575 "   :rtype: str";
2576
2577 static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
2578 {
2579         char *path;
2580         PropertyRNA *prop = self->prop;
2581         PyObject *ret;
2582
2583         path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
2584
2585         if(path==NULL) {
2586                 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));
2587                 return NULL;
2588         }
2589
2590         ret= PyUnicode_FromString(path);
2591         MEM_freeN(path);
2592
2593         return ret;
2594 }
2595
2596 static char pyrna_struct_type_recast_doc[] =
2597 ".. method:: type_recast()\n"
2598 "\n"
2599 "   Return a new instance, this is needed because types such as textures can be changed at runtime.\n"
2600 "\n"
2601 "   :return: a new instance of this object with the type initialized again.\n"
2602 "   :rtype: subclass of :class:`bpy_struct`";
2603
2604 static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
2605 {
2606         PointerRNA r_ptr;
2607         RNA_pointer_recast(&self->ptr, &r_ptr);
2608         return pyrna_struct_CreatePyObject(&r_ptr);
2609 }
2610
2611 static void pyrna_dir_members_py(PyObject *list, PyObject *self)
2612 {
2613         PyObject *dict;
2614         PyObject **dict_ptr;
2615         PyObject *list_tmp;
2616
2617         dict_ptr= _PyObject_GetDictPtr((PyObject *)self);
2618
2619         if(dict_ptr && (dict=*dict_ptr)) {
2620                 list_tmp = PyDict_Keys(dict);
2621                 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
2622                 Py_DECREF(list_tmp);
2623         }
2624
2625         dict= ((PyTypeObject *)Py_TYPE(self))->tp_dict;
2626         if(dict) {
2627                 list_tmp = PyDict_Keys(dict);
2628                 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
2629                 Py_DECREF(list_tmp);
2630         }
2631 }
2632
2633 static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
2634 {
2635         PyObject *pystring;
2636         const char *idname;
2637
2638         /* for looping over attrs and funcs */
2639         PointerRNA tptr;
2640         PropertyRNA *iterprop;
2641
2642         {
2643                 RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
2644                 iterprop= RNA_struct_find_property(&tptr, "functions");
2645
2646                 RNA_PROP_BEGIN(&tptr, itemptr, iterprop) {
2647                         idname= RNA_function_identifier(itemptr.data);
2648
2649                         pystring = PyUnicode_FromString(idname);
2650                         PyList_Append(list, pystring);
2651                         Py_DECREF(pystring);
2652                 }
2653                 RNA_PROP_END;
2654         }
2655
2656         {
2657                 /*
2658                  * Collect RNA attributes
2659                  */
2660                 char name[256], *nameptr;
2661
2662                 iterprop= RNA_struct_iterator_property(ptr->type);
2663
2664                 RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
2665                         nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
2666
2667                         if(nameptr) {
2668                                 pystring = PyUnicode_FromString(nameptr);
2669                                 PyList_Append(list, pystring);
2670                                 Py_DECREF(pystring);
2671
2672                                 if(name != nameptr)
2673                                         MEM_freeN(nameptr);
2674                         }
2675                 }
2676                 RNA_PROP_END;
2677         }
2678 }
2679
2680
2681 static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
2682 {
2683         PyObject *ret;
2684         PyObject *pystring;
2685
2686         /* Include this incase this instance is a subtype of a python class
2687          * In these instances we may want to return a function or variable provided by the subtype
2688          * */
2689         ret = PyList_New(0);
2690
2691         if (!BPy_StructRNA_CheckExact(self))
2692                 pyrna_dir_members_py(ret, (PyObject *)self);
2693
2694         pyrna_dir_members_rna(ret, &self->ptr);
2695
2696         if(self->ptr.type == &RNA_Context) {
2697                 ListBase lb = CTX_data_dir_get(self->ptr.data);
2698                 LinkData *link;
2699
2700                 for(link=lb.first; link; link=link->next) {
2701                         pystring = PyUnicode_FromString(link->data);
2702                         PyList_Append(ret, pystring);
2703                         Py_DECREF(pystring);
2704                 }
2705
2706                 BLI_freelistN(&lb);
2707         }
2708         return ret;
2709 }
2710
2711 //---------------getattr--------------------------------------------
2712 static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
2713 {
2714         char *name = _PyUnicode_AsString(pyname);
2715         PyObject *ret;
2716         PropertyRNA *prop;
2717         FunctionRNA *func;
2718         
2719         if(name == NULL) {
2720                 PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
2721                 ret = NULL;
2722         }
2723         else if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
2724                 /* annoying exception, maybe we need to have different types for this... */
2725                 if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idprops_check(self->ptr.type)) {
2726                         PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
2727                         ret = NULL;
2728                 }
2729                 else {
2730                         ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
2731                 }
2732         }
2733         else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
2734                   ret = pyrna_prop_to_py(&self->ptr, prop);
2735         }
2736         /* RNA function only if callback is declared (no optional functions) */
2737         else if ((func = RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) {
2738                 ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
2739         }
2740         else if (self->ptr.type == &RNA_Context) {
2741                 bContext *C = self->ptr.data;
2742                 if(C==NULL) {
2743                         PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name);
2744                         ret= NULL;
2745                 }
2746                 else {
2747                         PointerRNA newptr;
2748                         ListBase newlb;
2749                         short newtype;
2750
2751                         int done= CTX_data_get(C, name, &newptr, &newlb, &newtype);
2752
2753                         if(done==1) { /* found */
2754                                 switch(newtype) {
2755                                 case CTX_DATA_TYPE_POINTER:
2756                                         if(newptr.data == NULL) {
2757                                                 ret= Py_None;
2758                                                 Py_INCREF(ret);
2759                                         }
2760                                         else {
2761                                                 ret= pyrna_struct_CreatePyObject(&newptr);
2762                                         }
2763                                         break;
2764                                 case CTX_DATA_TYPE_COLLECTION:
2765                                         {
2766                                                 CollectionPointerLink *link;
2767                                                 PyObject *linkptr;
2768         
2769                                                 ret = PyList_New(0);
2770         
2771                                                 for(link=newlb.first; link; link=link->next) {
2772                                                         linkptr= pyrna_struct_CreatePyObject(&link->ptr);
2773                                                         PyList_Append(ret, linkptr);
2774                                                         Py_DECREF(linkptr);
2775                                                 }
2776                                         }
2777                                         break;
2778                                 default:
2779                                         /* should never happen */
2780                                         BLI_assert(!"Invalid context type");
2781
2782                                         PyErr_Format(PyExc_AttributeError, "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context", newtype, name);
2783                                         ret= NULL;
2784                                 }
2785                         }
2786                         else if (done==-1) { /* found but not set */
2787                                 ret = Py_None;
2788                                 Py_INCREF(ret);
2789                         }
2790                         else { /* not found in the context */
2791                                 /* lookup the subclass. raise an error if its not found */
2792                                 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
2793                         }
2794
2795                         BLI_freelistN(&newlb);
2796                 }
2797         }
2798         else {
2799 #if 0
2800                 PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
2801                 ret = NULL;
2802 #endif
2803                 /* Include this incase this instance is a subtype of a python class
2804                  * In these instances we may want to return a function or variable provided by the subtype
2805                  *
2806                  * Also needed to return methods when its not a subtype
2807                  * */
2808
2809                 /* The error raised here will be displayed */
2810                 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
2811         }
2812         
2813         return ret;
2814 }
2815
2816 #if 0
2817 static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname)
2818 {
2819          PyObject *dict= *(_PyObject_GetDictPtr((PyObject *)self));
2820          if (dict==NULL) /* unlikely */
2821                  return 0;
2822
2823         return PyDict_Contains(dict, pyname);
2824 }
2825 #endif
2826
2827 //--------------- setattr-------------------------------------------
2828 static int pyrna_is_deferred_prop(PyObject *value)
2829 {
2830         return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value)==2 && PyCallable_Check(PyTuple_GET_ITEM(value, 0)) && PyDict_CheckExact(PyTuple_GET_ITEM(value, 1));
2831 }
2832
2833 static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *pyname)
2834 {
2835         return PyType_Type.tp_getattro(cls, pyname);    
2836 }
2837
2838 static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
2839 {
2840         StructRNA *srna= srna_from_self(cls, "");
2841
2842         if(srna == NULL) {
2843                 if(value && pyrna_is_deferred_prop(value)) {
2844                         PyErr_Format(PyExc_AttributeError, "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'", ((PyTypeObject *)cls)->tp_name);
2845                         return -1;
2846                 }
2847
2848                 /* srna_from_self may set an error */
2849                 PyErr_Clear(); 
2850                 return PyType_Type.tp_setattro(cls, attr, value);
2851         }
2852
2853         if(value) {
2854                 /* check if the value is a property */
2855                 if(pyrna_is_deferred_prop(value)) {
2856                         int ret= deferred_register_prop(srna, attr, value);
2857                         if(ret < 0)
2858                                 return ret;
2859                         /* pass through, when the value isn't assigned it still works but gets confusing from script writers POV */
2860                 }
2861                 else {
2862                         /* remove existing property if its set or we also end up with confusement */
2863                         char *attr_str= _PyUnicode_AsString(attr);
2864                         RNA_def_property_free_identifier(srna, attr_str); /* ignore on failier */
2865                 }
2866         }
2867         else { /* __delattr__ */
2868                 /* first find if this is a registered property */
2869                 char *attr_str= _PyUnicode_AsString(attr);
2870                 int ret= RNA_def_property_free_identifier(srna, attr_str);
2871                 if (ret == -1) {
2872                         PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str);
2873                         return -1;
2874                 }
2875         }
2876         
2877         /* fallback to standard py, delattr/setattr */
2878         return PyType_Type.tp_setattro(cls, attr, value);
2879 }
2880                 
2881 static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObject *value )
2882 {
2883         char *name = _PyUnicode_AsString(pyname);
2884         PropertyRNA *prop= NULL;
2885
2886 #ifdef USE_PEDANTIC_WRITE
2887         if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
2888                 return -1;
2889         }
2890 #endif // USE_STRING_COERCE
2891
2892         if(name == NULL) {
2893                 PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
2894                 return -1;
2895         }
2896         else if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) {
2897                 if (!RNA_property_editable_flag(&self->ptr, prop)) {
2898                         PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
2899                         return -1;
2900                 }
2901         }
2902         else if (self->ptr.type == &RNA_Context) {
2903                 /* code just raises correct error, context prop's cant be set, unless its apart of the py class */
2904                 bContext *C = self->ptr.data;
2905                 if(C==NULL) {
2906                         PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", name);
2907                         return -1;
2908                 }
2909                 else {
2910                         PointerRNA newptr;
2911                         ListBase newlb;
2912                         short newtype;
2913
2914                         int done= CTX_data_get(C, name, &newptr, &newlb, &newtype);
2915
2916                         if(done==1) {
2917                                 PyErr_Format(PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name);
2918                                 BLI_freelistN(&newlb);
2919                                 return -1;
2920                         }
2921
2922                         BLI_freelistN(&newlb);
2923                 }
2924         }
2925
2926         /* pyrna_py_to_prop sets its own exceptions */
2927         if(prop) {
2928                 if(value == NULL) {
2929                         PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
2930                         return -1;
2931                 }
2932                 return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:");
2933         }
2934         else {
2935                 return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
2936         }
2937 }
2938
2939 static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
2940 {
2941         PyObject *ret;
2942         PointerRNA r_ptr;
2943
2944         /* Include this incase this instance is a subtype of a python class
2945          * In these instances we may want to return a function or variable provided by the subtype
2946          * */
2947         ret = PyList_New(0);
2948
2949         if (!BPy_PropertyRNA_CheckExact(self))
2950                 pyrna_dir_members_py(ret, (PyObject *)self);
2951
2952         if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr))
2953                 pyrna_dir_members_rna(ret, &r_ptr);
2954
2955         return ret;
2956 }
2957
2958
2959 static PyObject *pyrna_prop_array_getattro( BPy_PropertyRNA *self, PyObject *pyname )
2960 {
2961         return PyObject_GenericGetAttr((PyObject *)self, pyname);
2962 }
2963
2964 static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject *pyname )
2965 {
2966         char *name = _PyUnicode_AsString(pyname);
2967
2968         if(name == NULL) {
2969                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
2970                 return NULL;
2971         }
2972         else if(name[0] != '_') {
2973                 PyObject *ret;
2974                 PropertyRNA *prop;
2975                 FunctionRNA *func;
2976
2977                 PointerRNA r_ptr;
2978                 if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
2979                         if ((prop = RNA_struct_find_property(&r_ptr, name))) {
2980                                 ret = pyrna_prop_to_py(&r_ptr, prop);
2981
2982                                 return ret;
2983                         }
2984                         else if ((func = RNA_struct_find_function(&r_ptr, name))) {
2985                                 PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr);
2986                                 ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
2987                                 Py_DECREF(self_collection);
2988
2989                                 return ret;
2990                         }
2991                 }
2992         }
2993
2994         /* The error raised here will be displayed */
2995         return PyObject_GenericGetAttr((PyObject *)self, pyname);
2996 }
2997
2998 //--------------- setattr-------------------------------------------
2999 static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObject *value )
3000 {
3001         char *name = _PyUnicode_AsString(pyname);
3002         PropertyRNA *prop;
3003         PointerRNA r_ptr;
3004
3005 #ifdef USE_PEDANTIC_WRITE
3006         if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
3007                 return -1;
3008         }
3009 #endif // USE_STRING_COERCE
3010
3011         if(name == NULL) {
3012                 PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
3013                 return -1;
3014         }
3015         else if(value == NULL) {
3016                 PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
3017                 return -1;
3018         }
3019         else if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
3020                 if ((prop = RNA_struct_find_property(&r_ptr, name))) {
3021                         /* pyrna_py_to_prop sets its own exceptions */
3022                         return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
3023                 }
3024         }
3025
3026         PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
3027         return -1;
3028 }
3029
3030 /* odd case, we need to be able return a python method from a tp_getset */
3031 static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
3032 {
3033         PointerRNA r_ptr;
3034
3035         RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
3036         if(!r_ptr.data) {
3037                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.add(): not supported for this collection");
3038                 return NULL;
3039         }
3040         else {
3041                 return pyrna_struct_CreatePyObject(&r_ptr);
3042         }
3043 }
3044
3045 static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
3046 {
3047         int key= PyLong_AsLong(value);
3048
3049         if (key==-1 && PyErr_Occurred()) {
3050                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument");
3051                 return NULL;
3052         }
3053
3054         if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
3055                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove() not supported for this collection");
3056                 return NULL;
3057         }
3058
3059         Py_RETURN_NONE;
3060 }
3061
3062 static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args)
3063 {
3064         int key=0, pos=0;
3065
3066         if (!PyArg_ParseTuple(args, "ii", &key, &pos)) {
3067                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments");
3068                 return NULL;
3069         }
3070
3071         if(!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) {
3072                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move() not supported for this collection");
3073</