From a619de52cfc4aaa7371e418730a84d0dbd317673 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 Oct 2013 02:57:59 +0000 Subject: simplify & improve error handling for id-property python-api. --- source/blender/python/generic/idprop_py_api.c | 68 +++++++++++++++++---------- 1 file changed, 42 insertions(+), 26 deletions(-) (limited to 'source/blender/python/generic') diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 9d4b0433f20..93dc5b8397c 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -25,15 +25,16 @@ * \ingroup pygen */ - #include -#include "idprop_py_api.h" #include "MEM_guardedalloc.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "idprop_py_api.h" + + #include "BKE_idprop.h" @@ -329,22 +330,30 @@ static int idp_sequence_type(PyObject *seq_fast) return type; } -/* note: group can be a pointer array or a group. - * assume we already checked key is a string. */ -const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob) +/** + * \note group can be a pointer array or a group. + * assume we already checked key is a string. + * + * \return success. + */ +bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob) { IDProperty *prop = NULL; IDPropertyTemplate val = {0}; - const char *name = ""; + const char *name; if (name_obj) { Py_ssize_t name_size; name = _PyUnicode_AsStringAndSize(name_obj, &name_size); if (name_size > MAX_IDPROP_NAME) { - return "the length of IDProperty names is limited to 63 characters"; + PyErr_SetString(PyExc_KeyError, "the length of IDProperty names is limited to 63 characters"); + return false; } } + else { + name = ""; + } if (PyFloat_Check(ob)) { val.d = PyFloat_AsDouble(ob); @@ -353,7 +362,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty else if (PyLong_Check(ob)) { val.i = _PyLong_AsInt(ob); if (val.i == -1 && PyErr_Occurred()) { - return "error converting to an int"; + return false; } prop = IDP_New(IDP_INT, &val, name); } @@ -384,14 +393,13 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty int i; if (ob_seq_fast == NULL) { - PyErr_Print(); - PyErr_Clear(); - return "error converting the sequence"; + return false; } if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { Py_DECREF(ob_seq_fast); - return "only floats, ints and dicts are allowed in ID property arrays"; + PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays"); + return false; } /* validate sequence and derive type. @@ -418,19 +426,21 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty case IDP_IDPARRAY: prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { - const char *error; + bool ok; item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); - error = BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item); + ok = BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item); - if (error) { + if (ok == false) { Py_DECREF(ob_seq_fast); - return error; + return ok; } } break; default: + /* should never happen */ Py_DECREF(ob_seq_fast); - return "internal error with idp array.type"; + PyErr_SetString(PyExc_RuntimeError, "internal error with idp array.type"); + return false; } Py_DECREF(ob_seq_fast); @@ -456,16 +466,20 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty Py_XDECREF(vals); Py_XDECREF(key); Py_XDECREF(pval); - return "invalid element in subgroup dict template!"; + PyErr_Format(PyExc_TypeError, + "invalid id-property key type expected a string, not %.200s", + Py_TYPE(key)->tp_name); + return false; } - if (BPy_IDProperty_Map_ValidateAndCreate(key, prop, pval)) { + if (BPy_IDProperty_Map_ValidateAndCreate(key, prop, pval) == false) { IDP_FreeProperty(prop); MEM_freeN(prop); Py_XDECREF(keys); Py_XDECREF(vals); Py_XDECREF(key); Py_XDECREF(pval); - return "invalid element in subgroup dict template!"; + /* error is already set */ + return false; } Py_XDECREF(key); Py_XDECREF(pval); @@ -474,7 +488,10 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty Py_XDECREF(vals); } else { - return "invalid property value"; + PyErr_Format(PyExc_TypeError, + "invalid id-property type %.200s not supported", + Py_TYPE(ob)->tp_name); + return false; } if (group->type == IDP_IDPARRAY) { @@ -486,7 +503,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty IDP_ReplaceInGroup(group, prop); } - return NULL; + return true; } int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val) @@ -508,16 +525,15 @@ int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val) } } else { - const char *err; + bool ok; if (!PyUnicode_Check(key)) { PyErr_SetString(PyExc_TypeError, "only strings are allowed as subgroup keys"); return -1; } - err = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val); - if (err) { - PyErr_SetString(PyExc_KeyError, err); + ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val); + if (ok == false) { return -1; } -- cgit v1.2.3