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