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