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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-10-11 18:30:53 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-10-11 18:30:53 +0400
commit4f33d65ba1f02f2cd3f340d0123900ea1beffd2c (patch)
tree05ef40081ce6be190a171e0fee09b12344e16eb6 /source/blender/python
parent1ab9fc59b750b1dc5ebaacd30c6891949895a10d (diff)
parent79f21f88c2be305962f6432bf8b1af94056fd92b (diff)
Cycles: svn merge -r40411:40934 ^/trunk/blender
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/SConscript6
-rw-r--r--source/blender/python/generic/CMakeLists.txt4
-rw-r--r--source/blender/python/generic/IDProp.c2
-rw-r--r--source/blender/python/generic/bgl.c4
-rw-r--r--source/blender/python/generic/blf_py_api.c45
-rw-r--r--source/blender/python/generic/bpy_internal_import.c4
-rw-r--r--source/blender/python/generic/py_capi_utils.c19
-rw-r--r--source/blender/python/intern/CMakeLists.txt4
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c2
-rw-r--r--source/blender/python/intern/bpy_driver.c7
-rw-r--r--source/blender/python/intern/bpy_operator.c41
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c2
-rw-r--r--source/blender/python/intern/bpy_props.c42
-rw-r--r--source/blender/python/intern/bpy_rna.c350
-rw-r--r--source/blender/python/intern/bpy_rna.h8
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c10
-rw-r--r--source/blender/python/intern/bpy_rna_array.c12
-rw-r--r--source/blender/python/mathutils/mathutils.c10
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c2
19 files changed, 424 insertions, 150 deletions
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index 5cc3f3bedc4..3f47038687a 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -17,9 +17,6 @@ defs = []
if is_debug:
defs.append('_DEBUG')
-if env['WITH_BF_INTERNATIONAL']:
- defs.append('INTERNATIONAL')
-
sources = env.Glob('generic/*.c')
env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [363,165]) # ketsji is 360
@@ -43,5 +40,8 @@ if env['WITH_BF_PYTHON_SAFETY']:
if env['BF_BUILDINFO']:
defs.append('BUILD_DATE')
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
sources = env.Glob('intern/*.c')
env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361])
diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt
index 0a49036c15d..847a0d19a7f 100644
--- a/source/blender/python/generic/CMakeLists.txt
+++ b/source/blender/python/generic/CMakeLists.txt
@@ -48,8 +48,4 @@ set(SRC
py_capi_utils.h
)
-if(WITH_INTERNATIONAL)
- add_definitions(-DINTERNATIONAL)
-endif()
-
blender_add_lib(bf_python_ext "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c
index 2543d34f58c..e6883eb30af 100644
--- a/source/blender/python/generic/IDProp.c
+++ b/source/blender/python/generic/IDProp.c
@@ -269,7 +269,7 @@ static int idp_sequence_type(PyObject *seq)
PyObject *item;
int type= IDP_INT;
- int i, len = PySequence_Size(seq);
+ Py_ssize_t i, len = PySequence_Size(seq);
for (i=0; i < len; i++) {
item = PySequence_GetItem(seq, i);
if (PyFloat_Check(item)) {
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 44d42a479ec..35c211d5424 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -286,8 +286,8 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
Buffer *buffer;
int dimensions[MAX_DIMENSIONS];
- int i, type;
- int ndimensions = 0;
+ int type;
+ Py_ssize_t i, ndimensions = 0;
if(kwds && PyDict_Size(kwds)) {
PyErr_SetString(PyExc_TypeError,
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 87e4a301eff..b16efdf5a3d 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -31,15 +31,9 @@
#include "blf_py_api.h"
#include "../../blenfont/BLF_api.h"
-#include "../../blenfont/BLF_translation.h"
#include "BLI_utildefines.h"
-#ifdef INTERNATIONAL
-#include "DNA_userdef_types.h" /* is it bad level? */
-#endif
-
-
PyDoc_STRVAR(py_blf_position_doc,
".. function:: position(fontid, x, y, z)\n"
"\n"
@@ -371,33 +365,24 @@ static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args)
return PyLong_FromLong(BLF_load(filename));
}
-PyDoc_STRVAR(py_blf_gettext_doc,
-".. function:: gettext(msgid)\n"
+PyDoc_STRVAR(py_blf_unload_doc,
+".. function:: unload(filename)\n"
"\n"
-" Get a msg in local language.\n"
+" Unload an existing font.\n"
"\n"
-" :arg msgid: the source string.\n"
-" :type msgid: string\n"
-" :return: the localized string.\n"
-" :rtype: string\n"
+" :arg filename: the filename of the font.\n"
+" :type filename: string\n"
);
-static PyObject *py_blf_gettext(PyObject *UNUSED(self), PyObject *value)
+static PyObject *py_blf_unload(PyObject *UNUSED(self), PyObject *args)
{
-#ifdef INTERNATIONAL
- if ((U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_IFACE)) {
- const char *msgid= _PyUnicode_AsString(value);
- if(msgid == NULL) {
- PyErr_SetString(PyExc_TypeError, "blf.gettext expects a single string argument");
- return NULL;
- }
-
- return PyUnicode_FromString(BLF_gettext(msgid));
- }
- else
-#endif /* INTERNATIONAL */
- {
- return Py_INCREF(value), value;
- }
+ char* filename;
+
+ if (!PyArg_ParseTuple(args, "s:blf.unload", &filename))
+ return NULL;
+
+ BLF_unload(filename);
+
+ Py_RETURN_NONE;
}
/*----------------------------MODULE INIT-------------------------*/
@@ -415,7 +400,7 @@ static PyMethodDef BLF_methods[] = {
{"shadow_offset", (PyCFunction) py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc},
{"size", (PyCFunction) py_blf_size, METH_VARARGS, py_blf_size_doc},
{"load", (PyCFunction) py_blf_load, METH_VARARGS, py_blf_load_doc},
- {"gettext", (PyCFunction) py_blf_gettext, METH_O, py_blf_gettext_doc},
+ {"unload", (PyCFunction) py_blf_unload, METH_VARARGS, py_blf_unload_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 67ed90c79eb..d29bc798399 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -93,7 +93,7 @@ void bpy_import_main_set(struct Main *maggie)
/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
{
- BLI_snprintf(fn, fn_len, "%s%c%s", text->id.lib ? text->id.lib->filepath : bpy_import_main->name, SEP, text->id.name+2);
+ BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bpy_import_main, &text->id), SEP, text->id.name+2);
}
PyObject *bpy_text_import(Text *text)
@@ -120,7 +120,7 @@ PyObject *bpy_text_import(Text *text)
}
len= strlen(text->id.name+2);
- strncpy(modulename, text->id.name+2, len);
+ BLI_strncpy(modulename, text->id.name+2, len);
modulename[len - 3]= '\0'; /* remove .py */
return PyImport_ExecCodeModule(modulename, text->compiled);
}
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index d5bd44fc288..bf14102bb0d 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -107,7 +107,8 @@ int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObje
/* for debugging */
-void PyC_ObSpit(const char *name, PyObject *var) {
+void PyC_ObSpit(const char *name, PyObject *var)
+{
fprintf(stderr, "<%s> : ", name);
if (var==NULL) {
fprintf(stderr, "<NIL>");
@@ -126,7 +127,8 @@ void PyC_ObSpit(const char *name, PyObject *var) {
fprintf(stderr, "\n");
}
-void PyC_LineSpit(void) {
+void PyC_LineSpit(void)
+{
const char *filename;
int lineno;
@@ -363,12 +365,15 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
* chars since blender doesnt limit this */
return result;
}
- else if(PyBytes_Check(py_str)) {
- PyErr_Clear();
- return PyBytes_AS_STRING(py_str);
- }
else {
- return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(py_str)));
+ PyErr_Clear();
+
+ if(PyBytes_Check(py_str)) {
+ return PyBytes_AS_STRING(py_str);
+ }
+ else {
+ return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(py_str)));
+ }
}
}
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 807074b92ce..9a214718e73 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -99,4 +99,8 @@ if(WITH_CYCLES)
add_definitions(-DWITH_CYCLES)
endif()
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index b909a0d5f55..cd3d78410f2 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -40,6 +40,8 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
static PyTypeObject BlenderAppCbType;
static PyStructSequence_Field app_cb_info_fields[]= {
+ {(char *)"frame_change_pre", NULL},
+ {(char *)"frame_change_post", NULL},
{(char *)"render_pre", NULL},
{(char *)"render_post", NULL},
{(char *)"render_stats", NULL},
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index f3ef55d29c4..319790340ca 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -41,6 +41,9 @@
#include "bpy_driver.h"
+extern void BPY_update_rna_module(void);
+
+
/* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
PyObject *bpy_pydriver_Dict= NULL;
@@ -164,6 +167,10 @@ float BPY_driver_exec(ChannelDriver *driver)
if(use_gil)
gilstate= PyGILState_Ensure();
+ /* needed since drivers are updated directly after undo where 'main' is
+ * re-allocated [#28807] */
+ BPY_update_rna_module();
+
/* init global dictionary for py-driver evaluation settings */
if (!bpy_pydriver_Dict) {
if (bpy_pydriver_create_dict() != 0) {
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 7327679cc7e..dedc5df1f1c 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -408,12 +408,51 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
return (PyObject *)pyrna;
}
+static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
+{
+ wmOperatorType *ot;
+ wmOperator *op;
+ PointerRNA ptr;
+ char *opname= _PyUnicode_AsString(value);
+ BPy_StructRNA *pyrna= NULL;
+
+ if(opname==NULL) {
+ PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument");
+ return NULL;
+ }
+ ot= WM_operatortype_find(opname, TRUE);
+ if(ot==NULL) {
+ PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname);
+ return NULL;
+ }
+
+#ifdef PYRNA_FREE_SUPPORT
+ op= MEM_callocN(sizeof(wmOperator), __func__);
+#else
+ op= PyMem_MALLOC(sizeof(wmOperator));
+ memset(op, 0, sizeof(wmOperator));
+#endif
+ BLI_strncpy(op->idname, op->idname, sizeof(op->idname)); /* incase its needed */
+ op->type= ot;
+
+ RNA_pointer_create(NULL, &RNA_Operator, op, &ptr);
+
+ pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
+#ifdef PYRNA_FREE_SUPPORT
+ pyrna->freeptr= TRUE;
+#endif
+ op->ptr= &pyrna->ptr;
+
+ return (PyObject *)pyrna;
+}
+
static struct PyMethodDef bpy_ops_methods[]= {
{"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL},
{"call", (PyCFunction) pyop_call, METH_VARARGS, NULL},
{"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL},
{"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL},
- {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL},
+ {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL}, /* only for introspection, leaks memory */
+ {"get_instance", (PyCFunction) pyop_getinstance, METH_O, NULL}, /* only for introspection, leaks memory */
{"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index de29cb2aeac..b5ded8b3a65 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -125,7 +125,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
otmacro= WM_operatortype_macro_define(ot, opname);
- RNA_pointer_create(NULL, &RNA_OperatorTypeMacro, otmacro, &ptr_otmacro);
+ RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro);
return pyrna_struct_CreatePyObject(&ptr_otmacro);
}
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 5da142aeea7..5c668590dff 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -56,13 +56,13 @@ extern BPy_StructRNA *bpy_context_module;
static EnumPropertyItem property_flag_items[]= {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
- {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
+ {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem property_flag_enum_items[]= {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
- {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
+ {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""},
{0, NULL, 0, NULL, NULL}};
@@ -72,6 +72,7 @@ static EnumPropertyItem property_subtype_string_items[]= {
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
{PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
{PROP_FILENAME, "FILENAME", 0, "Filename", ""},
+ {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
{PROP_NONE, "NONE", 0, "None", ""},
{0, NULL, 0, NULL, NULL}};
@@ -266,6 +267,18 @@ static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_c
return 0;
}
+/* utility function we need for parsing int's in an if statement */
+static int py_long_as_int(PyObject *py_long, int *r_int)
+{
+ if(PyLong_CheckExact(py_long)) {
+ *r_int= (int)PyLong_AS_LONG(py_long);
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
/* this define runs at the start of each function and deals with
* returning a deferred property (to be registered later) */
#define BPY_PROPDEF_HEAD(_func) \
@@ -913,6 +926,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
for(i=0; i<seq_len; i++) {
EnumPropertyItem tmp= {0, "", 0, "", ""};
+ Py_ssize_t item_size;
Py_ssize_t id_str_size;
Py_ssize_t name_str_size;
Py_ssize_t desc_str_size;
@@ -920,13 +934,17 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
item= PySequence_Fast_GET_ITEM(seq_fast, i);
if( (PyTuple_CheckExact(item)) &&
- (PyTuple_GET_SIZE(item) == 3) &&
+ (item_size= PyTuple_GET_SIZE(item)) &&
+ (item_size == 3 || item_size == 4) &&
(tmp.identifier= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
(tmp.name= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
- (tmp.description= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size))
+ (tmp.description= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
+ (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1) /* TODO, number isnt ensured to be unique from the script author */
) {
if(is_enum_flag) {
- tmp.value= 1<<i;
+ if(item_size < 4) {
+ tmp.value= 1<<i;
+ }
if(def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
*defvalue |= tmp.value;
@@ -934,7 +952,9 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
}
}
else {
- tmp.value= i;
+ if(item_size < 4) {
+ tmp.value= i;
+ }
if(def && def_used == 0 && strcmp(def_cmp, tmp.identifier)==0) {
*defvalue= tmp.value;
@@ -949,7 +969,10 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
}
else {
MEM_freeN(items);
- PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected an tuple containing (identifier, name description)");
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): expected an tuple containing "
+ "(identifier, name description) and optionally a "
+ "unique number");
return NULL;
}
@@ -972,7 +995,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
PyErr_Format(PyExc_TypeError,
"EnumProperty(..., default=\'%s\'): not found in enum members",
- def);
+ def_cmp);
return NULL;
}
}
@@ -1080,8 +1103,9 @@ BPY_PROPDEF_DESC_DOC
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG'].\n"
" :type options: set\n"
" :arg items: sequence of enum items formatted:\n"
-" [(identifier, name, description), ...] where the identifier is used\n"
+" [(identifier, name, description, number), ...] where the identifier is used\n"
" for python access and other values are used for the interface.\n"
+" Note the item is optional.\n"
" For dynamic values a callback can be passed which returns a list in\n"
" the same format as the static list.\n"
" This function must take 2 arguments (self, context)\n"
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a63cee4e505..ba7e2d41e69 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -73,6 +73,10 @@
#include "../generic/IDProp.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
+#ifdef WITH_INTERNATIONAL
+#include "UI_interface.h" /* bad level call into editors */
+#endif
+
#define USE_PEDANTIC_WRITE
#define USE_MATHUTILS
#define USE_STRING_COERCE
@@ -80,6 +84,11 @@
static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
+#define BPY_DOC_ID_PROP_TYPE_NOTE \
+" .. note:: Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
+" :class:`bpy.types.PoseBone` classes support custom properties.\n"
+
+
int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
{
if(pysrna->ptr.type)
@@ -366,7 +375,7 @@ static int mathutils_rna_generic_check(BaseMathObject *bmo)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
return self->prop ? 0 : -1;
}
@@ -375,7 +384,7 @@ static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
if(self->prop==NULL)
return -1;
@@ -397,7 +406,7 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
float min, max;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
if(self->prop==NULL)
return -1;
@@ -448,7 +457,7 @@ static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtyp
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
if(self->prop==NULL)
return -1;
@@ -461,7 +470,7 @@ static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtyp
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
if(self->prop==NULL)
return -1;
@@ -505,7 +514,7 @@ static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
if(self->prop==NULL)
return -1;
@@ -518,7 +527,7 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
if(self->prop==NULL)
return -1;
@@ -859,7 +868,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
char type_fmt[64]= "";
int type;
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
type= RNA_property_type(self->prop);
@@ -922,7 +931,7 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
PyObject *ret;
const char *path;
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
if(id == NULL)
return pyrna_prop_str(self); /* fallback */
@@ -1519,6 +1528,12 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
param= _PyUnicode_AsString(value);
+#ifdef WITH_INTERNATIONAL
+ if(subtype == PROP_TRANSLATE) {
+ param= UI_translate_do_iface(param);
+ }
+#endif // WITH_INTERNATIONAL
+
}
#else // USE_STRING_COERCE
param= _PyUnicode_AsString(value);
@@ -1708,7 +1723,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
case PROP_COLLECTION:
{
- int seq_len, i;
+ Py_ssize_t seq_len, i;
PyObject *item;
PointerRNA itemptr;
ListBase *lb;
@@ -1726,7 +1741,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
seq_len= PySequence_Size(value);
- for(i=0; i<seq_len; i++) {
+ for(i=0; i < seq_len; i++) {
item= PySequence_GetItem(value, i);
if(item==NULL) {
@@ -1795,7 +1810,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
{
- PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
}
@@ -1874,7 +1889,7 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
//---------------sequence-------------------------------------------
static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
{
- PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_INT((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);
@@ -1884,7 +1899,7 @@ static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
{
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
return RNA_property_collection_length(&self->ptr, self->prop);
}
@@ -1893,7 +1908,7 @@ static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
* of 1000's of items in a linked list for eg. */
static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
{
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
}
@@ -1904,7 +1919,7 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
CollectionPropertyIterator iter;
int test;
- PYRNA_PROP_CHECK_INT(self)
+ PYRNA_PROP_CHECK_INT(self);
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
test= iter.valid;
@@ -1912,25 +1927,30 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
return test;
}
+
+/* notice getting the length of the collection is avoided unless negative
+ * index is used or to detect internal error with a valid index.
+ * This is done for faster lookups. */
+#define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
+ if(keynum < 0) { \
+ keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
+ if(keynum_abs < 0) { \
+ PyErr_Format(PyExc_IndexError, \
+ "bpy_prop_collection[%d]: out of range.", keynum); \
+ return ret_err; \
+ } \
+ } \
+
+
/* internal use only */
static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
{
PointerRNA newptr;
Py_ssize_t keynum_abs= keynum;
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
- /* notice getting the length of the collection is avoided unless negative index is used
- * or to detect internal error with a valid index.
- * This is done for faster lookups. */
- if(keynum < 0) {
- keynum_abs += RNA_property_collection_length(&self->ptr, self->prop);
-
- if(keynum_abs < 0) {
- PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum);
- return NULL;
- }
- }
+ PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
@@ -1953,11 +1973,40 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
}
}
+/* values type must have been already checked */
+static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
+{
+ Py_ssize_t keynum_abs= keynum;
+ const PointerRNA *ptr= (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
+
+ PYRNA_PROP_CHECK_INT(self);
+
+ PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
+
+ if(RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
+ const int len= RNA_property_collection_length(&self->ptr, self->prop);
+ if(keynum_abs >= len) {
+ PyErr_Format(PyExc_IndexError,
+ "bpy_prop_collection[index] = value: "
+ "index %d out of range, size %d", keynum, len);
+ }
+ else {
+
+ PyErr_Format(PyExc_IndexError,
+ "bpy_prop_collection[index] = value: "
+ "failed assignment (unknown reason)", keynum);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
{
int len;
- PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
len= pyrna_prop_array_length(self);
@@ -1974,7 +2023,7 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
{
PointerRNA newptr;
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
return pyrna_struct_CreatePyObject(&newptr);
@@ -1992,7 +2041,7 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py
PyObject *list;
PyObject *item;
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
list= PyList_New(0);
@@ -2031,11 +2080,11 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, Po
int count, totdim;
PyObject *tuple;
- PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
tuple= PyTuple_New(stop - start);
- /* PYRNA_PROP_CHECK_OBJ(self) isn't needed, internal use only */
+ /* PYRNA_PROP_CHECK_OBJ(self); isn't needed, internal use only */
totdim= RNA_property_array_dimension(ptr, prop, NULL);
@@ -2106,7 +2155,7 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, Po
static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
{
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
if (PyUnicode_Check(key)) {
return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
@@ -2163,9 +2212,131 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
}
}
+/* generic check to see if a PyObject is compatible with a collection
+ * -1 on failier, 0 on success, sets the error */
+static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
+{
+ StructRNA *prop_srna;
+
+ if(value == Py_None) {
+ if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key] = value: invalid, "
+ "this collection doesnt support None assignment");
+ return -1;
+ }
+ else {
+ return 0; /* None is OK */
+ }
+ }
+ else if (BPy_StructRNA_Check(value) == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key] = value: invalid, "
+ "expected a StructRNA type or None, not a %.200s",
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else if((prop_srna= RNA_property_pointer_type(&self->ptr, self->prop))) {
+ StructRNA *value_srna= ((BPy_StructRNA *)value)->ptr.type;
+ if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key] = value: invalid, "
+ "expected a '%.200s' type or None, not a '%.200s'",
+ RNA_struct_identifier(prop_srna),
+ RNA_struct_identifier(value_srna)
+ );
+ return -1;
+ }
+ else {
+ return 0; /* OK, this is the correct type!*/
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key] = value: internal error, "
+ "failed to get the collection type");
+ return -1;
+}
+
+/* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
+ * large blocks commented, we may support slice/key indicies later */
+static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
+{
+ PYRNA_PROP_CHECK_INT(self);
+
+ /* validate the assigned value */
+ if(value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "del bpy_prop_collection[key]: not supported");
+ return -1;
+ }
+ else if (pyrna_prop_collection_type_check(self, value) == -1) {
+ return -1; /* exception is set */
+ }
+
+#if 0
+ if (PyUnicode_Check(key)) {
+ return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
+ }
+ else
+#endif
+ if (PyIndex_Check(key)) {
+ Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+
+ return pyrna_prop_collection_ass_subscript_int(self, i, value);
+ }
+#if 0 /* TODO, fake slice assignment */
+ else if (PySlice_Check(key)) {
+ PySliceObject *key_slice= (PySliceObject *)key;
+ Py_ssize_t step= 1;
+
+ if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
+ return NULL;
+ }
+ else if (step != 1) {
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
+ return NULL;
+ }
+ else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
+ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
+ }
+ else {
+ Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
+
+ /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+ if(key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
+ if(key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL;
+
+ if(start < 0 || stop < 0) {
+ /* only get the length for negative values */
+ Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
+ if(start < 0) start += len;
+ if(stop < 0) start += len;
+ }
+
+ if (stop - start <= 0) {
+ return PyList_New(0);
+ }
+ else {
+ return pyrna_prop_collection_subscript_slice(self, start, stop);
+ }
+ }
+ }
+#endif
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key]: invalid key, "
+ "must be a string or an int, not %.200s",
+ Py_TYPE(key)->tp_name);
+ return -1;
+ }
+}
+
static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
{
- PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
/*if (PyUnicode_Check(key)) {
return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
@@ -2321,7 +2492,7 @@ static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t k
{
int len;
- PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
len= pyrna_prop_array_length(self);
@@ -2399,7 +2570,7 @@ static PyMappingMethods pyrna_prop_array_as_mapping= {
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 */
+ (objobjargproc) pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */
};
/* only for fast bool's, large structs, assign nb_bool on init */
@@ -2456,7 +2627,7 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
IDProperty *group;
const char *name= _PyUnicode_AsString(value);
- PYRNA_STRUCT_CHECK_INT(self)
+ PYRNA_STRUCT_CHECK_INT(self);
if (!name) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
@@ -2495,7 +2666,7 @@ static PySequenceMethods pyrna_prop_collection_as_sequence= {
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 */
+ (ssizeobjargproc)/* pyrna_prop_collection_ass_subscript_int */ NULL /* let mapping take this one */, /* sq_ass_item */
NULL, /* *was* sq_ass_slice */
(objobjproc)pyrna_prop_collection_contains, /* sq_contains */
(binaryfunc) NULL, /* sq_inplace_concat */
@@ -2521,7 +2692,7 @@ static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
IDProperty *group, *idprop;
const char *name= _PyUnicode_AsString(key);
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if(RNA_struct_idprops_check(self->ptr.type)==0) {
PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
@@ -2554,7 +2725,7 @@ static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObje
{
IDProperty *group;
- PYRNA_STRUCT_CHECK_INT(self)
+ PYRNA_STRUCT_CHECK_INT(self);
group= RNA_struct_idprops(&self->ptr, 1);
@@ -2587,8 +2758,7 @@ PyDoc_STRVAR(pyrna_struct_keys_doc,
" :return: custom property keys.\n"
" :rtype: list of strings\n"
"\n"
-" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes\n"
-" support custom properties.\n"
+BPY_DOC_ID_PROP_TYPE_NOTE
);
static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
{
@@ -2616,8 +2786,7 @@ PyDoc_STRVAR(pyrna_struct_items_doc,
" :return: custom property key, value pairs.\n"
" :rtype: list of key, value tuples\n"
"\n"
-" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone`\n"
-" classes support custom properties.\n"
+BPY_DOC_ID_PROP_TYPE_NOTE
);
static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
{
@@ -2645,8 +2814,7 @@ PyDoc_STRVAR(pyrna_struct_values_doc,
" :return: custom property values.\n"
" :rtype: list\n"
"\n"
-" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone`\n"
-" classes support custom properties.\n"
+BPY_DOC_ID_PROP_TYPE_NOTE
);
static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
{
@@ -2680,7 +2848,7 @@ static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *arg
const char *name;
int ret;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
return NULL;
@@ -2723,7 +2891,7 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *
PropertyRNA *prop;
const char *name;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
return NULL;
@@ -2757,7 +2925,7 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
PropertyRNA *r_prop;
int index= -1;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce))
return NULL;
@@ -2815,7 +2983,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
PropertyRNA *prop;
PyObject *ret;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "|s:path_from_id", &name))
return NULL;
@@ -2897,7 +3065,7 @@ static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
{
PointerRNA r_ptr;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
RNA_pointer_recast(&self->ptr, &r_ptr);
return pyrna_struct_CreatePyObject(&r_ptr);
@@ -2978,7 +3146,7 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
PyObject *ret;
PyObject *pystring;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
@@ -3025,7 +3193,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
PropertyRNA *prop;
FunctionRNA *func;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if(name == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
@@ -3246,7 +3414,7 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
const char *name= _PyUnicode_AsString(pyname);
PropertyRNA *prop= NULL;
- PYRNA_STRUCT_CHECK_INT(self)
+ PYRNA_STRUCT_CHECK_INT(self);
#ifdef USE_PEDANTIC_WRITE
if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
@@ -3496,18 +3664,28 @@ static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
Py_RETURN_NONE;
}
+static PyObject *pyrna_struct_get_rna_type(BPy_PropertyRNA *self)
+{
+ PointerRNA tptr;
+ RNA_pointer_create(NULL, &RNA_Property, self->prop, &tptr);
+ return pyrna_struct_Subtype(&tptr);
+}
+
+
+
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef pyrna_prop_getseters[]= {
- {(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
+ {(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`bpy.types.ID` object this datablock is from or None, (not available for all data types)", NULL},
+ {(char *)"rna_type", (getter)pyrna_struct_get_rna_type, (setter)NULL, (char *)"The property type for introspection", NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef pyrna_struct_getseters[]= {
- {(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
+ {(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`bpy.types.ID` object this datablock is from or None, (not available for all data types)", NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -3614,8 +3792,7 @@ PyDoc_STRVAR(pyrna_struct_get_doc,
" *key* is not found.\n"
" :type default: Undefined\n"
"\n"
-" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone`\n"
-" classes support custom properties.\n"
+BPY_DOC_ID_PROP_TYPE_NOTE
);
static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
{
@@ -3624,7 +3801,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
const char *key;
PyObject* def= Py_None;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
return NULL;
@@ -3681,7 +3858,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
const char *key;
PyObject* def= Py_None;
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
return NULL;
@@ -3954,7 +4131,7 @@ PyDoc_STRVAR(pyrna_prop_collection_foreach_get_doc,
);
static PyObject *pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args)
{
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
return foreach_getset(self, args, 0);
}
@@ -3974,7 +4151,7 @@ PyDoc_STRVAR(pyrna_prop_collection_foreach_set_doc,
);
static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
{
- PYRNA_PROP_CHECK_OBJ(self)
+ PYRNA_PROP_CHECK_OBJ(self);
return foreach_getset(self, args, 1);
}
@@ -3988,7 +4165,7 @@ static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self)
PyObject *iter= NULL;
int len;
- PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
len= pyrna_prop_array_length(self);
ret= pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
@@ -4130,8 +4307,8 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
-static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) {
-
+static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
+{
BPy_PropertyRNA *base;
if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base))
@@ -4696,7 +4873,11 @@ PyTypeObject pyrna_struct_meta_idprop_Type= {
NULL, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
+#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+ NULL, /* defer assignment */
+#else
+ &PyType_Type, /* struct _typeobject *tp_base; */
+#endif
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
NULL, /* descrsetfunc tp_descr_set; */
@@ -5267,7 +5448,11 @@ PyTypeObject pyrna_prop_collection_iter_Type= {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
+#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+ NULL, /* defer assignment */
+#else
PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
+#endif
NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
@@ -5296,7 +5481,11 @@ PyTypeObject pyrna_prop_collection_iter_Type= {
#endif
/*** Added in release 2.2 ***/
/* Iterators */
+#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+ NULL, /* defer assignment */
+#else
PyObject_SelfIter, /* getiterfunc tp_iter; */
+#endif
(iternextfunc) pyrna_prop_collection_iter_next, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
@@ -5682,8 +5871,15 @@ void BPY_rna_init(void)
mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb);
#endif
- /* metaclass */
+ /* for some reason MSVC complains of these */
+#if defined(_MSC_VER) || defined(FREE_WINDOWS)
pyrna_struct_meta_idprop_Type.tp_base= &PyType_Type;
+
+ pyrna_prop_collection_iter_Type.tp_iter= PyObject_SelfIter;
+ pyrna_prop_collection_iter_Type.tp_getattro= PyObject_GenericGetAttr;
+#endif
+
+ /* metaclass */
if(PyType_Ready(&pyrna_struct_meta_idprop_Type) < 0)
return;
@@ -5728,7 +5924,11 @@ PyObject *BPY_rna_module(void)
void BPY_update_rna_module(void)
{
+#if 0
RNA_main_pointer_create(G.main, rna_module_ptr);
+#else
+ rna_module_ptr->data= G.main; /* just set data is enough */
+#endif
}
#if 0
@@ -6228,7 +6428,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
ParameterIterator iter;
PointerRNA funcptr;
int err= 0, i, flag, ret_len=0;
- int is_static= RNA_function_flag(func) & FUNC_NO_SELF;
+ const char is_static= (RNA_function_flag(func) & FUNC_NO_SELF) != 0;
+
+ /* annoying!, need to check if the screen gets set to NULL which is a
+ * hint that the file was actually re-loaded. */
+ char is_valid_wm;
PropertyRNA *pret_single= NULL;
void *retdata_single= NULL;
@@ -6255,6 +6459,8 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if(C==NULL)
C= BPy_GetContext();
+ is_valid_wm= (CTX_wm_manager(C) != NULL);
+
bpy_context_set(C, &gilstate);
if (!is_static) {
@@ -6488,7 +6694,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if(err != 0) {
ReportList *reports;
/* alert the user, else they wont know unless they see the console. */
- if (!is_static && ptr->data && RNA_struct_is_a(ptr->type, &RNA_Operator)) {
+ if ( (!is_static) &&
+ (ptr->data) &&
+ (RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
+ (is_valid_wm == (CTX_wm_manager(C) != NULL)))
+ {
wmOperator *op= ptr->data;
reports= op->reports;
}
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 30f6c02115a..502fa25c872 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -44,9 +44,6 @@
/* support for inter references, currently only needed for corner case */
#define USE_PYRNA_STRUCT_REFERENCE
-/* use real collection iterators rather than faking with a list */
-#define USE_PYRNA_ITER
-
#else /* WITH_PYTHON_SAFETY */
/* default, no defines! */
@@ -67,6 +64,11 @@
* so prefer the leak to the memory bloat for now. */
// #define PYRNA_FREE_SUPPORT
+/* use real collection iterators rather than faking with a list
+ * this is needed so enums can be iterated over without crashing,
+ * since finishing the iteration frees temp allocated enums */
+#define USE_PYRNA_ITER
+
/* --- end bpy build options --- */
struct ID;
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 8bde1db96ca..c87a141f5bd 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -189,7 +189,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
float cfra= FLT_MAX;
const char *group_name= NULL;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw,
"s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
@@ -237,7 +237,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
float cfra= FLT_MAX;
const char *group_name= NULL;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw,
"s|ifs:bpy_struct.keyframe_delete()",
@@ -273,14 +273,14 @@ char pyrna_struct_driver_add_doc[] =
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: The driver(s) added.\n"
-" :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
+" :rtype: :class:`bpy.types.FCurve` or list if index is -1 with an array property.\n"
;
PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
int index= -1;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
@@ -356,7 +356,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
const char *path, *path_full;
int index= -1;
- PYRNA_STRUCT_CHECK_OBJ(self)
+ PYRNA_STRUCT_CHECK_OBJ(self);
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
return NULL;
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index e50ce233671..cab57724d6d 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -61,12 +61,12 @@ typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *)
static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[],
ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix)
{
- int i;
+ Py_ssize_t i;
/* not the last dimension */
if (dim + 1 < totdim) {
/* check that a sequence contains dimsize[dim] items */
- const int seq_size= PySequence_Size(seq);
+ const Py_ssize_t seq_size= PySequence_Size(seq);
if(seq_size == -1) {
PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'",
error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name);
@@ -147,8 +147,8 @@ static int count_items(PyObject *seq, int dim)
int totitem= 0;
if(dim > 1) {
- const int seq_size= PySequence_Size(seq);
- int i;
+ const Py_ssize_t seq_size= PySequence_Size(seq);
+ Py_ssize_t i;
for (i= 0; i < seq_size; i++) {
PyObject *item= PySequence_GetItem(seq, i);
if(item) {
@@ -281,9 +281,9 @@ static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *pro
static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
{
- unsigned int i;
int totdim= RNA_property_array_dimension(ptr, prop, NULL);
- const int seq_size= PySequence_Size(seq);
+ const Py_ssize_t seq_size= PySequence_Size(seq);
+ Py_ssize_t i;
/* Regarding PySequence_GetItem() failing.
*
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 50b75b09cb2..9adeae9dc29 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -94,11 +94,11 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
#if 1 /* approx 6x speedup for mathutils types */
int size;
- if( (VectorObject_Check(value) && (size= ((VectorObject *)value)->size)) ||
- (EulerObject_Check(value) && (size= 3)) ||
- (QuaternionObject_Check(value) && (size= 4)) ||
- (ColorObject_Check(value) && (size= 3))
- ) {
+ if( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
+ (size= EulerObject_Check(value) ? 3 : 0) ||
+ (size= QuaternionObject_Check(value) ? 4 : 0) ||
+ (size= ColorObject_Check(value) ? 3 : 0))
+ {
if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 947e4425d3f..9d1cfb1948a 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -193,7 +193,7 @@ static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value)
}
PyDoc_STRVAR(Quaternion_rotation_difference_doc,
-".. function:: difference(other)\n"
+".. function:: rotation_difference(other)\n"
"\n"
" Returns a quaternion representing the rotational difference.\n"
"\n"