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