forked from bartvdbraak/blender
New C/Py api utility function PyC_Err_Format_Prefix() which raises an error with the existing error as a suffix.
Use this to raise errors when assigning a string property fails even though the value to assign *is* a string. Before: TypeError: bpy_struct: item.attr= val: Object.name expected a string type, not str After: TypeError: bpy_struct: item.attr= val: Object.name error assigning string, UnicodeEncodeError('utf-8' codec can't encode character '\udce9' in position 23: surrogates not allowed)
This commit is contained in:
parent
5ba213a424
commit
264c63ef03
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user