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