2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Campbell Barton
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/python/intern/bpy_rna.c
24 * \ingroup pythonintern
26 * This file is the main interface between python and blenders data api (RNA),
27 * exposing RNA to python so blender data can be accessed in a python like way.
29 * The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base
30 * classes for most of the data python accesses in blender.
36 #include <float.h> /* FLT_MIN/MAX */
38 #include "RNA_types.h"
40 #include "BLI_dynstr.h"
41 #include "BLI_string.h"
42 #include "BLI_listbase.h"
43 #include "BLI_math_rotation.h"
44 #include "BLI_utildefines.h"
46 #include "BPY_extern.h"
49 #include "bpy_rna_anim.h"
50 #include "bpy_props.h"
52 #include "bpy_rna_callback.h"
53 #include "bpy_intern_string.h"
55 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
56 # include "BLI_ghash.h"
59 #include "RNA_enum_types.h"
60 #include "RNA_define.h" /* RNA_def_property_free_identifier */
61 #include "RNA_access.h"
63 #include "MEM_guardedalloc.h"
66 #include "BKE_idcode.h"
67 #include "BKE_context.h"
68 #include "BKE_global.h" /* evil G.* */
69 #include "BKE_report.h"
70 #include "BKE_idprop.h"
73 #include "../generic/idprop_py_api.h" /* for IDprop lookups */
74 #include "../generic/py_capi_utils.h"
75 #include "../generic/python_utildefines.h"
77 #define USE_PEDANTIC_WRITE
79 #define USE_STRING_COERCE
81 static PyObject *pyrna_struct_Subtype(PointerRNA *ptr);
82 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
84 #define BPY_DOC_ID_PROP_TYPE_NOTE \
87 " Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
88 " :class:`bpy.types.PoseBone` classes support custom properties.\n"
91 int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
93 if (pysrna->ptr.type) {
96 PyErr_Format(PyExc_ReferenceError,
97 "StructRNA of type %.200s has been removed",
98 Py_TYPE(pysrna)->tp_name);
102 int pyrna_prop_validity_check(BPy_PropertyRNA *self)
104 if (self->ptr.type) {
107 PyErr_Format(PyExc_ReferenceError,
108 "PropertyRNA of type %.200s.%.200s has been removed",
109 Py_TYPE(self)->tp_name, RNA_property_identifier(self->prop));
113 void pyrna_invalidate(BPy_DummyPointerRNA *self)
115 RNA_POINTER_INVALIDATE(&self->ptr);
118 #ifdef USE_PYRNA_INVALIDATE_GC
119 #define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1))
121 /* only for sizeof() */
122 struct gc_generation {
128 static void id_release_gc(struct ID *id)
131 // unsigned int i = 0;
132 for (j = 0; j < 3; j++) {
133 /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */
134 PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
135 PyGC_Head *g = gen->gc.gc_next;
136 while ((g = g->gc.gc_next) != gen) {
137 PyObject *ob = FROM_GC(g);
138 if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
139 BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob;
140 if (ob_ptr->ptr.id.data == id) {
141 pyrna_invalidate(ob_ptr);
142 // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
148 // printf("id_release_gc freed '%s': %d\n", id->name, i);
152 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
153 //#define DEBUG_RNA_WEAKREF
155 struct GHash *id_weakref_pool = NULL;
156 static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
157 static PyMethodDef id_free_weakref_cb_def = {"id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL};
159 /* adds a reference to the list, remember to decref */
160 static GHash *id_weakref_pool_get(ID *id)
162 GHash *weakinfo_hash = NULL;
164 if (id_weakref_pool) {
165 weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
168 /* first time, allocate pool */
169 id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool");
170 weakinfo_hash = NULL;
173 if (weakinfo_hash == NULL) {
174 /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */
175 weakinfo_hash = BLI_ghash_ptr_new("rna_id");
176 BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash);
179 return weakinfo_hash;
182 /* called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject() */
183 static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
186 PyObject *weakref_capsule;
187 PyObject *weakref_cb_py;
189 /* create a new function instance and insert the list as 'self' so we can remove ourself from it */
190 GHash *weakinfo_hash = id_weakref_pool_get(id); /* new or existing */
192 weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL);
193 weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
194 Py_DECREF(weakref_capsule);
196 /* add weakref to weakinfo_hash list */
197 weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
199 Py_DECREF(weakref_cb_py); /* function owned by the weakref now */
201 /* important to add at the end, since first removal looks at the end */
202 BLI_ghash_insert(weakinfo_hash, weakref, id); /* using a hash table as a set, all 'id's are the same */
203 /* weakinfo_hash owns the weakref */
207 /* workaround to get the last id without a lookup */
208 static ID *_id_tmp_ptr;
209 static void value_id_set(void *id)
211 _id_tmp_ptr = (ID *)id;
214 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
215 static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref)
217 /* important to search backwards */
218 GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL);
221 if (BLI_ghash_size(weakinfo_hash) > 1) {
222 BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
224 else { /* get the last id and free it */
225 BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set);
226 id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
234 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
236 GHashIterator weakinfo_hash_iter;
238 BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
240 #ifdef DEBUG_RNA_WEAKREF
241 fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
244 while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) {
245 PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
246 PyObject *item = PyWeakref_GET_OBJECT(weakref);
247 if (item != Py_None) {
249 #ifdef DEBUG_RNA_WEAKREF
250 PyC_ObSpit("id_release_weakref item ", item);
253 pyrna_invalidate((BPy_DummyPointerRNA *)item);
258 BLI_ghashIterator_step(&weakinfo_hash_iter);
261 BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
262 BLI_ghash_free(weakinfo_hash, NULL, NULL);
264 if (BLI_ghash_size(id_weakref_pool) == 0) {
265 BLI_ghash_free(id_weakref_pool, NULL, NULL);
266 id_weakref_pool = NULL;
267 #ifdef DEBUG_RNA_WEAKREF
268 printf("id_release_weakref freeing pool\n");
273 static void id_release_weakref(struct ID *id)
275 GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
277 id_release_weakref_list(id, weakinfo_hash);
281 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
283 void BPY_id_release(struct ID *id)
285 #ifdef USE_PYRNA_INVALIDATE_GC
289 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
290 if (id_weakref_pool) {
291 PyGILState_STATE gilstate = PyGILState_Ensure();
293 id_release_weakref(id);
295 PyGILState_Release(gilstate);
297 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
302 #ifdef USE_PEDANTIC_WRITE
303 static bool rna_disallow_writes = false;
305 static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
307 ID *id = ptr->id.data;
309 const short idcode = GS(id->name);
310 if (!ELEM(idcode, ID_WM, ID_SCR)) { /* may need more added here */
311 const char *idtype = BKE_idcode_to_name(idcode);
313 if (key && PyUnicode_Check(key)) pyname = _PyUnicode_AsString(key);
314 else pyname = "<UNKNOWN>";
316 /* make a nice string error */
317 BLI_assert(idtype != NULL);
318 PyErr_Format(PyExc_AttributeError,
319 "Writing to ID classes in this context is not allowed: "
320 "%.200s, %.200s datablock, error setting %.200s.%.200s",
321 id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname);
328 #endif /* USE_PEDANTIC_WRITE */
331 #ifdef USE_PEDANTIC_WRITE
332 bool pyrna_write_check(void)
334 return !rna_disallow_writes;
337 void pyrna_write_set(bool val)
339 rna_disallow_writes = !val;
341 #else /* USE_PEDANTIC_WRITE */
342 bool pyrna_write_check(void)
346 void pyrna_write_set(bool UNUSED(val))
350 #endif /* USE_PEDANTIC_WRITE */
352 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
353 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
354 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
355 static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
358 #include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */
360 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
361 Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
362 static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, const short order_fallback);
364 /* bpyrna vector/euler/quat callbacks */
365 static unsigned char mathutils_rna_array_cb_index = -1; /* index for our callbacks */
367 /* subtype not used much yet */
368 #define MATHUTILS_CB_SUBTYPE_EUL 0
369 #define MATHUTILS_CB_SUBTYPE_VEC 1
370 #define MATHUTILS_CB_SUBTYPE_QUAT 2
371 #define MATHUTILS_CB_SUBTYPE_COLOR 3
373 static int mathutils_rna_generic_check(BaseMathObject *bmo)
375 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
377 PYRNA_PROP_CHECK_INT(self);
379 return self->prop ? 0 : -1;
382 static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
384 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
386 PYRNA_PROP_CHECK_INT(self);
388 if (self->prop == NULL)
391 RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
393 /* Euler order exception */
394 if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
395 EulerObject *eul = (EulerObject *)bmo;
396 PropertyRNA *prop_eul_order = NULL;
397 eul->order = pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
403 static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
405 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
408 PYRNA_PROP_CHECK_INT(self);
410 if (self->prop == NULL)
413 #ifdef USE_PEDANTIC_WRITE
414 if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
417 #endif /* USE_PEDANTIC_WRITE */
419 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
420 PyErr_Format(PyExc_AttributeError,
421 "bpy_prop \"%.200s.%.200s\" is read-only",
422 RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
426 RNA_property_float_range(&self->ptr, self->prop, &min, &max);
428 if (min != -FLT_MAX || max != FLT_MAX) {
429 int i, len = RNA_property_array_length(&self->ptr, self->prop);
430 for (i = 0; i < len; i++) {
431 CLAMP(bmo->data[i], min, max);
435 RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
436 if (RNA_property_update_check(self->prop)) {
437 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
440 /* Euler order exception */
441 if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
442 EulerObject *eul = (EulerObject *)bmo;
443 PropertyRNA *prop_eul_order = NULL;
444 short order = pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
445 if (order != eul->order) {
446 RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
447 if (RNA_property_update_check(prop_eul_order)) {
448 RNA_property_update(BPy_GetContext(), &self->ptr, prop_eul_order);
455 static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
457 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
459 PYRNA_PROP_CHECK_INT(self);
461 if (self->prop == NULL)
464 bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index);
468 static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
470 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
472 PYRNA_PROP_CHECK_INT(self);
474 if (self->prop == NULL)
477 #ifdef USE_PEDANTIC_WRITE
478 if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
481 #endif /* USE_PEDANTIC_WRITE */
483 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
484 PyErr_Format(PyExc_AttributeError,
485 "bpy_prop \"%.200s.%.200s\" is read-only",
486 RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
490 RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
491 RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
493 if (RNA_property_update_check(self->prop)) {
494 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
500 static Mathutils_Callback mathutils_rna_array_cb = {
501 (BaseMathCheckFunc) mathutils_rna_generic_check,
502 (BaseMathGetFunc) mathutils_rna_vector_get,
503 (BaseMathSetFunc) mathutils_rna_vector_set,
504 (BaseMathGetIndexFunc) mathutils_rna_vector_get_index,
505 (BaseMathSetIndexFunc) mathutils_rna_vector_set_index
509 /* bpyrna matrix callbacks */
510 static unsigned char mathutils_rna_matrix_cb_index = -1; /* index for our callbacks */
512 static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
514 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
516 PYRNA_PROP_CHECK_INT(self);
518 if (self->prop == NULL)
521 RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
525 static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
527 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
529 PYRNA_PROP_CHECK_INT(self);
531 if (self->prop == NULL)
534 #ifdef USE_PEDANTIC_WRITE
535 if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
538 #endif /* USE_PEDANTIC_WRITE */
540 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
541 PyErr_Format(PyExc_AttributeError,
542 "bpy_prop \"%.200s.%.200s\" is read-only",
543 RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
547 /* can ignore clamping here */
548 RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
550 if (RNA_property_update_check(self->prop)) {
551 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
556 static Mathutils_Callback mathutils_rna_matrix_cb = {
557 mathutils_rna_generic_check,
558 mathutils_rna_matrix_get,
559 mathutils_rna_matrix_set,
564 static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, const short order_fallback)
566 /* attempt to get order */
567 if (*prop_eul_order == NULL)
568 *prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode");
570 if (*prop_eul_order) {
571 short order = RNA_property_enum_get(ptr, *prop_eul_order);
572 if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) /* could be quat or axisangle */
576 return order_fallback;
579 #endif /* USE_MATHUTILS */
581 /* note that PROP_NONE is included as a vector subtype. this is because its handy to
582 * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */
583 #define PROP_ALL_VECTOR_SUBTYPES \
585 case PROP_TRANSLATION: \
586 case PROP_DIRECTION: \
587 case PROP_VELOCITY: \
588 case PROP_ACCELERATION: \
590 case PROP_XYZ_LENGTH \
593 PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
595 PyObject *ret = NULL;
600 const int flag = RNA_property_flag(prop);
601 const int type = RNA_property_type(prop);
602 const bool is_thick = (flag & PROP_THICK_WRAP) != 0;
604 /* disallow dynamic sized arrays to be wrapped since the size could change
605 * to a size mathutils does not support */
606 if (flag & PROP_DYNAMIC) {
610 len = RNA_property_array_length(ptr, prop);
611 if (type == PROP_FLOAT) {
614 else if (type == PROP_INT) {
616 goto thick_wrap_slice;
626 subtype = RNA_property_subtype(prop);
627 totdim = RNA_property_array_dimension(ptr, prop, NULL);
629 if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
631 ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
634 case PROP_ALL_VECTOR_SUBTYPES:
635 if (len >= 2 && len <= 4) {
637 ret = Vector_CreatePyObject(NULL, len, NULL);
638 RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
641 PyObject *vec_cb = Vector_CreatePyObject_cb(ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC);
642 Py_DECREF(ret); /* the vector owns now */
643 ret = vec_cb; /* return the vector instead */
650 ret = Matrix_CreatePyObject(NULL, 4, 4, NULL);
651 RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
654 PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
655 Py_DECREF(ret); /* the matrix owns now */
656 ret = mat_cb; /* return the matrix instead */
661 ret = Matrix_CreatePyObject(NULL, 3, 3, NULL);
662 RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
665 PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
666 Py_DECREF(ret); /* the matrix owns now */
667 ret = mat_cb; /* return the matrix instead */
672 case PROP_QUATERNION:
673 if (len == 3) { /* euler */
675 /* attempt to get order, only needed for thick types since wrapped with update via callbacks */
676 PropertyRNA *prop_eul_order = NULL;
677 short order = pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ);
679 ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA */
680 RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
683 /* order will be updated from callback on use */
684 PyObject *eul_cb = Euler_CreatePyObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
685 Py_DECREF(ret); /* the euler owns now */
686 ret = eul_cb; /* return the euler instead */
691 ret = Quaternion_CreatePyObject(NULL, NULL);
692 RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
695 PyObject *quat_cb = Quaternion_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT);
696 Py_DECREF(ret); /* the quat owns now */
697 ret = quat_cb; /* return the quat instead */
702 case PROP_COLOR_GAMMA:
703 if (len == 3) { /* color */
705 ret = Color_CreatePyObject(NULL, NULL);
706 RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col);
709 PyObject *col_cb = Color_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR);
710 Py_DECREF(ret); /* the color owns now */
711 ret = col_cb; /* return the color instead */
722 /* this is an array we cant reference (since its not thin wrappable)
723 * and cannot be coerced into a mathutils type, so return as a list */
725 ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
728 ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
731 #else /* USE_MATHUTILS */
734 #endif /* USE_MATHUTILS */
739 /* same as RNA_enum_value_from_id but raises an exception */
740 int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
742 if (RNA_enum_value_from_id(item, identifier, value) == 0) {
743 const char *enum_str = BPy_enum_as_string(item);
744 PyErr_Format(PyExc_ValueError,
745 "%s: '%.200s' not found in (%s)",
746 error_prefix, identifier, enum_str);
747 MEM_freeN((void *)enum_str);
755 * checking the 'ptr->data' matches works in almost all cases,
756 * however there are a few RNA properties that are fake sub-structs and
757 * share the pointer with the parent, in those cases this happens 'a.b == a'
758 * see: r43352 for example.
760 * So compare the 'ptr->type' as well to avoid this problem.
761 * It's highly unlikely this would happen that 'ptr->data' and 'ptr->prop' would match,
762 * but _not_ 'ptr->type' but include this check for completeness.
765 static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
767 return (((a->ptr.data == b->ptr.data) &&
768 (a->ptr.type == b->ptr.type)) ? 0 : -1);
771 static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
773 return (((a->prop == b->prop) &&
774 (a->ptr.data == b->ptr.data) &&
775 (a->ptr.type == b->ptr.type)) ? 0 : -1);
778 static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
781 int ok = -1; /* zero is true */
783 if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b))
784 ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
791 res = ok ? Py_False : Py_True;
798 res = Py_NotImplemented;
805 return Py_INCREF_RET(res);
808 static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
811 int ok = -1; /* zero is true */
813 if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b))
814 ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
821 res = ok ? Py_False : Py_True;
828 res = Py_NotImplemented;
835 return Py_INCREF_RET(res);
838 /*----------------------repr--------------------------------------------*/
839 static PyObject *pyrna_struct_str(BPy_StructRNA *self)
844 if (!PYRNA_STRUCT_IS_VALID(self)) {
845 return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>",
846 Py_TYPE(self)->tp_name);
849 /* print name if available */
850 name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
852 ret = PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>",
853 RNA_struct_identifier(self->ptr.type),
855 MEM_freeN((void *)name);
859 return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>",
860 RNA_struct_identifier(self->ptr.type),
864 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
866 ID *id = self->ptr.id.data;
870 if (id == NULL || !PYRNA_STRUCT_IS_VALID(self))
871 return pyrna_struct_str(self); /* fallback */
873 tmp_str = PyUnicode_FromString(id->name + 2);
875 if (RNA_struct_is_ID(self->ptr.type)) {
876 ret = PyUnicode_FromFormat("bpy.data.%s[%R]",
877 BKE_idcode_to_name_plural(GS(id->name)),
882 path = RNA_path_from_ID_to_struct(&self->ptr);
884 if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */
885 ret = PyUnicode_FromFormat("bpy.data...%s",
889 ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
890 BKE_idcode_to_name_plural(GS(id->name)),
895 MEM_freeN((void *)path);
897 else { /* cant find, print something sane */
898 ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
899 BKE_idcode_to_name_plural(GS(id->name)),
901 RNA_struct_identifier(self->ptr.type));
910 static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
915 const char *type_id = NULL;
916 char type_fmt[64] = "";
919 PYRNA_PROP_CHECK_OBJ(self);
921 type = RNA_property_type(self->prop);
923 if (RNA_enum_id_from_value(property_type_items, type, &type_id) == 0) {
924 PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */
928 /* this should never fail */
932 while ((*c++ = tolower(*type_id++))) {}
934 if (type == PROP_COLLECTION) {
935 len = pyrna_prop_collection_length(self);
937 else if (RNA_property_array_check(self->prop)) {
938 len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
942 sprintf(--c, "[%d]", len);
945 /* if a pointer, try to print name of pointer target too */
946 if (type == PROP_POINTER) {
947 ptr = RNA_property_pointer_get(&self->ptr, self->prop);
948 name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
951 ret = PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
953 RNA_struct_identifier(self->ptr.type),
954 RNA_property_identifier(self->prop),
956 MEM_freeN((void *)name);
960 if (type == PROP_COLLECTION) {
962 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
963 return PyUnicode_FromFormat("<bpy_%.200s, %.200s>",
965 RNA_struct_identifier(r_ptr.type));
969 return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>",
971 RNA_struct_identifier(self->ptr.type),
972 RNA_property_identifier(self->prop));
975 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
977 ID *id = self->ptr.id.data;
982 PYRNA_PROP_CHECK_OBJ(self);
985 return pyrna_prop_str(self); /* fallback */
987 tmp_str = PyUnicode_FromString(id->name + 2);
989 path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
991 if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */
992 ret = PyUnicode_FromFormat("bpy.data...%s",
996 ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
997 BKE_idcode_to_name_plural(GS(id->name)),
1002 MEM_freeN((void *)path);
1004 else { /* cant find, print something sane */
1005 ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
1006 BKE_idcode_to_name_plural(GS(id->name)),
1008 RNA_property_identifier(self->prop));
1017 static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
1019 return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
1020 Py_TYPE(self)->tp_name,
1021 RNA_struct_identifier(self->ptr.type),
1022 RNA_function_identifier(self->func));
1026 static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self)
1028 return _Py_HashPointer(self->ptr.data);
1031 /* from python's meth_hash v3.1.2 */
1032 static long pyrna_prop_hash(BPy_PropertyRNA *self)
1035 if (self->ptr.data == NULL)
1038 x = _Py_HashPointer(self->ptr.data);
1042 y = _Py_HashPointer((void *)(self->prop));
1051 #ifdef USE_PYRNA_STRUCT_REFERENCE
1052 static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1054 Py_VISIT(self->reference);
1058 static int pyrna_struct_clear(BPy_StructRNA *self)
1060 Py_CLEAR(self->reference);
1063 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1065 /* use our own dealloc so we can free a property if we use one */
1066 static void pyrna_struct_dealloc(BPy_StructRNA *self)
1068 #ifdef PYRNA_FREE_SUPPORT
1069 if (self->freeptr && self->ptr.data) {
1070 IDP_FreeProperty(self->ptr.data);
1071 MEM_freeN(self->ptr.data);
1072 self->ptr.data = NULL;
1074 #endif /* PYRNA_FREE_SUPPORT */
1077 if (self->in_weakreflist != NULL) {
1078 PyObject_ClearWeakRefs((PyObject *)self);
1082 #ifdef USE_PYRNA_STRUCT_REFERENCE
1083 if (self->reference) {
1084 PyObject_GC_UnTrack(self);
1085 pyrna_struct_clear(self);
1087 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1089 /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1090 Py_TYPE(self)->tp_free(self);
1093 #ifdef USE_PYRNA_STRUCT_REFERENCE
1094 static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1096 if (self->reference) {
1097 // PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
1098 pyrna_struct_clear(self);
1100 /* reference is now NULL */
1103 self->reference = reference;
1104 Py_INCREF(reference);
1105 // PyObject_GC_Track(self); /* INITIALIZED TRACKED ? */
1108 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1110 /* use our own dealloc so we can free a property if we use one */
1111 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
1114 if (self->in_weakreflist != NULL) {
1115 PyObject_ClearWeakRefs((PyObject *)self);
1118 /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1119 Py_TYPE(self)->tp_free(self);
1122 static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
1125 if (self->in_weakreflist != NULL) {
1126 PyObject_ClearWeakRefs((PyObject *)self);
1129 /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1130 Py_TYPE(self)->tp_free(self);
1133 static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
1135 EnumPropertyItem *item;
1139 RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1141 result = BPy_enum_as_string(item);
1154 static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
1156 const char *param = _PyUnicode_AsString(item);
1158 if (param == NULL) {
1159 PyErr_Format(PyExc_TypeError,
1160 "%.200s expected a string enum, not %.200s",
1161 error_prefix, Py_TYPE(item)->tp_name);
1165 if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
1166 const char *enum_str = pyrna_enum_as_string(ptr, prop);
1167 PyErr_Format(PyExc_TypeError,
1168 "%.200s enum \"%.200s\" not found in (%.200s)",
1169 error_prefix, param, enum_str);
1170 MEM_freeN((void *)enum_str);
1178 /* 'value' _must_ be a set type, error check before calling */
1179 int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
1181 /* set of enum items, concatenate all values with OR */
1186 Py_ssize_t hash = 0;
1191 while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1192 const char *param = _PyUnicode_AsString(key);
1194 if (param == NULL) {
1195 PyErr_Format(PyExc_TypeError,
1196 "%.200s expected a string, not %.200s",
1197 error_prefix, Py_TYPE(key)->tp_name);
1201 if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
1212 static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1214 EnumPropertyItem *item;
1220 if (!PyAnySet_Check(value)) {
1221 PyErr_Format(PyExc_TypeError,
1222 "%.200s, %.200s.%.200s expected a set, not a %.200s",
1223 error_prefix, RNA_struct_identifier(ptr->type),
1224 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1228 RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1231 ret = pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix);
1234 if (PySet_GET_SIZE(value)) {
1235 PyErr_Format(PyExc_TypeError,
1236 "%.200s: empty enum \"%.200s\" could not have any values assigned",
1237 error_prefix, RNA_property_identifier(prop));
1251 PyObject *pyrna_enum_bitfield_to_py(EnumPropertyItem *items, int value)
1253 PyObject *ret = PySet_New(NULL);
1254 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1256 if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
1259 for (index = 0; identifier[index]; index++) {
1260 item = PyUnicode_FromString(identifier[index]);
1261 PySet_Add(ret, item);
1269 static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1271 PyObject *item, *ret = NULL;
1273 if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1274 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1276 ret = PySet_New(NULL);
1278 if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) {
1281 for (index = 0; identifier[index]; index++) {
1282 item = PyUnicode_FromString(identifier[index]);
1283 PySet_Add(ret, item);
1290 const char *identifier;
1291 if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) {
1292 ret = PyUnicode_FromString(identifier);
1295 EnumPropertyItem *enum_item;
1298 /* don't throw error here, can't trust blender 100% to give the
1299 * right values, python code should not generate error for that */
1300 RNA_property_enum_items(BPy_GetContext(), ptr, prop, &enum_item, NULL, &free);
1301 if (enum_item && enum_item->identifier) {
1302 ret = PyUnicode_FromString(enum_item->identifier);
1305 const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
1307 /* prefer not fail silently in case of api errors, maybe disable it later */
1308 printf("RNA Warning: Current value \"%d\" "
1309 "matches no enum in '%s', '%s', '%s'\n",
1310 val, RNA_struct_identifier(ptr->type),
1311 ptr_name, RNA_property_identifier(prop));
1313 #if 0 /* gives python decoding errors while generating docs :( */
1314 char error_str[256];
1315 BLI_snprintf(error_str, sizeof(error_str),
1316 "RNA Warning: Current value \"%d\" "
1317 "matches no enum in '%s', '%s', '%s'",
1318 val, RNA_struct_identifier(ptr->type),
1319 ptr_name, RNA_property_identifier(prop));
1321 PyErr_Warn(PyExc_RuntimeWarning, error_str);
1325 MEM_freeN((void *)ptr_name);
1327 ret = PyUnicode_FromString("");
1331 MEM_freeN(enum_item);
1333 PyErr_Format(PyExc_AttributeError,
1334 "RNA Error: Current value \"%d\" matches no enum", val);
1343 PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
1346 const int type = RNA_property_type(prop);
1348 if (RNA_property_array_check(prop)) {
1349 return pyrna_py_from_array(ptr, prop);
1352 /* see if we can coerce into a python type - PropertyType */
1355 ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1358 ret = PyLong_FromLong(RNA_property_int_get(ptr, prop));
1361 ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1365 const int subtype = RNA_property_subtype(prop);
1370 buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1371 #ifdef USE_STRING_COERCE
1372 /* only file paths get special treatment, they may contain non utf-8 chars */
1373 if (subtype == PROP_BYTESTRING) {
1374 ret = PyBytes_FromStringAndSize(buf, buf_len);
1376 else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1377 ret = PyC_UnicodeFromByteAndSize(buf, buf_len);
1380 ret = PyUnicode_FromStringAndSize(buf, buf_len);
1382 #else /* USE_STRING_COERCE */
1383 if (subtype == PROP_BYTESTRING) {
1384 ret = PyBytes_FromStringAndSize(buf, buf_len);
1387 ret = PyUnicode_FromStringAndSize(buf, buf_len);
1389 #endif /* USE_STRING_COERCE */
1390 if (buf_fixed != buf) {
1391 MEM_freeN((void *)buf);
1397 ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop));
1403 newptr = RNA_property_pointer_get(ptr, prop);
1405 ret = pyrna_struct_CreatePyObject(&newptr);
1413 case PROP_COLLECTION:
1414 ret = pyrna_prop_CreatePyObject(ptr, prop);
1417 PyErr_Format(PyExc_TypeError,
1418 "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", type);
1426 /* This function is used by operators and converting dicts into collections.
1427 * Its takes keyword args and fills them with property values */
1428 int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix)
1432 const char *arg_name = NULL;
1435 totkw = kw ? PyDict_Size(kw) : 0;
1437 RNA_STRUCT_BEGIN (ptr, prop)
1439 arg_name = RNA_property_identifier(prop);
1441 if (STREQ(arg_name, "rna_type")) {
1446 PyErr_Format(PyExc_TypeError,
1447 "%.200s: no keywords, expected \"%.200s\"",
1448 error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1453 item = PyDict_GetItemString(kw, arg_name); /* wont set an error */
1457 PyErr_Format(PyExc_TypeError,
1458 "%.200s: keyword \"%.200s\" missing",
1459 error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1460 error_val = -1; /* pyrna_py_to_prop sets the error */
1465 if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1474 if (error_val == 0 && totkw > 0) { /* some keywords were given that were not used :/ */
1475 PyObject *key, *value;
1478 while (PyDict_Next(kw, &pos, &key, &value)) {
1479 arg_name = _PyUnicode_AsString(key);
1480 if (RNA_struct_find_property(ptr, arg_name) == NULL) break;
1484 PyErr_Format(PyExc_TypeError,
1485 "%.200s: keyword \"%.200s\" unrecognized",
1486 error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1494 static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
1496 BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1498 pyfunc->func = func;
1499 return (PyObject *)pyfunc;
1503 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1505 /* XXX hard limits should be checked here */
1506 const int type = RNA_property_type(prop);
1509 if (RNA_property_array_check(prop)) {
1510 /* done getting the length */
1511 if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1516 /* Normal Property (not an array) */
1518 /* see if we can coerce into a python type - PropertyType */
1523 /* prefer not to have an exception here
1524 * however so many poll functions return None or a valid Object.
1525 * its a hassle to convert these into a bool before returning, */
1526 if (RNA_property_flag(prop) & PROP_OUTPUT) {
1527 param = PyObject_IsTrue(value);
1530 param = PyLong_AsLong(value);
1532 if (UNLIKELY(param & ~1)) { /* only accept 0/1 */
1533 param = -1; /* error out below */
1538 PyErr_Format(PyExc_TypeError,
1539 "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1540 error_prefix, RNA_struct_identifier(ptr->type),
1541 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1545 if (data) *((int *)data) = param;
1546 else RNA_property_boolean_set(ptr, prop, param);
1553 long param = PyLong_AsLongAndOverflow(value, &overflow);
1554 if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1555 PyErr_Format(PyExc_ValueError,
1556 "%.200s %.200s.%.200s value not in 'int' range "
1557 "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1558 error_prefix, RNA_struct_identifier(ptr->type),
1559 RNA_property_identifier(prop));
1562 else if (param == -1 && PyErr_Occurred()) {
1563 PyErr_Format(PyExc_TypeError,
1564 "%.200s %.200s.%.200s expected an int type, not %.200s",
1565 error_prefix, RNA_struct_identifier(ptr->type),
1566 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1570 int param_i = (int)param;
1572 RNA_property_int_clamp(ptr, prop, ¶m_i);
1573 *((int *)data) = param_i;
1576 RNA_property_int_set(ptr, prop, param_i);
1583 float param = PyFloat_AsDouble(value);
1584 if (PyErr_Occurred()) {
1585 PyErr_Format(PyExc_TypeError,
1586 "%.200s %.200s.%.200s expected a float type, not %.200s",
1587 error_prefix, RNA_struct_identifier(ptr->type),
1588 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1593 RNA_property_float_clamp(ptr, prop, (float *)¶m);
1594 *((float *)data) = param;
1597 RNA_property_float_set(ptr, prop, param);
1604 const int subtype = RNA_property_subtype(prop);
1607 if (subtype == PROP_BYTESTRING) {
1611 param = PyBytes_AsString(value);
1613 if (param == NULL) {
1614 if (PyBytes_Check(value)) {
1615 /* there was an error assigning a string type,
1616 * rather than setting a new error, prefix the existing one
1618 PyC_Err_Format_Prefix(PyExc_TypeError,
1619 "%.200s %.200s.%.200s error assigning bytes",
1620 error_prefix, RNA_struct_identifier(ptr->type),
1621 RNA_property_identifier(prop));
1624 PyErr_Format(PyExc_TypeError,
1625 "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1626 error_prefix, RNA_struct_identifier(ptr->type),
1627 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1633 /* same as unicode */
1634 if (data) *((char **)data) = (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1635 else RNA_property_string_set(ptr, prop, param);
1639 /* Unicode String */
1640 #ifdef USE_STRING_COERCE
1641 PyObject *value_coerce = NULL;
1642 if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1643 /* TODO, get size */
1644 param = PyC_UnicodeAsByte(value, &value_coerce);
1647 param = _PyUnicode_AsString(value);
1649 #else /* USE_STRING_COERCE */
1650 param = _PyUnicode_AsString(value);
1651 #endif /* USE_STRING_COERCE */
1653 if (param == NULL) {
1654 if (PyUnicode_Check(value)) {
1655 /* there was an error assigning a string type,
1656 * rather than setting a new error, prefix the existing one
1658 PyC_Err_Format_Prefix(PyExc_TypeError,
1659 "%.200s %.200s.%.200s error assigning string",
1660 error_prefix, RNA_struct_identifier(ptr->type),
1661 RNA_property_identifier(prop));
1664 PyErr_Format(PyExc_TypeError,
1665 "%.200s %.200s.%.200s expected a string type, not %.200s",
1666 error_prefix, RNA_struct_identifier(ptr->type),
1667 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1674 if (data) *((char **)data) = (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1675 else RNA_property_string_set(ptr, prop, param);
1677 #ifdef USE_STRING_COERCE
1678 Py_XDECREF(value_coerce);
1679 #endif /* USE_STRING_COERCE */
1687 /* type checkins is done by each function */
1688 if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1689 /* set of enum items, concatenate all values with OR */
1690 if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
1695 /* simple enum string */
1696 if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
1701 if (data) *((int *)data) = val;
1702 else RNA_property_enum_set(ptr, prop, val);
1708 PyObject *value_new = NULL;
1710 StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
1711 int flag = RNA_property_flag(prop);
1713 /* this is really nasty!, so we can fake the operator having direct properties eg:
1714 * layout.prop(self, "filepath")
1715 * ... which in fact should be
1716 * layout.prop(self.properties, "filepath")
1718 * we need to do this trick.
1719 * if the prop is not an operator type and the pyobject is an operator,
1720 * use its properties in place of its self.
1722 * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing
1723 * if this causes problems in the future it should be removed.
1725 if ((ptr_type == &RNA_AnyType) &&
1726 (BPy_StructRNA_Check(value)) &&
1727 (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator)))
1729 value = PyObject_GetAttrString(value, "properties");
1734 /* if property is an OperatorProperties pointer and value is a map,
1735 * forward back to pyrna_pydict_to_props */
1736 if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) {
1737 PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1738 return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
1741 /* another exception, allow to pass a collection as an RNA property */
1742 if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* ok to ignore idprop collections */
1744 BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
1745 if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1746 value = pyrna_struct_CreatePyObject(&c_ptr);
1750 PyErr_Format(PyExc_TypeError,
1751 "%.200s %.200s.%.200s collection has no type, "
1752 "cant be used as a %.200s type",
1753 error_prefix, RNA_struct_identifier(ptr->type),
1754 RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1759 if (!BPy_StructRNA_Check(value) && value != Py_None) {
1760 PyErr_Format(PyExc_TypeError,
1761 "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1762 error_prefix, RNA_struct_identifier(ptr->type),
1763 RNA_property_identifier(prop), RNA_struct_identifier(ptr_type),
1764 Py_TYPE(value)->tp_name);
1765 Py_XDECREF(value_new); return -1;
1767 else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
1768 PyErr_Format(PyExc_TypeError,
1769 "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1770 error_prefix, RNA_struct_identifier(ptr->type),
1771 RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1772 Py_XDECREF(value_new); return -1;
1774 else if ((value != Py_None) &&
1775 ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA *)value)->ptr.id.data))
1777 PyErr_Format(PyExc_TypeError,
1778 "%.200s %.200s.%.200s ID type does not support assignment to its self",
1779 error_prefix, RNA_struct_identifier(ptr->type),
1780 RNA_property_identifier(prop));
1781 Py_XDECREF(value_new); return -1;
1784 BPy_StructRNA *param = (BPy_StructRNA *)value;
1785 bool raise_error = false;
1788 if (flag & PROP_RNAPTR) {
1789 if (flag & PROP_THICK_WRAP) {
1790 if (value == Py_None)
1791 memset(data, 0, sizeof(PointerRNA));
1792 else if (RNA_struct_is_a(param->ptr.type, ptr_type))
1793 *((PointerRNA *)data) = param->ptr;
1798 /* for function calls, we sometimes want to pass the 'ptr' directly,
1799 * watch out that it remains valid!, possibly we could support this later if needed */
1800 BLI_assert(value_new == NULL);
1801 if (value == Py_None)
1802 *((void **)data) = NULL;
1803 else if (RNA_struct_is_a(param->ptr.type, ptr_type))
1804 *((PointerRNA **)data) = ¶m->ptr;
1809 else if (value == Py_None) {
1810 *((void **)data) = NULL;
1812 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1813 *((void **)data) = param->ptr.data;
1820 /* data == NULL, assign to RNA */
1821 if (value == Py_None) {
1822 PointerRNA valueptr = {{NULL}};
1823 RNA_property_pointer_set(ptr, prop, valueptr);
1825 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1826 RNA_property_pointer_set(ptr, prop, param->ptr);
1834 if (pyrna_struct_validity_check(param) == -1) {
1839 RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1840 PyErr_Format(PyExc_TypeError,
1841 "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1842 error_prefix, RNA_struct_identifier(ptr->type),
1843 RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1844 RNA_struct_identifier(param->ptr.type));
1846 Py_XDECREF(value_new); return -1;
1850 Py_XDECREF(value_new);
1854 case PROP_COLLECTION:
1856 Py_ssize_t seq_len, i;
1860 CollectionPointerLink *link;
1862 lb = (data) ? (ListBase *)data : NULL;
1864 /* convert a sequence of dict's into a collection */
1865 if (!PySequence_Check(value)) {
1866 PyErr_Format(PyExc_TypeError,
1867 "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
1868 error_prefix, RNA_struct_identifier(ptr->type),
1869 RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1873 seq_len = PySequence_Size(value);
1874 for (i = 0; i < seq_len; i++) {
1875 item = PySequence_GetItem(value, i);
1878 PyErr_Format(PyExc_TypeError,
1879 "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
1880 error_prefix, RNA_struct_identifier(ptr->type),
1881 RNA_property_identifier(prop), i);
1886 if (PyDict_Check(item) == 0) {
1887 PyErr_Format(PyExc_TypeError,
1888 "%.200s %.200s.%.200s expected a each sequence "
1889 "member to be a dict for an RNA collection, not %.200s",
1890 error_prefix, RNA_struct_identifier(ptr->type),
1891 RNA_property_identifier(prop), Py_TYPE(item)->tp_name);
1897 link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
1898 link->ptr = itemptr;
1899 BLI_addtail(lb, link);
1902 RNA_property_collection_add(ptr, prop, &itemptr);
1904 if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection") == -1) {
1905 PyObject *msg = PyC_ExceptionBuffer();
1906 const char *msg_char = _PyUnicode_AsString(msg);
1908 PyErr_Format(PyExc_TypeError,
1909 "%.200s %.200s.%.200s error converting a member of a collection "
1910 "from a dicts into an RNA collection, failed with: %s",
1911 error_prefix, RNA_struct_identifier(ptr->type),
1912 RNA_property_identifier(prop), msg_char);
1924 PyErr_Format(PyExc_AttributeError,
1925 "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
1926 error_prefix, RNA_struct_identifier(ptr->type),
1927 RNA_property_identifier(prop));
1932 /* Run rna property functions */
1933 if (RNA_property_update_check(prop)) {
1934 RNA_property_update(BPy_GetContext(), ptr, prop);
1940 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
1942 PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
1943 return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
1946 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
1949 PointerRNA *ptr = &self->ptr;
1950 PropertyRNA *prop = self->prop;
1952 const int totdim = RNA_property_array_dimension(ptr, prop, NULL);
1955 /* char error_str[512]; */
1956 if (pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
1962 /* see if we can coerce into a python type - PropertyType */
1963 switch (RNA_property_type(prop)) {
1966 int param = PyLong_AsLong(value);
1968 if (param < 0 || param > 1) {
1969 PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1973 RNA_property_boolean_set_index(ptr, prop, index, param);
1979 int param = PyLong_AsLong(value);
1980 if (param == -1 && PyErr_Occurred()) {
1981 PyErr_SetString(PyExc_TypeError, "expected an int type");
1985 RNA_property_int_clamp(ptr, prop, ¶m);
1986 RNA_property_int_set_index(ptr, prop, index, param);
1992 float param = PyFloat_AsDouble(value);
1993 if (PyErr_Occurred()) {
1994 PyErr_SetString(PyExc_TypeError, "expected a float type");
1998 RNA_property_float_clamp(ptr, prop, ¶m);
1999 RNA_property_float_set_index(ptr, prop, index, param);
2004 PyErr_SetString(PyExc_AttributeError, "not an array type");
2010 /* Run rna property functions */
2011 if (RNA_property_update_check(prop)) {
2012 RNA_property_update(BPy_GetContext(), ptr, prop);
2018 /* ---------------sequence------------------------------------------- */
2019 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
2021 PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2023 if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
2024 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
2026 return RNA_property_array_length(&self->ptr, self->prop);
2029 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
2031 PYRNA_PROP_CHECK_INT(self);
2033 return RNA_property_collection_length(&self->ptr, self->prop);
2036 /* bool functions are for speed, so we can avoid getting the length
2037 * of 1000's of items in a linked list for eg. */
2038 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
2040 PYRNA_PROP_CHECK_INT(self);
2042 return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
2045 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
2047 /* no callback defined, just iterate and find the nth item */
2048 CollectionPropertyIterator iter;
2051 PYRNA_PROP_CHECK_INT(self);
2053 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
2055 RNA_property_collection_end(&iter);
2060 /* notice getting the length of the collection is avoided unless negative
2061 * index is used or to detect internal error with a valid index.
2062 * This is done for faster lookups. */
2063 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
2065 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2066 if (keynum_abs < 0) { \
2067 PyErr_Format(PyExc_IndexError, \
2068 "bpy_prop_collection[%d]: out of range.", keynum); \
2074 /* internal use only */
2075 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2078 Py_ssize_t keynum_abs = keynum;
2080 PYRNA_PROP_CHECK_OBJ(self);
2082 PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
2084 if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2085 return pyrna_struct_CreatePyObject(&newptr);
2088 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2089 if (keynum_abs >= len) {
2090 PyErr_Format(PyExc_IndexError,
2091 "bpy_prop_collection[index]: "
2092 "index %d out of range, size %d", keynum, len);
2095 PyErr_Format(PyExc_RuntimeError,
2096 "bpy_prop_collection[index]: internal error, "
2097 "valid index %d given in %d sized collection but value not found",
2105 /* values type must have been already checked */
2106 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
2108 Py_ssize_t keynum_abs = keynum;
2109 const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2111 PYRNA_PROP_CHECK_INT(self);
2113 PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
2115 if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2116 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2117 if (keynum_abs >= len) {
2118 PyErr_Format(PyExc_IndexError,
2119 "bpy_prop_collection[index] = value: "
2120 "index %d out of range, size %d", keynum, len);
2124 PyErr_Format(PyExc_IndexError,
2125 "bpy_prop_collection[index] = value: "
2126 "failed assignment (unknown reason)", keynum);
2134 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2138 PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2140 len = pyrna_prop_array_length(self);
2142 if (keynum < 0) keynum += len;
2144 if (keynum >= 0 && keynum < len)
2145 return pyrna_prop_array_to_py_index(self, keynum);
2147 PyErr_Format(PyExc_IndexError,
2148 "bpy_prop_array[index]: index %d out of range", keynum);
2152 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2156 PYRNA_PROP_CHECK_OBJ(self);
2158 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2159 return pyrna_struct_CreatePyObject(&newptr);
2161 PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2164 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
2166 /* special case: bpy.data.objects["some_id_name", "//some_lib_name.blend"]
2167 * also for: bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)
2170 * error codes since this is not to be called directly from python,
2171 * this matches pythons __contains__ values capi.
2175 static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, PyObject *key,
2176 const char *err_prefix, const short err_not_found,
2180 const char *keyname;
2182 /* first validate the args, all we know is that they are a tuple */
2183 if (PyTuple_GET_SIZE(key) != 2) {
2184 PyErr_Format(PyExc_KeyError,
2185 "%s: tuple key must be a pair, not size %d",
2186 err_prefix, PyTuple_GET_SIZE(key));
2189 else if (self->ptr.type != &RNA_BlendData) {
2190 PyErr_Format(PyExc_KeyError,
2191 "%s: is only valid for bpy.data collections, not %.200s",
2192 err_prefix, RNA_struct_identifier(self->ptr.type));
2195 else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
2196 PyErr_Format(PyExc_KeyError,
2197 "%s: id must be a string, not %.200s",
2198 err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2202 PyObject *keylib = PyTuple_GET_ITEM(key, 1);
2206 if (keylib == Py_None) {
2209 else if (PyUnicode_Check(keylib)) {
2210 Main *bmain = self->ptr.data;
2211 const char *keylib_str = _PyUnicode_AsString(keylib);
2212 lib = BLI_findstring(&bmain->library, keylib_str, offsetof(Library, name));
2214 if (err_not_found) {
2215 PyErr_Format(PyExc_KeyError,
2216 "%s: lib name '%.240s' "
2217 "does not reference a valid library",
2218 err_prefix, keylib_str);
2228 PyErr_Format(PyExc_KeyError,
2229 "%s: lib must be a sting or None, not %.200s",
2230 err_prefix, Py_TYPE(keylib)->tp_name);
2234 /* lib is either a valid pointer or NULL,
2235 * either way can do direct comparison with id.lib */
2237 RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
2239 ID *id = itemptr.data; /* always an ID */
2240 if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
2250 /* we may want to fail silently as with collection.get() */
2251 if ((found == false) && err_not_found) {
2252 /* only runs for getitem access so use fixed string */
2253 PyErr_SetString(PyExc_KeyError,
2254 "bpy_prop_collection[key, lib]: not found");
2258 return found; /* 1 / 0, no exception */
2263 static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
2264 const char *err_prefix, const bool err_not_found)
2267 const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
2269 if (contains == 1) {
2270 return pyrna_struct_CreatePyObject(&ptr);
2278 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
2280 CollectionPropertyIterator rna_macro_iter;
2286 PYRNA_PROP_CHECK_OBJ(self);
2288 list = PyList_New(0);
2291 RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2292 RNA_property_collection_skip(&rna_macro_iter, start);
2294 /* add items until stop */
2295 for (count = start; rna_macro_iter.valid;
2296 RNA_property_collection_next(&rna_macro_iter))
2298 item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2299 PyList_APPEND(list, item);
2302 if (count == stop) {
2307 RNA_property_collection_end(&rna_macro_iter);
2312 /* TODO - dimensions
2313 * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
2314 * since at the moment it reads (and even allocates) the entire array for each index.
2316 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
2317 Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
2322 /* isn't needed, internal use only */
2323 // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2325 tuple = PyTuple_New(stop - start);
2327 totdim = RNA_property_array_dimension(ptr, prop, NULL);
2330 for (count = start; count < stop; count++)
2331 PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2334 switch (RNA_property_type(prop)) {
2337 float values_stack[PYRNA_STACK_ARRAY];
2339 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(float) * length); }
2340 else { values = values_stack; }
2341 RNA_property_float_get_array(ptr, prop, values);
2343 for (count = start; count < stop; count++)
2344 PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count]));
2346 if (values != values_stack) {
2353 int values_stack[PYRNA_STACK_ARRAY];
2355 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); }
2356 else { values = values_stack; }
2358 RNA_property_boolean_get_array(ptr, prop, values);
2359 for (count = start; count < stop; count++)
2360 PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count]));
2362 if (values != values_stack) {
2369 int values_stack[PYRNA_STACK_ARRAY];
2371 if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); }
2372 else { values = values_stack; }
2374 RNA_property_int_get_array(ptr, prop, values);
2375 for (count = start; count < stop; count++)
2376 PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count]));
2378 if (values != values_stack) {
2384 BLI_assert(!"Invalid array type");
2386 PyErr_SetString(PyExc_TypeError, "not an array type");
2395 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2397 PYRNA_PROP_CHECK_OBJ(self);
2399 if (PyUnicode_Check(key)) {
2400 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2402 else if (PyIndex_Check(key)) {
2403 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2404 if (i == -1 && PyErr_Occurred())
2407 return pyrna_prop_collection_subscript_int(self, i);
2409 else if (PySlice_Check(key)) {
2410 PySliceObject *key_slice = (PySliceObject *)key;
2411 Py_ssize_t step = 1;
2413 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2416 else if (step != 1) {
2417 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2420 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2421 return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2424 Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2426 /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2427 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2428 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL;
2430 if (start < 0 || stop < 0) {
2431 /* only get the length for negative values */
2432 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2433 if (start < 0) start += len;
2434 if (stop < 0) stop += len;
2437 if (stop - start <= 0) {
2438 return PyList_New(0);
2441 return pyrna_prop_collection_subscript_slice(self, start, stop);
2445 else if (PyTuple_Check(key)) {
2446 /* special case, for ID datablocks we */
2447 return pyrna_prop_collection_subscript_str_lib_pair(self, key,
2448 "bpy_prop_collection[id, lib]", true);
2451 PyErr_Format(PyExc_TypeError,
2452 "bpy_prop_collection[key]: invalid key, "
2453 "must be a string or an int, not %.200s",
2454 Py_TYPE(key)->tp_name);
2459 /* generic check to see if a PyObject is compatible with a collection
2460 * -1 on failure, 0 on success, sets the error */
2461 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2463 StructRNA *prop_srna;
2465 if (value == Py_None) {
2466 if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2467 PyErr_Format(PyExc_TypeError,
2468 "bpy_prop_collection[key] = value: invalid, "
2469 "this collection doesn't support None assignment");
2473 return 0; /* None is OK */
2476 else if (BPy_StructRNA_Check(value) == 0) {
2477 PyErr_Format(PyExc_TypeError,
2478 "bpy_prop_collection[key] = value: invalid, "
2479 "expected a StructRNA type or None, not a %.200s",
2480 Py_TYPE(value)->tp_name);
2483 else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
2484 StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
2485 if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2486 PyErr_Format(PyExc_TypeError,
2487 "bpy_prop_collection[key] = value: invalid, "
2488 "expected a '%.200s' type or None, not a '%.200s'",
2489 RNA_struct_identifier(prop_srna),
2490 RNA_struct_identifier(value_srna)
2495 return 0; /* OK, this is the correct type!*/
2499 PyErr_Format(PyExc_TypeError,
2500 "bpy_prop_collection[key] = value: internal error, "
2501 "failed to get the collection type");
2505 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2506 * large blocks commented, we may support slice/key indices later */
2507 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
2509 PYRNA_PROP_CHECK_INT(self);
2511 /* validate the assigned value */
2512 if (value == NULL) {
2513 PyErr_SetString(PyExc_TypeError,
2514 "del bpy_prop_collection[key]: not supported");
2517 else if (pyrna_prop_collection_type_check(self, value) == -1) {
2518 return -1; /* exception is set */
2522 if (PyUnicode_Check(key)) {
2523 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2527 if (PyIndex_Check(key)) {
2528 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2529 if (i == -1 && PyErr_Occurred())
2532 return pyrna_prop_collection_ass_subscript_int(self, i, value);
2534 #if 0 /* TODO, fake slice assignment */
2535 else if (PySlice_Check(key)) {
2536 PySliceObject *key_slice = (PySliceObject *)key;
2537 Py_ssize_t step = 1;
2539 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2542 else if (step != 1) {
2543 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2546 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2547 return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2550 Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2552 /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2553 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2554 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL;
2556 if (start < 0 || stop < 0) {
2557 /* only get the length for negative values */
2558 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2559 if (start < 0) start += len;
2560 if (stop < 0) stop += len;
2563 if (stop - start <= 0) {
2564 return PyList_New(0);
2567 return pyrna_prop_collection_subscript_slice(self, start, stop);
2573 PyErr_Format(PyExc_TypeError,
2574 "bpy_prop_collection[key]: invalid key, "
2575 "must be a string or an int, not %.200s",
2576 Py_TYPE(key)->tp_name);
2581 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2583 PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2586 if (PyUnicode_Check(key)) {
2587 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2591 if (PyIndex_Check(key)) {
2592 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2593 if (i == -1 && PyErr_Occurred())
2595 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
2597 else if (PySlice_Check(key)) {
2598 Py_ssize_t step = 1;
2599 PySliceObject *key_slice = (PySliceObject *)key;
2601 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2604 else if (step != 1) {
2605 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2608 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2609 /* note, no significant advantage with optimizing [:] slice as with collections
2610 * but include here for consistency with collection slice func */
2611 Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
2612 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2615 int len = pyrna_prop_array_length(self);
2616 Py_ssize_t start, stop, slicelength;
2618 if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0)
2621 if (slicelength <= 0) {
2622 return PyTuple_New(0);
2625 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2630 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2635 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
2636 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
2637 int start, int stop, int length, PyObject *value_orig)
2640 PyObject **value_items;
2642 void *values_alloc = NULL;
2645 if (value_orig == NULL) {
2646 PyErr_SetString(PyExc_TypeError,
2647 "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
2651 if (!(value = PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
2655 if (PySequence_Fast_GET_SIZE(value) != stop - start) {
2657 PyErr_SetString(PyExc_TypeError,
2658 "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported");
2662 value_items = PySequence_Fast_ITEMS(value);
2663 switch (RNA_property_type(prop)) {
2666 float values_stack[PYRNA_STACK_ARRAY];
2667 float *values, fval;
2670 RNA_property_float_range(ptr, prop, &min, &max);
2672 if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(float) * length); }
2673 else { values = values_stack; }
2674 if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2675 RNA_property_float_get_array(ptr, prop, values);
2677 for (count = start; count < stop; count++) {
2678 fval = PyFloat_AsDouble(value_items[count - start]);
2679 CLAMP(fval, min, max);
2680 values[count] = fval;
2683 if (PyErr_Occurred()) ret = -1;
2684 else RNA_property_float_set_array(ptr, prop, values);
2689 int values_stack[PYRNA_STACK_ARRAY];
2691 if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); }
2692 else { values = values_stack; }
2694 if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2695 RNA_property_boolean_get_array(ptr, prop, values);
2697 for (count = start; count < stop; count++)
2698 values[count] = PyLong_AsLong(value_items[count - start]);
2700 if (PyErr_Occurred()) ret = -1;
2701 else RNA_property_boolean_set_array(ptr, prop, values);
2706 int values_stack[PYRNA_STACK_ARRAY];
2710 RNA_property_int_range(ptr, prop, &min, &max);
2712 if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); }
2713 else { values = values_stack; }
2715 if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2716 RNA_property_int_get_array(ptr, prop, values);
2718 for (count = start; count < stop; count++) {
2719 ival = PyLong_AsLong(value_items[count - start]);
2720 CLAMP(ival, min, max);
2721 values[count] = ival;
2724 if (PyErr_Occurred()) ret = -1;
2725 else RNA_property_int_set_array(ptr, prop, values);
2729 PyErr_SetString(PyExc_TypeError, "not an array type");
2737 PyMem_FREE(values_alloc);
2744 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
2748 PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2750 len = pyrna_prop_array_length(self);
2752 if (keynum < 0) keynum += len;
2754 if (keynum >= 0 && keynum < len)
2755 return pyrna_py_to_prop_array_index(self, keynum, value);
2757 PyErr_SetString(PyExc_IndexError,
2758 "bpy_prop_array[index] = value: index out of range");
2762 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
2764 /* char *keyname = NULL; */ /* not supported yet */
2767 PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2769 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
2770 PyErr_Format(PyExc_AttributeError,
2771 "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
2772 RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type));
2776 else if (PyIndex_Check(key)) {
2777 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2778 if (i == -1 && PyErr_Occurred()) {
2782 ret = prop_subscript_ass_array_int(self, i, value);
2785 else if (PySlice_Check(key)) {
2786 int len = RNA_property_array_length(&self->ptr, self->prop);
2787 Py_ssize_t start, stop, step, slicelength;
2789 if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
2792 else if (slicelength <= 0) {
2793 ret = 0; /* do nothing */
2795 else if (step == 1) {
2796 ret = prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
2799 PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
2804 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
2809 if (RNA_property_update_check(self->prop)) {
2810 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
2817 /* for slice only */
2818 static PyMappingMethods pyrna_prop_array_as_mapping = {
2819 (lenfunc) pyrna_prop_array_length, /* mp_length */
2820 (binaryfunc) pyrna_prop_array_subscript, /* mp_subscript */
2821 (objobjargproc) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
2824 static PyMappingMethods pyrna_prop_collection_as_mapping = {
2825 (lenfunc) pyrna_prop_collection_length, /* mp_length */
2826 (binaryfunc) pyrna_prop_collection_subscript, /* mp_subscript */
2827 (objobjargproc) pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */
2830 /* only for fast bool's, large structs, assign nb_bool on init */
2831 static PyNumberMethods pyrna_prop_array_as_number = {
2833 NULL, /* nb_subtract */
2834 NULL, /* nb_multiply */
2835 NULL, /* nb_remainder */
2836 NULL, /* nb_divmod */
2837 NULL, /* nb_power */
2838 NULL, /* nb_negative */
2839 NULL, /* nb_positive */
2840 NULL, /* nb_absolute */
2841 (inquiry) pyrna_prop_array_bool, /* nb_bool */
2843 static PyNumberMethods pyrna_prop_collection_as_number = {
2845 NULL, /* nb_subtract */
2846 NULL, /* nb_multiply */
2847 NULL, /* nb_remainder */
2848 NULL, /* nb_divmod */
2849 NULL, /* nb_power */
2850 NULL, /* nb_negative */
2851 NULL, /* nb_positive */
2852 NULL, /* nb_absolute */
2853 (inquiry) pyrna_prop_collection_bool, /* nb_bool */
2856 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
2858 return pyrna_array_contains_py(&self->ptr, self->prop, value);
2861 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
2863 PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
2865 if (PyTuple_Check(key)) {
2866 /* special case, for ID datablocks we */
2867 return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
2868 "(id, lib) in bpy_prop_collection", false, NULL);
2872 /* key in dict style check */
2873 const char *keyname = _PyUnicode_AsString(key);
2875 if (keyname == NULL) {
2876 PyErr_SetString(PyExc_TypeError,
2877 "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
2881 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2888 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
2891 const char *name = _PyUnicode_AsString(value);
2893 PYRNA_STRUCT_CHECK_INT(self);
2896 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
2900 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2901 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
2905 group = RNA_struct_idprops(&self->ptr, 0);
2910 return IDP_GetPropertyFromGroup(group, name) ? 1 : 0;
2913 static PySequenceMethods pyrna_prop_array_as_sequence = {
2914 (lenfunc)pyrna_prop_array_length,
2915 NULL, /* sq_concat */
2916 NULL, /* sq_repeat */
2917 (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2918 NULL, /* sq_slice */
2919 (ssizeobjargproc)prop_subscript_ass_array_int, /* sq_ass_item */
2920 NULL, /* *was* sq_ass_slice */
2921 (objobjproc)pyrna_prop_array_contains, /* sq_contains */
2922 (binaryfunc) NULL, /* sq_inplace_concat */
2923 (ssizeargfunc) NULL, /* sq_inplace_repeat */
2926 static PySequenceMethods pyrna_prop_collection_as_sequence = {
2927 (lenfunc)pyrna_prop_collection_length,
2928 NULL, /* sq_concat */
2929 NULL, /* sq_repeat */
2930 (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2931 NULL, /* *was* sq_slice */
2932 (ssizeobjargproc)/* pyrna_prop_collection_ass_subscript_int */ NULL /* let mapping take this one */, /* sq_ass_item */
2933 NULL, /* *was* sq_ass_slice */
2934 (objobjproc)pyrna_prop_collection_contains, /* sq_contains */
2935 (binaryfunc) NULL, /* sq_inplace_concat */
2936 (ssizeargfunc) NULL, /* sq_inplace_repeat */
2939 static PySequenceMethods pyrna_struct_as_sequence = {
2940 NULL, /* Cant set the len otherwise it can evaluate as false */
2941 NULL, /* sq_concat */
2942 NULL, /* sq_repeat */
2943 NULL, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2944 NULL, /* *was* sq_slice */
2945 NULL, /* sq_ass_item */
2946 NULL, /* *was* sq_ass_slice */
2947 (objobjproc)pyrna_struct_contains, /* sq_contains */
2948 (binaryfunc) NULL, /* sq_inplace_concat */
2949 (ssizeargfunc) NULL, /* sq_inplace_repeat */
2952 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
2954 /* mostly copied from BPy_IDGroup_Map_GetItem */
2955 IDProperty *group, *idprop;
2956 const char *name = _PyUnicode_AsString(key);
2958 PYRNA_STRUCT_CHECK_OBJ(self);
2960 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
2961 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");