24#define USE_STRING_COERCE
26#ifdef USE_STRING_COERCE
57 return PyBytes_FromStringAndSize(
IDP_String(prop), prop->
len);
60#ifdef USE_STRING_COERCE
63 return PyUnicode_FromStringAndSize(
IDP_String(prop), prop->
len - 1);
69 return PyLong_FromLong(
long(
IDP_Int(prop)));
74 return PyFloat_FromDouble(
double(
IDP_Float(prop)));
84 return PyBool_FromLong(
IDP_Bool(prop));
92 group->parent = parent;
93 return (PyObject *)group;
104 array->owner_id = id;
106 return (PyObject *)
array;
111 PyObject *seq = PyList_New(prop->
len);
117 PyExc_RuntimeError,
"%s: IDP_IDPARRAY: PyList_New(%d) failed", __func__, prop->
len);
121 for (i = 0; i < prop->
len; i++) {
130 PyList_SET_ITEM(seq, i,
wrap);
145 return _Py_HashPointer(
self->prop);
150 return PyUnicode_FromFormat(
"<bpy id prop: owner=\"%s\", name=\"%s\", address=%p>",
151 self->owner_id ?
self->owner_id->name :
"<NONE>",
158 switch (prop->
type) {
186 switch (prop->
type) {
189 if (!PyUnicode_Check(value)) {
190 PyErr_SetString(PyExc_TypeError,
"expected a string!");
194# ifdef USE_STRING_COERCE
197 PyObject *value_coerce =
nullptr;
200 alloc_len = strlen(st) + 1;
202 st = PyUnicode_AsUTF8(value);
205 Py_XDECREF(value_coerce);
208 length_ssize_t st_len;
209 st = PyUnicode_AsUTF8AndSize(value, &st_len);
218 int ivalue = PyLong_AsSsize_t(value);
219 if (ivalue == -1 && PyErr_Occurred()) {
220 PyErr_SetString(PyExc_TypeError,
"expected an int type");
227 float fvalue =
float(PyFloat_AsDouble(value));
228 if (fvalue == -1 && PyErr_Occurred()) {
229 PyErr_SetString(PyExc_TypeError,
"expected a float");
236 double dvalue = PyFloat_AsDouble(value);
237 if (dvalue == -1 && PyErr_Occurred()) {
238 PyErr_SetString(PyExc_TypeError,
"expected a float");
245 PyErr_SetString(PyExc_AttributeError,
"attempt to set read-only attribute!");
254 return PyUnicode_FromString(
self->prop->name);
262 if (!PyUnicode_Check(value)) {
263 PyErr_SetString(PyExc_TypeError,
"expected a string!");
267 name = PyUnicode_AsUTF8AndSize(value, &name_len);
270 PyErr_SetString(PyExc_TypeError,
"string length cannot exceed 63 characters!");
274 memcpy(
self->prop->name, name, name_len + 1);
281 return PyLong_FromLong(
self->prop->type);
289 "The name of this Group.",
291 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr},
297 PyErr_SetString(PyExc_TypeError,
"len() of unsized object");
301 return self->prop->len;
310 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
314 name = PyUnicode_AsUTF8(item);
316 if (name ==
nullptr) {
317 PyErr_SetString(PyExc_TypeError,
"only strings are allowed as keys of ID properties");
323 if (idprop ==
nullptr) {
324 PyErr_SetString(PyExc_KeyError,
"key not in subgroup dict");
335 PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
339 Py_ssize_t i,
len = PySequence_Fast_GET_SIZE(seq_fast);
341 for (i = 0; i <
len; i++) {
342 item = seq_fast_items[i];
343 if (PyFloat_Check(item)) {
351 else if (PyBool_Check(item)) {
358 else if (PyLong_Check(item)) {
365 else if (PyMapping_Check(item)) {
382 const char *name =
nullptr;
385 name = PyUnicode_AsUTF8AndSize(name_obj, &name_len);
387 if (name ==
nullptr) {
388 PyErr_Format(PyExc_KeyError,
389 "invalid id-property key, expected a string, not a %.200s",
390 Py_TYPE(name_obj)->tp_name);
395 PyErr_SetString(PyExc_KeyError,
396 "the length of IDProperty names is limited to 63 characters");
434 const bool do_conversion,
435 const bool can_create)
438 const double value = PyFloat_AsDouble(ob);
444 else if (do_conversion) {
445 switch (prop_exist->
type) {
462 if (!prop && can_create) {
471 const bool do_conversion,
472 const bool can_create)
481 else if (do_conversion) {
482 switch (prop_exist->
type) {
499 if (!prop && can_create) {
508 const bool do_conversion,
509 const bool can_create)
514 const int value = PyC_Long_AsI32(ob);
515 if (value == -1 && PyErr_Occurred()) {
521 else if (do_conversion) {
522 const int64_t value = PyC_Long_AsI64(ob);
523 if (value == -1 && PyErr_Occurred()) {
526 switch (prop_exist->
type) {
546 if (!prop && can_create) {
547 const int value = PyC_Long_AsI32(ob);
548 if (value == -1 && PyErr_Occurred()) {
560 const bool can_create)
563 Py_ssize_t value_len = 0;
564 const char *value =
nullptr;
566#ifdef USE_STRING_COERCE
567 PyObject *value_coerce =
nullptr;
570 value = PyUnicode_AsUTF8AndSize(ob, &value_len);
581 if (!prop && can_create) {
589#ifdef USE_STRING_COERCE
590 Py_XDECREF(value_coerce);
600 const bool can_create)
603 Py_ssize_t value_len = PyBytes_GET_SIZE(ob);
604 const char *value = PyBytes_AS_STRING(ob);
614 if (!prop && can_create) {
669 const bool can_create)
677 memcpy(
IDP_Array(prop_exist), buffer.buf, buffer.len);
682 if (!prop && can_create) {
685 val.
array.
len = buffer.len / buffer.itemsize;
687 memcpy(
IDP_Array(prop), buffer.buf, buffer.len);
695 const bool do_conversion,
696 const bool can_create)
701 PyObject **ob_seq_fast_items;
705 ob_seq_fast_items = PySequence_Fast_ITEMS(ob);
711 PyErr_SetString(PyExc_TypeError,
712 "only floats, ints, booleans and dicts are allowed in ID property arrays");
717 PyErr_SetString(PyExc_RuntimeError,
"internal error with idp array.type");
722 val.
array.
len = PySequence_Fast_GET_SIZE(ob);
729 if (prop_exist && prop_exist->
len == val.
array.
len) {
740 for (i = 0; i < val.
array.
len; i++) {
741 item = ob_seq_fast_items[i];
742 const double value = PyFloat_AsDouble(item);
743 if ((value == -1.0) && PyErr_Occurred()) {
747 static_cast<float *
>(prop_data)[i] =
float(value);
750 static_cast<double *
>(prop_data)[i] = value;
759 (prop_exist->
subtype ==
IDP_INT || (do_conversion && (to_float || to_double)))))
765 for (i = 0; i < val.
array.
len; i++) {
766 item = ob_seq_fast_items[i];
767 if (to_float || to_double) {
768 const int64_t value = PyC_Long_AsI64(item);
769 if ((value == -1) && PyErr_Occurred()) {
773 static_cast<float *
>(prop_data)[i] =
float(value);
776 static_cast<double *
>(prop_data)[i] =
double(value);
780 const int value = PyC_Long_AsI32(item);
781 if ((value == -1) && PyErr_Occurred()) {
784 static_cast<int *
>(prop_data)[i] = value;
798 for (i = 0; i < val.
array.
len; i++) {
799 item = ob_seq_fast_items[i];
801 if ((value == -1) && PyErr_Occurred()) {
805 static_cast<int *
>(prop_data)[i] = value;
808 static_cast<bool *
>(prop_data)[i] =
bool(value);
820 if (prop || !can_create) {
828 prop_data =
static_cast<double *
>(
IDP_Array(prop));
829 for (i = 0; i < val.
array.
len; i++) {
830 item = ob_seq_fast_items[i];
831 if (((prop_data[i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) {
841 prop_data =
static_cast<int *
>(
IDP_Array(prop));
842 for (i = 0; i < val.
array.
len; i++) {
843 item = ob_seq_fast_items[i];
844 if (((prop_data[i] = PyC_Long_AsI32(item)) == -1) && PyErr_Occurred()) {
853 for (i = 0; i < val.
array.
len; i++) {
854 item = ob_seq_fast_items[i];
864 bool *prop_data =
static_cast<bool *
>(
IDP_Array(prop));
865 for (i = 0; i < val.
array.
len; i++) {
866 item = ob_seq_fast_items[i];
868 if ((value == -1) && PyErr_Occurred()) {
872 prop_data[i] = (value != 0);
883 const bool do_conversion,
884 const bool can_create)
887 bool use_buffer =
false;
888 int idp_buffer_type = -1;
890 if (PyObject_CheckBuffer(ob)) {
891 if (PyObject_GetBuffer(ob, &buffer, PyBUF_ND | PyBUF_FORMAT) == -1) {
898 if (idp_buffer_type != -1) {
901 if (!can_create && (!prop_exist || (prop_exist->
type != idp_buffer_type) ||
902 (prop_exist->
len != buffer.len)))
904 PyBuffer_Release(&buffer);
911 PyBuffer_Release(&buffer);
918 prop_exist, name, buffer, idp_buffer_type, do_conversion, can_create);
919 PyBuffer_Release(&buffer);
923 PyObject *ob_seq_fast = PySequence_Fast(ob,
"py -> idprop");
924 if (ob_seq_fast !=
nullptr) {
926 prop_exist, name, ob_seq_fast, do_conversion, can_create);
927 Py_DECREF(ob_seq_fast);
944 PyObject *keys, *vals, *key, *pval;
947 keys = PyMapping_Keys(ob);
948 vals = PyMapping_Values(ob);
953 len = PyMapping_Length(ob);
954 for (i = 0; i <
len; i++) {
955 key = PySequence_GetItem(keys, i);
956 pval = PySequence_GetItem(vals, i);
978 const bool can_create)
985 PyErr_SetString(PyExc_ValueError,
"Cannot assign an embedded ID pointer to an id-property");
996 if (!prop && can_create) {
1005 const bool do_conversion,
1006 const bool can_create)
1008 if (name ==
nullptr) {
1012 if (PyFloat_Check(ob)) {
1015 if (PyBool_Check(ob)) {
1016 return idp_from_PyBool(prop_exist, name, ob, do_conversion, can_create);
1018 if (PyLong_Check(ob)) {
1019 return idp_from_PyLong(prop_exist, name, ob, do_conversion, can_create);
1021 if (PyUnicode_Check(ob)) {
1024 if (PyBytes_Check(ob)) {
1027 if (PySequence_Check(ob)) {
1033 if (PyMapping_Check(ob)) {
1038 PyExc_TypeError,
"invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name);
1058 if (new_prop ==
nullptr) {
1076 if (prop != prop_exist) {
1077 PyErr_Format(PyExc_TypeError,
1078 "Cannot assign a '%.200s' value to the existing '%s' %s IDProperty",
1079 Py_TYPE(ob)->tp_name,
1090 if (new_prop ==
nullptr) {
1093 if (new_prop == prop_exist) {
1108 prop_exist->
ui_data =
nullptr;
1122 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
1126 if (val ==
nullptr) {
1128 const char *name = PyUnicode_AsUTF8(key);
1130 if (name ==
nullptr) {
1131 PyErr_Format(PyExc_KeyError,
"expected a string, not %.200s", Py_TYPE(key)->tp_name);
1141 PyErr_SetString(PyExc_KeyError,
"property not found in group");
1165 ret = PyObject_GetIter(iterable);
1166 Py_DECREF(iterable);
1176 switch (prop->
type) {
1190 PyObject *seq = PyList_New(prop->
len);
1195 PyExc_RuntimeError,
"%s: IDP_ARRAY: PyList_New(%d) failed", __func__, prop->
len);
1202 for (i = 0; i < prop->
len; i++) {
1203 PyList_SET_ITEM(seq, i, PyFloat_FromDouble(
array[i]));
1209 for (i = 0; i < prop->
len; i++) {
1210 PyList_SET_ITEM(seq, i, PyFloat_FromDouble(
array[i]));
1216 for (i = 0; i < prop->
len; i++) {
1217 PyList_SET_ITEM(seq, i, PyLong_FromLong(
array[i]));
1223 for (i = 0; i < prop->
len; i++) {
1224 PyList_SET_ITEM(seq, i, PyBool_FromLong(
array[i]));
1230 PyExc_RuntimeError,
"%s: invalid/corrupt array type '%d'!", __func__, prop->
subtype);
1238 PyObject *seq = PyList_New(prop->
len);
1244 PyExc_RuntimeError,
"%s: IDP_IDPARRAY: PyList_New(%d) failed", __func__, prop->
len);
1248 for (i = 0; i < prop->
len; i++) {
1257 PyList_SET_ITEM(seq, i,
wrap);
1262 PyObject *dict = _PyDict_NewPresized(prop->
len);
1274 PyDict_SetItemString(dict, loop->
name,
wrap);
1281 PyErr_Format(PyExc_RuntimeError,
1282 "%s ERROR: '%s' property exists with a bad type code '%d'!",
1297 if (
self->group ==
nullptr) {
1298 return PyUnicode_FromFormat(
"<%s>", Py_TYPE(
self)->tp_name);
1300 return PyUnicode_FromFormat(
"<%s \"%s\">", Py_TYPE(
self)->tp_name,
self->group->prop->name);
1305 if (
self->group !=
nullptr) {
1306 PyObject_GC_UnTrack(
self);
1308 Py_CLEAR(
self->group);
1309 PyObject_GC_Del(
self);
1314 Py_VISIT(
self->group);
1320 Py_CLEAR(
self->group);
1326 return (
self->group !=
nullptr);
1331 if (
self->len_init ==
self->group->prop->len) {
1334 PyErr_SetString(PyExc_RuntimeError,
"IDPropertyGroup changed size during iteration");
1340 if (
self->cur !=
nullptr) {
1347 return PyUnicode_FromString(cur->
name);
1349 PyErr_SetNone(PyExc_StopIteration);
1355 if (
self->cur !=
nullptr) {
1364 PyErr_SetNone(PyExc_StopIteration);
1370 if (
self->cur !=
nullptr) {
1377 PyObject *
ret = PyTuple_New(2);
1379 PyUnicode_FromString(cur->
name),
1383 PyErr_SetNone(PyExc_StopIteration);
1394#define SHARED_MEMBER_SET(member, value) \
1396 k_ty->member = v_ty->member = i_ty->member = value; \
1405 k_ty->tp_name =
"IDPropertyGroupIterKeys";
1406 v_ty->tp_name =
"IDPropertyGroupIterValues";
1407 i_ty->tp_name =
"IDPropertyGroupIterItems";
1423#undef SHARED_MEMBER_SET
1427 const bool reversed,
1432 iter->reversed = reversed;
1433 iter->group = group;
1434 if (group !=
nullptr) {
1436 BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
1437 PyObject_GC_Track(iter);
1439 (reversed ? group->prop->data.group.last : group->prop->data.group.first));
1440 iter->len_init = group->prop->
len;
1443 iter->cur =
nullptr;
1446 return (PyObject *)iter;
1482 if (
self->group ==
nullptr) {
1483 return PyUnicode_FromFormat(
"<%s>", Py_TYPE(
self)->tp_name);
1485 return PyUnicode_FromFormat(
"<%s \"%s\">", Py_TYPE(
self)->tp_name,
self->group->prop->name);
1490 if (
self->group !=
nullptr) {
1491 PyObject_GC_UnTrack(
self);
1493 Py_CLEAR(
self->group);
1494 PyObject_GC_Del(
self);
1499 Py_VISIT(
self->group);
1505 Py_CLEAR(
self->group);
1511 return (
self->group !=
nullptr);
1533 if (
self->group ==
nullptr) {
1536 return self->group->prop->len;
1541 if (
self->group ==
nullptr) {
1549 if (
self->group ==
nullptr) {
1553 PyObject *list = PySequence_List((PyObject *)
self);
1554 const int result = PySequence_Contains(list, value);
1561 if (
self->group ==
nullptr) {
1565 PyObject *list = PySequence_List((PyObject *)
self);
1566 const int result = PySequence_Contains(list, value);
1608 BPy_IDGroup_View_reversed_doc,
1609 "Return a reverse iterator over the ID Property keys values or items.");
1614 result->reversed = !
self->reversed;
1615 return (PyObject *)
result;
1622 BPy_IDGroup_View_reversed_doc},
1638 k_ty->tp_name =
"IDPropertyGroupViewKeys";
1639 v_ty->tp_name =
"IDPropertyGroupViewValues";
1640 i_ty->tp_name =
"IDPropertyGroupViewItems";
1651#define SHARED_MEMBER_SET(member, value) \
1653 k_ty->member = v_ty->member = i_ty->member = value; \
1666#undef SHARED_MEMBER_SET
1677 BPy_IDGroup_pop_doc,
1678 ".. method:: pop(key, default)\n"
1680 " Remove an item from the group, returning a Python representation.\n"
1682 " :raises KeyError: When the item doesn't exist.\n"
1684 " :arg key: Name of item to remove.\n"
1686 " :arg default: Value to return when key isn't found, otherwise raise an exception.\n"
1687 " :type default: Any\n");
1694 PyObject *def =
nullptr;
1696 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
1701 if (idprop ==
nullptr) {
1702 if (def ==
nullptr) {
1703 PyErr_SetString(PyExc_KeyError,
"item not in group");
1706 return Py_NewRef(def);
1710 if (pyform ==
nullptr) {
1725 printf(
"%s: ID Property Error found and corrected!\n", func);
1728 for (j =
len; j < prop->
len; j++) {
1729 PyList_SET_ITEM(seq, j, Py_NewRef(Py_None));
1738 PyObject *list = PyList_New(prop->
len);
1743 loop = loop->
next, i++)
1745 PyList_SET_ITEM(list, i, PyUnicode_FromString(loop->
name));
1749 for (; loop; loop = loop->
next, i++) {
1753 if (i != prop->
len) {
1765 PyObject *list = PyList_New(prop->
len);
1770 loop = loop->
next, i++)
1775 if (i != prop->
len) {
1787 PyObject *seq = PyList_New(prop->
len);
1792 loop = loop->
next, i++)
1794 PyObject *item = PyTuple_New(2);
1797 PyList_SET_ITEM(seq, i, item);
1800 if (i != prop->
len) {
1836 BPy_IDGroup_keys_doc,
1837 ".. method:: keys()\n"
1839 " Return the keys associated with this group as a list of strings.\n");
1847 BPy_IDGroup_values_doc,
1848 ".. method:: values()\n"
1850 " Return the values associated with this group.\n");
1858 BPy_IDGroup_items_doc,
1859 ".. method:: items()\n"
1861 " Iterate through the items in the dict; behaves like dictionary method items.\n");
1869 const char *name = PyUnicode_AsUTF8(value);
1872 PyErr_Format(PyExc_TypeError,
"expected a string, not a %.200s", Py_TYPE(value)->tp_name);
1881 BPy_IDGroup_update_doc,
1882 ".. method:: update(other)\n"
1884 " Update key, values.\n"
1886 " :arg other: Updates the values in the group with this.\n"
1888 " :type other: :class:`IDPropertyGroup` | dict[str, Any]\n");
1891 PyObject *pkey, *pval;
1903 else if (PyDict_Check(value)) {
1904 while (PyDict_Next(value, &i, &pkey, &pval)) {
1906 if (PyErr_Occurred()) {
1912 PyErr_Format(PyExc_TypeError,
1913 "expected a dict or an IDPropertyGroup type, not a %.200s",
1914 Py_TYPE(value)->tp_name);
1923 BPy_IDGroup_to_dict_doc,
1924 ".. method:: to_dict()\n"
1926 " Return a purely Python version of the group.\n");
1934 BPy_IDGroup_clear_doc,
1935 ".. method:: clear()\n"
1937 " Clear all members from this group.\n");
1946 BPy_IDGroup_get_doc,
1947 ".. method:: get(key, default=None)\n"
1949 " Return the value for key, if it exists, else default.\n");
1954 PyObject *def = Py_None;
1956 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
1972#if (defined(__GNUC__) && !defined(__clang__))
1973# pragma GCC diagnostic push
1974# pragma GCC diagnostic ignored "-Wcast-function-type"
1978 {
"pop", (PyCFunction)
BPy_IDGroup_pop, METH_VARARGS, BPy_IDGroup_pop_doc},
1979 {
"keys", (PyCFunction)
BPy_IDGroup_keys, METH_NOARGS, BPy_IDGroup_keys_doc},
1983 {
"get", (PyCFunction)
BPy_IDGroup_get, METH_VARARGS, BPy_IDGroup_get_doc},
1986 {
nullptr,
nullptr, 0,
nullptr},
1989#if (defined(__GNUC__) && !defined(__clang__))
1990# pragma GCC diagnostic pop
2020 PyVarObject_HEAD_INIT(
nullptr, 0)
2080 switch (
self->prop->subtype) {
2082 *elem_size =
sizeof(
float);
2083 return &PyFloat_Type;
2085 *elem_size =
sizeof(
double);
2086 return &PyFloat_Type;
2088 *elem_size =
sizeof(
int8_t);
2089 return &PyBool_Type;
2091 *elem_size =
sizeof(
int);
2092 return &PyLong_Type;
2101 return PyUnicode_FromFormat(
"<bpy id property array [%d]>",
self->prop->len);
2106 BPy_IDArray_get_typecode_doc,
2107 "The type of the data in the array {'f': float, 'd': double, 'i': int, 'b': bool}.");
2110 const char *typecode;
2111 switch (
self->prop->subtype) {
2125 PyErr_Format(PyExc_RuntimeError,
2126 "%s: invalid/corrupt array type '%d'!",
2128 self->prop->subtype);
2133 return PyUnicode_FromString(typecode);
2141 BPy_IDArray_get_typecode_doc,
2143 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr},
2148 BPy_IDArray_to_list_doc,
2149 ".. method:: to_list()\n"
2151 " Return the array as a list.\n");
2157#if (defined(__GNUC__) && !defined(__clang__))
2158# pragma GCC diagnostic push
2159# pragma GCC diagnostic ignored "-Wcast-function-type"
2164 {
nullptr,
nullptr, 0,
nullptr},
2167#if (defined(__GNUC__) && !defined(__clang__))
2168# pragma GCC diagnostic pop
2173 return self->prop->len;
2178 if (index < 0 || index >=
self->prop->len) {
2179 PyErr_SetString(PyExc_IndexError,
"index out of range!");
2183 switch (
self->prop->subtype) {
2185 return PyFloat_FromDouble(((
float *)
IDP_Array(
self->prop))[index]);
2187 return PyFloat_FromDouble(((
double *)
IDP_Array(
self->prop))[index]);
2189 return PyLong_FromLong(
long(((
int *)
IDP_Array(
self->prop))[index]));
2195 PyExc_RuntimeError,
"%s: invalid/corrupt array type '%d'!", __func__,
self->prop->subtype);
2202 if (index < 0 || index >=
self->prop->len) {
2203 PyErr_SetString(PyExc_RuntimeError,
"index out of range!");
2207 switch (
self->prop->subtype) {
2209 const float f =
float(PyFloat_AsDouble(value));
2210 if (f == -1 && PyErr_Occurred()) {
2217 const double d = PyFloat_AsDouble(value);
2218 if (d == -1 && PyErr_Occurred()) {
2225 const int i = PyC_Long_AsI32(value);
2226 if (i == -1 && PyErr_Occurred()) {
2235 if (i == -1 && PyErr_Occurred()) {
2268 end = prop->
len + end + 1;
2271 begin = std::min(begin, end);
2273 tuple = PyTuple_New(end - begin);
2279 PyTuple_SET_ITEM(tuple,
count - begin, PyFloat_FromDouble(
array[
count]));
2286 PyTuple_SET_ITEM(tuple,
count - begin, PyFloat_FromDouble(
array[
count]));
2293 PyTuple_SET_ITEM(tuple,
count - begin, PyLong_FromLong(
array[
count]));
2300 PyTuple_SET_ITEM(tuple,
count - begin, PyBool_FromLong(
long(
array[
count])));
2320 begin = std::min(begin, end);
2322 size = (end - begin);
2323 alloc_len = size * elem_size;
2328 if (
PyC_AsArray(vec, elem_size, seq, size, py_type,
"slice assignment: ") == -1) {
2333 memcpy((
void *)(((
char *)
IDP_Array(prop)) + (begin * elem_size)), vec, alloc_len);
2341 if (PyIndex_Check(item)) {
2343 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2344 if (i == -1 && PyErr_Occurred()) {
2348 i +=
self->prop->len;
2352 if (PySlice_Check(item)) {
2353 Py_ssize_t start, stop, step, slicelength;
2355 if (PySlice_GetIndicesEx(item,
self->prop->len, &start, &stop, &step, &slicelength) < 0) {
2359 if (slicelength <= 0) {
2360 return PyTuple_New(0);
2366 PyErr_SetString(PyExc_TypeError,
"slice steps not supported with vectors");
2370 PyErr_Format(PyExc_TypeError,
2371 "vector indices must be integers, not %.200s",
2373 Py_TYPE(item)->tp_name);
2379 if (PyIndex_Check(item)) {
2380 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2381 if (i == -1 && PyErr_Occurred()) {
2385 i +=
self->prop->len;
2389 if (PySlice_Check(item)) {
2390 Py_ssize_t start, stop, step, slicelength;
2392 if (PySlice_GetIndicesEx(item,
self->prop->len, &start, &stop, &step, &slicelength) < 0) {
2400 PyErr_SetString(PyExc_TypeError,
"slice steps not supported with vectors");
2405 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
2421 return sizeof(
float);
2427 return sizeof(bool);
2436 const int length = itemsize * prop->
len;
2438 if (PyBuffer_FillInfo(view, (PyObject *)
self,
IDP_Array(prop), length,
false, flags) == -1) {
2442 view->itemsize = itemsize;
2445 Py_ssize_t *shape =
static_cast<Py_ssize_t *
>(
MEM_mallocN(
sizeof(Py_ssize_t), __func__));
2446 shape[0] = prop->
len;
2447 view->shape = shape;
2469 PyVarObject_HEAD_INIT(
nullptr, 0)
2555 iter->reversed =
false;
2556 iter->group = group;
2557 if (group !=
nullptr) {
2559 BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
2560 PyObject_GC_Track(iter);
2587 PyModuleDef_HEAD_INIT,
2600 PyObject *submodule;
2630 {
nullptr,
nullptr, 0,
nullptr},
2636 "This module provides access id property types (currently mainly for docs).");
2638 PyModuleDef_HEAD_INIT,
2652 PyObject *submodule;
2653 PyObject *sys_modules = PyImport_GetModuleDict();
2659 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
IDProperty * IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
IDPropertyUIData * IDP_TryConvertUIData(IDPropertyUIData *src, eIDPropertyUIDataType src_type, eIDPropertyUIDataType dst_type)
#define IDP_IDPArray(prop)
void IDP_FreeFromGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
eIDPropertyUIDataType IDP_ui_data_type(const IDProperty *prop)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
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_FreeProperty(IDProperty *prop)
void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist)
void IDP_ClearProperty(IDProperty *prop)
IDProperty * IDP_New(char type, const IDPropertyTemplate *val, const char *name, eIDPropertyFlag flags={}) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
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()
#define BLI_assert_unreachable()
typedef double(DMatrix)[4][4]
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)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
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 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)
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 IDProperty * idp_from_PySequence_Buffer(IDProperty *prop_exist, const char *name, Py_buffer &buffer, const int idp_type, const bool, const bool can_create)
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
bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob)
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(StringRefNull 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(StringRefNull 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(StringRefNull 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)
#define PyTuple_SET_ITEMS(op_arg,...)
IDPropertyUIData * ui_data
struct IDPropertyTemplate::@30 array
struct IDPropertyTemplate::@29 string
ccl_device_inline int mod(int x, int m)