simplify & improve error handling for id-property python-api.
This commit is contained in:
@@ -25,15 +25,16 @@
|
|||||||
* \ingroup pygen
|
* \ingroup pygen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
|
||||||
#include "idprop_py_api.h"
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "BLI_string.h"
|
#include "BLI_string.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
|
#include "idprop_py_api.h"
|
||||||
|
|
||||||
|
|
||||||
#include "BKE_idprop.h"
|
#include "BKE_idprop.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -329,22 +330,30 @@ static int idp_sequence_type(PyObject *seq_fast)
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note: group can be a pointer array or a group.
|
/**
|
||||||
* assume we already checked key is a string. */
|
* \note group can be a pointer array or a group.
|
||||||
const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob)
|
* 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;
|
IDProperty *prop = NULL;
|
||||||
IDPropertyTemplate val = {0};
|
IDPropertyTemplate val = {0};
|
||||||
|
|
||||||
const char *name = "";
|
const char *name;
|
||||||
|
|
||||||
if (name_obj) {
|
if (name_obj) {
|
||||||
Py_ssize_t name_size;
|
Py_ssize_t name_size;
|
||||||
name = _PyUnicode_AsStringAndSize(name_obj, &name_size);
|
name = _PyUnicode_AsStringAndSize(name_obj, &name_size);
|
||||||
if (name_size > MAX_IDPROP_NAME) {
|
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)) {
|
if (PyFloat_Check(ob)) {
|
||||||
val.d = PyFloat_AsDouble(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)) {
|
else if (PyLong_Check(ob)) {
|
||||||
val.i = _PyLong_AsInt(ob);
|
val.i = _PyLong_AsInt(ob);
|
||||||
if (val.i == -1 && PyErr_Occurred()) {
|
if (val.i == -1 && PyErr_Occurred()) {
|
||||||
return "error converting to an int";
|
return false;
|
||||||
}
|
}
|
||||||
prop = IDP_New(IDP_INT, &val, name);
|
prop = IDP_New(IDP_INT, &val, name);
|
||||||
}
|
}
|
||||||
@@ -384,14 +393,13 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (ob_seq_fast == NULL) {
|
if (ob_seq_fast == NULL) {
|
||||||
PyErr_Print();
|
return false;
|
||||||
PyErr_Clear();
|
|
||||||
return "error converting the sequence";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) {
|
if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) {
|
||||||
Py_DECREF(ob_seq_fast);
|
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.
|
/* validate sequence and derive type.
|
||||||
@@ -418,19 +426,21 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
|
|||||||
case IDP_IDPARRAY:
|
case IDP_IDPARRAY:
|
||||||
prop = IDP_NewIDPArray(name);
|
prop = IDP_NewIDPArray(name);
|
||||||
for (i = 0; i < val.array.len; i++) {
|
for (i = 0; i < val.array.len; i++) {
|
||||||
const char *error;
|
bool ok;
|
||||||
item = PySequence_Fast_GET_ITEM(ob_seq_fast, i);
|
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);
|
Py_DECREF(ob_seq_fast);
|
||||||
return error;
|
return ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
/* should never happen */
|
||||||
Py_DECREF(ob_seq_fast);
|
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);
|
Py_DECREF(ob_seq_fast);
|
||||||
@@ -456,16 +466,20 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
|
|||||||
Py_XDECREF(vals);
|
Py_XDECREF(vals);
|
||||||
Py_XDECREF(key);
|
Py_XDECREF(key);
|
||||||
Py_XDECREF(pval);
|
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);
|
IDP_FreeProperty(prop);
|
||||||
MEM_freeN(prop);
|
MEM_freeN(prop);
|
||||||
Py_XDECREF(keys);
|
Py_XDECREF(keys);
|
||||||
Py_XDECREF(vals);
|
Py_XDECREF(vals);
|
||||||
Py_XDECREF(key);
|
Py_XDECREF(key);
|
||||||
Py_XDECREF(pval);
|
Py_XDECREF(pval);
|
||||||
return "invalid element in subgroup dict template!";
|
/* error is already set */
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Py_XDECREF(key);
|
Py_XDECREF(key);
|
||||||
Py_XDECREF(pval);
|
Py_XDECREF(pval);
|
||||||
@@ -474,7 +488,10 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
|
|||||||
Py_XDECREF(vals);
|
Py_XDECREF(vals);
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
if (group->type == IDP_IDPARRAY) {
|
||||||
@@ -486,7 +503,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
|
|||||||
IDP_ReplaceInGroup(group, prop);
|
IDP_ReplaceInGroup(group, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val)
|
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 {
|
else {
|
||||||
const char *err;
|
bool ok;
|
||||||
|
|
||||||
if (!PyUnicode_Check(key)) {
|
if (!PyUnicode_Check(key)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "only strings are allowed as subgroup keys");
|
PyErr_SetString(PyExc_TypeError, "only strings are allowed as subgroup keys");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val);
|
ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val);
|
||||||
if (err) {
|
if (ok == false) {
|
||||||
PyErr_SetString(PyExc_KeyError, err);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user