[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40217] trunk/blender/source/blender/ python: New C/Py api utility function PyC_Err_Format_Prefix() which raises an error with the existing error as a suffix.

Campbell Barton ideasman42 at gmail.com
Thu Sep 15 12:43:55 CEST 2011


Revision: 40217
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40217
Author:   campbellbarton
Date:     2011-09-15 10:43:55 +0000 (Thu, 15 Sep 2011)
Log Message:
-----------
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)

Modified Paths:
--------------
    trunk/blender/source/blender/python/generic/py_capi_utils.c
    trunk/blender/source/blender/python/generic/py_capi_utils.h
    trunk/blender/source/blender/python/intern/bpy_rna.c

Modified: trunk/blender/source/blender/python/generic/py_capi_utils.c
===================================================================
--- trunk/blender/source/blender/python/generic/py_capi_utils.c	2011-09-15 08:07:42 UTC (rev 40216)
+++ trunk/blender/source/blender/python/generic/py_capi_utils.c	2011-09-15 10:43:55 UTC (rev 40217)
@@ -208,6 +208,44 @@
 	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
 

Modified: trunk/blender/source/blender/python/generic/py_capi_utils.h
===================================================================
--- trunk/blender/source/blender/python/generic/py_capi_utils.h	2011-09-15 08:07:42 UTC (rev 40216)
+++ trunk/blender/source/blender/python/generic/py_capi_utils.h	2011-09-15 10:43:55 UTC (rev 40217)
@@ -34,6 +34,7 @@
 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);
 

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c	2011-09-15 08:07:42 UTC (rev 40216)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c	2011-09-15 10:43:55 UTC (rev 40217)
@@ -1525,10 +1525,22 @@
 #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 @@
 			 * 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) {




More information about the Bf-blender-cvs mailing list