diff options
Diffstat (limited to 'source/blender/python/generic/idprop_py_api.c')
-rw-r--r-- | source/blender/python/generic/idprop_py_api.c | 142 |
1 files changed, 101 insertions, 41 deletions
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 11646f3f3df..2e15b7b1413 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -98,7 +98,7 @@ static PyObject *idprop_py_from_idp_array(ID *id, IDProperty *prop) static PyObject *idprop_py_from_idp_idparray(ID *id, IDProperty *prop) { - PyObject *seq = PyList_New(prop->len), *wrap; + PyObject *seq = PyList_New(prop->len); IDProperty *array = IDP_IDPArray(prop); int i; @@ -110,10 +110,13 @@ static PyObject *idprop_py_from_idp_idparray(ID *id, IDProperty *prop) } for (i = 0; i < prop->len; i++) { - wrap = BPy_IDGroup_WrapData(id, array++, prop); + PyObject *wrap = BPy_IDGroup_WrapData(id, array++, prop); - if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ + /* BPy_IDGroup_MapDataToPy sets the error */ + if (UNLIKELY(wrap == NULL)) { + Py_DECREF(seq); return NULL; + } PyList_SET_ITEM(seq, i, wrap); } @@ -378,8 +381,10 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, } else if (PyUnicode_Check(ob)) { #ifdef USE_STRING_COERCE + Py_ssize_t value_size; PyObject *value_coerce = NULL; - val.string.str = PyC_UnicodeAsByte(ob, &value_coerce); + val.string.str = PyC_UnicodeAsByteAndSize(ob, &value_size, &value_coerce); + val.string.len = (int)value_size + 1; val.string.subtype = IDP_STRING_SUB_UTF8; prop = IDP_New(IDP_STRING, &val, name); Py_XDECREF(value_coerce); @@ -657,7 +662,7 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) } case IDP_IDPARRAY: { - PyObject *seq = PyList_New(prop->len), *wrap; + PyObject *seq = PyList_New(prop->len); IDProperty *array = IDP_IDPArray(prop); int i; @@ -669,10 +674,13 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) } for (i = 0; i < prop->len; i++) { - wrap = BPy_IDGroup_MapDataToPy(array++); + PyObject *wrap = BPy_IDGroup_MapDataToPy(array++); - if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ + /* BPy_IDGroup_MapDataToPy sets the error */ + if (UNLIKELY(wrap == NULL)) { + Py_DECREF(seq); return NULL; + } PyList_SET_ITEM(seq, i, wrap); } @@ -680,14 +688,17 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) } case IDP_GROUP: { - PyObject *dict = PyDict_New(), *wrap; + PyObject *dict = _PyDict_NewPresized(prop->len); IDProperty *loop; for (loop = prop->data.group.first; loop; loop = loop->next) { - wrap = BPy_IDGroup_MapDataToPy(loop); + PyObject *wrap = BPy_IDGroup_MapDataToPy(loop); - if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ + /* BPy_IDGroup_MapDataToPy sets the error */ + if (UNLIKELY(wrap == NULL)) { + Py_DECREF(dict); return NULL; + } PyDict_SetItemString(dict, loop->name, wrap); Py_DECREF(wrap); @@ -702,7 +713,17 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) return NULL; } -static PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value) +PyDoc_STRVAR(BPy_IDGroup_pop_doc, +".. method:: pop(key)\n" +"\n" +" Remove an item from the group, returning a Python representation.\n" +"\n" +" :raises KeyError: When the item doesn't exist.\n" +"\n" +" :arg key: Name of item to remove.\n" +" :type key: string\n" +); +static PyObject *BPy_IDGroup_pop(BPy_IDProperty *self, PyObject *value) { IDProperty *idprop; PyObject *pyform; @@ -735,7 +756,12 @@ static PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value) return NULL; } -static PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self) +PyDoc_STRVAR(BPy_IDGroup_iter_items_doc, +".. method:: iteritems()\n" +"\n" +" Iterate through the items in the dict; behaves like dictionary method iteritems.\n" +); +static PyObject *BPy_IDGroup_iter_items(BPy_IDProperty *self) { BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type); iter->group = self; @@ -829,18 +855,32 @@ PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop) return seq; } - -static PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self) +PyDoc_STRVAR(BPy_IDGroup_keys_doc, +".. method:: keys()\n" +"\n" +" Return the keys associated with this group as a list of strings.\n" +); +static PyObject *BPy_IDGroup_keys(BPy_IDProperty *self) { return BPy_Wrap_GetKeys(self->prop); } -static PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self) +PyDoc_STRVAR(BPy_IDGroup_values_doc, +".. method:: values()\n" +"\n" +" Return the values associated with this group.\n" +); +static PyObject *BPy_IDGroup_values(BPy_IDProperty *self) { return BPy_Wrap_GetValues(self->id, self->prop); } -static PyObject *BPy_IDGroup_GetItems(BPy_IDProperty *self) +PyDoc_STRVAR(BPy_IDGroup_items_doc, +".. method:: items()\n" +"\n" +" Return the items associated with this group.\n" +); +static PyObject *BPy_IDGroup_items(BPy_IDProperty *self) { return BPy_Wrap_GetItems(self->id, self->prop); } @@ -859,7 +899,15 @@ static int BPy_IDGroup_Contains(BPy_IDProperty *self, PyObject *value) return IDP_GetPropertyFromGroup(self->prop, name) ? 1 : 0; } -static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value) +PyDoc_STRVAR(BPy_IDGroup_update_doc, +".. method:: update(other)\n" +"\n" +" Update key, values.\n" +"\n" +" :arg other: Updates the values in the group with this.\n" +" :type other: :class:`IDPropertyGroup` or dict\n" +); +static PyObject *BPy_IDGroup_update(BPy_IDProperty *self, PyObject *value) { PyObject *pkey, *pval; Py_ssize_t i = 0; @@ -890,19 +938,33 @@ static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value) Py_RETURN_NONE; } +PyDoc_STRVAR(BPy_IDGroup_to_dict_doc, +".. method:: to_dict()\n" +"\n" +" Return a purely python version of the group.\n" +); static PyObject *BPy_IDGroup_to_dict(BPy_IDProperty *self) { return BPy_IDGroup_MapDataToPy(self->prop); } +PyDoc_STRVAR(BPy_IDGroup_clear_doc, +".. method:: clear()\n" +"\n" +" Clear all members from this group.\n" +); static PyObject *BPy_IDGroup_clear(BPy_IDProperty *self) { IDP_ClearProperty(self->prop); Py_RETURN_NONE; } -/* Matches python dict.get(key, [default]) */ -static PyObject *BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args) +PyDoc_STRVAR(BPy_IDGroup_get_doc, +".. method:: get(key, default=None)\n" +"\n" +" Return the value for key, if it exists, else default.\n" +); +static PyObject *BPy_IDGroup_get(BPy_IDProperty *self, PyObject *args) { IDProperty *idprop; const char *key; @@ -923,24 +985,15 @@ static PyObject *BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args) } static struct PyMethodDef BPy_IDGroup_methods[] = { - {"pop", (PyCFunction)BPy_IDGroup_Pop, METH_O, - "pop an item from the group; raises KeyError if the item doesn't exist"}, - {"iteritems", (PyCFunction)BPy_IDGroup_IterItems, METH_NOARGS, - "iterate through the items in the dict; behaves like dictionary method iteritems"}, - {"keys", (PyCFunction)BPy_IDGroup_GetKeys, METH_NOARGS, - "get the keys associated with this group as a list of strings"}, - {"values", (PyCFunction)BPy_IDGroup_GetValues, METH_NOARGS, - "get the values associated with this group"}, - {"items", (PyCFunction)BPy_IDGroup_GetItems, METH_NOARGS, - "get the items associated with this group"}, - {"update", (PyCFunction)BPy_IDGroup_Update, METH_O, - "updates the values in the group with the values of another or a dict"}, - {"get", (PyCFunction)BPy_IDGroup_Get, METH_VARARGS, - "idprop.get(k[,d]) -> idprop[k] if k in idprop, else d. d defaults to None"}, - {"to_dict", (PyCFunction)BPy_IDGroup_to_dict, METH_NOARGS, - "return a purely python version of the group"}, - {"clear", (PyCFunction)BPy_IDGroup_clear, METH_NOARGS, - "clear all members from this group"}, + {"pop", (PyCFunction)BPy_IDGroup_pop, METH_O, BPy_IDGroup_pop_doc}, + {"iteritems", (PyCFunction)BPy_IDGroup_iter_items, METH_NOARGS, BPy_IDGroup_iter_items_doc}, + {"keys", (PyCFunction)BPy_IDGroup_keys, METH_NOARGS, BPy_IDGroup_keys_doc}, + {"values", (PyCFunction)BPy_IDGroup_values, METH_NOARGS, BPy_IDGroup_values_doc}, + {"items", (PyCFunction)BPy_IDGroup_items, METH_NOARGS, BPy_IDGroup_items_doc}, + {"update", (PyCFunction)BPy_IDGroup_update, METH_O, BPy_IDGroup_update_doc}, + {"get", (PyCFunction)BPy_IDGroup_get, METH_VARARGS, BPy_IDGroup_get_doc}, + {"to_dict", (PyCFunction)BPy_IDGroup_to_dict, METH_NOARGS, BPy_IDGroup_to_dict_doc}, + {"clear", (PyCFunction)BPy_IDGroup_clear, METH_NOARGS, BPy_IDGroup_clear_doc}, {NULL, NULL, 0, NULL} }; @@ -1049,7 +1102,10 @@ static PyObject *BPy_IDArray_repr(BPy_IDArray *self) return PyUnicode_FromFormat("<bpy id property array [%d]>", self->prop->len); } -static PyObject *BPy_IDArray_GetType(BPy_IDArray *self) +PyDoc_STRVAR(BPy_IDArray_get_typecode_doc, +"The type of the data in the array {'f': float, 'd': double, 'i': int}." +); +static PyObject *BPy_IDArray_get_typecode(BPy_IDArray *self) { switch (self->prop->subtype) { case IDP_FLOAT: return PyUnicode_FromString("f"); @@ -1066,18 +1122,22 @@ static PyObject *BPy_IDArray_GetType(BPy_IDArray *self) static PyGetSetDef BPy_IDArray_getseters[] = { /* matches pythons array.typecode */ - {(char *)"typecode", (getter)BPy_IDArray_GetType, (setter)NULL, (char *)"The type of the data in the array, is an int.", NULL}, + {(char *)"typecode", (getter)BPy_IDArray_get_typecode, (setter)NULL, BPy_IDArray_get_typecode_doc, NULL}, {NULL, NULL, NULL, NULL, NULL}, }; +PyDoc_STRVAR(BPy_IDArray_to_list_doc, +".. method:: to_list()\n" +"\n" +" Return the array as a list.\n" +); static PyObject *BPy_IDArray_to_list(BPy_IDArray *self) { return BPy_IDGroup_MapDataToPy(self->prop); } static PyMethodDef BPy_IDArray_methods[] = { - {"to_list", (PyCFunction)BPy_IDArray_to_list, METH_NOARGS, - "return the array as a list"}, + {"to_list", (PyCFunction)BPy_IDArray_to_list, METH_NOARGS, BPy_IDArray_to_list_doc}, {NULL, NULL, 0, NULL} }; |