diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index a1571dc028c..d5bd44fc288 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -208,6 +208,44 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) return item; } +/* similar to PyErr_Format(), + * + * implimentation - we cant actually preprend the existing exception, + * because it could have _any_ argiments given to it, so instead we get its + * __str__ output and raise our own exception including it. + */ +PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...) +{ + PyObject *error_value_prefix; + va_list args; + + va_start(args, format); + error_value_prefix= PyUnicode_FromFormatV(format, args); /* can fail and be NULL */ + va_end(args); + + if(PyErr_Occurred()) { + PyObject *error_type, *error_value, *error_traceback; + PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyErr_Format(exception_type_prefix, + "%S, %.200s(%S)", + error_value_prefix, + Py_TYPE(error_value)->tp_name, + error_value + ); + } + else { + PyErr_SetObject(exception_type_prefix, + error_value_prefix + ); + } + + Py_XDECREF(error_value_prefix); + + /* dumb to always return NULL but matches PyErr_Format */ + return NULL; +} + + /* returns the exception string as a new PyUnicode object, depends on external traceback module */ #if 0 diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 96c93ab71f8..03a8637710e 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -34,6 +34,7 @@ void PyC_ObSpit(const char *name, PyObject *var); void PyC_LineSpit(void); PyObject * PyC_ExceptionBuffer(void); PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...); +PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...); void PyC_FileAndNum(const char **filename, int *lineno); int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 4c382efdda3..a63cee4e505 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1525,10 +1525,22 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb #endif // USE_STRING_COERCE if (param==NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s expected a string type, not %.200s", - error_prefix, RNA_struct_identifier(ptr->type), - RNA_property_identifier(prop), Py_TYPE(value)->tp_name); + if(PyUnicode_Check(value)) { + /* there was an error assigning a string type, + * rather than setting a new error, prefix the existing one + */ + PyC_Err_Format_Prefix(PyExc_TypeError, + "%.200s %.200s.%.200s error assigning string", + error_prefix, RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop)); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s %.200s.%.200s expected a string type, not %.200s", + error_prefix, RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop), Py_TYPE(value)->tp_name); + } + return -1; } else { @@ -6427,14 +6439,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param * no line number since the func has finished calling on error, * re-raise the exception with more info since it would be slow to * create prefix on every call (when there are no errors) */ - if(err == -1 && PyErr_Occurred()) { - PyObject *error_type, *error_value, *error_traceback; - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - PyErr_Format(error_type, - "class %.200s, function %.200s: incompatible return value%S", - RNA_struct_identifier(ptr->type), RNA_function_identifier(func), - error_value); + if(err == -1) { + PyC_Err_Format_Prefix(PyExc_RuntimeError, + "class %.200s, function %.200s: incompatible return value ", + RNA_struct_identifier(ptr->type), RNA_function_identifier(func) + ); } } else if (ret_len > 1) {