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