Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_rna.c21
-rw-r--r--source/blender/python/intern/bpy_rna.c487
-rw-r--r--source/blender/python/intern/bpy_rna.h2
4 files changed, 342 insertions, 169 deletions
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index f4fccd30dbe..2ed365ad79f 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -79,6 +79,7 @@ extern EnumPropertyItem operator_context_items[];
extern EnumPropertyItem wm_report_items[];
+extern EnumPropertyItem property_type_items[];
extern EnumPropertyItem property_unit_items[];
struct bContext;
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index f8e6720fe92..7c4b48b09f6 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -32,6 +32,16 @@
#include "rna_internal.h"
+EnumPropertyItem property_type_items[] = {
+ {PROP_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
+ {PROP_INT, "INT", 0, "Integer", ""},
+ {PROP_FLOAT, "FLOAT", 0, "Float", ""},
+ {PROP_STRING, "STRING", 0, "String", ""},
+ {PROP_ENUM, "ENUM", 0, "Enumeration", ""},
+ {PROP_POINTER, "POINTER", 0, "Pointer", ""},
+ {PROP_COLLECTION, "COLLECTION", 0, "Collection", ""},
+ {0, NULL, 0, NULL, NULL}};
+
EnumPropertyItem property_unit_items[] = {
{PROP_UNIT_NONE, "NONE", 0, "None", ""},
{PROP_UNIT_LENGTH, "LENGTH", 0, "Length", ""},
@@ -907,15 +917,6 @@ static void rna_def_property(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem type_items[] = {
- {PROP_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
- {PROP_INT, "INT", 0, "Integer", ""},
- {PROP_FLOAT, "FLOAT", 0, "Float", ""},
- {PROP_STRING, "STRING", 0, "String", ""},
- {PROP_ENUM, "ENUM", 0, "Enumeration", ""},
- {PROP_POINTER, "POINTER", 0, "Pointer", ""},
- {PROP_COLLECTION, "COLLECTION", 0, "Collection", ""},
- {0, NULL, 0, NULL, NULL}};
static EnumPropertyItem subtype_items[] = {
{PROP_NONE, "NONE", 0, "None", ""},
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
@@ -961,7 +962,7 @@ static void rna_def_property(BlenderRNA *brna)
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_enum_items(prop, type_items);
+ RNA_def_property_enum_items(prop, property_type_items);
RNA_def_property_enum_funcs(prop, "rna_Property_type_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Type", "Data type of the property");
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 1064b87ba61..8d9678df389 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -34,6 +34,7 @@
#include "RNA_access.h"
#include "RNA_define.h" /* for defining our own rna */
+#include "RNA_enum_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_utildefines.h"
@@ -55,8 +56,11 @@
#include "../generic/Mathutils.h" /* so we can have mathutils callbacks */
#include "../generic/IDProp.h" /* for IDprop lookups */
+#include <string.h>
-static PyObject *prop_subscript_array_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
+static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
+static Py_ssize_t pyrna_prop_array_length(BPy_PropertyRNA *self);
+static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self );
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
@@ -241,7 +245,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
if(is_thick) {
/* this is an array we cant reference (since its not thin wrappable)
* and cannot be coerced into a mathutils type, so return as a list */
- ret = prop_subscript_array_slice(NULL, ptr, prop, 0, len, len);
+ ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
} else {
ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
}
@@ -333,12 +337,12 @@ static PyObject *pyrna_struct_repr( BPy_StructRNA *self )
/* print name if available */
name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE);
if(name) {
- pyob= PyUnicode_FromFormat( "[BPy_StructRNA \"%.200s\" -> \"%.200s\"]", RNA_struct_identifier(self->ptr.type), name);
+ pyob= PyUnicode_FromFormat( "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name);
MEM_freeN(name);
return pyob;
}
- return PyUnicode_FromFormat( "[BPy_StructRNA \"%.200s\"]", RNA_struct_identifier(self->ptr.type));
+ return PyUnicode_FromFormat( "<bpy_struct, %.200s>", RNA_struct_identifier(self->ptr.type));
}
static PyObject *pyrna_prop_repr( BPy_PropertyRNA *self )
@@ -346,6 +350,30 @@ static PyObject *pyrna_prop_repr( BPy_PropertyRNA *self )
PyObject *pyob;
PointerRNA ptr;
char *name;
+ const char *type_id= NULL;
+ char type_fmt[64]= "";
+ int type= RNA_property_type(self->prop);
+
+ if(RNA_enum_id_from_value(property_type_items, type, &type_id)==0) {
+ PyErr_SetString(PyExc_SystemError, "could not use property type, internal error"); /* should never happen */
+ return NULL;
+ }
+ else {
+ /* this should never fail */
+ int len = -1;
+ char *c= type_fmt;
+
+ while ( (*c++= tolower(*type_id++)) ) {} ;
+
+ if(type==PROP_COLLECTION) {
+ len= pyrna_prop_collection_length(self);
+ } else if (RNA_property_array_check(&self->ptr, self->prop)) {
+ len= pyrna_prop_array_length(self);
+ }
+
+ if(len != -1)
+ sprintf(--c, "[%d]", len);
+ }
/* if a pointer, try to print name of pointer target too */
if(RNA_property_type(self->prop) == PROP_POINTER) {
@@ -353,13 +381,13 @@ static PyObject *pyrna_prop_repr( BPy_PropertyRNA *self )
name= RNA_struct_name_get_alloc(&ptr, NULL, FALSE);
if(name) {
- pyob= PyUnicode_FromFormat( "[BPy_PropertyRNA \"%.200s\" -> \"%.200s\" -> \"%.200s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name);
+ pyob= PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name);
MEM_freeN(name);
return pyob;
}
}
- return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%.200s\" -> \"%.200s\"]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
+ return PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
}
static long pyrna_struct_hash( BPy_StructRNA *self )
@@ -1022,7 +1050,7 @@ static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *va
}
//---------------sequence-------------------------------------------
-static int pyrna_prop_array_length(BPy_PropertyRNA *self)
+static Py_ssize_t pyrna_prop_array_length(BPy_PropertyRNA *self)
{
if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
@@ -1030,24 +1058,13 @@ static int pyrna_prop_array_length(BPy_PropertyRNA *self)
return RNA_property_array_length(&self->ptr, self->prop);
}
-static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA *self )
+static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self )
{
- Py_ssize_t len;
-
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- len = RNA_property_collection_length(&self->ptr, self->prop);
- } else if (RNA_property_array_check(&self->ptr, self->prop)) {
- len = pyrna_prop_array_length(self);
- } else {
- PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
- len = -1; /* error value */
- }
-
- return len;
+ return RNA_property_collection_length(&self->ptr, self->prop);
}
/* internal use only */
-static PyObject *prop_subscript_collection_int(BPy_PropertyRNA *self, int keynum)
+static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
{
PointerRNA newptr;
@@ -1060,7 +1077,7 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA *self, int keynum
return NULL;
}
-static PyObject *prop_subscript_array_int(BPy_PropertyRNA *self, int keynum)
+static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyRNA *self, int keynum)
{
int len= pyrna_prop_array_length(self);
@@ -1073,7 +1090,7 @@ static PyObject *prop_subscript_array_int(BPy_PropertyRNA *self, int keynum)
return NULL;
}
-static PyObject *prop_subscript_collection_str(BPy_PropertyRNA *self, char *keyname)
+static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, char *keyname)
{
PointerRNA newptr;
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
@@ -1082,9 +1099,9 @@ static PyObject *prop_subscript_collection_str(BPy_PropertyRNA *self, char *keyn
PyErr_Format(PyExc_KeyError, "key \"%.200s\" not found", keyname);
return NULL;
}
-/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA *self, char *keyname) */
+/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
-static PyObject *prop_subscript_collection_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
+static PyObject *pyrna_prop_collection_subscript_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
{
PointerRNA newptr;
PyObject *list = PyList_New(stop - start);
@@ -1111,7 +1128,7 @@ static PyObject *prop_subscript_collection_slice(PointerRNA *ptr, PropertyRNA *p
* note: could also use pyrna_prop_to_py_index(self, count) in a loop but its a lot slower
* since at the moment it reads (and even allocates) the entire array for each index.
*/
-static PyObject *prop_subscript_array_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
+static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
{
int count, totdim;
@@ -1183,17 +1200,17 @@ static PyObject *prop_subscript_array_slice(BPy_PropertyRNA *self, PointerRNA *p
return list;
}
-static PyObject *prop_subscript_collection(BPy_PropertyRNA *self, PyObject *key)
+static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
{
if (PyUnicode_Check(key)) {
- return prop_subscript_collection_str(self, _PyUnicode_AsString(key));
+ return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
}
else if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
- return prop_subscript_collection_int(self, i);
+ return pyrna_prop_collection_subscript_int(self, i);
}
else if (PySlice_Check(key)) {
int len= RNA_property_collection_length(&self->ptr, self->prop);
@@ -1206,7 +1223,7 @@ static PyObject *prop_subscript_collection(BPy_PropertyRNA *self, PyObject *key)
return PyList_New(0);
}
else if (step == 1) {
- return prop_subscript_collection_slice(&self->ptr, self->prop, start, stop, len);
+ return pyrna_prop_collection_subscript_slice(&self->ptr, self->prop, start, stop, len);
}
else {
PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
@@ -1219,16 +1236,16 @@ static PyObject *prop_subscript_collection(BPy_PropertyRNA *self, PyObject *key)
}
}
-static PyObject *prop_subscript_array(BPy_PropertyRNA *self, PyObject *key)
+static PyObject *pyrna_prop_array_subscript(BPy_PropertyRNA *self, PyObject *key)
{
/*if (PyUnicode_Check(key)) {
- return prop_subscript_array_str(self, _PyUnicode_AsString(key));
+ return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
} else*/
if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
- return prop_subscript_array_int(self, PyLong_AsSsize_t(key));
+ return pyrna_prop_array_subscript_int(self, PyLong_AsSsize_t(key));
}
else if (PySlice_Check(key)) {
Py_ssize_t start, stop, step, slicelength;
@@ -1241,7 +1258,7 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA *self, PyObject *key)
return PyList_New(0);
}
else if (step == 1) {
- return prop_subscript_array_slice(self, &self->ptr, self->prop, start, stop, len);
+ return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
}
else {
PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
@@ -1254,18 +1271,6 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA *self, PyObject *key)
}
}
-static PyObject *pyrna_prop_subscript( BPy_PropertyRNA *self, PyObject *key )
-{
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- return prop_subscript_collection(self, key);
- } else if (RNA_property_array_check(&self->ptr, self->prop)) {
- return prop_subscript_array(self, key);
- }
-
- PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
- return NULL;
-}
-
/* could call (pyrna_py_to_prop_index(self, i, value) in a loop but it is slow */
static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length, PyObject *value_orig)
{
@@ -1355,7 +1360,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
}
-static int prop_subscript_ass_array_int(BPy_PropertyRNA *self, int keynum, PyObject *value)
+static int prop_subscript_ass_array_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
{
int len= pyrna_prop_array_length(self);
@@ -1368,7 +1373,7 @@ static int prop_subscript_ass_array_int(BPy_PropertyRNA *self, int keynum, PyObj
return -1;
}
-static int pyrna_prop_ass_subscript( BPy_PropertyRNA *self, PyObject *key, PyObject *value )
+static int pyrna_prop_array_ass_subscript( BPy_PropertyRNA *self, PyObject *key, PyObject *value )
{
/* char *keyname = NULL; */ /* not supported yet */
@@ -1376,12 +1381,6 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA *self, PyObject *key, PyObj
PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
return -1;
}
-
- /* maybe one day we can support this... */
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%.200s\" from \"%.200s\" is a collection, assignment not supported", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
- return -1;
- }
if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
@@ -1416,39 +1415,40 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA *self, PyObject *key, PyObj
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
}
+/* for slice only */
+static PyMappingMethods pyrna_prop_array_as_mapping = {
+ ( lenfunc ) pyrna_prop_array_length, /* mp_length */
+ ( binaryfunc ) pyrna_prop_array_subscript, /* mp_subscript */
+ ( objobjargproc ) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
+};
-static PyMappingMethods pyrna_prop_as_mapping = {
- ( lenfunc ) pyrna_prop_len, /* mp_length */
- ( binaryfunc ) pyrna_prop_subscript, /* mp_subscript */
- ( objobjargproc ) pyrna_prop_ass_subscript, /* mp_ass_subscript */
+static PyMappingMethods pyrna_prop_collection_as_mapping = {
+ ( lenfunc ) pyrna_prop_collection_length, /* mp_length */
+ ( binaryfunc ) pyrna_prop_collection_subscript, /* mp_subscript */
+ ( objobjargproc ) NULL, /* mp_ass_subscript */
};
-static int pyrna_prop_contains(BPy_PropertyRNA *self, PyObject *value)
-{
- PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- /* key in dict style check */
- char *keyname = _PyUnicode_AsString(value);
+static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
+{
+ return pyrna_array_contains_py(&self->ptr, self->prop, value);
+}
- if(keyname==NULL) {
- PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, key must be a string type");
- return -1;
- }
+static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value)
+{
+ PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
+ /* key in dict style check */
+ char *keyname = _PyUnicode_AsString(value);
- if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
- return 1;
- }
- else if (RNA_property_array_check(&self->ptr, self->prop)) {
- /* value in list style check */
- return pyrna_array_contains_py(&self->ptr, self->prop, value);
- }
- else {
- PyErr_SetString(PyExc_TypeError, "PropertyRNA - type is not an array or a collection");
+ if(keyname==NULL) {
+ PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, key must be a string type");
return -1;
}
+ if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
+ return 1;
+
return 0;
}
@@ -1475,28 +1475,26 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
return IDP_GetPropertyFromGroup(group, name) ? 1:0;
}
-static PyObject *pyrna_prop_item(BPy_PropertyRNA *self, Py_ssize_t index)
-{
- /* reuse subscript functions */
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- return prop_subscript_collection_int(self, index);
- } else if (RNA_property_array_check(&self->ptr, self->prop)) {
- return prop_subscript_array_int(self, index);
- }
-
- PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
- return NULL;
-}
-
-static PySequenceMethods pyrna_prop_as_sequence = {
- NULL, /* Cant set the len otherwise it can evaluate as false */
+static PySequenceMethods pyrna_prop_array_as_sequence = {
+ (lenfunc)pyrna_prop_array_length, /* Cant set the len otherwise it can evaluate as false */
NULL, /* sq_concat */
NULL, /* sq_repeat */
- (ssizeargfunc)pyrna_prop_item, /* sq_item */ /* Only set this so PySequence_Check() returns True */
+ (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
NULL, /* sq_slice */
+ (ssizeobjargproc)prop_subscript_ass_array_int, /* sq_ass_item */
+ NULL, /* *was* sq_ass_slice */
+ (objobjproc)pyrna_prop_array_contains, /* sq_contains */
+};
+
+static PySequenceMethods pyrna_prop_collection_as_sequence = {
+ (lenfunc)pyrna_prop_collection_length, /* Cant set the len otherwise it can evaluate as false */
+ NULL, /* sq_concat */
+ NULL, /* sq_repeat */
+ (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
+ NULL, /* *was* sq_slice */
NULL, /* sq_ass_item */
- NULL, /* sq_ass_slice */
- (objobjproc)pyrna_prop_contains, /* sq_contains */
+ NULL, /* *was* sq_ass_slice */
+ (objobjproc)pyrna_prop_collection_contains, /* sq_contains */
};
static PySequenceMethods pyrna_struct_as_sequence = {
@@ -1504,9 +1502,9 @@ static PySequenceMethods pyrna_struct_as_sequence = {
NULL, /* sq_concat */
NULL, /* sq_repeat */
NULL, /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* sq_slice */
+ NULL, /* *was* sq_slice */
NULL, /* sq_ass_item */
- NULL, /* sq_ass_slice */
+ NULL, /* *was* sq_ass_slice */
(objobjproc)pyrna_struct_contains, /* sq_contains */
};
@@ -2079,61 +2077,52 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
}
-static PyObject *pyrna_prop_getattro( BPy_PropertyRNA *self, PyObject *pyname )
+static PyObject *pyrna_prop_array_getattro( BPy_PropertyRNA *self, PyObject *pyname )
+{
+ return PyObject_GenericGetAttr((PyObject *)self, pyname);
+}
+
+static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject *pyname )
{
char *name = _PyUnicode_AsString(pyname);
if(name[0] != '_') {
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- PyObject *ret;
- PropertyRNA *prop;
- FunctionRNA *func;
+ PyObject *ret;
+ PropertyRNA *prop;
+ FunctionRNA *func;
- PointerRNA r_ptr;
- if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
- if ((prop = RNA_struct_find_property(&r_ptr, name))) {
- ret = pyrna_prop_to_py(&r_ptr, prop);
+ PointerRNA r_ptr;
+ if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
+ if ((prop = RNA_struct_find_property(&r_ptr, name))) {
+ ret = pyrna_prop_to_py(&r_ptr, prop);
- return ret;
- }
- else if ((func = RNA_struct_find_function(&r_ptr, name))) {
- PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr);
- ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
- Py_DECREF(self_collection);
+ return ret;
+ }
+ else if ((func = RNA_struct_find_function(&r_ptr, name))) {
+ PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr);
+ ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
+ Py_DECREF(self_collection);
- return ret;
- }
+ return ret;
}
}
}
- else {
- /* annoying exception, maybe we need to have different types for this... */
- if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) &&
- (RNA_property_type(self->prop) != PROP_COLLECTION) &&
- RNA_property_array_check(&self->ptr, self->prop)==0
- ) {
- PyErr_SetString(PyExc_AttributeError, "PropertyRNA - no __getitem__ support for this type");
- return NULL;
- }
- }
/* The error raised here will be displayed */
return PyObject_GenericGetAttr((PyObject *)self, pyname);
}
//--------------- setattr-------------------------------------------
-static int pyrna_prop_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObject *value )
+static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObject *value )
{
char *name = _PyUnicode_AsString(pyname);
PropertyRNA *prop;
+ PointerRNA r_ptr;
- if (RNA_property_type(self->prop) == PROP_COLLECTION) {
- PointerRNA r_ptr;
- if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
- if ((prop = RNA_struct_find_property(&r_ptr, name))) {
- /* pyrna_py_to_prop sets its own exceptions */
- return pyrna_py_to_prop(&r_ptr, prop, NULL, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
- }
+ if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
+ if ((prop = RNA_struct_find_property(&r_ptr, name))) {
+ /* pyrna_py_to_prop sets its own exceptions */
+ return pyrna_py_to_prop(&r_ptr, prop, NULL, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
}
}
@@ -2596,24 +2585,30 @@ static PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
/* A bit of a kludge, make a list out of a collection or array,
* then return the lists iter function, not especially fast but convenient for now */
-PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
+PyObject *pyrna_prop_array_iter(BPy_PropertyRNA *self)
{
/* Try get values from a collection */
PyObject *ret;
PyObject *iter= NULL;
+ int len= pyrna_prop_array_length(self);
+ ret = pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
- if(RNA_property_array_check(&self->ptr, self->prop)) {
- int len= pyrna_prop_array_length(self);
- ret = prop_subscript_array_slice(self, &self->ptr, self->prop, 0, len, len);
- }
- else if ((ret = pyrna_prop_values(self))) {
- /* do nothing */
- }
- else {
- PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
- return NULL;
+ /* we know this is a list so no need to PyIter_Check
+ * otherwise it could be NULL (unlikely) if conversion failed */
+ if(ret) {
+ iter = PyObject_GetIter(ret);
+ Py_DECREF(ret);
}
-
+
+ return iter;
+}
+
+PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
+{
+ /* Try get values from a collection */
+ PyObject *ret;
+ PyObject *iter= NULL;
+ ret = pyrna_prop_values(self);
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL (unlikely) if conversion failed */
@@ -2647,6 +2642,18 @@ static struct PyMethodDef pyrna_struct_methods[] = {
};
static struct PyMethodDef pyrna_prop_methods[] = {
+ {"path_to_id", (PyCFunction)pyrna_prop_path_to_id, METH_NOARGS, NULL},
+ {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyMethodDef pyrna_prop_array_methods[] = {
+ {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
+ {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyMethodDef pyrna_prop_collection_methods[] = {
{"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, NULL},
{"items", (PyCFunction)pyrna_prop_items, METH_NOARGS,NULL},
{"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, NULL},
@@ -2656,14 +2663,6 @@ static struct PyMethodDef pyrna_prop_methods[] = {
/* moved into a getset */
{"add", (PyCFunction)pyrna_prop_add, METH_NOARGS, NULL},
{"remove", (PyCFunction)pyrna_prop_remove, METH_O, NULL},
-
- /* almost the same as the srna function */
- {"path_to_id", (PyCFunction)pyrna_prop_path_to_id, METH_NOARGS, NULL},
-
- /* array accessor function */
- {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
- {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL},
- {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
@@ -2694,7 +2693,7 @@ static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *k
if (!PyArg_ParseTuple(args, "O!:Base BPy_PropertyRNA", &pyrna_prop_Type, &base))
return NULL;
- if (type == &pyrna_prop_Type) {
+ if (ELEM3(type, &pyrna_prop_Type, &pyrna_prop_array_Type, &pyrna_prop_collection_Type)) {
return pyrna_prop_CreatePyObject(&base->ptr, base->prop);
} else {
BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0);
@@ -3177,8 +3176,8 @@ PyTypeObject pyrna_prop_Type = {
/* Method suites for standard classes */
NULL, /* PyNumberMethods *tp_as_number; */
- &pyrna_prop_as_sequence, /* PySequenceMethods *tp_as_sequence; */
- &pyrna_prop_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
@@ -3187,8 +3186,8 @@ PyTypeObject pyrna_prop_Type = {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
- ( getattrofunc ) pyrna_prop_getattro, /* getattrofunc tp_getattro; */
- ( setattrofunc ) pyrna_prop_setattro, /* setattrofunc tp_setattro; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL, /* PyBufferProcs *tp_as_buffer; */
@@ -3213,7 +3212,7 @@ PyTypeObject pyrna_prop_Type = {
/*** Added in release 2.2 ***/
/* Iterators */
- (getiterfunc)pyrna_prop_iter, /* getiterfunc tp_iter; */
+ NULL, /* getiterfunc tp_iter; */
NULL, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
@@ -3241,6 +3240,166 @@ PyTypeObject pyrna_prop_Type = {
NULL
};
+PyTypeObject pyrna_prop_array_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "PropertyArrayRNA", /* tp_name */
+ sizeof( BPy_PropertyRNA ), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ NULL, /* tp_dealloc */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
+ NULL,/* subclassed */ /* tp_repr */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ &pyrna_prop_array_as_sequence, /* PySequenceMethods *tp_as_sequence; */
+ &pyrna_prop_array_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+
+ /* will only use these if this is a subtype of a py class */
+ ( getattrofunc ) pyrna_prop_array_getattro, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ (getiterfunc)pyrna_prop_array_iter, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ pyrna_prop_array_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
+ &pyrna_prop_Type, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
+PyTypeObject pyrna_prop_collection_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "PropertyCollectionRNA", /* tp_name */
+ sizeof( BPy_PropertyRNA ), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ NULL, /* tp_dealloc */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
+ NULL, /* subclassed */ /* tp_repr */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ &pyrna_prop_collection_as_sequence, /* PySequenceMethods *tp_as_sequence; */
+ &pyrna_prop_collection_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+
+ /* will only use these if this is a subtype of a py class */
+ ( getattrofunc ) pyrna_prop_collection_getattro, /* getattrofunc tp_getattro; */
+ ( setattrofunc ) pyrna_prop_collection_setattro, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ (getiterfunc)pyrna_prop_collection_iter, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ pyrna_prop_collection_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
+ &pyrna_prop_Type, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
static struct PyMethodDef pyrna_struct_subtype_methods[] = {
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, ""},
@@ -3497,8 +3656,12 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
{
BPy_PropertyRNA *pyrna;
+ PyTypeObject *type;
+ if (RNA_property_type(prop) == PROP_COLLECTION) type= &pyrna_prop_collection_Type;
+ else if (RNA_property_array_check(ptr, prop)) type= &pyrna_prop_array_Type;
+ else type= &pyrna_prop_Type;
- pyrna = ( BPy_PropertyRNA * ) PyObject_NEW( BPy_PropertyRNA, &pyrna_prop_Type );
+ pyrna = ( BPy_PropertyRNA * ) PyObject_NEW(BPy_PropertyRNA, type);
if( !pyrna ) {
PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_rna object" );
@@ -3526,6 +3689,12 @@ void BPY_rna_init(void)
if( PyType_Ready( &pyrna_prop_Type ) < 0 )
return;
+
+ if( PyType_Ready( &pyrna_prop_array_Type ) < 0 )
+ return;
+
+ if( PyType_Ready( &pyrna_prop_collection_Type ) < 0 )
+ return;
}
/* bpy.data from python */
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 42b111b6e0c..77f6ec00d48 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -32,6 +32,8 @@
extern PyTypeObject pyrna_struct_Type;
extern PyTypeObject pyrna_prop_Type;
+extern PyTypeObject pyrna_prop_array_Type;
+extern PyTypeObject pyrna_prop_collection_Type;
#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
#define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type)