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