35febecfe157e2391d02afe951b025a64f98cc24
[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_compat.h"
27 //#include "blendef.h"
28 #include "BLI_dynstr.h"
29
30 #include "MEM_guardedalloc.h"
31 #include "BKE_global.h" /* evil G.* */
32
33 /* floats bigger then this are displayed as inf in the docstrings */
34 #define MAXFLOAT_DOC 10000000
35
36 static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
37 {
38         return (a->ptr.data==b->ptr.data) ? 0 : -1;
39 }
40
41 static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b )
42 {
43         return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1;
44 }
45
46
47 /* For some reason python3 needs these :/ */
48 static PyObject *pyrna_struct_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op)
49 {
50         int cmp_result= -1; /* assume false */
51         if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) {
52                 cmp_result= pyrna_struct_compare(a, b);
53         }
54
55         return Py_CmpToRich(op, cmp_result);
56 }
57
58 static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, int op)
59 {
60         int cmp_result= -1; /* assume false */
61         if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) {
62                 cmp_result= pyrna_prop_compare(a, b);
63         }
64
65         return Py_CmpToRich(op, cmp_result);
66 }
67
68 /*----------------------repr--------------------------------------------*/
69 static PyObject *pyrna_struct_repr( BPy_StructRNA * self )
70 {
71         return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\"]", RNA_struct_identifier(&self->ptr));
72 }
73
74 static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self )
75 {
76         return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" ]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop) );
77 }
78
79 static long pyrna_struct_hash( BPy_StructRNA * self )
80 {
81         return (long)self->ptr.data;
82 }
83
84 /* use our own dealloc so we can free a property if we use one */
85 static void pyrna_struct_dealloc( BPy_StructRNA * self )
86 {
87         /* Note!! for some weired reason calling PyObject_DEL() directly crashes blender! */
88         if (self->freeptr && self->ptr.data) {
89                 IDP_FreeProperty(self->ptr.data);
90                 MEM_freeN(self->ptr.data);
91                 self->ptr.data= NULL;
92         }
93
94         ((PyObject *)self)->ob_type->tp_free(self);
95         return;
96 }
97
98 static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
99 {
100         const EnumPropertyItem *item;
101         int totitem, i;
102
103         DynStr *dynstr= BLI_dynstr_new();
104         char *cstring;
105
106         RNA_property_enum_items(ptr, prop, &item, &totitem);
107
108         for (i=0; i<totitem; i++) {
109                 
110                 BLI_dynstr_appendf(dynstr, i?", '%s'":"'%s'", item[i].identifier);
111         }
112         
113         cstring = BLI_dynstr_get_cstring(dynstr);
114         BLI_dynstr_free(dynstr);
115         return cstring;
116 }
117
118 PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
119 {
120         PyObject *ret;
121         int type = RNA_property_type(ptr, prop);
122         int len = RNA_property_array_length(ptr, prop);
123         /* resolve path */
124         
125         if (len > 0) {
126                 /* resolve the array from a new pytype */
127                 return pyrna_prop_CreatePyObject(ptr, prop);
128         }
129         
130         /* see if we can coorce into a python type - PropertyType */
131         switch (type) {
132         case PROP_BOOLEAN:
133                 ret = PyBool_FromLong( RNA_property_boolean_get(ptr, prop) );
134                 break;
135         case PROP_INT:
136                 ret = PyLong_FromSize_t( (size_t)RNA_property_int_get(ptr, prop) );
137                 break;
138         case PROP_FLOAT:
139                 ret = PyFloat_FromDouble( RNA_property_float_get(ptr, prop) );
140                 break;
141         case PROP_STRING:
142         {
143                 char *buf;
144                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
145                 ret = PyUnicode_FromString( buf );
146                 MEM_freeN(buf);
147                 break;
148         }
149         case PROP_ENUM:
150         {
151                 const char *identifier;
152                 int val = RNA_property_enum_get(ptr, prop);
153                 
154                 if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) {
155                         ret = PyUnicode_FromString( identifier );
156                 } else {
157                         PyErr_Format(PyExc_AttributeError, "enum \"%d\" not found", val);
158                         ret = NULL;
159                 }
160
161                 break;
162         }
163         case PROP_POINTER:
164         {
165                 PointerRNA newptr;
166                 newptr= RNA_property_pointer_get(ptr, prop);
167                 if (newptr.data) {
168                         ret = pyrna_struct_CreatePyObject(&newptr);
169                 } else {
170                         ret = Py_None;
171                         Py_INCREF(ret);
172                 }
173                 break;
174         }
175         case PROP_COLLECTION:
176                 ret = pyrna_prop_CreatePyObject(ptr, prop);
177                 break;
178         default:
179                 PyErr_SetString(PyExc_AttributeError, "unknown type (pyrna_prop_to_py)");
180                 ret = NULL;
181                 break;
182         }
183         
184         return ret;
185 }
186
187
188 int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
189 {
190         int type = RNA_property_type(ptr, prop);
191         int len = RNA_property_array_length(ptr, prop);
192         /* resolve path */
193         
194         if (len > 0) {
195                 PyObject *item;
196                 int i;
197                 
198                 if (!PySequence_Check(value)) {
199                         PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array.");
200                         return -1;
201                 }
202                 
203                 if ((int)PySequence_Length(value) != len) {
204                         PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array.");
205                         return -1;
206                 }
207                 
208                 /* for arrays we have a limited number of types */
209                 switch (type) {
210                 case PROP_BOOLEAN:
211                 {
212                         int *param_arr = MEM_mallocN(sizeof(char) * len, "pyrna bool array");
213                         
214                         /* collect the variables before assigning, incase one of them is incorrect */
215                         for (i=0; i<len; i++) {
216                                 item = PySequence_GetItem(value, i);
217                                 param_arr[i] = PyObject_IsTrue( item );
218                                 Py_DECREF(item);
219                                 
220                                 if (param_arr[i] < 0) {
221                                         MEM_freeN(param_arr);
222                                         PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence is not a boolean");
223                                         return -1;
224                                 }
225                         }
226                         
227                         RNA_property_boolean_set_array(ptr, prop, param_arr);
228                         
229                         MEM_freeN(param_arr);
230                         break;
231                 }
232                 case PROP_INT:
233                 {
234                         int *param_arr = MEM_mallocN(sizeof(int) * len, "pyrna int array");
235                         
236                         /* collect the variables before assigning, incase one of them is incorrect */
237                         for (i=0; i<len; i++) {
238                                 item = PySequence_GetItem(value, i);
239                                 param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
240                                 Py_DECREF(item);
241                         }
242                         
243                         if (PyErr_Occurred()) {
244                                 MEM_freeN(param_arr);
245                                 PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as an int");
246                                 return -1;
247                         }
248                         
249                         RNA_property_int_set_array(ptr, prop, param_arr);
250                         
251                         MEM_freeN(param_arr);
252                         break;
253                 }
254                 case PROP_FLOAT:
255                 {
256                         float *param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array");
257                         
258                         /* collect the variables before assigning, incase one of them is incorrect */
259                         for (i=0; i<len; i++) {
260                                 item = PySequence_GetItem(value, i);
261                                 param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
262                                 Py_DECREF(item);
263                         }
264                         
265                         if (PyErr_Occurred()) {
266                                 MEM_freeN(param_arr);
267                                 PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as a float");
268                                 return -1;
269                         }
270                         
271                         RNA_property_float_set_array(ptr, prop, param_arr);
272                         
273                         MEM_freeN(param_arr);
274                         break;
275                 }
276                 }
277         } else {
278                 /* Normal Property (not an array) */
279                 
280                 /* see if we can coorce into a python type - PropertyType */
281                 switch (type) {
282                 case PROP_BOOLEAN:
283                 {
284                         int param = PyObject_IsTrue( value );
285                         
286                         if( param < 0 ) {
287                                 PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
288                                 return -1;
289                         } else {
290                                 RNA_property_boolean_set(ptr, prop, param);
291                         }
292                         break;
293                 }
294                 case PROP_INT:
295                 {
296                         int param = PyLong_AsSsize_t(value);
297                         if (PyErr_Occurred()) {
298                                 PyErr_SetString(PyExc_TypeError, "expected an int type");
299                                 return -1;
300                         } else {
301                                 RNA_property_int_set(ptr, prop, param);
302                         }
303                         break;
304                 }
305                 case PROP_FLOAT:
306                 {
307                         float param = PyFloat_AsDouble(value);
308                         if (PyErr_Occurred()) {
309                                 PyErr_SetString(PyExc_TypeError, "expected a float type");
310                                 return -1;
311                         } else {
312                                 RNA_property_float_set(ptr, prop, param);
313                         }
314                         break;
315                 }
316                 case PROP_STRING:
317                 {
318                         char *param = _PyUnicode_AsString(value);
319                         
320                         if (param==NULL) {
321                                 PyErr_SetString(PyExc_TypeError, "expected a string type");
322                                 return -1;
323                         } else {
324                                 RNA_property_string_set(ptr, prop, param);
325                         }
326                         break;
327                 }
328                 case PROP_ENUM:
329                 {
330                         char *param = _PyUnicode_AsString(value);
331                         
332                         if (param==NULL) {
333                                 char *enum_str= pyrna_enum_as_string(ptr, prop);
334                                 PyErr_Format(PyExc_TypeError, "expected a string enum type in (%s)", enum_str);
335                                 MEM_freeN(enum_str);
336                                 return -1;
337                         } else {
338                                 int val;
339                                 if (RNA_property_enum_value(ptr, prop, param, &val)) {
340                                         RNA_property_enum_set(ptr, prop, val);
341                                 } else {
342                                         char *enum_str= pyrna_enum_as_string(ptr, prop);
343                                         PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found in (%s)", param, enum_str);
344                                         MEM_freeN(enum_str);
345                                         return -1;
346                                 }
347                         }
348                         
349                         break;
350                 }
351                 case PROP_POINTER:
352                 {
353                         PyErr_SetString(PyExc_AttributeError, "cant assign pointers yet");
354                         return -1;
355                         break;
356                 }
357                 case PROP_COLLECTION:
358                         PyErr_SetString(PyExc_AttributeError, "cant assign to collections");
359                         return -1;
360                         break;
361                 default:
362                         PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_prop)");
363                         return -1;
364                         break;
365                 }
366         }
367         
368         return 0;
369 }
370
371
372 static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index)
373 {
374         PyObject *ret;
375         int type = RNA_property_type(ptr, prop);
376         
377         /* resolve path */
378         
379         /* see if we can coorce into a python type - PropertyType */
380         switch (type) {
381         case PROP_BOOLEAN:
382                 ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) );
383                 break;
384         case PROP_INT:
385                 ret = PyLong_FromSize_t( (size_t)RNA_property_int_get_index(ptr, prop, index) );
386                 break;
387         case PROP_FLOAT:
388                 ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) );
389                 break;
390         default:
391                 PyErr_SetString(PyExc_AttributeError, "not an array type");
392                 ret = NULL;
393                 break;
394         }
395         
396         return ret;
397 }
398
399 static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value)
400 {
401         int ret = 0;
402         int type = RNA_property_type(ptr, prop);
403         
404         /* resolve path */
405         
406         /* see if we can coorce into a python type - PropertyType */
407         switch (type) {
408         case PROP_BOOLEAN:
409         {
410                 int param = PyObject_IsTrue( value );
411                 
412                 if( param < 0 ) {
413                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
414                         ret = -1;
415                 } else {
416                         RNA_property_boolean_set_index(ptr, prop, index, param);
417                 }
418                 break;
419         }
420         case PROP_INT:
421         {
422                 int param = PyLong_AsSsize_t(value);
423                 if (PyErr_Occurred()) {
424                         PyErr_SetString(PyExc_TypeError, "expected an int type");
425                         ret = -1;
426                 } else {
427                         RNA_property_int_set_index(ptr, prop, index, param);
428                 }
429                 break;
430         }
431         case PROP_FLOAT:
432         {
433                 float param = PyFloat_AsDouble(value);
434                 if (PyErr_Occurred()) {
435                         PyErr_SetString(PyExc_TypeError, "expected a float type");
436                         ret = -1;
437                 } else {
438                         RNA_property_float_set_index(ptr, prop, index, param);
439                 }
440                 break;
441         }
442         default:
443                 PyErr_SetString(PyExc_AttributeError, "not an array type");
444                 ret = -1;
445                 break;
446         }
447         
448         return ret;
449 }
450
451 //---------------sequence-------------------------------------------
452 static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
453 {
454         Py_ssize_t len;
455         
456         if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
457                 len = RNA_property_collection_length(&self->ptr, self->prop);
458         } else {
459                 len = RNA_property_array_length(&self->ptr, self->prop);
460                 
461                 if (len==0) { /* not an array*/
462                         PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
463                         return -1;
464                 }
465         }
466         
467         return len;
468 }
469
470 static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
471 {
472         PyObject *ret;
473         PointerRNA newptr;
474         int keynum = 0;
475         char *keyname = NULL;
476         
477         if (PyUnicode_Check(key)) {
478                 keyname = _PyUnicode_AsString(key);
479         } else if (PyLong_Check(key)) {
480                 keynum = PyLong_AsSsize_t(key);
481         } else {
482                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int");
483                 return NULL;
484         }
485         
486         if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
487                 int ok;
488                 if (keyname)    ok = RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr);
489                 else                    ok = RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr);
490                 
491                 if (ok) {
492                         ret = pyrna_struct_CreatePyObject(&newptr);
493                 } else {
494                         PyErr_SetString(PyExc_AttributeError, "out of range");
495                         ret = NULL;
496                 }
497                 
498         } else if (keyname) {
499                 PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections");
500                 ret = NULL;
501         } else {
502                 int len = RNA_property_array_length(&self->ptr, self->prop);
503                 
504                 if (len==0) { /* not an array*/
505                         PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum);
506                         ret = NULL;
507                 }
508                 
509                 if (keynum >= len){
510                         PyErr_SetString(PyExc_AttributeError, "index out of range");
511                         ret = NULL;
512                 } else { /* not an array*/
513                         ret = pyrna_prop_to_py_index(&self->ptr, self->prop, keynum);
514                 }
515         }
516         
517         return ret;
518 }
519
520
521 static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value )
522 {
523         int ret = 0;
524         int keynum = 0;
525         char *keyname = NULL;
526         
527         if (!RNA_property_editable(&self->ptr, self->prop)) {
528                 PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, self->prop), RNA_struct_identifier(&self->ptr) );
529                 return -1;
530         }
531         
532         if (PyUnicode_Check(key)) {
533                 keyname = _PyUnicode_AsString(key);
534         } else if (PyLong_Check(key)) {
535                 keynum = PyLong_AsSsize_t(key);
536         } else {
537                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int");
538                 return -1;
539         }
540         
541         if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
542                 PyErr_SetString(PyExc_AttributeError, "assignment is not supported for collections (yet)");
543                 ret = -1;
544         } else if (keyname) {
545                 PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections");
546                 ret = -1;
547         } else {
548                 int len = RNA_property_array_length(&self->ptr, self->prop);
549                 
550                 if (len==0) { /* not an array*/
551                         PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum);
552                         ret = -1;
553                 }
554                 
555                 if (keynum >= len){
556                         PyErr_SetString(PyExc_AttributeError, "index out of range");
557                         ret = -1;
558                 } else { /* not an array*/
559                         ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
560                 }
561         }
562         
563         return ret;
564 }
565
566
567
568 static PyMappingMethods pyrna_prop_as_mapping = {
569         ( inquiry ) pyrna_prop_len,     /* mp_length */
570         ( binaryfunc ) pyrna_prop_subscript,    /* mp_subscript */
571         ( objobjargproc ) pyrna_prop_assign_subscript,  /* mp_ass_subscript */
572 };
573
574
575 PyObject *pyrna_struct_to_docstring(BPy_StructRNA *self)
576 {
577         PyObject *ret;
578         PropertyRNA *prop;
579         
580         DynStr *dynstr;
581         const char *identifier;
582         const char *desc;
583         char *readonly;
584         char *result;
585         int len;
586         int i; /* general iter */
587         
588         dynstr= BLI_dynstr_new();
589         BLI_dynstr_appendf(dynstr, "RNA %s: %s\n", RNA_struct_identifier(&self->ptr), RNA_struct_ui_name(&self->ptr));
590         
591         /* Add EPI ===='s */
592         i = BLI_dynstr_get_len(dynstr);
593         while (--i)
594                 BLI_dynstr_append(dynstr, "=");
595         
596         BLI_dynstr_append(dynstr, "\n");
597         /* done */
598         
599         {
600                 PropertyRNA *iterprop;
601                 CollectionPropertyIterator iter;
602                 
603                 iterprop= RNA_struct_iterator_property(&self->ptr);
604                 RNA_property_collection_begin(&self->ptr, iterprop, &iter);
605                 
606                 for(; iter.valid; RNA_property_collection_next(&iter)) {
607                         prop = iter.ptr.data;
608                         identifier = RNA_property_identifier(&iter.ptr, prop);
609                         desc = RNA_property_ui_description(&iter.ptr, prop);
610                         
611                         readonly = (RNA_property_editable(&self->ptr, prop)) ? "" : " *readonly*";
612                         len = RNA_property_array_length(&iter.ptr, prop);       
613                         
614                         switch(RNA_property_type(&iter.ptr, prop)) {
615                         case PROP_BOOLEAN:
616                         {       
617                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
618                                 
619                                 if (len==0)     BLI_dynstr_appendf(dynstr, "@type %s: bool\n", identifier);
620                                 else            BLI_dynstr_appendf(dynstr, "@type %s: bool[%d]\n", identifier, len);
621                                 break;
622                         }
623                         case PROP_INT:
624                         {
625                                 int hardmin, hardmax;
626                                 RNA_property_int_range(&iter.ptr, prop, &hardmin, &hardmax); 
627                                 
628                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s in (%d, %d)%s\n", identifier, desc, hardmin, hardmax, readonly);
629                                 
630                                 if (len==0)     BLI_dynstr_appendf(dynstr, "@type %s: int\n", identifier);
631                                 else            BLI_dynstr_appendf(dynstr, "@type %s: int[%d]\n", identifier, len);
632                                 break;
633                         }
634                         case PROP_FLOAT:
635                         {
636                                 float hardmin, hardmax;
637                                 RNA_property_float_range(&iter.ptr, prop, &hardmin, &hardmax);
638                                 
639                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s in (", identifier, desc);
640                                 
641                                 if (hardmin < -MAXFLOAT_DOC)BLI_dynstr_append(dynstr, "-inf, ");
642                                 else                                            BLI_dynstr_appendf(dynstr, "%.3f, ", hardmin);
643                                                 
644                                 if (hardmax >  MAXFLOAT_DOC)BLI_dynstr_append(dynstr, "inf");
645                                 else                                            BLI_dynstr_appendf(dynstr, "%.3f", hardmax);
646                                 
647                                 BLI_dynstr_appendf(dynstr, ")%s\n", readonly);
648                                                 
649                                                 
650                                 if (len==0)     BLI_dynstr_appendf(dynstr, "@type %s: float\n", identifier);
651                                 else            BLI_dynstr_appendf(dynstr, "@type %s: float[%d]\n", identifier, len);
652                                 break;
653                         }
654                         case PROP_STRING:
655                         {
656                                 int maxlen = RNA_property_string_maxlength(&iter.ptr, prop);
657                                 
658                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s (%d maximum length)%s\n", identifier, desc, maxlen, readonly);
659                                 BLI_dynstr_appendf(dynstr, "@type %s: string\n", identifier);
660                                 break;
661                         }
662                         case PROP_ENUM:
663                         {
664                                 char *enum_str= pyrna_enum_as_string(&iter.ptr, prop);
665                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
666                                 BLI_dynstr_appendf(dynstr, "@type %s: enum in [%s]\n", identifier, enum_str);
667                                 MEM_freeN(enum_str);
668                                 break;
669                         }
670                         case PROP_POINTER:
671                         {
672                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
673                                 
674                                 // TODO - why does this crash sometimes
675                                 // PointerRNA newptr;
676                                 // newptr= RNA_property_pointer_get(&iter.ptr, prop);
677                                 
678                                 // Use this instead, its not that useful
679                                 BLI_dynstr_appendf(dynstr, "@type %s: PyRNA %s\n", identifier, RNA_struct_identifier(&iter.ptr));
680                                 break;
681                         }
682                         case PROP_COLLECTION:
683                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
684                                 BLI_dynstr_appendf(dynstr, "@type %s: PyRNA Collection\n", identifier);
685                                 break;
686                         default:
687                                 BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
688                                 BLI_dynstr_appendf(dynstr, "@type %s: <unknown>\n", identifier);
689                                 break; 
690                         }
691                 }
692                 
693                 RNA_property_collection_end(&iter);
694         }
695         
696         result= BLI_dynstr_get_cstring(dynstr);
697         BLI_dynstr_free(dynstr);
698         
699         ret = PyUnicode_FromString(result);
700         MEM_freeN(result);
701         
702         return ret;
703 }
704
705
706 //---------------getattr--------------------------------------------
707 static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
708 {
709         char *name = _PyUnicode_AsString(pyname);
710         PyObject *ret;
711         PropertyRNA *prop;
712         
713         /* Include this incase this instance is a subtype of a python class
714          * In these instances we may want to return a function or variable provided by the subtype
715          * */
716         ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
717         if (ret)        return ret;
718         else            PyErr_Clear();
719         /* done with subtypes */
720         
721         if ( strcmp( name, "__doc__" ) == 0 ) {
722                 ret = pyrna_struct_to_docstring(self);
723         } else {
724                 prop = RNA_struct_find_property(&self->ptr, name);
725                 
726                 if (prop==NULL) {
727                         PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
728                         ret = NULL;
729                 } else {
730                         ret = pyrna_prop_to_py(&self->ptr, prop);
731                 }
732         }
733         
734         return ret;
735 }
736
737 //--------------- setattr-------------------------------------------
738 static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObject * value )
739 {
740         char *name = _PyUnicode_AsString(pyname);
741         PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name);
742         
743         if (prop==NULL) {
744                 PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
745                 return -1;
746         }               
747         
748         if (!RNA_property_editable(&self->ptr, prop)) {
749                 PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, prop), RNA_struct_identifier(&self->ptr) );
750                 return -1;
751         }
752                 
753         /* pyrna_py_to_prop sets its own exceptions */
754         return pyrna_py_to_prop(&self->ptr, prop, value);
755 }
756
757 static PyObject *pyrna_struct_dir( BPy_StructRNA * self )
758 {
759         PyObject *ret = PyList_New(0);
760         PyObject *item;
761         PropertyRNA *prop;
762         PropertyRNA *iterprop;
763         CollectionPropertyIterator iter;
764
765         iterprop= RNA_struct_iterator_property(&self->ptr);
766         RNA_property_collection_begin(&self->ptr, iterprop, &iter);
767
768
769         for(; iter.valid; RNA_property_collection_next(&iter)) {
770                 prop = iter.ptr.data;
771                 item = PyUnicode_FromString( RNA_property_identifier(&iter.ptr, prop) );
772                 PyList_Append(ret, item);
773                 Py_DECREF(item);
774         }
775
776         RNA_property_collection_end(&iter);
777
778         return ret;
779 }
780
781
782
783 PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
784 {
785         PyObject *ret;
786         if (RNA_property_type(&self->ptr, self->prop) != PROP_COLLECTION) {
787                 PyErr_SetString( PyExc_TypeError, "keys() is only valid for collection types" );
788                 ret = NULL;
789         } else {
790                 PyObject *item;
791                 CollectionPropertyIterator iter;
792                 PropertyRNA *nameprop;
793                 char name[256], *nameptr;
794
795                 ret = PyList_New(0);
796                 
797                 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
798                 for(; iter.valid; RNA_property_collection_next(&iter)) {
799                         nameprop= RNA_struct_name_property(&iter.ptr);
800                         if(iter.ptr.data && nameprop) {
801                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));                                
802                                 
803                                 /* add to python list */
804                                 item = PyUnicode_FromString( nameptr );
805                                 PyList_Append(ret, item);
806                                 Py_DECREF(item);
807                                 /* done */
808                                 
809                                 if ((char *)&name != nameptr)
810                                         MEM_freeN(nameptr);
811                         }
812                 }
813                 RNA_property_collection_end(&iter);
814         }
815         
816         return ret;
817 }
818
819 PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
820 {
821         PyObject *ret;
822         if (RNA_property_type(&self->ptr, self->prop) != PROP_COLLECTION) {
823                 PyErr_SetString( PyExc_TypeError, "items() is only valid for collection types" );
824                 ret = NULL;
825         } else {
826                 PyObject *item;
827                 CollectionPropertyIterator iter;
828                 PropertyRNA *nameprop;
829                 char name[256], *nameptr;
830
831                 ret = PyList_New(0);
832                 
833                 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
834                 for(; iter.valid; RNA_property_collection_next(&iter)) {
835                         nameprop= RNA_struct_name_property(&iter.ptr);
836                         if(iter.ptr.data && nameprop) {
837                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
838                                 
839                                 /* add to python list */
840                                 item = Py_BuildValue("(NN)", PyUnicode_FromString( nameptr ), pyrna_struct_CreatePyObject(&iter.ptr));
841                                 PyList_Append(ret, item);
842                                 Py_DECREF(item);
843                                 /* done */
844                                 
845                                 if ((char *)&name != nameptr)
846                                         MEM_freeN(nameptr);
847                         }
848                 }
849                 RNA_property_collection_end(&iter);
850         }
851         
852         return ret;
853 }
854
855
856 PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
857 {
858         PyObject *ret;
859         if (RNA_property_type(&self->ptr, self->prop) != PROP_COLLECTION) {
860                 PyErr_SetString( PyExc_TypeError, "values() is only valid for collection types" );
861                 ret = NULL;
862         } else {
863                 PyObject *item;
864                 CollectionPropertyIterator iter;
865                 PropertyRNA *nameprop;
866                 
867                 ret = PyList_New(0);
868                 
869                 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
870                 for(; iter.valid; RNA_property_collection_next(&iter)) {
871                         nameprop= RNA_struct_name_property(&iter.ptr);
872                         if(iter.ptr.data && nameprop) {
873                                 
874                                 /* add to python list */
875                                 item = pyrna_struct_CreatePyObject(&iter.ptr);
876                                 PyList_Append(ret, item);
877                                 Py_DECREF(item);
878                                 /* done */
879                                 
880                         }
881                 }
882                 RNA_property_collection_end(&iter);
883         }
884         
885         return ret;
886 }
887
888 /* A bit of a kludge, make a list out of a collection or array,
889  * then return the lists iter function, not especially fast but convenient for now */
890 PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
891 {
892         /* Try get values from a collection */
893         PyObject *ret = pyrna_prop_values(self);
894         
895         if (ret==NULL) {
896                 /* collection did not work, try array */
897                 int len = RNA_property_array_length(&self->ptr, self->prop);
898                 
899                 if (len) {
900                         int i;
901                         PyErr_Clear();
902                         ret = PyList_New(len);
903                         
904                         for (i=0; i < len; i++) {
905                                 PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(&self->ptr, self->prop, i));
906                         }
907                 }
908         }
909         
910         if (ret) {
911                 /* we know this is a list so no need to PyIter_Check */
912                 PyObject *iter = PyObject_GetIter(ret); 
913                 Py_DECREF(ret);
914                 return iter;
915         }
916         
917         PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
918         return NULL;
919 }
920
921 static struct PyMethodDef pyrna_struct_methods[] = {
922         {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""},
923         {NULL, NULL, 0, NULL}
924 };
925
926 static struct PyMethodDef pyrna_prop_methods[] = {
927         {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""},
928         {"items", (PyCFunction)pyrna_prop_items, METH_NOARGS, ""},
929         {"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, ""},
930         {NULL, NULL, 0, NULL}
931 };
932
933 /* only needed for subtyping, so a new class gets a valid BPy_StructRNA
934  * todo - also accept useful args */
935 static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
936
937         BPy_StructRNA *base = NULL;
938         
939         if (!PyArg_ParseTuple(args, "O!:Base BPy_StructRNA", &pyrna_struct_Type, &base))
940                 return NULL;
941         
942         if (type == &pyrna_struct_Type) {
943                 return pyrna_struct_CreatePyObject(&base->ptr);
944         } else {
945                 BPy_StructRNA *ret = (BPy_StructRNA *) type->tp_alloc(type, 0);
946                 ret->ptr = base->ptr;
947                 return (PyObject *)ret;
948         }
949 }
950
951 /* only needed for subtyping, so a new class gets a valid BPy_StructRNA
952  * todo - also accept useful args */
953 static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
954
955         BPy_PropertyRNA *base = NULL;
956         
957         if (!PyArg_ParseTuple(args, "O!:Base BPy_PropertyRNA", &pyrna_prop_Type, &base))
958                 return NULL;
959         
960         if (type == &pyrna_prop_Type) {
961                 return pyrna_prop_CreatePyObject(&base->ptr, base->prop);
962         } else {
963                 BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0);
964                 ret->ptr = base->ptr;
965                 ret->prop = base->prop;
966                 return (PyObject *)ret;
967         }
968 }
969
970 /*-----------------------BPy_StructRNA method def------------------------------*/
971 PyTypeObject pyrna_struct_Type = {
972 #if (PY_VERSION_HEX >= 0x02060000)
973         PyVarObject_HEAD_INIT(NULL, 0)
974 #else
975         /* python 2.5 and below */
976         PyObject_HEAD_INIT( NULL )  /* required py macro */
977         0,                          /* ob_size */
978 #endif
979         "StructRNA",                    /* tp_name */
980         sizeof( BPy_StructRNA ),        /* tp_basicsize */
981         0,                      /* tp_itemsize */
982         /* methods */
983         ( destructor ) pyrna_struct_dealloc,/* tp_dealloc */
984         NULL,                       /* printfunc tp_print; */
985         NULL,                                           /* getattrfunc tp_getattr; */
986         NULL,                                           /* setattrfunc tp_setattr; */
987         ( cmpfunc ) pyrna_struct_compare,       /* tp_compare */
988         ( reprfunc ) pyrna_struct_repr, /* tp_repr */
989
990         /* Method suites for standard classes */
991
992         NULL,                       /* PyNumberMethods *tp_as_number; */
993         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
994         NULL,                                           /* PyMappingMethods *tp_as_mapping; */
995
996         /* More standard operations (here for binary compatibility) */
997
998         ( hashfunc )pyrna_struct_hash,  /* hashfunc tp_hash; */
999         NULL,                                           /* ternaryfunc tp_call; */
1000         NULL,                       /* reprfunc tp_str; */
1001         ( getattrofunc ) pyrna_struct_getattro, /* getattrofunc tp_getattro; */
1002         ( setattrofunc ) pyrna_struct_setattro, /* setattrofunc tp_setattro; */
1003
1004         /* Functions to access object as input/output buffer */
1005         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1006
1007   /*** Flags to define presence of optional/expanded features ***/
1008         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
1009
1010         NULL,                                           /*  char *tp_doc;  Documentation string */
1011   /*** Assigned meaning in release 2.0 ***/
1012         /* call function for all accessible objects */
1013         NULL,                       /* traverseproc tp_traverse; */
1014
1015         /* delete references to contained objects */
1016         NULL,                       /* inquiry tp_clear; */
1017
1018   /***  Assigned meaning in release 2.1 ***/
1019   /*** rich comparisons ***/
1020         (richcmpfunc)pyrna_struct_richcmp,      /* richcmpfunc tp_richcompare; */
1021
1022   /***  weak reference enabler ***/
1023         0,                          /* long tp_weaklistoffset; */
1024
1025   /*** Added in release 2.2 ***/
1026         /*   Iterators */
1027         NULL,                       /* getiterfunc tp_iter; */
1028         NULL,                       /* iternextfunc tp_iternext; */
1029
1030   /*** Attribute descriptor and subclassing stuff ***/
1031         pyrna_struct_methods,           /* struct PyMethodDef *tp_methods; */
1032         NULL,                       /* struct PyMemberDef *tp_members; */
1033         NULL,                                           /* struct PyGetSetDef *tp_getset; */
1034         NULL,                       /* struct _typeobject *tp_base; */
1035         NULL,                       /* PyObject *tp_dict; */
1036         NULL,                       /* descrgetfunc tp_descr_get; */
1037         NULL,                       /* descrsetfunc tp_descr_set; */
1038         0,                          /* long tp_dictoffset; */
1039         NULL,                       /* initproc tp_init; */
1040         NULL,                       /* allocfunc tp_alloc; */
1041         pyrna_struct_new,                       /* newfunc tp_new; */
1042         /*  Low-level free-memory routine */
1043         NULL,                       /* freefunc tp_free;  */
1044         /* For PyObject_IS_GC */
1045         NULL,                       /* inquiry tp_is_gc;  */
1046         NULL,                       /* PyObject *tp_bases; */
1047         /* method resolution order */
1048         NULL,                       /* PyObject *tp_mro;  */
1049         NULL,                       /* PyObject *tp_cache; */
1050         NULL,                       /* PyObject *tp_subclasses; */
1051         NULL,                       /* PyObject *tp_weaklist; */
1052         NULL
1053 };
1054
1055 /*-----------------------BPy_PropertyRNA method def------------------------------*/
1056 PyTypeObject pyrna_prop_Type = {
1057 #if (PY_VERSION_HEX >= 0x02060000)
1058         PyVarObject_HEAD_INIT(NULL, 0)
1059 #else
1060         /* python 2.5 and below */
1061         PyObject_HEAD_INIT( NULL )  /* required py macro */
1062         0,                          /* ob_size */
1063 #endif
1064         
1065         "PropertyRNA",          /* tp_name */
1066         sizeof( BPy_PropertyRNA ),                      /* tp_basicsize */
1067         0,                      /* tp_itemsize */
1068         /* methods */
1069         NULL,                                           /* tp_dealloc */
1070         NULL,                       /* printfunc tp_print; */
1071         NULL,                                           /* getattrfunc tp_getattr; */
1072         NULL,                       /* setattrfunc tp_setattr; */
1073         ( cmpfunc ) pyrna_prop_compare, /* tp_compare */
1074         ( reprfunc ) pyrna_prop_repr,   /* tp_repr */
1075
1076         /* Method suites for standard classes */
1077
1078         NULL,                       /* PyNumberMethods *tp_as_number; */
1079         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
1080         &pyrna_prop_as_mapping,         /* PyMappingMethods *tp_as_mapping; */
1081
1082         /* More standard operations (here for binary compatibility) */
1083
1084         NULL,                                           /* hashfunc tp_hash; */
1085         NULL,                       /* ternaryfunc tp_call; */
1086         NULL,                       /* reprfunc tp_str; */
1087         NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */      /* getattrofunc tp_getattro; */ /* will only use these if this is a subtype of a py class */
1088         NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */      /* setattrofunc tp_setattro; */
1089
1090         /* Functions to access object as input/output buffer */
1091         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1092
1093   /*** Flags to define presence of optional/expanded features ***/
1094         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
1095
1096         NULL,                                           /*  char *tp_doc;  Documentation string */
1097   /*** Assigned meaning in release 2.0 ***/
1098         /* call function for all accessible objects */
1099         NULL,                       /* traverseproc tp_traverse; */
1100
1101         /* delete references to contained objects */
1102         NULL,                       /* inquiry tp_clear; */
1103
1104   /***  Assigned meaning in release 2.1 ***/
1105   /*** rich comparisons ***/
1106         (richcmpfunc)pyrna_prop_richcmp,        /* richcmpfunc tp_richcompare; */
1107
1108   /***  weak reference enabler ***/
1109         0,                          /* long tp_weaklistoffset; */
1110
1111   /*** Added in release 2.2 ***/
1112         /*   Iterators */
1113         (getiterfunc)pyrna_prop_iter,   /* getiterfunc tp_iter; */
1114         NULL,                       /* iternextfunc tp_iternext; */
1115
1116   /*** Attribute descriptor and subclassing stuff ***/
1117         pyrna_prop_methods,                     /* struct PyMethodDef *tp_methods; */
1118         NULL,                       /* struct PyMemberDef *tp_members; */
1119         NULL,                                           /* struct PyGetSetDef *tp_getset; */
1120         NULL,                       /* struct _typeobject *tp_base; */
1121         NULL,                       /* PyObject *tp_dict; */
1122         NULL,                       /* descrgetfunc tp_descr_get; */
1123         NULL,                       /* descrsetfunc tp_descr_set; */
1124         0,                          /* long tp_dictoffset; */
1125         NULL,                       /* initproc tp_init; */
1126         NULL,                       /* allocfunc tp_alloc; */
1127         pyrna_prop_new,                         /* newfunc tp_new; */
1128         /*  Low-level free-memory routine */
1129         NULL,                       /* freefunc tp_free;  */
1130         /* For PyObject_IS_GC */
1131         NULL,                       /* inquiry tp_is_gc;  */
1132         NULL,                       /* PyObject *tp_bases; */
1133         /* method resolution order */
1134         NULL,                       /* PyObject *tp_mro;  */
1135         NULL,                       /* PyObject *tp_cache; */
1136         NULL,                       /* PyObject *tp_subclasses; */
1137         NULL,                       /* PyObject *tp_weaklist; */
1138         NULL
1139 };
1140
1141 /*-----------------------CreatePyObject---------------------------------*/
1142 PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
1143 {
1144         BPy_StructRNA *pyrna;
1145
1146         pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
1147
1148         if( !pyrna ) {
1149                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
1150                 return NULL;
1151         }
1152         
1153         pyrna->ptr= *ptr;
1154         pyrna->freeptr= 0;
1155         
1156         return ( PyObject * ) pyrna;
1157 }
1158
1159 PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
1160 {
1161         BPy_PropertyRNA *pyrna;
1162
1163         pyrna = ( BPy_PropertyRNA * ) PyObject_NEW( BPy_PropertyRNA, &pyrna_prop_Type );
1164
1165         if( !pyrna ) {
1166                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_rna object" );
1167                 return NULL;
1168         }
1169         
1170         pyrna->ptr = *ptr;
1171         pyrna->prop = prop;
1172         
1173         /* TODO - iterator? */
1174                 
1175         return ( PyObject * ) pyrna;
1176 }
1177
1178
1179 PyObject *BPY_rna_module( void )
1180 {
1181         PointerRNA ptr;
1182         
1183         if( PyType_Ready( &pyrna_struct_Type ) < 0 )
1184                 return NULL;
1185         
1186         /* This can't be set in the pytype struct because some compilers complain */
1187         pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; 
1188         pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; 
1189         
1190         if( PyType_Ready( &pyrna_prop_Type ) < 0 )
1191                 return NULL;
1192         
1193         /* for now, return the base RNA type rather then a real module */
1194         RNA_main_pointer_create(G.main, &ptr);
1195         
1196         //submodule = Py_InitModule3( "rna", M_rna_methods, "rna module" );
1197         return pyrna_struct_CreatePyObject(&ptr);
1198 }
1199
1200 /* This is a way we can access docstrings for RNA types
1201  * without having the datatypes in blender */
1202 PyObject *BPY_rna_doc( void )
1203 {
1204         PointerRNA ptr;
1205         
1206         /* for now, return the base RNA type rather then a real module */
1207         RNA_blender_rna_pointer_create(&ptr);
1208         
1209         return pyrna_struct_CreatePyObject(&ptr);
1210 }
1211
1212