RNA: Commit of the API patch by vekoon. This adds Functions to RNA,
[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 "bpy_util.h"
28 //#include "blendef.h"
29 #include "BLI_dynstr.h"
30 #include "BLI_listbase.h"
31 #include "float.h" /* FLT_MIN/MAX */
32
33 #include "RNA_define.h" /* for defining our own rna */
34
35 #include "MEM_guardedalloc.h"
36 #include "BKE_context.h"
37 #include "BKE_global.h" /* evil G.* */
38
39 static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
40 {
41         return (a->ptr.data==b->ptr.data) ? 0 : -1;
42 }
43
44 static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b )
45 {
46         return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1;
47 }
48
49 static int pyrna_func_compare( BPy_FunctionRNA * a, BPy_FunctionRNA * b )
50 {
51         return (a->func==b->func && a->ptr.data==b->ptr.data ) ? 0 : -1;
52 }
53
54
55 /* For some reason python3 needs these :/ */
56 static PyObject *pyrna_struct_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op)
57 {
58         int cmp_result= -1; /* assume false */
59         if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) {
60                 cmp_result= pyrna_struct_compare(a, b);
61         }
62
63         return Py_CmpToRich(op, cmp_result);
64 }
65
66 static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, int op)
67 {
68         int cmp_result= -1; /* assume false */
69         if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) {
70                 cmp_result= pyrna_prop_compare(a, b);
71         }
72
73         return Py_CmpToRich(op, cmp_result);
74 }
75
76 static PyObject *pyrna_func_richcmp(BPy_FunctionRNA * a, BPy_FunctionRNA * b, int op)
77 {
78         int cmp_result= -1; /* assume false */
79         if (BPy_FunctionRNA_Check(a) && BPy_FunctionRNA_Check(b)) {
80                 cmp_result= pyrna_func_compare(a, b);
81         }
82
83         return Py_CmpToRich(op, cmp_result);
84 }
85
86 /*----------------------repr--------------------------------------------*/
87 static PyObject *pyrna_struct_repr( BPy_StructRNA * self )
88 {
89         PropertyRNA *prop;
90         char str[512];
91
92         /* print name if available */
93         prop= RNA_struct_name_property(&self->ptr);
94         if(prop) {
95                 RNA_property_string_get(&self->ptr, prop, str);
96                 return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(&self->ptr), str);
97         }
98
99         return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\"]", RNA_struct_identifier(&self->ptr));
100 }
101
102 static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self )
103 {
104         PropertyRNA *prop;
105         PointerRNA ptr;
106         char str[512];
107
108         /* if a pointer, try to print name of pointer target too */
109         if(RNA_property_type(&self->ptr, self->prop) == PROP_POINTER) {
110                 ptr= RNA_property_pointer_get(&self->ptr, self->prop);
111
112                 if(ptr.data) {
113                         prop= RNA_struct_name_property(&ptr);
114                         if(prop) {
115                                 RNA_property_string_get(&ptr, prop, str);
116                                 return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop), str);
117                         }
118                 }
119         }
120
121         return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop));
122 }
123
124 static PyObject *pyrna_func_repr( BPy_FunctionRNA * self )
125 {
126         return PyUnicode_FromFormat( "[BPy_FunctionRNA \"%s\"]", RNA_function_identifier(&self->ptr, self->func));
127 }
128
129 static long pyrna_struct_hash( BPy_StructRNA * self )
130 {
131         return (long)self->ptr.data;
132 }
133
134 /* use our own dealloc so we can free a property if we use one */
135 static void pyrna_struct_dealloc( BPy_StructRNA * self )
136 {
137         /* Note!! for some weired reason calling PyObject_DEL() directly crashes blender! */
138         if (self->freeptr && self->ptr.data) {
139                 IDP_FreeProperty(self->ptr.data);
140                 MEM_freeN(self->ptr.data);
141                 self->ptr.data= NULL;
142         }
143
144         Py_TYPE(self)->tp_free(self);
145         return;
146 }
147
148 /* use our own dealloc so we can free a property if we use one */
149 static void pyrna_function_dealloc( BPy_FunctionRNA * self )
150 {
151         if (Py_TYPE(self)->tp_free)
152                 Py_TYPE(self)->tp_free(self);
153
154         return;
155 }
156
157 static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
158 {
159         const EnumPropertyItem *item;
160         int totitem;
161         
162         RNA_property_enum_items(ptr, prop, &item, &totitem);
163         return (char*)BPy_enum_as_string((EnumPropertyItem*)item);
164 }
165
166 PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
167 {
168         PyObject *ret;
169         int type = RNA_property_type(ptr, prop);
170         int len = RNA_property_array_length(ptr, prop);
171
172         if (len > 0) {
173                 /* resolve the array from a new pytype */
174                 return pyrna_prop_CreatePyObject(ptr, prop);
175         }
176         
177         /* see if we can coorce into a python type - PropertyType */
178         switch (type) {
179         case PROP_BOOLEAN:
180                 ret = PyBool_FromLong( RNA_property_boolean_get(ptr, prop) );
181                 break;
182         case PROP_INT:
183                 ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get(ptr, prop) );
184                 break;
185         case PROP_FLOAT:
186                 ret = PyFloat_FromDouble( RNA_property_float_get(ptr, prop) );
187                 break;
188         case PROP_STRING:
189         {
190                 char *buf;
191                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
192                 ret = PyUnicode_FromString( buf );
193                 MEM_freeN(buf);
194                 break;
195         }
196         case PROP_ENUM:
197         {
198                 const char *identifier;
199                 int val = RNA_property_enum_get(ptr, prop);
200                 
201                 if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) {
202                         ret = PyUnicode_FromString( identifier );
203                 } else {
204                         PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
205                         ret = NULL;
206                 }
207
208                 break;
209         }
210         case PROP_POINTER:
211         {
212                 PointerRNA newptr;
213                 newptr= RNA_property_pointer_get(ptr, prop);
214                 if (newptr.data) {
215                         ret = pyrna_struct_CreatePyObject(&newptr);
216                 } else {
217                         ret = Py_None;
218                         Py_INCREF(ret);
219                 }
220                 break;
221         }
222         case PROP_COLLECTION:
223                 ret = pyrna_prop_CreatePyObject(ptr, prop);
224                 break;
225         default:
226                 PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
227                 ret = NULL;
228                 break;
229         }
230         
231         return ret;
232 }
233
234 PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
235 {
236         return pyrna_func_CreatePyObject(ptr, func);
237 }
238
239 int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
240 {
241         int type = RNA_property_type(ptr, prop);
242         int len = RNA_property_array_length(ptr, prop);
243         
244         if (len > 0) {
245                 PyObject *item;
246                 int i;
247                 
248                 if (!PySequence_Check(value)) {
249                         PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array.");
250                         return -1;
251                 }
252                 
253                 if ((int)PySequence_Length(value) != len) {
254                         PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array.");
255                         return -1;
256                 }
257                 
258                 /* for arrays we have a limited number of types */
259                 switch (type) {
260                 case PROP_BOOLEAN:
261                 {
262                         int *param_arr = MEM_mallocN(sizeof(char) * len, "pyrna bool array");
263                         
264                         /* collect the variables before assigning, incase one of them is incorrect */
265                         for (i=0; i<len; i++) {
266                                 item = PySequence_GetItem(value, i);
267                                 param_arr[i] = PyObject_IsTrue( item );
268                                 Py_DECREF(item);
269                                 
270                                 if (param_arr[i] < 0) {
271                                         MEM_freeN(param_arr);
272                                         PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence is not a boolean");
273                                         return -1;
274                                 }
275                         }
276                         
277                         RNA_property_boolean_set_array(ptr, prop, param_arr);
278                         
279                         MEM_freeN(param_arr);
280                         break;
281                 }
282                 case PROP_INT:
283                 {
284                         int *param_arr = MEM_mallocN(sizeof(int) * len, "pyrna int array");
285                         
286                         /* collect the variables before assigning, incase one of them is incorrect */
287                         for (i=0; i<len; i++) {
288                                 item = PySequence_GetItem(value, i);
289                                 param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
290                                 Py_DECREF(item);
291                         }
292                         
293                         if (PyErr_Occurred()) {
294                                 MEM_freeN(param_arr);
295                                 PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as an int");
296                                 return -1;
297                         }
298                         
299                         RNA_property_int_set_array(ptr, prop, param_arr);
300                         
301                         MEM_freeN(param_arr);
302                         break;
303                 }
304                 case PROP_FLOAT:
305                 {
306                         float *param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array");
307                         
308                         /* collect the variables before assigning, incase one of them is incorrect */
309                         for (i=0; i<len; i++) {
310                                 item = PySequence_GetItem(value, i);
311                                 param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
312                                 Py_DECREF(item);
313                         }
314                         
315                         if (PyErr_Occurred()) {
316                                 MEM_freeN(param_arr);
317                                 PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as a float");
318                                 return -1;
319                         }
320                         
321                         RNA_property_float_set_array(ptr, prop, param_arr);
322                         
323                         MEM_freeN(param_arr);
324                         break;
325                 }
326                 }
327         } else {
328                 /* Normal Property (not an array) */
329                 
330                 /* see if we can coorce into a python type - PropertyType */
331                 switch (type) {
332                 case PROP_BOOLEAN:
333                 {
334                         int param = PyObject_IsTrue( value );
335                         
336                         if( param < 0 ) {
337                                 PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
338                                 return -1;
339                         } else {
340                                 RNA_property_boolean_set(ptr, prop, param);
341                         }
342                         break;
343                 }
344                 case PROP_INT:
345                 {
346                         int param = PyLong_AsSsize_t(value);
347                         if (PyErr_Occurred()) {
348                                 PyErr_SetString(PyExc_TypeError, "expected an int type");
349                                 return -1;
350                         } else {
351                                 RNA_property_int_set(ptr, prop, param);
352                         }
353                         break;
354                 }
355                 case PROP_FLOAT:
356                 {
357                         float param = PyFloat_AsDouble(value);
358                         if (PyErr_Occurred()) {
359                                 PyErr_SetString(PyExc_TypeError, "expected a float type");
360                                 return -1;
361                         } else {
362                                 RNA_property_float_set(ptr, prop, param);
363                         }
364                         break;
365                 }
366                 case PROP_STRING:
367                 {
368                         char *param = _PyUnicode_AsString(value);
369                         
370                         if (param==NULL) {
371                                 PyErr_SetString(PyExc_TypeError, "expected a string type");
372                                 return -1;
373                         } else {
374                                 RNA_property_string_set(ptr, prop, param);
375                         }
376                         break;
377                 }
378                 case PROP_ENUM:
379                 {
380                         char *param = _PyUnicode_AsString(value);
381                         
382                         if (param==NULL) {
383                                 char *enum_str= pyrna_enum_as_string(ptr, prop);
384                                 PyErr_Format(PyExc_TypeError, "expected a string enum type in (%s)", enum_str);
385                                 MEM_freeN(enum_str);
386                                 return -1;
387                         } else {
388                                 int val;
389                                 if (RNA_property_enum_value(ptr, prop, param, &val)) {
390                                         RNA_property_enum_set(ptr, prop, val);
391                                 } else {
392                                         char *enum_str= pyrna_enum_as_string(ptr, prop);
393                                         PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found in (%s)", param, enum_str);
394                                         MEM_freeN(enum_str);
395                                         return -1;
396                                 }
397                         }
398                         
399                         break;
400                 }
401                 case PROP_POINTER:
402                 {
403                         StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
404
405                         if(!BPy_StructRNA_Check(value)) {
406                                 PointerRNA tmp;
407                                 RNA_pointer_create(NULL, ptype, NULL, &tmp);
408                                 PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp));
409                                 return -1;
410                         } else {
411                                 BPy_StructRNA *param= (BPy_StructRNA*)value;
412
413                                 if(RNA_struct_is_a(&param->ptr, ptype)) {
414                                         RNA_property_pointer_set(ptr, prop, param->ptr);
415                                 } else {
416                                         PointerRNA tmp;
417                                         RNA_pointer_create(NULL, ptype, NULL, &tmp);
418                                         PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp));
419                                         return -1;
420                                 }
421                         }
422                         break;
423                 }
424                 case PROP_COLLECTION:
425                         PyErr_SetString(PyExc_AttributeError, "cant assign to collections");
426                         return -1;
427                         break;
428                 default:
429                         PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_prop)");
430                         return -1;
431                         break;
432                 }
433         }
434         
435         return 0;
436 }
437
438 static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index)
439 {
440         PyObject *ret;
441         int type = RNA_property_type(ptr, prop);
442         
443         /* see if we can coorce into a python type - PropertyType */
444         switch (type) {
445         case PROP_BOOLEAN:
446                 ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) );
447                 break;
448         case PROP_INT:
449                 ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get_index(ptr, prop, index) );
450                 break;
451         case PROP_FLOAT:
452                 ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) );
453                 break;
454         default:
455                 PyErr_SetString(PyExc_AttributeError, "not an array type");
456                 ret = NULL;
457                 break;
458         }
459         
460         return ret;
461 }
462
463 static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value)
464 {
465         int ret = 0;
466         int type = RNA_property_type(ptr, prop);
467         
468         /* see if we can coorce into a python type - PropertyType */
469         switch (type) {
470         case PROP_BOOLEAN:
471         {
472                 int param = PyObject_IsTrue( value );
473                 
474                 if( param < 0 ) {
475                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
476                         ret = -1;
477                 } else {
478                         RNA_property_boolean_set_index(ptr, prop, index, param);
479                 }
480                 break;
481         }
482         case PROP_INT:
483         {
484                 int param = PyLong_AsSsize_t(value);
485                 if (PyErr_Occurred()) {
486                         PyErr_SetString(PyExc_TypeError, "expected an int type");
487                         ret = -1;
488                 } else {
489                         RNA_property_int_set_index(ptr, prop, index, param);
490                 }
491                 break;
492         }
493         case PROP_FLOAT:
494         {
495                 float param = PyFloat_AsDouble(value);
496                 if (PyErr_Occurred()) {
497                         PyErr_SetString(PyExc_TypeError, "expected a float type");
498                         ret = -1;
499                 } else {
500                         RNA_property_float_set_index(ptr, prop, index, param);
501                 }
502                 break;
503         }
504         default:
505                 PyErr_SetString(PyExc_AttributeError, "not an array type");
506                 ret = -1;
507                 break;
508         }
509         
510         return ret;
511 }
512
513 //---------------sequence-------------------------------------------
514 static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
515 {
516         Py_ssize_t len;
517         
518         if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
519                 len = RNA_property_collection_length(&self->ptr, self->prop);
520         } else {
521                 len = RNA_property_array_length(&self->ptr, self->prop);
522                 
523                 if (len==0) { /* not an array*/
524                         PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
525                         return -1;
526                 }
527         }
528         
529         return len;
530 }
531
532 static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
533 {
534         PyObject *ret;
535         PointerRNA newptr;
536         int keynum = 0;
537         char *keyname = NULL;
538         
539         if (PyUnicode_Check(key)) {
540                 keyname = _PyUnicode_AsString(key);
541         } else if (PyLong_Check(key)) {
542                 keynum = PyLong_AsSsize_t(key);
543         } else {
544                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int");
545                 return NULL;
546         }
547         
548         if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
549                 int ok;
550                 if (keyname)    ok = RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr);
551                 else                    ok = RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr);
552                 
553                 if (ok) {
554                         ret = pyrna_struct_CreatePyObject(&newptr);
555                 } else {
556                         PyErr_SetString(PyExc_AttributeError, "out of range");
557                         ret = NULL;
558                 }
559                 
560         } else if (keyname) {
561                 PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections");
562                 ret = NULL;
563         } else {
564                 int len = RNA_property_array_length(&self->ptr, self->prop);
565                 
566                 if (len==0) { /* not an array*/
567                         PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum);
568                         ret = NULL;
569                 }
570                 
571                 if (keynum >= len){
572                         PyErr_SetString(PyExc_AttributeError, "index out of range");
573                         ret = NULL;
574                 } else { /* not an array*/
575                         ret = pyrna_prop_to_py_index(&self->ptr, self->prop, keynum);
576                 }
577         }
578         
579         return ret;
580 }
581
582
583 static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value )
584 {
585         int ret = 0;
586         int keynum = 0;
587         char *keyname = NULL;
588         
589         if (!RNA_property_editable(&self->ptr, self->prop)) {
590                 PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, self->prop), RNA_struct_identifier(&self->ptr) );
591                 return -1;
592         }
593         
594         if (PyUnicode_Check(key)) {
595                 keyname = _PyUnicode_AsString(key);
596         } else if (PyLong_Check(key)) {
597                 keynum = PyLong_AsSsize_t(key);
598         } else {
599                 PyErr_SetString(PyExc_AttributeError, "PropertyRNA - invalid key, key must be a string or an int");
600                 return -1;
601         }
602         
603         if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
604                 PyErr_SetString(PyExc_AttributeError, "PropertyRNA - assignment is not supported for collections (yet)");
605                 ret = -1;
606         } else if (keyname) {
607                 PyErr_SetString(PyExc_AttributeError, "PropertyRNA - string keys are only supported for collections");
608                 ret = -1;
609         } else {
610                 int len = RNA_property_array_length(&self->ptr, self->prop);
611                 
612                 if (len==0) { /* not an array*/
613                         PyErr_Format(PyExc_AttributeError, "PropertyRNA - not an array or collection %d", keynum);
614                         ret = -1;
615                 }
616                 
617                 if (keynum >= len){
618                         PyErr_SetString(PyExc_AttributeError, "PropertyRNA - index out of range");
619                         ret = -1;
620                 } else {
621                         ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
622                 }
623         }
624         
625         return ret;
626 }
627
628
629
630 static PyMappingMethods pyrna_prop_as_mapping = {
631         ( inquiry ) pyrna_prop_len,     /* mp_length */
632         ( binaryfunc ) pyrna_prop_subscript,    /* mp_subscript */
633         ( objobjargproc ) pyrna_prop_assign_subscript,  /* mp_ass_subscript */
634 };
635
636 static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
637 {
638         PyObject *ret, *dict;
639         PyObject *pystring;
640         
641         /* Include this incase this instance is a subtype of a python class
642          * In these instances we may want to return a function or variable provided by the subtype
643          * */
644
645         if (BPy_StructRNA_CheckExact(self)) {
646                 ret = PyList_New(0);
647         } else {
648                 pystring = PyUnicode_FromString("__dict__");
649                 dict = PyObject_GenericGetAttr((PyObject *)self, pystring);
650                 Py_DECREF(pystring);
651
652                 if (dict==NULL) {
653                         PyErr_Clear();
654                         ret = PyList_New(0);
655                 }
656                 else {
657                         ret = PyDict_Keys(dict);
658                         Py_DECREF(dict);
659                 }
660         }
661         
662         /* Collect RNA items*/
663         {
664                 PropertyRNA *iterprop, *nameprop;
665                 CollectionPropertyIterator iter;
666                 char name[256], *nameptr;
667
668                 iterprop= RNA_struct_iterator_property(&self->ptr);
669                 RNA_property_collection_begin(&self->ptr, iterprop, &iter);
670
671                 for(; iter.valid; RNA_property_collection_next(&iter)) {
672                         if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
673                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
674                                 
675                                 pystring = PyUnicode_FromString(nameptr);
676                                 PyList_Append(ret, pystring);
677                                 Py_DECREF(pystring);
678                                 
679                                 if ((char *)&name != nameptr)
680                                         MEM_freeN(nameptr);
681                         }
682                 }
683                 
684                 RNA_property_collection_end(&iter);
685         }
686         
687         return ret;
688 }
689
690
691 //---------------getattr--------------------------------------------
692 static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
693 {
694         char *name = _PyUnicode_AsString(pyname);
695         PyObject *ret;
696         PropertyRNA *prop;
697         FunctionRNA *func;
698         
699         /* Include this incase this instance is a subtype of a python class
700          * In these instances we may want to return a function or variable provided by the subtype
701          * 
702          * Also needed to return methods when its not a subtype
703          * */
704         ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
705         if (ret)        return ret;
706         else            PyErr_Clear();
707         /* done with subtypes */
708         
709         if ((prop = RNA_struct_find_property(&self->ptr, name))) {
710                 ret = pyrna_prop_to_py(&self->ptr, prop);
711         }
712         else if ((func = RNA_struct_find_function(&self->ptr, name))) {
713                 ret = pyrna_func_to_py(&self->ptr, func);
714         }
715         else if (self->ptr.type == &RNA_Context) {
716                 PointerRNA newptr;
717                 ListBase newlb;
718
719                 CTX_data_get(self->ptr.data, name, &newptr, &newlb);
720
721         if (newptr.data) {
722             ret = pyrna_struct_CreatePyObject(&newptr);
723                 }
724                 else if (newlb.first) {
725                         CollectionPointerLink *link;
726                         PyObject *linkptr;
727
728                         ret = PyList_New(0);
729
730                         for(link=newlb.first; link; link=link->next) {
731                                 linkptr= pyrna_struct_CreatePyObject(&link->ptr);
732                                 PyList_Append(ret, linkptr);
733                                 Py_DECREF(linkptr);
734                         }
735                 }
736         else {
737             ret = Py_None;
738             Py_INCREF(ret);
739         }
740
741                 BLI_freelistN(&newlb);
742         }
743         else {
744                 PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" not found", name);
745                 ret = NULL;
746         }
747         
748         return ret;
749 }
750
751 //--------------- setattr-------------------------------------------
752 static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObject * value )
753 {
754         char *name = _PyUnicode_AsString(pyname);
755         PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name);
756         
757         if (prop==NULL) {
758                 if (!BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) {
759                         return 0;
760                 }
761                 else {
762                         PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" not found", name);
763                         return -1;
764                 }
765         }               
766         
767         if (!RNA_property_editable(&self->ptr, prop)) {
768                 PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, prop), RNA_struct_identifier(&self->ptr) );
769                 return -1;
770         }
771                 
772         /* pyrna_py_to_prop sets its own exceptions */
773         return pyrna_py_to_prop(&self->ptr, prop, value);
774 }
775
776 PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
777 {
778         PyObject *ret;
779         if (RNA_property_type(&self->ptr, self->prop) != PROP_COLLECTION) {
780                 PyErr_SetString( PyExc_TypeError, "keys() is only valid for collection types" );
781                 ret = NULL;
782         } else {
783                 PyObject *item;
784                 CollectionPropertyIterator iter;
785                 PropertyRNA *nameprop;
786                 char name[256], *nameptr;
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                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));                                
794                                 
795                                 /* add to python list */
796                                 item = PyUnicode_FromString( nameptr );
797                                 PyList_Append(ret, item);
798                                 Py_DECREF(item);
799                                 /* done */
800                                 
801                                 if ((char *)&name != nameptr)
802                                         MEM_freeN(nameptr);
803                         }
804                 }
805                 RNA_property_collection_end(&iter);
806         }
807         
808         return ret;
809 }
810
811 PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
812 {
813         PyObject *ret;
814         if (RNA_property_type(&self->ptr, self->prop) != PROP_COLLECTION) {
815                 PyErr_SetString( PyExc_TypeError, "items() is only valid for collection types" );
816                 ret = NULL;
817         } else {
818                 PyObject *item;
819                 CollectionPropertyIterator iter;
820                 PropertyRNA *nameprop;
821                 char name[256], *nameptr;
822
823                 ret = PyList_New(0);
824                 
825                 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
826                 for(; iter.valid; RNA_property_collection_next(&iter)) {
827                         if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
828                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
829                                 
830                                 /* add to python list */
831                                 item = Py_BuildValue("(NN)", PyUnicode_FromString( nameptr ), pyrna_struct_CreatePyObject(&iter.ptr));
832                                 PyList_Append(ret, item);
833                                 Py_DECREF(item);
834                                 /* done */
835                                 
836                                 if ((char *)&name != nameptr)
837                                         MEM_freeN(nameptr);
838                         }
839                 }
840                 RNA_property_collection_end(&iter);
841         }
842         
843         return ret;
844 }
845
846
847 PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
848 {
849         PyObject *ret;
850         if (RNA_property_type(&self->ptr, self->prop) != PROP_COLLECTION) {
851                 PyErr_SetString( PyExc_TypeError, "values() is only valid for collection types" );
852                 ret = NULL;
853         } else {
854                 PyObject *item;
855                 CollectionPropertyIterator iter;
856                 PropertyRNA *nameprop;
857                 
858                 ret = PyList_New(0);
859                 
860                 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
861                 for(; iter.valid; RNA_property_collection_next(&iter)) {
862                         if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
863                                 item = pyrna_struct_CreatePyObject(&iter.ptr);
864                                 PyList_Append(ret, item);
865                                 Py_DECREF(item);
866                         }
867                 }
868                 RNA_property_collection_end(&iter);
869         }
870         
871         return ret;
872 }
873
874 /* A bit of a kludge, make a list out of a collection or array,
875  * then return the lists iter function, not especially fast but convenient for now */
876 PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
877 {
878         /* Try get values from a collection */
879         PyObject *ret = pyrna_prop_values(self);
880         
881         if (ret==NULL) {
882                 /* collection did not work, try array */
883                 int len = RNA_property_array_length(&self->ptr, self->prop);
884                 
885                 if (len) {
886                         int i;
887                         PyErr_Clear();
888                         ret = PyList_New(len);
889                         
890                         for (i=0; i < len; i++) {
891                                 PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(&self->ptr, self->prop, i));
892                         }
893                 }
894         }
895         
896         if (ret) {
897                 /* we know this is a list so no need to PyIter_Check */
898                 PyObject *iter = PyObject_GetIter(ret); 
899                 Py_DECREF(ret);
900                 return iter;
901         }
902         
903         PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
904         return NULL;
905 }
906
907 static struct PyMethodDef pyrna_struct_methods[] = {
908         {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""},
909         {NULL, NULL, 0, NULL}
910 };
911
912 static struct PyMethodDef pyrna_prop_methods[] = {
913         {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""},
914         {"items", (PyCFunction)pyrna_prop_items, METH_NOARGS, ""},
915         {"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, ""},
916         {NULL, NULL, 0, NULL}
917 };
918
919 /* only needed for subtyping, so a new class gets a valid BPy_StructRNA
920  * todo - also accept useful args */
921 static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
922
923         BPy_StructRNA *base = NULL;
924         
925         if (!PyArg_ParseTuple(args, "O!:Base BPy_StructRNA", &pyrna_struct_Type, &base))
926                 return NULL;
927         
928         if (type == &pyrna_struct_Type) {
929                 return pyrna_struct_CreatePyObject(&base->ptr);
930         } else {
931                 BPy_StructRNA *ret = (BPy_StructRNA *) type->tp_alloc(type, 0);
932                 ret->ptr = base->ptr;
933                 return (PyObject *)ret;
934         }
935 }
936
937 /* only needed for subtyping, so a new class gets a valid BPy_StructRNA
938  * todo - also accept useful args */
939 static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
940
941         BPy_PropertyRNA *base = NULL;
942         
943         if (!PyArg_ParseTuple(args, "O!:Base BPy_PropertyRNA", &pyrna_prop_Type, &base))
944                 return NULL;
945         
946         if (type == &pyrna_prop_Type) {
947                 return pyrna_prop_CreatePyObject(&base->ptr, base->prop);
948         } else {
949                 BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0);
950                 ret->ptr = base->ptr;
951                 ret->prop = base->prop;
952                 return (PyObject *)ret;
953         }
954 }
955
956 /* only needed for subtyping, so a new class gets a valid BPy_FunctionRNA
957 * todo - also accept useful args */
958 static PyObject * pyrna_func_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
959
960         BPy_FunctionRNA *base = NULL;
961
962         if (!PyArg_ParseTuple(args, "O!:Base BPy_FunctionRNA", &pyrna_func_Type, &base))
963                 return NULL;
964
965         if (type == &pyrna_func_Type) {
966                 return pyrna_func_CreatePyObject(&base->ptr, base->func);
967         } else {
968                 BPy_FunctionRNA *ret = (BPy_FunctionRNA *) type->tp_alloc(type, 0);
969                 ret->ptr = base->ptr;
970                 ret->func = base->func;
971                 return (PyObject *)ret;
972         }
973 }
974
975 int pyrna_py_to_param(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value)
976 {
977         /* XXX hard limits should be checked here */
978         int type = RNA_property_type(ptr, prop);
979         int len = RNA_property_array_length(ptr, prop);
980         
981         if (len > 0) {
982                 PyObject *item;
983                 int i;
984                 
985                 if (!PySequence_Check(value)) {
986                         PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array.");
987                         return -1;
988                 }
989                 
990                 if ((int)PySequence_Length(value) != len) {
991                         PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array.");
992                         return -1;
993                 }
994                 
995                 /* for arrays we have a limited number of types */
996                 switch (type) {
997                 case PROP_BOOLEAN:
998                 {
999                         int *param_arr = (int*)data;
1000                         
1001                         /* collect the variables before assigning, incase one of them is incorrect */
1002                         for (i=0; i<len; i++) {
1003                                 item = PySequence_GetItem(value, i);
1004                                 param_arr[i] = PyObject_IsTrue( item );
1005                                 Py_DECREF(item);
1006                                 
1007                                 if (param_arr[i] < 0) {
1008                                         PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence is not a boolean");
1009                                         return -1;
1010                                 }
1011                         }
1012                         
1013                         break;
1014                 }
1015                 case PROP_INT:
1016                 {
1017                         int *param_arr = (int*)data;
1018                         
1019                         /* collect the variables */
1020                         for (i=0; i<len; i++) {
1021                                 item = PySequence_GetItem(value, i);
1022                                 param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
1023                                 Py_DECREF(item);
1024                         }
1025                         
1026                         if (PyErr_Occurred()) {
1027                                 PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as an int");
1028                                 return -1;
1029                         }
1030
1031                         break;
1032                 }
1033                 case PROP_FLOAT:
1034                 {
1035                         float *param_arr = (float*)data;
1036                         
1037                         /* collect the variables */
1038                         for (i=0; i<len; i++) {
1039                                 item = PySequence_GetItem(value, i);
1040                                 param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
1041                                 Py_DECREF(item);
1042                         }
1043                         
1044                         if (PyErr_Occurred()) {
1045                                 PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as a float");
1046                                 return -1;
1047                         }
1048                         
1049                         break;
1050                 }
1051                 }
1052         } else {
1053                 /* Normal Property (not an array) */
1054                 
1055                 /* see if we can coorce into a python type - PropertyType */
1056                 switch (type) {
1057                 case PROP_BOOLEAN:
1058                 {
1059                         int param = PyObject_IsTrue( value );
1060                         
1061                         if( param < 0 ) {
1062                                 PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1063                                 return -1;
1064                         } else {
1065                                 *((int*)data)= param;
1066                         }
1067                         break;
1068                 }
1069                 case PROP_INT:
1070                 {
1071                         int param = PyLong_AsSsize_t(value);
1072                         if (PyErr_Occurred()) {
1073                                 PyErr_SetString(PyExc_TypeError, "expected an int type");
1074                                 return -1;
1075                         } else {
1076                                 *((int*)data)= param;
1077                         }
1078                         break;
1079                 }
1080                 case PROP_FLOAT:
1081                 {
1082                         float param = PyFloat_AsDouble(value);
1083                         if (PyErr_Occurred()) {
1084                                 PyErr_SetString(PyExc_TypeError, "expected a float type");
1085                                 return -1;
1086                         } else {
1087                                 *((float*)data)= param;
1088                         }
1089                         break;
1090                 }
1091                 case PROP_STRING:
1092                 {
1093                         char *param = _PyUnicode_AsString(value);
1094                         
1095                         if (param==NULL) {
1096                                 PyErr_SetString(PyExc_TypeError, "expected a string type");
1097                                 return -1;
1098                         } else {
1099                                 *((char**)data)= param;
1100                         }
1101                         break;
1102                 }
1103                 case PROP_ENUM:
1104                 {
1105                         char *param = _PyUnicode_AsString(value);
1106                         
1107                         if (param==NULL) {
1108                                 char *enum_str= pyrna_enum_as_string(ptr, prop);
1109                                 PyErr_Format(PyExc_TypeError, "expected a string enum type in (%s)", enum_str);
1110                                 MEM_freeN(enum_str);
1111                                 return -1;
1112                         } else {
1113                                 int val;
1114                                 if (RNA_property_enum_value(ptr, prop, param, &val)) {
1115                                         *((int*)data)= val;
1116                                 } else {
1117                                         char *enum_str= pyrna_enum_as_string(ptr, prop);
1118                                         PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found in (%s)", param, enum_str);
1119                                         MEM_freeN(enum_str);
1120                                         return -1;
1121                                 }
1122                         }
1123                         
1124                         break;
1125                 }
1126                 case PROP_POINTER:
1127                 {
1128                         StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
1129
1130                         if(!BPy_StructRNA_Check(value)) {
1131                                 PointerRNA tmp;
1132                                 RNA_pointer_create(NULL, ptype, NULL, &tmp);
1133                                 PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp));
1134                                 return -1;
1135                         } else {
1136                                 BPy_StructRNA *param= (BPy_StructRNA*)value;
1137
1138                                 if(ptype == &RNA_AnyType) {
1139                                         *((PointerRNA*)data)= param->ptr;
1140                                 }
1141                                 else if(RNA_struct_is_a(&param->ptr, ptype)) {
1142                                         *((void**)data)= param->ptr.data;
1143                                 } else {
1144                                         PointerRNA tmp;
1145                                         RNA_pointer_create(NULL, ptype, NULL, &tmp);
1146                                         PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp));
1147                                         return -1;
1148                                 }
1149                         }
1150                         break;
1151                 }
1152                 case PROP_COLLECTION:
1153                         PyErr_SetString(PyExc_AttributeError, "cant pass collections yet");
1154                         return -1;
1155                         break;
1156                 default:
1157                         PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_param)");
1158                         return -1;
1159                         break;
1160                 }
1161         }
1162         
1163         return 0;
1164 }
1165
1166 PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
1167 {
1168         PyObject *ret;
1169         int type = RNA_property_type(ptr, prop);
1170         int len = RNA_property_array_length(ptr, prop);
1171         int a;
1172
1173         if(len > 0) {
1174                 /* resolve the array from a new pytype */
1175                 ret = PyTuple_New(len);
1176
1177                 switch (type) {
1178                 case PROP_BOOLEAN:
1179                         for(a=0; a<len; a++)
1180                                 PyTuple_SET_ITEM(ret, a, PyBool_FromLong( ((int*)data)[a] ));
1181                         break;
1182                 case PROP_INT:
1183                         for(a=0; a<len; a++)
1184                                 PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t( (Py_ssize_t)((int*)data)[a] ));
1185                         break;
1186                 case PROP_FLOAT:
1187                         for(a=0; a<len; a++)
1188                                 PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] ));
1189                         break;
1190                 default:
1191                         PyErr_Format(PyExc_AttributeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
1192                         ret = NULL;
1193                         break;
1194                 }
1195         }
1196         else {
1197                 /* see if we can coorce into a python type - PropertyType */
1198                 switch (type) {
1199                 case PROP_BOOLEAN:
1200                         ret = PyBool_FromLong( *(int*)data );
1201                         break;
1202                 case PROP_INT:
1203                         ret = PyLong_FromSsize_t( (Py_ssize_t)*(int*)data );
1204                         break;
1205                 case PROP_FLOAT:
1206                         ret = PyFloat_FromDouble( *(float*)data );
1207                         break;
1208                 case PROP_STRING:
1209                 {
1210                         ret = PyUnicode_FromString( *(char**)data );
1211                         break;
1212                 }
1213                 case PROP_ENUM:
1214                 {
1215                         const char *identifier;
1216                         int val = *(int*)data;
1217                         
1218                         if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) {
1219                                 ret = PyUnicode_FromString( identifier );
1220                         } else {
1221                                 PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
1222                                 ret = NULL;
1223                         }
1224
1225                         break;
1226                 }
1227                 case PROP_POINTER:
1228                 {
1229                         PointerRNA newptr;
1230                         StructRNA *type= RNA_property_pointer_type(ptr, prop);
1231
1232                         if(type == &RNA_AnyType) {
1233                                 /* in this case we get the full ptr */
1234                                 newptr= *(PointerRNA*)data;
1235                         }
1236                         else {
1237                                 /* XXX this is missing the ID part! */
1238                                 RNA_pointer_create(NULL, type, *(void**)data, &newptr);
1239                         }
1240
1241                         if (newptr.data) {
1242                                 ret = pyrna_struct_CreatePyObject(&newptr);
1243                         } else {
1244                                 ret = Py_None;
1245                                 Py_INCREF(ret);
1246                         }
1247                         break;
1248                 }
1249                 case PROP_COLLECTION:
1250                         /* XXX not supported yet
1251                          * ret = pyrna_prop_CreatePyObject(ptr, prop); */
1252                         break;
1253                 default:
1254                         PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
1255                         ret = NULL;
1256                         break;
1257                 }
1258         }
1259
1260         return ret;
1261 }
1262
1263 static PyObject * pyrna_func_call(BPy_FunctionRNA * self, PyObject *args, PyObject *kw)
1264 {
1265         PointerRNA funcptr;
1266         ParameterList *parms;
1267         ParameterIterator iter;
1268         PropertyRNA *pret, *parm;
1269         PyObject *ret, *item;
1270         int i, tlen, err= 0;
1271         const char *tid, *fid, *pid;
1272         void *retdata= NULL;
1273
1274         /* setup */
1275         RNA_pointer_create(NULL, &RNA_Function, self->func, &funcptr);
1276
1277         pret= RNA_function_return(&self->ptr, self->func);
1278         tlen= PyTuple_GET_SIZE(args);
1279
1280         parms= RNA_parameter_list_create(&self->ptr, self->func);
1281         RNA_parameter_list_begin(parms, &iter);
1282
1283         /* parse function parameters */
1284         for (i= 0; iter.valid; RNA_parameter_list_next(&iter), i++) {
1285                 parm= iter.parm;
1286
1287                 if (parm==pret) {
1288                         retdata= iter.data;
1289                         continue;
1290                 }
1291
1292                 pid= RNA_property_identifier(&funcptr, parm);
1293                 item= NULL;
1294
1295                 if (i < tlen)
1296                         item= PyTuple_GET_ITEM(args, i);
1297
1298                 if (kw != NULL)
1299                         item= PyDict_GetItemString(kw, pid);
1300
1301                 if (item==NULL) {
1302                         /* XXX need to add flag for optional required parameters
1303                         if (flag & PARAM_OPTIONAL)
1304                                 continue; */
1305
1306                         tid= RNA_struct_identifier(&self->ptr);
1307                         fid= RNA_function_identifier(&self->ptr, self->func);
1308
1309                         PyErr_Format(PyExc_AttributeError, "%s.%s(): required parameter \"%s\" not specified", tid, fid, pid);
1310                         err= -1;
1311                         break;
1312                 }
1313
1314                 err= pyrna_py_to_param(&funcptr, parm, iter.data, item);
1315
1316                 if(err!=0)
1317                         break;
1318         }
1319
1320         ret= NULL;
1321         if (err==0) {
1322                 /* call function */
1323                 RNA_function_call(&self->ptr, self->func, parms);
1324
1325                 /* return value */
1326                 if(pret)
1327                         ret= pyrna_param_to_py(&funcptr, pret, retdata);
1328         }
1329
1330         /* cleanup */
1331         RNA_parameter_list_end(&iter);
1332         RNA_parameter_list_free(parms);
1333
1334         if (ret)
1335                 return ret;
1336
1337         if (err==-1)
1338                 return NULL;
1339
1340         Py_RETURN_NONE;
1341 }
1342
1343 /*-----------------------BPy_StructRNA method def------------------------------*/
1344 PyTypeObject pyrna_struct_Type = {
1345 #if (PY_VERSION_HEX >= 0x02060000)
1346         PyVarObject_HEAD_INIT(NULL, 0)
1347 #else
1348         /* python 2.5 and below */
1349         PyObject_HEAD_INIT( NULL )  /* required py macro */
1350         0,                          /* ob_size */
1351 #endif
1352         "StructRNA",                    /* tp_name */
1353         sizeof( BPy_StructRNA ),        /* tp_basicsize */
1354         0,                      /* tp_itemsize */
1355         /* methods */
1356         ( destructor ) pyrna_struct_dealloc,/* tp_dealloc */
1357         NULL,                       /* printfunc tp_print; */
1358         NULL,                                           /* getattrfunc tp_getattr; */
1359         NULL,                                           /* setattrfunc tp_setattr; */
1360         NULL,                                           /* tp_compare */ /* DEPRECATED in python 3.0! */
1361         ( reprfunc ) pyrna_struct_repr, /* tp_repr */
1362
1363         /* Method suites for standard classes */
1364
1365         NULL,                       /* PyNumberMethods *tp_as_number; */
1366         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
1367         NULL,                                           /* PyMappingMethods *tp_as_mapping; */
1368
1369         /* More standard operations (here for binary compatibility) */
1370
1371         ( hashfunc )pyrna_struct_hash,  /* hashfunc tp_hash; */
1372         NULL,                                           /* ternaryfunc tp_call; */
1373         NULL,                       /* reprfunc tp_str; */
1374         ( getattrofunc ) pyrna_struct_getattro, /* getattrofunc tp_getattro; */
1375         ( setattrofunc ) pyrna_struct_setattro, /* setattrofunc tp_setattro; */
1376
1377         /* Functions to access object as input/output buffer */
1378         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1379
1380   /*** Flags to define presence of optional/expanded features ***/
1381         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
1382
1383         NULL,                                           /*  char *tp_doc;  Documentation string */
1384   /*** Assigned meaning in release 2.0 ***/
1385         /* call function for all accessible objects */
1386         NULL,                       /* traverseproc tp_traverse; */
1387
1388         /* delete references to contained objects */
1389         NULL,                       /* inquiry tp_clear; */
1390
1391   /***  Assigned meaning in release 2.1 ***/
1392   /*** rich comparisons ***/
1393         (richcmpfunc)pyrna_struct_richcmp,      /* richcmpfunc tp_richcompare; */
1394
1395   /***  weak reference enabler ***/
1396         0,                          /* long tp_weaklistoffset; */
1397
1398   /*** Added in release 2.2 ***/
1399         /*   Iterators */
1400         NULL,                       /* getiterfunc tp_iter; */
1401         NULL,                       /* iternextfunc tp_iternext; */
1402
1403   /*** Attribute descriptor and subclassing stuff ***/
1404         pyrna_struct_methods,                   /* struct PyMethodDef *tp_methods; */
1405         NULL,                       /* struct PyMemberDef *tp_members; */
1406         NULL,                                           /* struct PyGetSetDef *tp_getset; */
1407         NULL,                       /* struct _typeobject *tp_base; */
1408         NULL,                       /* PyObject *tp_dict; */
1409         NULL,                       /* descrgetfunc tp_descr_get; */
1410         NULL,                       /* descrsetfunc tp_descr_set; */
1411         0,                          /* long tp_dictoffset; */
1412         NULL,                       /* initproc tp_init; */
1413         NULL,                       /* allocfunc tp_alloc; */
1414         pyrna_struct_new,                       /* newfunc tp_new; */
1415         /*  Low-level free-memory routine */
1416         NULL,                       /* freefunc tp_free;  */
1417         /* For PyObject_IS_GC */
1418         NULL,                       /* inquiry tp_is_gc;  */
1419         NULL,                       /* PyObject *tp_bases; */
1420         /* method resolution order */
1421         NULL,                       /* PyObject *tp_mro;  */
1422         NULL,                       /* PyObject *tp_cache; */
1423         NULL,                       /* PyObject *tp_subclasses; */
1424         NULL,                       /* PyObject *tp_weaklist; */
1425         NULL
1426 };
1427
1428 /*-----------------------BPy_PropertyRNA method def------------------------------*/
1429 PyTypeObject pyrna_prop_Type = {
1430 #if (PY_VERSION_HEX >= 0x02060000)
1431         PyVarObject_HEAD_INIT(NULL, 0)
1432 #else
1433         /* python 2.5 and below */
1434         PyObject_HEAD_INIT( NULL )  /* required py macro */
1435         0,                          /* ob_size */
1436 #endif
1437         
1438         "PropertyRNA",          /* tp_name */
1439         sizeof( BPy_PropertyRNA ),                      /* tp_basicsize */
1440         0,                      /* tp_itemsize */
1441         /* methods */
1442         NULL,                                           /* tp_dealloc */
1443         NULL,                       /* printfunc tp_print; */
1444         NULL,                                           /* getattrfunc tp_getattr; */
1445         NULL,                       /* setattrfunc tp_setattr; */
1446         NULL,                                           /* tp_compare */ /* DEPRECATED in python 3.0! */
1447         ( reprfunc ) pyrna_prop_repr,   /* tp_repr */
1448
1449         /* Method suites for standard classes */
1450
1451         NULL,                       /* PyNumberMethods *tp_as_number; */
1452         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
1453         &pyrna_prop_as_mapping,         /* PyMappingMethods *tp_as_mapping; */
1454
1455         /* More standard operations (here for binary compatibility) */
1456
1457         NULL,                                           /* hashfunc tp_hash; */
1458         NULL,                       /* ternaryfunc tp_call; */
1459         NULL,                       /* reprfunc tp_str; */
1460         NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */      /* getattrofunc tp_getattro; */ /* will only use these if this is a subtype of a py class */
1461         NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */      /* setattrofunc tp_setattro; */
1462
1463         /* Functions to access object as input/output buffer */
1464         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1465
1466   /*** Flags to define presence of optional/expanded features ***/
1467         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
1468
1469         NULL,                                           /*  char *tp_doc;  Documentation string */
1470   /*** Assigned meaning in release 2.0 ***/
1471         /* call function for all accessible objects */
1472         NULL,                       /* traverseproc tp_traverse; */
1473
1474         /* delete references to contained objects */
1475         NULL,                       /* inquiry tp_clear; */
1476
1477   /***  Assigned meaning in release 2.1 ***/
1478   /*** rich comparisons ***/
1479         (richcmpfunc)pyrna_prop_richcmp,        /* richcmpfunc tp_richcompare; */
1480
1481   /***  weak reference enabler ***/
1482         0,                          /* long tp_weaklistoffset; */
1483
1484   /*** Added in release 2.2 ***/
1485         /*   Iterators */
1486         (getiterfunc)pyrna_prop_iter,   /* getiterfunc tp_iter; */
1487         NULL,                       /* iternextfunc tp_iternext; */
1488
1489   /*** Attribute descriptor and subclassing stuff ***/
1490         pyrna_prop_methods,                     /* struct PyMethodDef *tp_methods; */
1491         NULL,                       /* struct PyMemberDef *tp_members; */
1492         NULL,                                           /* struct PyGetSetDef *tp_getset; */
1493         NULL,                       /* struct _typeobject *tp_base; */
1494         NULL,                       /* PyObject *tp_dict; */
1495         NULL,                       /* descrgetfunc tp_descr_get; */
1496         NULL,                       /* descrsetfunc tp_descr_set; */
1497         0,                          /* long tp_dictoffset; */
1498         NULL,                       /* initproc tp_init; */
1499         NULL,                       /* allocfunc tp_alloc; */
1500         pyrna_prop_new,                         /* newfunc tp_new; */
1501         /*  Low-level free-memory routine */
1502         NULL,                       /* freefunc tp_free;  */
1503         /* For PyObject_IS_GC */
1504         NULL,                       /* inquiry tp_is_gc;  */
1505         NULL,                       /* PyObject *tp_bases; */
1506         /* method resolution order */
1507         NULL,                       /* PyObject *tp_mro;  */
1508         NULL,                       /* PyObject *tp_cache; */
1509         NULL,                       /* PyObject *tp_subclasses; */
1510         NULL,                       /* PyObject *tp_weaklist; */
1511         NULL
1512 };
1513
1514 /*-----------------------BPy_FunctionRNA method def------------------------------*/
1515 PyTypeObject pyrna_func_Type = {
1516 #if (PY_VERSION_HEX >= 0x02060000)
1517         PyVarObject_HEAD_INIT(NULL, 0)
1518 #else
1519         /* python 2.5 and below */
1520         PyObject_HEAD_INIT( NULL )  /* required py macro */
1521         0,                          /* ob_size */
1522 #endif
1523
1524         "FunctionRNA",          /* tp_name */
1525         sizeof( BPy_FunctionRNA ),                      /* tp_basicsize */
1526         0,                      /* tp_itemsize */
1527         /* methods */
1528         ( destructor ) pyrna_function_dealloc,  /* tp_dealloc */
1529         NULL,                       /* printfunc tp_print; */
1530         NULL,                                           /* getattrfunc tp_getattr; */
1531         NULL,                       /* setattrfunc tp_setattr; */
1532         ( cmpfunc ) pyrna_func_compare, /* tp_compare */
1533         ( reprfunc ) pyrna_func_repr,   /* tp_repr */
1534
1535         /* Method suites for standard classes */
1536
1537         NULL,                       /* PyNumberMethods *tp_as_number; */
1538         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
1539         NULL,           /* PyMappingMethods *tp_as_mapping; */
1540
1541         /* More standard operations (here for binary compatibility) */
1542
1543         NULL,                                           /* hashfunc tp_hash; */
1544         (ternaryfunc)pyrna_func_call,                       /* ternaryfunc tp_call; */
1545         NULL,                       /* reprfunc tp_str; */
1546         NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */      /* getattrofunc tp_getattro; */ /* will only use these if this is a subtype of a py class */
1547         NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */      /* setattrofunc tp_setattro; */
1548
1549         /* Functions to access object as input/output buffer */
1550         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1551
1552         /*** Flags to define presence of optional/expanded features ***/
1553         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
1554
1555         NULL,                                           /*  char *tp_doc;  Documentation string */
1556         /*** Assigned meaning in release 2.0 ***/
1557         /* call function for all accessible objects */
1558         NULL,                       /* traverseproc tp_traverse; */
1559
1560         /* delete references to contained objects */
1561         NULL,                       /* inquiry tp_clear; */
1562
1563         /***  Assigned meaning in release 2.1 ***/
1564         /*** rich comparisons ***/
1565         (richcmpfunc)pyrna_func_richcmp,        /* richcmpfunc tp_richcompare; */
1566
1567         /***  weak reference enabler ***/
1568         0,                          /* long tp_weaklistoffset; */
1569
1570         /*** Added in release 2.2 ***/
1571         /*   Iterators */
1572         (getiterfunc)NULL,      /* getiterfunc tp_iter; */
1573         NULL,                       /* iternextfunc tp_iternext; */
1574
1575         /*** Attribute descriptor and subclassing stuff ***/
1576         NULL,                   /* struct PyMethodDef *tp_methods; */
1577         NULL,                       /* struct PyMemberDef *tp_members; */
1578         NULL,                                           /* struct PyGetSetDef *tp_getset; */
1579         NULL,                       /* struct _typeobject *tp_base; */
1580         NULL,                       /* PyObject *tp_dict; */
1581         NULL,                       /* descrgetfunc tp_descr_get; */
1582         NULL,                       /* descrsetfunc tp_descr_set; */
1583         0,                          /* long tp_dictoffset; */
1584         NULL,                       /* initproc tp_init; */
1585         NULL,                       /* allocfunc tp_alloc; */
1586         pyrna_func_new,                         /* newfunc tp_new; */
1587         /*  Low-level free-memory routine */
1588         NULL,                       /* freefunc tp_free;  */
1589         /* For PyObject_IS_GC */
1590         NULL,                       /* inquiry tp_is_gc;  */
1591         NULL,                       /* PyObject *tp_bases; */
1592         /* method resolution order */
1593         NULL,                       /* PyObject *tp_mro;  */
1594         NULL,                       /* PyObject *tp_cache; */
1595         NULL,                       /* PyObject *tp_subclasses; */
1596         NULL,                       /* PyObject *tp_weaklist; */
1597         NULL
1598 };
1599
1600 PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
1601 {
1602         PyObject *newclass = NULL;
1603         PropertyRNA *nameprop;
1604
1605         if (ptr->type==NULL) {
1606                 newclass= NULL; /* Nothing to do */
1607         } else if ((newclass= RNA_struct_py_type_get(ptr->data))) {
1608                 Py_INCREF(newclass);
1609         } else if ((nameprop = RNA_struct_name_property(ptr))) {
1610                 /* for now, return the base RNA type rather then a real module */
1611                 
1612                 /* Assume RNA_struct_py_type_get(ptr->data) was alredy checked */
1613                 
1614                 /* subclass equivelents
1615                 - class myClass(myBase):
1616                         some='value' # or ...
1617                 - myClass = type(name='myClass', bases=(myBase,), dict={'some':'value'})
1618                 */
1619                 char name[256], *nameptr;
1620
1621                 PyObject *args = PyTuple_New(3);
1622                 PyObject *bases = PyTuple_New(1);
1623                 PyObject *dict = PyDict_New();
1624                 
1625                 nameptr= RNA_property_string_get_alloc(ptr, nameprop, name, sizeof(name));
1626                 
1627                 // arg 1
1628                 //PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(tp_name));
1629                 PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(nameptr));
1630                 
1631                 // arg 2
1632                 PyTuple_SET_ITEM(bases, 0, (PyObject *)&pyrna_struct_Type);
1633                 Py_INCREF(&pyrna_struct_Type);
1634
1635                 PyTuple_SET_ITEM(args, 1, bases);
1636                 
1637                 // arg 3 - add an instance of the rna 
1638                 PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
1639                 
1640                 if (PyErr_Occurred()) {
1641                         PyErr_Print();
1642                         PyErr_Clear();
1643                 }
1644                 
1645                 newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
1646                 // Set this later
1647                 
1648
1649                 if (newclass) {
1650                         PyObject *rna;
1651                         RNA_struct_py_type_set(ptr->data, (void *)newclass); /* Store for later use */
1652
1653                         /* Not 100% needed but useful,
1654                          * having an instance within a type looks wrong however this instance IS an rna type */
1655                         rna = pyrna_struct_CreatePyObject(ptr);
1656                         PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", rna);
1657                         Py_DECREF(rna);
1658                         /* done with rna instance */
1659                 }
1660                 
1661                 Py_DECREF(args);
1662                 
1663                 if (name != nameptr)
1664                         MEM_freeN(nameptr);
1665         }
1666         
1667         return newclass;
1668 }
1669
1670 /*-----------------------CreatePyObject---------------------------------*/
1671 PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
1672 {
1673         BPy_StructRNA *pyrna= NULL;
1674         
1675         if (ptr->data==NULL && ptr->type==NULL) { /* Operator RNA has NULL data */
1676                 Py_RETURN_NONE;
1677         }
1678         
1679         if (ptr->type == &RNA_Struct) { /* always return a python subtype from rna struct types */
1680                 PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
1681                 
1682                 if (tp) {
1683                         pyrna = (BPy_StructRNA *) tp->tp_alloc(tp, 0);
1684                 }
1685                 else {
1686                         fprintf(stderr, "Could not make type\n");
1687                         pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
1688                 }
1689         }
1690         else {
1691                 pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
1692         }
1693         
1694         if( !pyrna ) {
1695                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
1696                 return NULL;
1697         }
1698         
1699         pyrna->ptr= *ptr;
1700         pyrna->freeptr= 0;
1701         return ( PyObject * ) pyrna;
1702 }
1703
1704 PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
1705 {
1706         BPy_PropertyRNA *pyrna;
1707
1708         pyrna = ( BPy_PropertyRNA * ) PyObject_NEW( BPy_PropertyRNA, &pyrna_prop_Type );
1709
1710         if( !pyrna ) {
1711                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_rna object" );
1712                 return NULL;
1713         }
1714         
1715         pyrna->ptr = *ptr;
1716         pyrna->prop = prop;
1717                 
1718         return ( PyObject * ) pyrna;
1719 }
1720
1721 PyObject *pyrna_func_CreatePyObject( PointerRNA *ptr, FunctionRNA *func )
1722 {
1723         BPy_FunctionRNA *pyrna;
1724
1725         pyrna = ( BPy_FunctionRNA * ) PyObject_NEW( BPy_FunctionRNA, &pyrna_func_Type );
1726
1727         if( !pyrna ) {
1728                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_FunctionRNA object" );
1729                 return NULL;
1730         }
1731
1732         pyrna->ptr = *ptr;
1733         pyrna->func = func;
1734
1735         /* TODO - iterator? */
1736
1737         return ( PyObject * ) pyrna;
1738 }
1739
1740
1741 PyObject *BPY_rna_module( void )
1742 {
1743         PointerRNA ptr;
1744         
1745         /* This can't be set in the pytype struct because some compilers complain */
1746         pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; 
1747         pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; 
1748         
1749         if( PyType_Ready( &pyrna_struct_Type ) < 0 )
1750                 return NULL;
1751         
1752         if( PyType_Ready( &pyrna_prop_Type ) < 0 )
1753                 return NULL;
1754
1755         if( PyType_Ready( &pyrna_func_Type ) < 0 )
1756                 return NULL;
1757         
1758         /* for now, return the base RNA type rather then a real module */
1759         RNA_main_pointer_create(G.main, &ptr);
1760         
1761         return pyrna_struct_CreatePyObject(&ptr);
1762 }
1763
1764 #if 0
1765 /* This is a way we can access docstrings for RNA types
1766  * without having the datatypes in blender */
1767 PyObject *BPY_rna_doc( void )
1768 {
1769         PointerRNA ptr;
1770         
1771         /* for now, return the base RNA type rather then a real module */
1772         RNA_blender_rna_pointer_create(&ptr);
1773         
1774         return pyrna_struct_CreatePyObject(&ptr);
1775 }
1776 #endif
1777
1778
1779 /* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a differnt type
1780  * the self->ptr and self->prop are always set to the "structs" collection */
1781 //---------------getattr--------------------------------------------
1782 static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA * self, PyObject *pyname )
1783 {
1784         PointerRNA newptr;
1785         PyObject *ret;
1786         
1787         ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
1788         if (ret)        return ret;
1789         else            PyErr_Clear();
1790         
1791         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, _PyUnicode_AsString(pyname), &newptr)) {
1792                 return pyrna_struct_Subtype(&newptr);
1793         }
1794         else { /* Override the error */
1795                 PyErr_Format(PyExc_AttributeError, "bpy.types.%s not a valid RNA_Struct", _PyUnicode_AsString(pyname));
1796                 return NULL;
1797         }
1798 }
1799
1800 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self);
1801 static struct PyMethodDef pyrna_basetype_methods[] = {
1802         {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""},
1803         {NULL, NULL, 0, NULL}
1804 };
1805
1806 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
1807 {
1808         PyObject *list, *name;
1809         PyMethodDef *meth;
1810         
1811         list= pyrna_prop_keys(self); /* like calling structs.keys(), avoids looping here */
1812
1813         for(meth=pyrna_basetype_methods; meth->ml_name; meth++) {
1814                 name = PyUnicode_FromString(meth->ml_name);
1815                 PyList_Append(list, name);
1816                 Py_DECREF(name);
1817         }
1818         
1819         return list;
1820 }
1821
1822 PyTypeObject pyrna_basetype_Type = {};
1823
1824 PyObject *BPY_rna_types(void)
1825 {
1826         BPy_BaseTypeRNA *self;
1827         pyrna_basetype_Type.tp_name = "RNA_Types";
1828         pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
1829         pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
1830         pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1831         pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
1832         
1833         if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
1834                 return NULL;
1835         
1836         self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
1837         
1838         /* avoid doing this lookup for every getattr */
1839         RNA_blender_rna_pointer_create(&self->ptr);
1840         self->prop = RNA_struct_find_property(&self->ptr, "structs");
1841         
1842         return (PyObject *)self;
1843 }
1844
1845
1846
1847 /* Orphan functions, not sure where they should go */
1848
1849 /* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
1850  * This isnt incorrect since its a python object - but be careful */
1851 PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
1852 {
1853         static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
1854         char *id, *name="", *description="";
1855         float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
1856         
1857         if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
1858                 return NULL;
1859         
1860         if (PyTuple_Size(args) > 0) {
1861                 PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
1862                 return NULL;
1863         }
1864         
1865         if (self) {
1866                 StructRNA *srna = PyCObject_AsVoidPtr(self);
1867                 RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
1868                 Py_RETURN_NONE;
1869         } else {
1870                 PyObject *ret = PyTuple_New(2);
1871                 PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_FloatProperty, NULL));
1872                 PyTuple_SET_ITEM(ret, 1, kw);
1873                 Py_INCREF(kw);
1874                 return ret;
1875         }
1876 }
1877
1878 PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
1879 {
1880         static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
1881         char *id, *name="", *description="";
1882         int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0;
1883         
1884         if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
1885                 return NULL;
1886         
1887         if (PyTuple_Size(args) > 0) {
1888                 PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
1889                 return NULL;
1890         }
1891         
1892         if (self) {
1893                 StructRNA *srna = PyCObject_AsVoidPtr(self);
1894                 RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
1895                 Py_RETURN_NONE;
1896         } else {
1897                 PyObject *ret = PyTuple_New(2);
1898                 PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL));
1899                 PyTuple_SET_ITEM(ret, 1, kw);
1900                 Py_INCREF(kw);
1901                 return ret;
1902         }
1903 }
1904
1905 PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
1906 {
1907         static char *kwlist[] = {"attr", "name", "description", "default", NULL};
1908         char *id, *name="", *description="";
1909         int def=0;
1910         
1911         if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:IntProperty", kwlist, &id, &name, &description, &def))
1912                 return NULL;
1913         
1914         if (PyTuple_Size(args) > 0) {
1915                 PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
1916                 return NULL;
1917         }
1918         
1919         if (self) {
1920                 StructRNA *srna = PyCObject_AsVoidPtr(self);
1921                 RNA_def_boolean(srna, id, def, name, description);
1922                 Py_RETURN_NONE;
1923         } else {
1924                 PyObject *ret = PyTuple_New(2);
1925                 PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL));
1926                 PyTuple_SET_ITEM(ret, 1, kw);
1927                 Py_INCREF(kw);
1928                 return ret;
1929         }
1930 }