26#define USE_STRING_COERCE
28#ifdef USE_STRING_COERCE
59 return PyBytes_FromStringAndSize(
IDP_String(prop), prop->
len);
62#ifdef USE_STRING_COERCE
65 return PyUnicode_FromStringAndSize(
IDP_String(prop), prop->
len - 1);
71 return PyLong_FromLong(
long(
IDP_Int(prop)));
76 return PyFloat_FromDouble(
double(
IDP_Float(prop)));
86 return PyBool_FromLong(
IDP_Bool(prop));
95 return (PyObject *)group;
106 array->owner_id = id;
108 return (PyObject *)
array;
113 PyObject *seq = PyList_New(prop->
len);
119 PyExc_RuntimeError,
"%s: IDP_IDPARRAY: PyList_New(%d) failed", __func__, prop->
len);
123 for (
i = 0;
i < prop->
len;
i++) {
132 PyList_SET_ITEM(seq,
i,
wrap);
152 return PyUnicode_FromFormat(
"<bpy id prop: owner=\"%s\", name=\"%s\", address=%p>",
153 self->owner_id ?
self->owner_id->name :
"<NONE>",
160 switch (prop->
type) {
188 switch (prop->
type) {
191 if (!PyUnicode_Check(value)) {
192 PyErr_SetString(PyExc_TypeError,
"expected a string!");
196# ifdef USE_STRING_COERCE
199 PyObject *value_coerce =
nullptr;
202 alloc_len = strlen(st) + 1;
204 st = PyUnicode_AsUTF8(value);
207 Py_XDECREF(value_coerce);
210 length_ssize_t st_len;
211 st = PyUnicode_AsUTF8AndSize(value, &st_len);
220 int ivalue = PyLong_AsSsize_t(value);
221 if (ivalue == -1 && PyErr_Occurred()) {
222 PyErr_SetString(PyExc_TypeError,
"expected an int type");
229 float fvalue = float(PyFloat_AsDouble(value));
230 if (fvalue == -1 && PyErr_Occurred()) {
231 PyErr_SetString(PyExc_TypeError,
"expected a float");
238 double dvalue = PyFloat_AsDouble(value);
239 if (dvalue == -1 && PyErr_Occurred()) {
240 PyErr_SetString(PyExc_TypeError,
"expected a float");
247 PyErr_SetString(PyExc_AttributeError,
"attempt to set read-only attribute!");
256 return PyUnicode_FromString(
self->prop->name);
264 if (!PyUnicode_Check(value)) {
265 PyErr_SetString(PyExc_TypeError,
"expected a string!");
269 name = PyUnicode_AsUTF8AndSize(value, &name_len);
272 PyErr_SetString(PyExc_TypeError,
"string length cannot exceed 63 characters!");
276 memcpy(
self->prop->name, name, name_len + 1);
283 return PyLong_FromLong(
self->prop->type);
291 "The name of this Group.",
293 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr},
299 PyErr_SetString(PyExc_TypeError,
"len() of unsized object");
303 return self->prop->len;
312 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
316 name = PyUnicode_AsUTF8(item);
318 if (name ==
nullptr) {
319 PyErr_SetString(PyExc_TypeError,
"only strings are allowed as keys of ID properties");
325 if (idprop ==
nullptr) {
326 PyErr_SetString(PyExc_KeyError,
"key not in subgroup dict");
337 PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
341 Py_ssize_t
i,
len = PySequence_Fast_GET_SIZE(seq_fast);
343 for (
i = 0;
i <
len;
i++) {
344 item = seq_fast_items[
i];
345 if (PyFloat_Check(item)) {
353 else if (PyBool_Check(item)) {
360 else if (PyLong_Check(item)) {
367 else if (PyMapping_Check(item)) {
384 const char *name =
nullptr;
387 name = PyUnicode_AsUTF8AndSize(name_obj, &name_len);
389 if (name ==
nullptr) {
390 PyErr_Format(PyExc_KeyError,
391 "invalid id-property key, expected a string, not a %.200s",
392 Py_TYPE(name_obj)->tp_name);
397 PyErr_SetString(PyExc_KeyError,
398 "the length of IDProperty names is limited to 63 characters");
436 const bool do_conversion,
437 const bool can_create)
440 const double value = PyFloat_AsDouble(ob);
446 else if (do_conversion) {
447 switch (prop_exist->
type) {
464 if (!prop && can_create) {
473 const bool do_conversion,
474 const bool can_create)
483 else if (do_conversion) {
484 switch (prop_exist->
type) {
486 IDP_Int(prop_exist) = int(value);
501 if (!prop && can_create) {
510 const bool do_conversion,
511 const bool can_create)
516 const int value = PyC_Long_AsI32(ob);
517 if (value == -1 && PyErr_Occurred()) {
523 else if (do_conversion) {
524 const int64_t value = PyC_Long_AsI64(ob);
525 if (value == -1 && PyErr_Occurred()) {
528 switch (prop_exist->
type) {
548 if (!prop && can_create) {
549 const int value = PyC_Long_AsI32(ob);
550 if (value == -1 && PyErr_Occurred()) {
562 const bool can_create)
565 Py_ssize_t value_len = 0;
566 const char *value =
nullptr;
568#ifdef USE_STRING_COERCE
569 PyObject *value_coerce =
nullptr;
572 value = PyUnicode_AsUTF8AndSize(ob, &value_len);
583 if (!prop && can_create) {
591#ifdef USE_STRING_COERCE
592 Py_XDECREF(value_coerce);
602 const bool can_create)
605 Py_ssize_t value_len = PyBytes_GET_SIZE(ob);
606 const char *value = PyBytes_AS_STRING(ob);
616 if (!prop && can_create) {
668 const Py_buffer &buffer,
671 const bool can_create)
679 memcpy(
IDP_Array(prop_exist), buffer.buf, buffer.len);
684 if (!prop && can_create) {
687 val.
array.
len = buffer.len / buffer.itemsize;
689 memcpy(
IDP_Array(prop), buffer.buf, buffer.len);
697 const bool do_conversion,
698 const bool can_create)
703 PyObject **ob_seq_fast_items;
707 ob_seq_fast_items = PySequence_Fast_ITEMS(ob);
713 PyErr_SetString(PyExc_TypeError,
714 "only floats, ints, booleans and dicts are allowed in ID property arrays");
719 PyErr_SetString(PyExc_RuntimeError,
"internal error with idp array.type");
724 val.
array.
len = PySequence_Fast_GET_SIZE(ob);
731 if (prop_exist && prop_exist->
len == val.
array.
len) {
743 item = ob_seq_fast_items[
i];
744 const double value = PyFloat_AsDouble(item);
745 if ((value == -1.0) && PyErr_Occurred()) {
749 static_cast<float *
>(prop_data)[
i] =
float(value);
752 static_cast<double *
>(prop_data)[
i] = value;
761 (prop_exist->
subtype ==
IDP_INT || (do_conversion && (to_float || to_double)))))
768 item = ob_seq_fast_items[
i];
769 if (to_float || to_double) {
770 const int64_t value = PyC_Long_AsI64(item);
771 if ((value == -1) && PyErr_Occurred()) {
775 static_cast<float *
>(prop_data)[
i] =
float(value);
778 static_cast<double *
>(prop_data)[
i] =
double(value);
782 const int value = PyC_Long_AsI32(item);
783 if ((value == -1) && PyErr_Occurred()) {
786 static_cast<int *
>(prop_data)[
i] = value;
801 item = ob_seq_fast_items[
i];
803 if ((value == -1) && PyErr_Occurred()) {
807 static_cast<int *
>(prop_data)[
i] = value;
810 static_cast<bool *
>(prop_data)[
i] =
bool(value);
822 if (prop || !can_create) {
830 prop_data =
static_cast<double *
>(
IDP_Array(prop));
832 item = ob_seq_fast_items[
i];
833 if (((prop_data[
i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) {
843 prop_data =
static_cast<int *
>(
IDP_Array(prop));
845 item = ob_seq_fast_items[
i];
846 if (((prop_data[
i] = PyC_Long_AsI32(item)) == -1) && PyErr_Occurred()) {
856 item = ob_seq_fast_items[
i];
866 bool *prop_data =
static_cast<bool *
>(
IDP_Array(prop));
868 item = ob_seq_fast_items[
i];
870 if ((value == -1) && PyErr_Occurred()) {
874 prop_data[
i] = (value != 0);
885 const bool do_conversion,
886 const bool can_create)
889 bool use_buffer =
false;
890 int idp_buffer_type = -1;
892 if (PyObject_CheckBuffer(ob)) {
893 if (PyObject_GetBuffer(ob, &buffer, PyBUF_ND | PyBUF_FORMAT) == -1) {
900 if (idp_buffer_type != -1) {
903 if (!can_create && (!prop_exist || (prop_exist->
type != idp_buffer_type) ||
904 (prop_exist->
len != buffer.len)))
906 PyBuffer_Release(&buffer);
913 PyBuffer_Release(&buffer);
920 prop_exist, name, buffer, idp_buffer_type, do_conversion, can_create);
921 PyBuffer_Release(&buffer);
925 PyObject *ob_seq_fast = PySequence_Fast(ob,
"py -> idprop");
926 if (ob_seq_fast !=
nullptr) {
928 prop_exist, name, ob_seq_fast, do_conversion, can_create);
929 Py_DECREF(ob_seq_fast);
946 PyObject *keys, *vals, *key, *pval;
949 keys = PyMapping_Keys(ob);
950 vals = PyMapping_Values(ob);
955 len = PyMapping_Length(ob);
956 for (
i = 0;
i <
len;
i++) {
957 key = PySequence_GetItem(keys,
i);
958 pval = PySequence_GetItem(vals,
i);
980 const bool can_create)
987 PyErr_SetString(PyExc_ValueError,
"Cannot assign an embedded ID pointer to an id-property");
998 if (!prop && can_create) {
1007 const bool do_conversion,
1008 const bool can_create)
1010 if (name ==
nullptr) {
1014 if (PyFloat_Check(ob)) {
1017 if (PyBool_Check(ob)) {
1018 return idp_from_PyBool(prop_exist, name, ob, do_conversion, can_create);
1020 if (PyLong_Check(ob)) {
1021 return idp_from_PyLong(prop_exist, name, ob, do_conversion, can_create);
1023 if (PyUnicode_Check(ob)) {
1026 if (PyBytes_Check(ob)) {
1029 if (PySequence_Check(ob)) {
1035 if (PyMapping_Check(ob)) {
1040 PyExc_TypeError,
"invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name);
1060 if (new_prop ==
nullptr) {
1078 if (prop != prop_exist) {
1079 PyErr_Format(PyExc_TypeError,
1080 "Cannot assign a '%.200s' value to the existing '%s' %s IDProperty",
1081 Py_TYPE(ob)->tp_name,
1092 if (new_prop ==
nullptr) {
1095 if (new_prop == prop_exist) {
1110 prop_exist->
ui_data =
nullptr;
1124 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
1128 if (val ==
nullptr) {
1130 const char *name = PyUnicode_AsUTF8(key);
1132 if (name ==
nullptr) {
1133 PyErr_Format(PyExc_KeyError,
"expected a string, not %.200s", Py_TYPE(key)->tp_name);
1143 PyErr_SetString(PyExc_KeyError,
"property not found in group");
1167 ret = PyObject_GetIter(iterable);
1168 Py_DECREF(iterable);
1178 switch (prop->
type) {
1192 PyObject *seq = PyList_New(prop->
len);
1197 PyExc_RuntimeError,
"%s: IDP_ARRAY: PyList_New(%d) failed", __func__, prop->
len);
1204 for (
i = 0;
i < prop->
len;
i++) {
1205 PyList_SET_ITEM(seq,
i, PyFloat_FromDouble(
array[
i]));
1211 for (
i = 0;
i < prop->
len;
i++) {
1212 PyList_SET_ITEM(seq,
i, PyFloat_FromDouble(
array[
i]));
1218 for (
i = 0;
i < prop->
len;
i++) {
1219 PyList_SET_ITEM(seq,
i, PyLong_FromLong(
array[
i]));
1225 for (
i = 0;
i < prop->
len;
i++) {
1226 PyList_SET_ITEM(seq,
i, PyBool_FromLong(
array[
i]));
1232 PyExc_RuntimeError,
"%s: invalid/corrupt array type '%d'!", __func__, prop->
subtype);
1240 PyObject *seq = PyList_New(prop->
len);
1246 PyExc_RuntimeError,
"%s: IDP_IDPARRAY: PyList_New(%d) failed", __func__, prop->
len);
1250 for (
i = 0;
i < prop->
len;
i++) {
1259 PyList_SET_ITEM(seq,
i,
wrap);
1264 PyObject *dict = _PyDict_NewPresized(prop->
len);
1276 PyDict_SetItemString(dict, loop->
name,
wrap);
1283 PyErr_Format(PyExc_RuntimeError,
1284 "%s ERROR: '%s' property exists with a bad type code '%d'!",
1299 if (
self->group ==
nullptr) {
1300 return PyUnicode_FromFormat(
"<%s>", Py_TYPE(
self)->tp_name);
1302 return PyUnicode_FromFormat(
"<%s \"%s\">", Py_TYPE(
self)->tp_name,
self->group->prop->name);
1307 if (
self->group !=
nullptr) {
1308 PyObject_GC_UnTrack(
self);
1310 Py_CLEAR(
self->group);
1311 PyObject_GC_Del(
self);
1316 Py_VISIT(
self->group);
1322 Py_CLEAR(
self->group);
1328 return (
self->group !=
nullptr);
1333 if (
self->len_init ==
self->group->prop->len) {
1336 PyErr_SetString(PyExc_RuntimeError,
"IDPropertyGroup changed size during iteration");
1342 if (
self->cur !=
nullptr) {
1349 return PyUnicode_FromString(cur->
name);
1351 PyErr_SetNone(PyExc_StopIteration);
1357 if (
self->cur !=
nullptr) {
1366 PyErr_SetNone(PyExc_StopIteration);
1372 if (
self->cur !=
nullptr) {
1379 PyObject *
ret = PyTuple_New(2);
1381 PyUnicode_FromString(cur->
name),
1385 PyErr_SetNone(PyExc_StopIteration);
1396#define SHARED_MEMBER_SET(member, value) \
1398 k_ty->member = v_ty->member = i_ty->member = value; \
1407 k_ty->tp_name =
"IDPropertyGroupIterKeys";
1408 v_ty->tp_name =
"IDPropertyGroupIterValues";
1409 i_ty->tp_name =
"IDPropertyGroupIterItems";
1425#undef SHARED_MEMBER_SET
1429 const bool reversed,
1435 iter->
group = group;
1436 if (group !=
nullptr) {
1438 BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
1439 PyObject_GC_Track(iter);
1442 iter->len_init = group->
prop->
len;
1445 iter->
cur =
nullptr;
1448 return (PyObject *)iter;
1484 if (
self->group ==
nullptr) {
1485 return PyUnicode_FromFormat(
"<%s>", Py_TYPE(
self)->tp_name);
1487 return PyUnicode_FromFormat(
"<%s \"%s\">", Py_TYPE(
self)->tp_name,
self->group->prop->name);
1492 if (
self->group !=
nullptr) {
1493 PyObject_GC_UnTrack(
self);
1495 Py_CLEAR(
self->group);
1496 PyObject_GC_Del(
self);
1501 Py_VISIT(
self->group);
1507 Py_CLEAR(
self->group);
1513 return (
self->group !=
nullptr);
1535 if (
self->group ==
nullptr) {
1538 return self->group->prop->len;
1543 if (
self->group ==
nullptr) {
1551 if (
self->group ==
nullptr) {
1555 PyObject *list = PySequence_List((PyObject *)
self);
1556 const int result = PySequence_Contains(list, value);
1563 if (
self->group ==
nullptr) {
1567 PyObject *list = PySequence_List((PyObject *)
self);
1568 const int result = PySequence_Contains(list, value);
1610 BPy_IDGroup_View_reversed_doc,
1611 "Return a reverse iterator over the ID Property keys values or items.");
1617 return (PyObject *)
result;
1624 BPy_IDGroup_View_reversed_doc},
1640 k_ty->tp_name =
"IDPropertyGroupViewKeys";
1641 v_ty->tp_name =
"IDPropertyGroupViewValues";
1642 i_ty->tp_name =
"IDPropertyGroupViewItems";
1653#define SHARED_MEMBER_SET(member, value) \
1655 k_ty->member = v_ty->member = i_ty->member = value; \
1668#undef SHARED_MEMBER_SET
1679 BPy_IDGroup_pop_doc,
1680 ".. method:: pop(key, default)\n"
1682 " Remove an item from the group, returning a Python representation.\n"
1684 " :raises KeyError: When the item doesn't exist.\n"
1686 " :arg key: Name of item to remove.\n"
1688 " :arg default: Value to return when key isn't found, otherwise raise an exception.\n"
1689 " :type default: Any\n");
1696 PyObject *def =
nullptr;
1698 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
1703 if (idprop ==
nullptr) {
1704 if (def ==
nullptr) {
1705 PyErr_SetString(PyExc_KeyError,
"item not in group");
1708 return Py_NewRef(def);
1712 if (pyform ==
nullptr) {
1727 printf(
"%s: ID Property Error found and corrected!\n", func);
1730 for (j =
len; j < prop->
len; j++) {
1731 PyList_SET_ITEM(seq, j, Py_NewRef(Py_None));
1740 PyObject *list = PyList_New(prop->
len);
1745 loop = loop->
next,
i++)
1747 PyList_SET_ITEM(list,
i, PyUnicode_FromString(loop->
name));
1751 for (; loop; loop = loop->
next,
i++) {
1755 if (
i != prop->
len) {
1767 PyObject *list = PyList_New(prop->
len);
1772 loop = loop->
next,
i++)
1777 if (
i != prop->
len) {
1789 PyObject *seq = PyList_New(prop->
len);
1794 loop = loop->
next,
i++)
1796 PyObject *item = PyTuple_New(2);
1799 PyList_SET_ITEM(seq,
i, item);
1802 if (
i != prop->
len) {
1838 BPy_IDGroup_keys_doc,
1839 ".. method:: keys()\n"
1841 " Return the keys associated with this group as a list of strings.\n");
1849 BPy_IDGroup_values_doc,
1850 ".. method:: values()\n"
1852 " Return the values associated with this group.\n");
1860 BPy_IDGroup_items_doc,
1861 ".. method:: items()\n"
1863 " Iterate through the items in the dict; behaves like dictionary method items.\n");
1871 const char *name = PyUnicode_AsUTF8(value);
1874 PyErr_Format(PyExc_TypeError,
"expected a string, not a %.200s", Py_TYPE(value)->tp_name);
1883 BPy_IDGroup_update_doc,
1884 ".. method:: update(other)\n"
1886 " Update key, values.\n"
1888 " :arg other: Updates the values in the group with this.\n"
1890 " :type other: :class:`IDPropertyGroup` | dict[str, Any]\n");
1893 PyObject *pkey, *pval;
1905 else if (PyDict_Check(value)) {
1906 while (PyDict_Next(value, &
i, &pkey, &pval)) {
1908 if (PyErr_Occurred()) {
1914 PyErr_Format(PyExc_TypeError,
1915 "expected a dict or an IDPropertyGroup type, not a %.200s",
1916 Py_TYPE(value)->tp_name);
1925 BPy_IDGroup_to_dict_doc,
1926 ".. method:: to_dict()\n"
1928 " Return a purely Python version of the group.\n");
1936 BPy_IDGroup_clear_doc,
1937 ".. method:: clear()\n"
1939 " Clear all members from this group.\n");
1948 BPy_IDGroup_get_doc,
1949 ".. method:: get(key, default=None)\n"
1951 " Return the value for key, if it exists, else default.\n");
1956 PyObject *def = Py_None;
1958 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
1976# pragma clang diagnostic push
1977# pragma clang diagnostic ignored "-Wcast-function-type"
1979# pragma GCC diagnostic push
1980# pragma GCC diagnostic ignored "-Wcast-function-type"
1985 {
"pop", (PyCFunction)
BPy_IDGroup_pop, METH_VARARGS, BPy_IDGroup_pop_doc},
1986 {
"keys", (PyCFunction)
BPy_IDGroup_keys, METH_NOARGS, BPy_IDGroup_keys_doc},
1990 {
"get", (PyCFunction)
BPy_IDGroup_get, METH_VARARGS, BPy_IDGroup_get_doc},
1993 {
nullptr,
nullptr, 0,
nullptr},
1998# pragma clang diagnostic pop
2000# pragma GCC diagnostic pop
2031 PyVarObject_HEAD_INIT(
nullptr, 0)
2091 switch (
self->prop->subtype) {
2093 *elem_size =
sizeof(float);
2094 return &PyFloat_Type;
2096 *elem_size =
sizeof(double);
2097 return &PyFloat_Type;
2099 *elem_size =
sizeof(int8_t);
2100 return &PyBool_Type;
2102 *elem_size =
sizeof(int);
2103 return &PyLong_Type;
2112 return PyUnicode_FromFormat(
"<bpy id property array [%d]>",
self->prop->len);
2117 BPy_IDArray_get_typecode_doc,
2118 "The type of the data in the array {'f': float, 'd': double, 'i': int, 'b': bool}.");
2121 const char *typecode;
2122 switch (
self->prop->subtype) {
2136 PyErr_Format(PyExc_RuntimeError,
2137 "%s: invalid/corrupt array type '%d'!",
2139 self->prop->subtype);
2144 return PyUnicode_FromString(typecode);
2152 BPy_IDArray_get_typecode_doc,
2154 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr},
2159 BPy_IDArray_to_list_doc,
2160 ".. method:: to_list()\n"
2162 " Return the array as a list.\n");
2170# pragma clang diagnostic push
2171# pragma clang diagnostic ignored "-Wcast-function-type"
2173# pragma GCC diagnostic push
2174# pragma GCC diagnostic ignored "-Wcast-function-type"
2180 {
nullptr,
nullptr, 0,
nullptr},
2185# pragma clang diagnostic pop
2187# pragma GCC diagnostic pop
2193 return self->prop->len;
2198 if (index < 0 || index >=
self->prop->len) {
2199 PyErr_SetString(PyExc_IndexError,
"index out of range!");
2203 switch (
self->prop->subtype) {
2205 return PyFloat_FromDouble(((
float *)
IDP_Array(
self->prop))[index]);
2207 return PyFloat_FromDouble(((
double *)
IDP_Array(
self->prop))[index]);
2209 return PyLong_FromLong(
long(((
int *)
IDP_Array(
self->prop))[index]));
2211 return PyBool_FromLong(
long(((int8_t *)
IDP_Array(
self->prop))[index]));
2215 PyExc_RuntimeError,
"%s: invalid/corrupt array type '%d'!", __func__,
self->prop->subtype);
2222 if (index < 0 || index >=
self->prop->len) {
2223 PyErr_SetString(PyExc_RuntimeError,
"index out of range!");
2227 switch (
self->prop->subtype) {
2229 const float f = float(PyFloat_AsDouble(value));
2230 if (f == -1 && PyErr_Occurred()) {
2237 const double d = PyFloat_AsDouble(value);
2238 if (d == -1 && PyErr_Occurred()) {
2245 const int i = PyC_Long_AsI32(value);
2246 if (
i == -1 && PyErr_Occurred()) {
2255 if (
i == -1 && PyErr_Occurred()) {
2288 end = prop->
len + end + 1;
2293 tuple = PyTuple_New(end -
begin);
2343 alloc_len =
size * elem_size;
2348 if (
PyC_AsArray(vec, elem_size, seq,
size, py_type,
"slice assignment: ") == -1) {
2353 memcpy((
void *)(((
char *)
IDP_Array(prop)) + (
begin * elem_size)), vec, alloc_len);
2361 if (PyIndex_Check(item)) {
2363 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2364 if (
i == -1 && PyErr_Occurred()) {
2368 i +=
self->prop->len;
2372 if (PySlice_Check(item)) {
2373 Py_ssize_t start,
stop,
step, slicelength;
2375 if (PySlice_GetIndicesEx(item,
self->prop->len, &start, &
stop, &
step, &slicelength) < 0) {
2379 if (slicelength <= 0) {
2380 return PyTuple_New(0);
2386 PyErr_SetString(PyExc_TypeError,
"slice steps not supported with vectors");
2390 PyErr_Format(PyExc_TypeError,
2391 "vector indices must be integers, not %.200s",
2393 Py_TYPE(item)->tp_name);
2399 if (PyIndex_Check(item)) {
2400 Py_ssize_t
i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2401 if (
i == -1 && PyErr_Occurred()) {
2405 i +=
self->prop->len;
2409 if (PySlice_Check(item)) {
2410 Py_ssize_t start,
stop,
step, slicelength;
2412 if (PySlice_GetIndicesEx(item,
self->prop->len, &start, &
stop, &
step, &slicelength) < 0) {
2420 PyErr_SetString(PyExc_TypeError,
"slice steps not supported with vectors");
2425 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
2441 return sizeof(float);
2444 return sizeof(double);
2447 return sizeof(bool);
2456 const int length = itemsize * prop->
len;
2462 view->itemsize = itemsize;
2466 shape[0] = prop->
len;
2467 view->shape = shape;
2489 PyVarObject_HEAD_INIT(
nullptr, 0)
2576 iter->
group = group;
2577 if (group !=
nullptr) {
2579 BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
2580 PyObject_GC_Track(iter);
2620 PyObject *submodule;
2650 {
nullptr,
nullptr, 0,
nullptr},
2656 "This module provides access id property types (currently mainly for docs).");
2672 PyObject *submodule;
2673 PyObject *sys_modules = PyImport_GetModuleDict();
2679 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
IDPropertyUIData * IDP_TryConvertUIData(IDPropertyUIData *src, eIDPropertyUIDataType src_type, eIDPropertyUIDataType dst_type)
#define IDP_IDPArray(prop)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_FreeFromGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
eIDPropertyUIDataType IDP_ui_data_type(const IDProperty *prop)
void IDP_AssignStringMaxSize(IDProperty *prop, const char *st, size_t st_maxncpy) ATTR_NONNULL()
const char * IDP_type_str(eIDPropertyType type, short sub_type)
void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist, int flag)
void IDP_FreeProperty(IDProperty *prop)
IDProperty * IDP_New(char type, const IDPropertyTemplate *val, blender::StringRef name, eIDPropertyFlag flags={}) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_ClearProperty(IDProperty *prop)
void IDP_AppendArray(IDProperty *prop, IDProperty *item)
void IDP_AssignID(IDProperty *prop, ID *id, int flag)
void IDP_ResizeArray(IDProperty *prop, int newlen)
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, bool do_overwrite) ATTR_NONNULL()
IDProperty * IDP_NewIDPArray(blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BLI_assert_unreachable()
ID and Library types, which are fundamental for SDNA.
@ IDP_FLAG_OVERRIDABLE_LIBRARY
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
PyObject * BPy_Wrap_GetKeys(IDProperty *prop)
static PyObject * BPy_IDGroup_clear(BPy_IDProperty *self)
static IDProperty * idp_from_PyLong(IDProperty *prop_exist, const char *name, PyObject *ob, const bool do_conversion, const bool can_create)
static PyMethodDef IDProp_methods[]
static int BPy_Group_ViewItems_Contains(BPy_IDGroup_View *self, PyObject *value)
static PyObject * idprop_py_from_idp_double(const IDProperty *prop)
static PyObject * idprop_py_from_idp_idparray(ID *id, IDProperty *prop)
static PyObject * BPyInit_idprop_types()
static PySequenceMethods BPy_IDGroup_ViewItems_as_sequence
PyTypeObject BPy_IDGroup_ViewItems_Type
static IDProperty * idp_from_PySequence_Buffer(IDProperty *prop_exist, const char *name, const Py_buffer &buffer, const int idp_type, const bool, const bool can_create)
static PyObject * BPy_Group_ViewItems_iter(BPy_IDGroup_View *self)
static PyGetSetDef BPy_IDGroup_getseters[]
PyDoc_STRVAR(BPy_IDGroup_View_reversed_doc, "Return a reverse iterator over the ID Property keys values or items.")
PyTypeObject BPy_IDGroup_ViewValues_Type
static PyObject * BPy_IDGroup_IterItems_CreatePyObject(BPy_IDProperty *group, const bool reversed)
static int BPy_Group_ViewKeys_Contains(BPy_IDGroup_View *self, PyObject *value)
PyObject * BPyInit_idprop()
static PyObject * BPy_IDGroup_IterValues_CreatePyObject(BPy_IDProperty *group, const bool reversed)
PyTypeObject BPy_IDGroup_ViewKeys_Type
bool pyrna_id_CheckPyObject(PyObject *obj)
static PyObject * BPy_IDGroup_keys(BPy_IDProperty *self)
static PyObject * BPy_IDGroup_IterKeys_CreatePyObject(BPy_IDProperty *group, const bool reversed)
static PyObject * BPy_IDGroup_GetName(BPy_IDProperty *self, void *)
static PyMethodDef BPy_IDGroup_View_methods[]
static PyObject * BPy_Group_ViewValues_iter(BPy_IDGroup_View *self)
PyObject * BPy_Wrap_GetKeys_View_WithID(ID *id, IDProperty *prop)
static PyGetSetDef BPy_IDArray_getseters[]
static PyObject * BPy_IDGroup_to_dict(BPy_IDProperty *self)
PyObject * BPy_Wrap_GetItems(ID *id, IDProperty *prop)
int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val)
static PyObject * idprop_py_from_idp_array(ID *id, IDProperty *prop)
bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, IDProperty *group, PyObject *ob)
static IDProperty * idp_from_PyBool(IDProperty *prop_exist, const char *name, PyObject *ob, const bool do_conversion, const bool can_create)
static void BPy_IDGroup_Iter_dealloc(BPy_IDGroup_Iter *self)
static void BPy_IDArray_releasebuffer(BPy_IDArray *, Py_buffer *view)
static int BPy_IDGroup_View_traverse(BPy_IDGroup_View *self, visitproc visit, void *arg)
static PyMethodDef BPy_IDArray_methods[]
static IDProperty * idp_from_PyMapping(IDProperty *, const char *name, PyObject *ob, const bool, const bool)
static PyObject * BPy_IDGroup_pop(BPy_IDProperty *self, PyObject *args)
static Py_ssize_t BPy_Group_View_len(BPy_IDGroup_View *self)
static IDProperty * idp_from_PyUnicode(IDProperty *prop_exist, const char *name, PyObject *ob, const bool, const bool can_create)
static PyObject * BPy_IDArray_repr(BPy_IDArray *self)
static int BPy_IDArray_SetItem(BPy_IDArray *self, Py_ssize_t index, PyObject *value)
static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject *value)
static const char * idp_format_from_array_type(int type)
static IDProperty * idp_from_PyObject(IDProperty *prop_exist, const char *name, PyObject *ob, const bool do_conversion, const bool can_create)
static BPy_IDGroup_View * IDGroup_View_New_WithType(BPy_IDProperty *group, PyTypeObject *type)
PyTypeObject BPy_IDGroup_IterKeys_Type
static PyObject * BPy_Group_IterKeys_next(BPy_IDGroup_Iter *self)
static PyObject * BPy_IDArray_GetItem(BPy_IDArray *self, Py_ssize_t index)
PyObject * BPy_Wrap_GetValues(ID *id, IDProperty *prop)
static PyObject * BPy_IDGroup_Iter_repr(BPy_IDGroup_Iter *self)
static void IDGroup_Iter_init_type()
PyObject * BPy_Wrap_GetItems_View_WithID(ID *id, IDProperty *prop)
static int itemsize_by_idarray_type(int array_type)
static IDProperty * idp_from_PySequence_Fast(IDProperty *prop_exist, const char *name, PyObject *ob, const bool do_conversion, const bool can_create)
static PyObject * BPy_Group_IterValues_next(BPy_IDGroup_Iter *self)
static int BPy_IDGroup_View_is_gc(BPy_IDGroup_View *self)
static PyObject * BPy_IDGroup_update(BPy_IDProperty *self, PyObject *value)
static PyObject * BPy_IDArray_to_list(BPy_IDArray *self)
static PySequenceMethods BPy_IDGroup_ViewValues_as_sequence
static PyObject * BPy_IDGroup_get(BPy_IDProperty *self, PyObject *args)
static const char * idp_try_read_name(PyObject *name_obj)
PyTypeObject BPy_IDGroup_Type
PyTypeObject BPy_IDArray_Type
static int BPy_IDGroup_Iter_clear(BPy_IDGroup_Iter *self)
PyObject * pyrna_id_CreatePyObject(ID *id)
static PyObject * BPy_Group_IterItems_next(BPy_IDGroup_Iter *self)
PyObject * BPy_IDGroup_MapDataToPy(IDProperty *prop)
static PySequenceMethods BPy_IDGroup_Seq
static int BPy_IDGroup_Contains(BPy_IDProperty *self, PyObject *value)
static PyObject * idprop_py_from_idp_int(const IDProperty *prop)
PyTypeObject BPy_IDGroup_IterValues_Type
static PyObject * idprop_py_from_idp_bool(const IDProperty *prop)
static int BPy_Group_ViewValues_Contains(BPy_IDGroup_View *self, PyObject *value)
static IDProperty * idp_from_PySequence(IDProperty *prop_exist, const char *name, PyObject *ob, const bool do_conversion, const bool can_create)
static PyModuleDef IDProp_types_module_def
static PyBufferProcs BPy_IDArray_Buffer
static bool BPy_Group_Iter_same_size_or_raise_error(BPy_IDGroup_Iter *self)
static IDProperty * idp_from_PyFloat(IDProperty *prop_exist, const char *name, PyObject *ob, const bool do_conversion, const bool can_create)
static void BPy_IDGroup_View_dealloc(BPy_IDGroup_View *self)
static void BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len, const char *func)
static PySequenceMethods BPy_IDArray_Seq
static PyObject * IDGroup_Iter_New_WithType(BPy_IDProperty *group, const bool reversed, PyTypeObject *type)
static PyObject * BPy_IDGroup_ViewKeys_CreatePyObject(BPy_IDProperty *group)
static PyObject * BPy_IDArray_slice(BPy_IDArray *self, int begin, int end)
static void IDGroup_View_init_type()
static PyObject * BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item)
static PyMappingMethods BPy_IDArray_AsMapping
static PyObject * BPy_IDArray_get_typecode(BPy_IDArray *self, void *)
static int BPy_IDGroup_SetName(BPy_IDProperty *self, PyObject *value, void *)
static PyObject * BPy_IDGroup_repr(BPy_IDProperty *self)
static PyObject * BPy_IDGroup_ViewItems_CreatePyObject(BPy_IDProperty *group)
static PyModuleDef IDProp_module_def
static PyObject * idprop_py_from_idp_float(const IDProperty *prop)
static int BPy_IDGroup_Iter_is_gc(BPy_IDGroup_Iter *self)
static PySequenceMethods BPy_IDGroup_ViewKeys_as_sequence
static Py_ssize_t BPy_IDGroup_Map_Len(BPy_IDProperty *self)
static PyTypeObject * idp_array_py_type(BPy_IDArray *self, size_t *elem_size)
static PyObject * BPy_IDGroup_View_repr(BPy_IDGroup_View *self)
static char idp_sequence_type(PyObject *seq_fast)
static PyMethodDef BPy_IDGroup_methods[]
static int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject *val)
static int BPy_IDGroup_View_clear(BPy_IDGroup_View *self)
static PyObject * idprop_py_from_idp_id(IDProperty *prop)
static PyObject * BPy_IDGroup_items(BPy_IDProperty *self)
static int BPy_IDArray_ass_slice(BPy_IDArray *self, int begin, int end, PyObject *seq)
static PyObject * BPy_IDGroup_values(BPy_IDProperty *self)
PyObject * BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent)
static PyObject * BPy_Group_ViewKeys_iter(BPy_IDGroup_View *self)
bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
static IDProperty * idp_from_PyBytes(IDProperty *prop_exist, const char *name, PyObject *ob, const bool, const bool can_create)
static int BPy_IDArray_getbuffer(BPy_IDArray *self, Py_buffer *view, int flags)
PyTypeObject BPy_IDGroup_IterItems_Type
static PyObject * BPy_IDGroup_View_reversed(BPy_IDGroup_View *self, PyObject *)
static PyObject * BPy_IDArray_subscript(BPy_IDArray *self, PyObject *item)
static PyObject * BPy_IDGroup_ViewValues_CreatePyObject(BPy_IDProperty *group)
static Py_hash_t BPy_IDGroup_hash(BPy_IDProperty *self)
static PyObject * idprop_py_from_idp_string(const IDProperty *prop)
static Py_ssize_t BPy_IDArray_Len(BPy_IDArray *self)
static int idp_array_type_from_formatstr_and_size(const char *typestr, Py_ssize_t itemsize)
static int BPy_IDGroup_Iter_traverse(BPy_IDGroup_Iter *self, visitproc visit, void *arg)
static PyObject * BPy_IDGroup_iter(BPy_IDProperty *self)
#define SHARED_MEMBER_SET(member, value)
static PyObject * idprop_py_from_idp_group(ID *id, IDProperty *prop, IDProperty *parent)
PyObject * BPy_Wrap_GetValues_View_WithID(ID *id, IDProperty *prop)
static PyMappingMethods BPy_IDGroup_Mapping
static IDProperty * idp_from_DatablockPointer(IDProperty *prop_exist, const char *name, PyObject *ob, const bool, const bool can_create)
#define BPy_IDGroup_Check(v)
void IDPropertyUIData_Init_Types()
void * MEM_mallocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
std::unique_ptr< IDProperty, IDPropertyDeleter > create_bool(StringRef prop_name, bool value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_BOOLEAN, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRef prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRef prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
float wrap(float value, float max, float min)
const char * PyC_UnicodeAsBytesAndSize(PyObject *py_str, Py_ssize_t *r_size, PyObject **r_coerce)
char PyC_StructFmt_type_from_str(const char *typestr)
PyObject * PyC_UnicodeFromBytesAndSize(const char *str, Py_ssize_t size)
bool PyC_StructFmt_type_is_int_any(char format)
int PyC_Long_AsBool(PyObject *value)
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
bool PyC_StructFmt_type_is_float_any(char format)
const char * PyC_UnicodeAsBytes(PyObject *py_str, PyObject **r_coerce)
header-only compatibility defines.
#define PyTuple_SET_ITEMS(op_arg,...)
PyObject_VAR_HEAD BPy_IDProperty * group
PyObject_VAR_HEAD BPy_IDProperty * group
PyObject_VAR_HEAD struct ID * owner_id
struct IDProperty * parent
IDPropertyUIData * ui_data
struct IDPropertyTemplate::@347174163205254236177334334344125337263066142041 string
struct IDPropertyTemplate::@057340115353163137130262213324257034202360355133 array