Blender V4.3
bpy_rna.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
15#include <Python.h>
16
17#include <cfloat> /* FLT_MIN/MAX */
18#include <cstddef>
19
20#include "RNA_path.hh"
21#include "RNA_types.hh"
22
23#include "BLI_bitmap.h"
24#include "BLI_dynstr.h"
25#include "BLI_listbase.h"
26#include "BLI_math_rotation.h"
27#include "BLI_string.h"
28#include "BLI_utildefines.h"
29
30#include "BPY_extern.hh"
31#include "BPY_extern_clog.hh"
32
33#include "bpy_capi_utils.hh"
34#include "bpy_intern_string.hh"
35#include "bpy_props.hh"
36#include "bpy_rna.hh"
37#include "bpy_rna_anim.hh"
38#include "bpy_rna_callback.hh"
39
40#ifdef USE_PYRNA_INVALIDATE_WEAKREF
41# include "BLI_ghash.h"
42#endif
43
44#include "RNA_access.hh"
45#include "RNA_define.hh" /* RNA_def_property_free_identifier */
46#include "RNA_enum_types.hh"
47#include "RNA_prototypes.hh"
48
49#include "CLG_log.h"
50
51#include "MEM_guardedalloc.h"
52
53#include "BKE_context.hh"
54#include "BKE_global.hh" /* evil G.* */
55#include "BKE_idprop.hh"
56#include "BKE_idtype.hh"
57#include "BKE_main.hh"
58#include "BKE_report.hh"
59
60/* Only for types. */
61#include "BKE_node.hh"
62
64
65#include "../generic/idprop_py_api.hh" /* For IDprop lookups. */
71
72#define USE_PEDANTIC_WRITE
73#define USE_MATHUTILS
74#define USE_STRING_COERCE
75
83#define USE_POSTPONED_ANNOTATIONS
84
85/* Unfortunately Python needs to hold a global reference to the context.
86 * If we remove this is means `bpy.context` won't be usable from some parts of the code:
87 * `bpy.app.handler` callbacks for example.
88 * Even though this is arguably "correct", it's going to cause problems for existing scripts,
89 * so accept having this for the time being. */
90
91BPy_StructRNA *bpy_context_module = nullptr; /* for fast access */
92
94 PyTypeObject *tp,
95 void **instance);
96
97static PyObject *pyrna_srna_Subtype(StructRNA *srna);
98static PyObject *pyrna_struct_Subtype(PointerRNA *ptr);
100
101static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class);
102static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class);
103
105
106#define BPY_DOC_ID_PROP_TYPE_NOTE \
107 " .. note::\n" \
108 "\n" \
109 " Only the :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \
110 " :class:`bpy.types.PoseBone` classes support custom properties.\n"
111
113{
114 if (pysrna->ptr.type) {
115 return 0;
116 }
117 return -1;
118}
119
121{
122 PyErr_Format(
123 PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name);
124}
125
127{
128 if (pysrna->ptr.type) {
129 return 0;
130 }
132 return -1;
133}
134
136{
137 if (self->ptr.type) {
138 return 0;
139 }
140 PyErr_Format(PyExc_ReferenceError,
141 "PropertyRNA of type %.200s.%.200s has been removed",
142 Py_TYPE(self)->tp_name,
144 return -1;
145}
146
151
152#ifdef USE_PYRNA_INVALIDATE_GC
153# define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1))
154
155/* Only for sizeof(). */
156struct gc_generation {
157 PyGC_Head head;
158 int threshold;
159 int count;
160} gc_generation;
161
162static void id_release_gc(struct ID *id)
163{
164 uint j;
165 // uint i = 0;
166 for (j = 0; j < 3; j++) {
167 /* Hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed. */
168 PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
169 PyGC_Head *g = gen->gc.gc_next;
170 while ((g = g->gc.gc_next) != gen) {
171 PyObject *ob = FROM_GC(g);
172 if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) ||
173 PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type))
174 {
176 if (ob_ptr->ptr.owner_id == id) {
177 pyrna_invalidate(ob_ptr);
178 // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
179 // i++;
180 }
181 }
182 }
183 }
184 // printf("id_release_gc freed '%s': %d\n", id->name, i);
185}
186#endif
187
188#ifdef USE_PYRNA_INVALIDATE_WEAKREF
189// #define DEBUG_RNA_WEAKREF
190
191struct GHash *id_weakref_pool = nullptr;
192static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
193static PyMethodDef id_free_weakref_cb_def = {
194 "id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, nullptr};
195
199static void id_weakref_pool_free_value_fn(void *p)
200{
201 GHash *weakinfo_hash = static_cast<GHash *>(p);
202 BLI_ghash_free(weakinfo_hash, nullptr, nullptr);
203}
204
205/* Adds a reference to the list, remember to decref. */
206static GHash *id_weakref_pool_get(ID *id)
207{
208 GHash *weakinfo_hash = static_cast<GHash *>(BLI_ghash_lookup(id_weakref_pool, (void *)id));
209 if (weakinfo_hash == nullptr) {
210 /* This could be a set, values are used to keep a reference back to the ID
211 * (all of them are the same). */
212 weakinfo_hash = BLI_ghash_ptr_new("rna_id");
213 BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash);
214 }
215 return weakinfo_hash;
216}
217
218/* Called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject(). */
219static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
220{
221 PyObject *weakref;
222 PyObject *weakref_capsule;
223 PyObject *weakref_cb_py;
224
225 /* Create a new function instance and insert the list as 'self'
226 * so we can remove ourself from it. */
227 GHash *weakinfo_hash = id_weakref_pool_get(id); /* New or existing. */
228
229 weakref_capsule = PyCapsule_New(weakinfo_hash, nullptr, nullptr);
230 weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
231 Py_DECREF(weakref_capsule);
232
233 /* Add weakref to weakinfo_hash list. */
234 weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
235
236 Py_DECREF(weakref_cb_py); /* Function owned by the weakref now. */
237
238 /* Important to add at the end of the hash, since first removal looks at the end. */
239
240 /* Using a hash table as a set, all 'id's are the same. */
241 BLI_ghash_insert(weakinfo_hash, weakref, id);
242 /* weakinfo_hash owns the weakref */
243}
244
245/* Workaround to get the last id without a lookup. */
246static ID *_id_tmp_ptr;
247static void value_id_set(void *id)
248{
249 _id_tmp_ptr = (ID *)id;
250}
251
252static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
253static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref)
254{
255 /* Important to search backwards. */
256 GHash *weakinfo_hash = static_cast<GHash *>(PyCapsule_GetPointer(weakinfo_pair, nullptr));
257
258 if (BLI_ghash_len(weakinfo_hash) > 1) {
259 BLI_ghash_remove(weakinfo_hash, weakref, nullptr, nullptr);
260 }
261 else { /* Get the last id and free it. */
262 BLI_ghash_remove(weakinfo_hash, weakref, nullptr, value_id_set);
263 id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
264 }
265
266 Py_DECREF(weakref);
267
268 Py_RETURN_NONE;
269}
270
271static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
272{
273 GHashIterator weakinfo_hash_iter;
274
275 BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
276
277# ifdef DEBUG_RNA_WEAKREF
278 fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash));
279# endif
280
281 while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) {
282 PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
283 PyObject *item = PyWeakref_GET_OBJECT(weakref);
284 if (item != Py_None) {
285
286# ifdef DEBUG_RNA_WEAKREF
287 PyC_ObSpit("id_release_weakref item ", item);
288# endif
289
291 }
292
293 Py_DECREF(weakref);
294
295 BLI_ghashIterator_step(&weakinfo_hash_iter);
296 }
297
298 BLI_ghash_remove(id_weakref_pool, (void *)id, nullptr, nullptr);
299 BLI_ghash_free(weakinfo_hash, nullptr, nullptr);
300}
301
302static void id_release_weakref(struct ID *id)
303{
304 GHash *weakinfo_hash = static_cast<GHash *>(BLI_ghash_lookup(id_weakref_pool, (void *)id));
305 if (weakinfo_hash) {
306 id_release_weakref_list(id, weakinfo_hash);
307 }
308}
309
310#endif /* USE_PYRNA_INVALIDATE_WEAKREF */
311
313{
314#ifdef USE_PYRNA_INVALIDATE_GC
315 id_release_gc(id);
316#endif
317
318#ifdef USE_PYRNA_INVALIDATE_WEAKREF
319 /* Check for nullptr since this may run before Python has been started. */
320 if (id_weakref_pool != nullptr) {
321 PyGILState_STATE gilstate = PyGILState_Ensure();
322
323 id_release_weakref(id);
324
325 PyGILState_Release(gilstate);
326 }
327#endif /* USE_PYRNA_INVALIDATE_WEAKREF */
328
329 (void)id;
330}
331
332#ifdef USE_PEDANTIC_WRITE
333static bool rna_disallow_writes = false;
334
335static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
336{
337 ID *id = ptr->owner_id;
338 if (id) {
339 const short idcode = GS(id->name);
340 /* May need more ID types added here. */
341 if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
342 const char *idtype = BKE_idtype_idcode_to_name(idcode);
343 const char *pyname;
344 if (key && PyUnicode_Check(key)) {
345 pyname = PyUnicode_AsUTF8(key);
346 }
347 else {
348 pyname = "<UNKNOWN>";
349 }
350
351 /* Make a nice string error. */
352 BLI_assert(idtype != nullptr);
353 PyErr_Format(PyExc_AttributeError,
354 "Writing to ID classes in this context is not allowed: "
355 "%.200s, %.200s datablock, error setting %.200s.%.200s",
356 id->name + 2,
357 idtype,
359 pyname);
360
361 return true;
362 }
363 }
364 return false;
365}
366#endif /* USE_PEDANTIC_WRITE */
367
368#ifdef USE_PEDANTIC_WRITE
370{
371 return !rna_disallow_writes;
372}
373
374void pyrna_write_set(bool val)
375{
376 rna_disallow_writes = !val;
377}
378#else /* USE_PEDANTIC_WRITE */
380{
381 return true;
382}
383void pyrna_write_set(bool /*val*/)
384{
385 /* pass */
386}
387#endif /* USE_PEDANTIC_WRITE */
388
391static int pyrna_py_to_prop(
392 PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
393static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
394
395#ifdef USE_MATHUTILS
396# include "../mathutils/mathutils.hh" /* So we can have mathutils callbacks. */
397
400 PropertyRNA *prop,
401 Py_ssize_t start,
402 Py_ssize_t stop,
403 Py_ssize_t length);
405 const short order_fallback,
406 PropertyRNA **r_prop_eul_order);
407
408/* `bpyrna` vector/euler/quaternion callbacks. */
409static uchar mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */
410
411/* Sub-type not used much yet. */
412# define MATHUTILS_CB_SUBTYPE_EUL 0
413# define MATHUTILS_CB_SUBTYPE_VEC 1
414# define MATHUTILS_CB_SUBTYPE_QUAT 2
415# define MATHUTILS_CB_SUBTYPE_COLOR 3
416
418{
419 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
420
422
423 return self->prop ? 0 : -1;
424}
425
426static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
427{
428 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
429
431
432 if (self->prop == nullptr) {
433 return -1;
434 }
435
436 RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
437
438 /* Euler order exception. */
439 if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
440 EulerObject *eul = (EulerObject *)bmo;
441 PropertyRNA *prop_eul_order = nullptr;
442 eul->order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
443 }
444
445 return 0;
446}
447
448static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
449{
450 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
451 float min, max;
452
454
455 if (self->prop == nullptr) {
456 return -1;
457 }
458
459# ifdef USE_PEDANTIC_WRITE
460 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
461 return -1;
462 }
463# endif /* USE_PEDANTIC_WRITE */
464
465 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
466 PyErr_Format(PyExc_AttributeError,
467 "bpy_prop \"%.200s.%.200s\" is read-only",
468 RNA_struct_identifier(self->ptr.type),
470 return -1;
471 }
472
473 RNA_property_float_range(&self->ptr, self->prop, &min, &max);
474
475 if (min != -FLT_MAX || max != FLT_MAX) {
476 int i, len = RNA_property_array_length(&self->ptr, self->prop);
477 for (i = 0; i < len; i++) {
478 CLAMP(bmo->data[i], min, max);
479 }
480 }
481
482 RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
483 if (RNA_property_update_check(self->prop)) {
485 }
486
487 /* Euler order exception. */
488 if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
489 EulerObject *eul = (EulerObject *)bmo;
490 PropertyRNA *prop_eul_order = nullptr;
491 const short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
492 if (order != eul->order) {
493 RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
494 if (RNA_property_update_check(prop_eul_order)) {
495 RNA_property_update(BPY_context_get(), &self->ptr, prop_eul_order);
496 }
497 }
498 }
499 return 0;
500}
501
502static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int /*subtype*/, int index)
503{
504 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
505
507
508 if (self->prop == nullptr) {
509 return -1;
510 }
511
512 bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index);
513 return 0;
514}
515
516static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int /*subtype*/, int index)
517{
518 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
519
521
522 if (self->prop == nullptr) {
523 return -1;
524 }
525
526# ifdef USE_PEDANTIC_WRITE
527 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
528 return -1;
529 }
530# endif /* USE_PEDANTIC_WRITE */
531
532 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
533 PyErr_Format(PyExc_AttributeError,
534 "bpy_prop \"%.200s.%.200s\" is read-only",
535 RNA_struct_identifier(self->ptr.type),
537 return -1;
538 }
539
540 RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
541 RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
542
543 if (RNA_property_update_check(self->prop)) {
545 }
546
547 return 0;
548}
549
557
558/* bpyrna matrix callbacks */
559static uchar mathutils_rna_matrix_cb_index = -1; /* Index for our callbacks. */
560
561static int mathutils_rna_matrix_get(BaseMathObject *bmo, int /*subtype*/)
562{
563 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
564
566
567 if (self->prop == nullptr) {
568 return -1;
569 }
570
571 RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
572 return 0;
573}
574
575static int mathutils_rna_matrix_set(BaseMathObject *bmo, int /*subtype*/)
576{
577 BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
578
580
581 if (self->prop == nullptr) {
582 return -1;
583 }
584
585# ifdef USE_PEDANTIC_WRITE
586 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
587 return -1;
588 }
589# endif /* USE_PEDANTIC_WRITE */
590
591 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
592 PyErr_Format(PyExc_AttributeError,
593 "bpy_prop \"%.200s.%.200s\" is read-only",
594 RNA_struct_identifier(self->ptr.type),
596 return -1;
597 }
598
599 /* Can ignore clamping here. */
600 RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
601
602 if (RNA_property_update_check(self->prop)) {
604 }
605 return 0;
606}
607
615
617 const short order_fallback,
618 PropertyRNA **r_prop_eul_order)
619{
620 /* Attempt to get order. */
621 if (*r_prop_eul_order == nullptr) {
622 *r_prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode");
623 }
624
625 if (*r_prop_eul_order) {
626 const short order = RNA_property_enum_get(ptr, *r_prop_eul_order);
627 /* Could be quaternion or axis-angle. */
628 if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) {
629 return order;
630 }
631 }
632
633 return order_fallback;
634}
635
636#endif /* USE_MATHUTILS */
637
642#define PROP_ALL_VECTOR_SUBTYPES \
643 PROP_COORDS: \
644 case PROP_TRANSLATION: \
645 case PROP_DIRECTION: \
646 case PROP_VELOCITY: \
647 case PROP_ACCELERATION: \
648 case PROP_XYZ: \
649 case PROP_XYZ_LENGTH
650
652{
653 PyObject *ret = nullptr;
654
655#ifdef USE_MATHUTILS
656 int subtype, totdim;
657 int len;
658 const int flag = RNA_property_flag(prop);
659 const int type = RNA_property_type(prop);
660 const bool is_thick = (flag & PROP_THICK_WRAP) != 0;
661
662 /* disallow dynamic sized arrays to be wrapped since the size could change
663 * to a size mathutils does not support */
664 if (flag & PROP_DYNAMIC) {
665 return nullptr;
666 }
667
669 if (type == PROP_FLOAT) {
670 /* pass */
671 }
672 else if (type == PROP_INT) {
673 if (is_thick) {
674 goto thick_wrap_slice;
675 }
676 else {
677 return nullptr;
678 }
679 }
680 else {
681 return nullptr;
682 }
683
684 subtype = RNA_property_subtype(prop);
685 totdim = RNA_property_array_dimension(ptr, prop, nullptr);
686
687 if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
688 if (!is_thick) {
689 /* Owned by the mathutils PyObject. */
691 }
692
693 switch (subtype) {
695 if (len >= 2 && len <= 4) {
696 if (is_thick) {
697 ret = Vector_CreatePyObject(nullptr, len, nullptr);
699 }
700 else {
701 PyObject *vec_cb = Vector_CreatePyObject_cb(
703 Py_DECREF(ret); /* The vector owns 'ret' now. */
704 ret = vec_cb; /* Return the vector instead. */
705 }
706 }
707 break;
708 case PROP_MATRIX:
709 if (len == 16) {
710 if (is_thick) {
711 ret = Matrix_CreatePyObject(nullptr, 4, 4, nullptr);
713 }
714 else {
715 PyObject *mat_cb = Matrix_CreatePyObject_cb(
717 Py_DECREF(ret); /* The matrix owns 'ret' now. */
718 ret = mat_cb; /* Return the matrix instead. */
719 }
720 }
721 else if (len == 9) {
722 if (is_thick) {
723 ret = Matrix_CreatePyObject(nullptr, 3, 3, nullptr);
725 }
726 else {
727 PyObject *mat_cb = Matrix_CreatePyObject_cb(
729 Py_DECREF(ret); /* The matrix owns 'ret' now. */
730 ret = mat_cb; /* Return the matrix instead. */
731 }
732 }
733 break;
734 case PROP_EULER:
735 case PROP_QUATERNION:
736 if (len == 3) { /* Euler. */
737 if (is_thick) {
738 /* Attempt to get order,
739 * only needed for thick types since wrapped with update via callbacks. */
740 PropertyRNA *prop_eul_order = nullptr;
741 const short order = pyrna_rotation_euler_order_get(
742 ptr, EULER_ORDER_XYZ, &prop_eul_order);
743
744 ret = Euler_CreatePyObject(nullptr, order, nullptr); /* TODO: get order from RNA. */
746 }
747 else {
748 /* Order will be updated from callback on use. */
749 /* TODO: get order from RNA. */
750 PyObject *eul_cb = Euler_CreatePyObject_cb(
752 Py_DECREF(ret); /* The euler owns 'ret' now. */
753 ret = eul_cb; /* Return the euler instead. */
754 }
755 }
756 else if (len == 4) {
757 if (is_thick) {
758 ret = Quaternion_CreatePyObject(nullptr, nullptr);
760 }
761 else {
762 PyObject *quat_cb = Quaternion_CreatePyObject_cb(
764 Py_DECREF(ret); /* The quat owns 'ret' now. */
765 ret = quat_cb; /* Return the quat instead. */
766 }
767 }
768 break;
769 case PROP_COLOR:
770 case PROP_COLOR_GAMMA:
771 if (len == 3) { /* Color. */
772 if (is_thick) {
773 ret = Color_CreatePyObject(nullptr, nullptr);
775 }
776 else {
777 PyObject *col_cb = Color_CreatePyObject_cb(
779 Py_DECREF(ret); /* The color owns 'ret' now. */
780 ret = col_cb; /* Return the color instead. */
781 }
782 }
783 break;
784 default:
785 break;
786 }
787 }
788
789 if (ret == nullptr) {
790 if (is_thick) {
791 /* This is an array we can't reference (since it is not thin wrappable)
792 * and cannot be coerced into a mathutils type, so return as a list. */
793 thick_wrap_slice:
794 ret = pyrna_prop_array_subscript_slice(nullptr, ptr, prop, 0, len, len);
795 }
796 else {
797 ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */
798 }
799 }
800#else /* USE_MATHUTILS */
801 (void)ptr;
802 (void)prop;
803#endif /* USE_MATHUTILS */
804
805 return ret;
806}
807
808/* NOTE(@ideasman42): Regarding comparison `__cmp__`:
809 * checking the 'ptr->data' matches works in almost all cases,
810 * however there are a few RNA properties that are fake sub-structs and
811 * share the pointer with the parent, in those cases this happens 'a.b == a'
812 * see: r43352 for example.
813 *
814 * So compare the 'ptr->type' as well to avoid this problem.
815 * It's highly unlikely this would happen that 'ptr->data' and 'ptr->prop' would match,
816 * but _not_ 'ptr->type' but include this check for completeness. */
817
819{
820 return (((a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ? 0 : -1);
821}
822
824{
825 return (((a->prop == b->prop) && (a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ?
826 0 :
827 -1);
828}
829
830static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
831{
832 PyObject *res;
833 int ok = -1; /* Zero is true. */
834
837 }
838
839 switch (op) {
840 case Py_NE:
841 ok = !ok;
843 case Py_EQ:
844 res = ok ? Py_False : Py_True;
845 break;
846
847 case Py_LT:
848 case Py_LE:
849 case Py_GT:
850 case Py_GE:
851 res = Py_NotImplemented;
852 break;
853 default:
854 PyErr_BadArgument();
855 return nullptr;
856 }
857
858 return Py_NewRef(res);
859}
860
861static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
862{
863 PyObject *res;
864 int ok = -1; /* Zero is true. */
865
868 }
869
870 switch (op) {
871 case Py_NE:
872 ok = !ok;
874 case Py_EQ:
875 res = ok ? Py_False : Py_True;
876 break;
877
878 case Py_LT:
879 case Py_LE:
880 case Py_GT:
881 case Py_GE:
882 res = Py_NotImplemented;
883 break;
884 default:
885 PyErr_BadArgument();
886 return nullptr;
887 }
888
889 return Py_NewRef(res);
890}
891
892/*----------------------repr--------------------------------------------*/
894{
895 PyObject *ret;
896 const char *name;
897 const char *extra_info = "";
898
900 return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name);
901 }
902
903 ID *id = self->ptr.owner_id;
904 if (id && id != DEG_get_original_id(id)) {
905 extra_info = ", evaluated";
906 }
907
908 /* Print name if available.
909 *
910 * Always include the pointer address since it can help identify unique data,
911 * or when data is re-allocated internally. */
912 name = RNA_struct_name_get_alloc(&self->ptr, nullptr, 0, nullptr);
913 if (name) {
914 ret = PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\") at %p%s>",
915 RNA_struct_identifier(self->ptr.type),
916 name,
917 self->ptr.data,
918 extra_info);
919 MEM_freeN((void *)name);
920 return ret;
921 }
922
923 return PyUnicode_FromFormat("<bpy_struct, %.200s at %p%s>",
924 RNA_struct_identifier(self->ptr.type),
925 self->ptr.data,
926 extra_info);
927}
928
930{
931 ID *id = self->ptr.owner_id;
932 PyObject *tmp_str;
933 PyObject *ret;
934
935 if (id == nullptr || !PYRNA_STRUCT_IS_VALID(self) || (DEG_get_original_id(id) != id)) {
936 /* fallback */
937 return pyrna_struct_str(self);
938 }
939
940 tmp_str = PyUnicode_FromString(id->name + 2);
941
942 if (RNA_struct_is_ID(self->ptr.type) && (id->flag & ID_FLAG_EMBEDDED_DATA) == 0) {
943 ret = PyUnicode_FromFormat(
944 "bpy.data.%s[%R]", BKE_idtype_idcode_to_name_plural(GS(id->name)), tmp_str);
945 }
946 else {
947 ID *real_id = nullptr;
948 const std::optional<std::string> path = RNA_path_from_real_ID_to_struct(
949 G_MAIN, &self->ptr, &real_id);
950 if (path) {
951 /* 'real_id' may be nullptr in some cases, although the only valid one is evaluated data,
952 * which should have already been caught above.
953 * So assert, but handle it without crashing for release builds. */
954 BLI_assert(real_id != nullptr);
955
956 if (real_id != nullptr) {
957 Py_DECREF(tmp_str);
958 tmp_str = PyUnicode_FromString(real_id->name + 2);
959 ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
961 tmp_str,
962 path->c_str());
963 }
964 else {
965 /* Can't find the path, print something useful as a fallback. */
966 ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
968 tmp_str,
969 RNA_struct_identifier(self->ptr.type));
970 }
971 }
972 else {
973 /* Can't find the path, print something useful as a fallback. */
974 ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
976 tmp_str,
977 RNA_struct_identifier(self->ptr.type));
978 }
979 }
980
981 Py_DECREF(tmp_str);
982
983 return ret;
984}
985
987{
988 PyObject *ret;
990 const char *name;
991 const char *type_id = nullptr;
992 char type_lower[64];
993 char type_count[16];
994 int type;
995
997
998 type = RNA_property_type(self->prop);
999
1000 if (RNA_enum_id_from_value(rna_enum_property_type_items, type, &type_id) == 0) {
1001 /* Should never happen. */
1002 PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error");
1003 return nullptr;
1004 }
1005
1006 STRNCPY(type_lower, type_id);
1007 BLI_str_tolower_ascii(type_lower, sizeof(type_lower));
1008
1009 int len = -1;
1010 if (type == PROP_COLLECTION) {
1012 }
1013 else if (RNA_property_array_check(self->prop)) {
1015 }
1016
1017 if (len != -1) {
1018 SNPRINTF(type_count, "[%d]", len);
1019 }
1020 else {
1021 type_count[0] = '\0';
1022 }
1023
1024 /* If a pointer, try to print name of pointer target too. */
1025 if (type == PROP_POINTER) {
1026 ptr = RNA_property_pointer_get(&self->ptr, self->prop);
1027 name = RNA_struct_name_get_alloc(&ptr, nullptr, 0, nullptr);
1028
1029 if (name) {
1030 ret = PyUnicode_FromFormat("<bpy_%.200s%.200s, %.200s.%.200s(\"%.200s\")>",
1031 type_lower,
1032 type_count,
1033 RNA_struct_identifier(self->ptr.type),
1035 name);
1036 MEM_freeN((void *)name);
1037 return ret;
1038 }
1039 }
1040 if (type == PROP_COLLECTION) {
1041 PointerRNA r_ptr;
1042 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
1043 return PyUnicode_FromFormat(
1044 "<bpy_%.200s%.200s, %.200s>", type_lower, type_count, RNA_struct_identifier(r_ptr.type));
1045 }
1046 }
1047
1048 return PyUnicode_FromFormat("<bpy_%.200s%.200s, %.200s.%.200s>",
1049 type_lower,
1050 type_count,
1051 RNA_struct_identifier(self->ptr.type),
1053}
1054
1055static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index)
1056{
1057 ID *id = self->ptr.owner_id;
1058 PyObject *tmp_str;
1059 PyObject *ret;
1060
1062
1063 if (id == nullptr) {
1064 /* Fallback. */
1065 return pyrna_prop_str(self);
1066 }
1067
1068 tmp_str = PyUnicode_FromString(id->name + 2);
1069
1070 /* Note that using G_MAIN is absolutely not ideal, but we have no access to actual Main DB from
1071 * here. */
1072 ID *real_id = nullptr;
1073 const std::optional<std::string> path = RNA_path_from_real_ID_to_property_index(
1074 G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id);
1075
1076 if (path) {
1077 if (real_id != id) {
1078 Py_DECREF(tmp_str);
1079 tmp_str = PyUnicode_FromString(real_id->name + 2);
1080 }
1081 const char *data_delim = ((*path)[0] == '[') ? "" : ".";
1082 ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s",
1084 tmp_str,
1085 data_delim,
1086 path->c_str());
1087 }
1088 else {
1089 /* Can't find the path, print something useful as a fallback. */
1090 ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
1092 tmp_str,
1094 }
1095
1096 Py_DECREF(tmp_str);
1097
1098 return ret;
1099}
1100
1102{
1103 return pyrna_prop_repr_ex(self, 0, -1);
1104}
1105
1107{
1108 return pyrna_prop_repr_ex((BPy_PropertyRNA *)self, self->arraydim, self->arrayoffset);
1109}
1110
1112{
1113 return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
1114 Py_TYPE(self)->tp_name,
1115 RNA_struct_identifier(self->ptr.type),
1117}
1118
1120{
1121 return _Py_HashPointer(self->ptr.data);
1122}
1123
1124/* From Python's meth_hash v3.1.2. */
1126{
1127 long x, y;
1128 if (self->ptr.data == nullptr) {
1129 x = 0;
1130 }
1131 else {
1132 x = _Py_HashPointer(self->ptr.data);
1133 if (x == -1) {
1134 return -1;
1135 }
1136 }
1137 y = _Py_HashPointer((void *)(self->prop));
1138 if (y == -1) {
1139 return -1;
1140 }
1141 x ^= y;
1142 if (x == -1) {
1143 x = -2;
1144 }
1145 return x;
1146}
1147
1148#ifdef USE_PYRNA_STRUCT_REFERENCE
1149static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1150{
1151 Py_VISIT(self->reference);
1152 return 0;
1153}
1154
1155static int pyrna_struct_clear(BPy_StructRNA *self)
1156{
1157 Py_CLEAR(self->reference);
1158 return 0;
1159}
1160#endif /* !USE_PYRNA_STRUCT_REFERENCE */
1161
1162/* Use our own dealloc so we can free a property if we use one. */
1164{
1165#ifdef PYRNA_FREE_SUPPORT
1166 if (self->freeptr && self->ptr.data) {
1167 IDP_FreeProperty(self->ptr.data);
1168 self->ptr.data = nullptr;
1169 }
1170#endif /* PYRNA_FREE_SUPPORT */
1171
1172#ifdef USE_WEAKREFS
1173 if (self->in_weakreflist != nullptr) {
1174 PyObject_ClearWeakRefs((PyObject *)self);
1175 }
1176#endif
1177
1178#ifdef USE_PYRNA_STRUCT_REFERENCE
1179 if (self->reference) {
1180 PyObject_GC_UnTrack(self);
1181 pyrna_struct_clear(self);
1182 }
1183 else {
1184 PyTypeObject *base = Py_TYPE(self)->tp_base;
1185 /* Python temporarily tracks these types when freeing, see Python bug 26617. */
1186 if (base && PyType_IS_GC(base)) {
1187 PyObject_GC_UnTrack(self);
1188 }
1189 BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
1190 }
1191#endif /* !USE_PYRNA_STRUCT_REFERENCE */
1192
1193 /* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1194 Py_TYPE(self)->tp_free(self);
1195}
1196
1197#ifdef USE_PYRNA_STRUCT_REFERENCE
1198static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1199{
1200 if (self->reference) {
1201 PyObject_GC_UnTrack(self);
1202 Py_CLEAR(self->reference);
1203 }
1204 /* Reference is now nullptr. */
1205
1206 if (reference) {
1207 self->reference = reference;
1208 Py_INCREF(reference);
1209 BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
1210 PyObject_GC_Track(self);
1211 }
1212}
1213#endif /* !USE_PYRNA_STRUCT_REFERENCE */
1214
1215/* Use our own dealloc so we can free a property if we use one. */
1217{
1218#ifdef USE_WEAKREFS
1219 if (self->in_weakreflist != nullptr) {
1220 PyObject_ClearWeakRefs((PyObject *)self);
1221 }
1222#endif
1223 /* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1224 Py_TYPE(self)->tp_free(self);
1225}
1226
1228{
1229#ifdef USE_WEAKREFS
1230 if (self->in_weakreflist != nullptr) {
1231 PyObject_ClearWeakRefs((PyObject *)self);
1232 }
1233#endif
1234 /* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1235 Py_TYPE(self)->tp_free(self);
1236}
1237
1239{
1240 const EnumPropertyItem *item;
1241 const char *result;
1242 bool free = false;
1243
1244 RNA_property_enum_items(BPY_context_get(), ptr, prop, &item, nullptr, &free);
1245 if (item) {
1246 result = pyrna_enum_repr(item);
1247 }
1248 else {
1249 result = "";
1250 }
1251
1252 if (free) {
1253 MEM_freeN((void *)item);
1254 }
1255
1256 return result;
1257}
1258
1260 PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *r_value, const char *error_prefix)
1261{
1262 const char *param = PyUnicode_AsUTF8(item);
1263
1264 if (param == nullptr) {
1265 PyErr_Format(PyExc_TypeError,
1266 "%.200s expected a string enum, not %.200s",
1267 error_prefix,
1268 Py_TYPE(item)->tp_name);
1269 return -1;
1270 }
1271
1272 if (!RNA_property_enum_value(BPY_context_get(), ptr, prop, param, r_value)) {
1273 const char *enum_str = pyrna_enum_as_string(ptr, prop);
1274 PyErr_Format(PyExc_TypeError,
1275 "%.200s enum \"%.200s\" not found in (%s)",
1276 error_prefix,
1277 param,
1278 enum_str);
1279 MEM_freeN((void *)enum_str);
1280 return -1;
1281 }
1282
1283 return 0;
1284}
1285
1287 PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1288{
1289 const EnumPropertyItem *item;
1290 int ret;
1291 bool free = false;
1292
1293 *r_value = 0;
1294
1295 if (!PyAnySet_Check(value)) {
1296 PyErr_Format(PyExc_TypeError,
1297 "%.200s, %.200s.%.200s expected a set, not a %.200s",
1298 error_prefix,
1301 Py_TYPE(value)->tp_name);
1302 return -1;
1303 }
1304
1305 RNA_property_enum_items(BPY_context_get(), ptr, prop, &item, nullptr, &free);
1306
1307 if (item) {
1308 ret = pyrna_enum_bitfield_from_set(item, value, r_value, error_prefix);
1309 }
1310 else {
1311 if (PySet_GET_SIZE(value)) {
1312 PyErr_Format(PyExc_TypeError,
1313 "%.200s: empty enum \"%.200s\" could not have any values assigned",
1314 error_prefix,
1316 ret = -1;
1317 }
1318 else {
1319 ret = 0;
1320 }
1321 }
1322
1323 if (free) {
1324 MEM_freeN((void *)item);
1325 }
1326
1327 return ret;
1328}
1329
1330static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1331{
1332 PyObject *item, *ret = nullptr;
1333
1334 if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1335 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1336
1337 ret = PySet_New(nullptr);
1338
1339 if (RNA_property_enum_bitflag_identifiers(BPY_context_get(), ptr, prop, val, identifier)) {
1340 int index;
1341
1342 for (index = 0; identifier[index]; index++) {
1343 item = PyUnicode_FromString(identifier[index]);
1344 PySet_Add(ret, item);
1345 Py_DECREF(item);
1346 }
1347 }
1348 }
1349 else {
1350 const char *identifier;
1351 if (RNA_property_enum_identifier(BPY_context_get(), ptr, prop, val, &identifier)) {
1352 ret = PyUnicode_FromString(identifier);
1353 }
1354 else {
1355 /* Static, no need to free. */
1356 const EnumPropertyItem *enum_item;
1357 bool free_dummy;
1358 RNA_property_enum_items_ex(nullptr, ptr, prop, true, &enum_item, nullptr, &free_dummy);
1359 BLI_assert(!free_dummy);
1360
1361 /* Do not print warning in case of #rna_enum_dummy_NULL_items,
1362 * this one will never match any value... */
1363 if (enum_item != rna_enum_dummy_NULL_items) {
1364 const char *ptr_name = RNA_struct_name_get_alloc(ptr, nullptr, 0, nullptr);
1365
1366 /* Prefer not to fail silently in case of API errors, maybe disable it later. */
1368 "current value '%d' "
1369 "matches no enum in '%s', '%s', '%s'",
1370 val,
1372 ptr_name,
1374
1375#if 0 /* Gives Python decoding errors while generating docs :( */
1376 char error_str[256];
1377 BLI_snprintf(error_str,
1378 sizeof(error_str),
1379 "RNA Warning: Current value \"%d\" "
1380 "matches no enum in '%s', '%s', '%s'",
1381 val,
1383 ptr_name,
1385
1386 PyErr_Warn(PyExc_RuntimeWarning, error_str);
1387#endif
1388
1389 if (ptr_name) {
1390 MEM_freeN((void *)ptr_name);
1391 }
1392 }
1393
1394 ret = PyUnicode_FromString("");
1395#if 0
1396 PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
1397 ret = nullptr;
1398#endif
1399 }
1400 }
1401
1402 return ret;
1403}
1404
1406{
1407 PyObject *ret;
1408 const int type = RNA_property_type(prop);
1409
1410 if (RNA_property_array_check(prop)) {
1411 return pyrna_py_from_array(ptr, prop);
1412 }
1413
1414 /* See if we can coerce into a Python type - 'PropertyType'. */
1415 switch (type) {
1416 case PROP_BOOLEAN:
1417 ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1418 break;
1419 case PROP_INT:
1420 ret = PyLong_FromLong(RNA_property_int_get(ptr, prop));
1421 break;
1422 case PROP_FLOAT:
1423 ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1424 break;
1425 case PROP_STRING: {
1426 const int subtype = RNA_property_subtype(prop);
1427 const char *buf;
1428 int buf_len;
1429 char buf_fixed[32];
1430
1431 buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1432#ifdef USE_STRING_COERCE
1433 /* Only file paths get special treatment, they may contain non UTF-8 chars. */
1434 if (subtype == PROP_BYTESTRING) {
1435 ret = PyBytes_FromStringAndSize(buf, buf_len);
1436 }
1437 else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1438 ret = PyC_UnicodeFromBytesAndSize(buf, buf_len);
1439 }
1440 else {
1441 ret = PyUnicode_FromStringAndSize(buf, buf_len);
1442 }
1443#else /* USE_STRING_COERCE */
1444 if (subtype == PROP_BYTESTRING) {
1445 ret = PyBytes_FromStringAndSize(buf, buf_len);
1446 }
1447 else {
1448 ret = PyUnicode_FromStringAndSize(buf, buf_len);
1449 }
1450#endif /* USE_STRING_COERCE */
1451 if (buf_fixed != buf) {
1452 MEM_freeN((void *)buf);
1453 }
1454 break;
1455 }
1456 case PROP_ENUM: {
1458 break;
1459 }
1460 case PROP_POINTER: {
1461 PointerRNA newptr;
1462 newptr = RNA_property_pointer_get(ptr, prop);
1463 if (newptr.data) {
1465 }
1466 else {
1467 ret = Py_None;
1468 Py_INCREF(ret);
1469 }
1470 break;
1471 }
1472 case PROP_COLLECTION:
1474 break;
1475 default:
1476 PyErr_Format(PyExc_TypeError,
1477 "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)",
1478 type);
1479 ret = nullptr;
1480 break;
1481 }
1482
1483 return ret;
1484}
1485
1487 PyObject *kw,
1488 const bool all_args,
1489 const char *error_prefix)
1490{
1491 int error_val = 0;
1492 int totkw;
1493 const char *arg_name = nullptr;
1494 PyObject *item;
1495
1496 totkw = kw ? PyDict_Size(kw) : 0;
1497
1498 RNA_STRUCT_BEGIN (ptr, prop) {
1499 arg_name = RNA_property_identifier(prop);
1500
1501 if (STREQ(arg_name, "rna_type")) {
1502 continue;
1503 }
1504
1505 if (kw == nullptr) {
1506 PyErr_Format(
1507 PyExc_TypeError, "%.200s: no keywords, expected \"%.200s\"", error_prefix, arg_name);
1508 error_val = -1;
1509 break;
1510 }
1511
1512 item = PyDict_GetItemString(kw, arg_name); /* Won't set an error. */
1513
1514 if (item == nullptr) {
1515 if (all_args) {
1516 PyErr_Format(PyExc_TypeError,
1517 "%.200s: keyword \"%.200s\" missing",
1518 error_prefix,
1519 arg_name ? arg_name : "<UNKNOWN>");
1520 error_val = -1; /* pyrna_py_to_prop sets the error. */
1521 break;
1522 }
1523 }
1524 else {
1525 if (pyrna_py_to_prop(ptr, prop, nullptr, item, error_prefix)) {
1526 error_val = -1;
1527 break;
1528 }
1529 totkw--;
1530 }
1531 }
1533
1534 if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */
1535 PyObject *key, *value;
1536 Py_ssize_t pos = 0;
1537
1538 while (PyDict_Next(kw, &pos, &key, &value)) {
1539 arg_name = PyUnicode_AsUTF8(key);
1540 if (RNA_struct_find_property(ptr, arg_name) == nullptr) {
1541 break;
1542 }
1543 arg_name = nullptr;
1544 }
1545
1546 PyErr_Format(PyExc_TypeError,
1547 "%.200s: keyword \"%.200s\" unrecognized",
1548 error_prefix,
1549 arg_name ? arg_name : "<UNKNOWN>");
1550 error_val = -1;
1551 }
1552
1553 return error_val;
1554}
1555
1556static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
1557{
1559 pyfunc->ptr = *ptr;
1560 pyfunc->func = func;
1561 return (PyObject *)pyfunc;
1562}
1563
1565 PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1566{
1567 /* XXX hard limits should be checked here. */
1568 const int type = RNA_property_type(prop);
1569
1570 if (RNA_property_array_check(prop)) {
1571 /* Done getting the length. */
1572 if (pyrna_py_to_array(ptr, prop, static_cast<char *>(data), value, error_prefix) == -1) {
1573 return -1;
1574 }
1575 }
1576 else {
1577 /* Normal Property (not an array). */
1578
1579 /* See if we can coerce into a Python type - 'PropertyType'. */
1580 switch (type) {
1581 case PROP_BOOLEAN: {
1582 int param;
1583 /* Prefer not to have an exception here
1584 * however so many poll functions return None or a valid Object.
1585 * It's a hassle to convert these into a bool before returning. */
1586 if (RNA_parameter_flag(prop) & PARM_OUTPUT) {
1587 param = PyObject_IsTrue(value);
1588 }
1589 else {
1590 param = PyC_Long_AsI32(value);
1591
1592 if (UNLIKELY(param & ~1)) { /* Only accept 0/1. */
1593 param = -1; /* Error out below. */
1594 }
1595 }
1596
1597 if (param == -1) {
1598 PyErr_Format(PyExc_TypeError,
1599 "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1600 error_prefix,
1603 Py_TYPE(value)->tp_name);
1604 return -1;
1605 }
1606
1607 if (data) {
1608 *((bool *)data) = param;
1609 }
1610 else {
1611 RNA_property_boolean_set(ptr, prop, param);
1612 }
1613
1614 break;
1615 }
1616 case PROP_INT: {
1617 int overflow;
1618 const long param = PyLong_AsLongAndOverflow(value, &overflow);
1619 if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1620 PyErr_Format(PyExc_ValueError,
1621 "%.200s %.200s.%.200s value not in 'int' range "
1622 "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1623 error_prefix,
1626 return -1;
1627 }
1628 if (param == -1 && PyErr_Occurred()) {
1629 PyErr_Format(PyExc_TypeError,
1630 "%.200s %.200s.%.200s expected an int type, not %.200s",
1631 error_prefix,
1634 Py_TYPE(value)->tp_name);
1635 return -1;
1636 }
1637
1638 int param_i = int(param);
1639 if (data) {
1640 RNA_property_int_clamp(ptr, prop, &param_i);
1641 *((int *)data) = param_i;
1642 }
1643 else {
1644 RNA_property_int_set(ptr, prop, param_i);
1645 }
1646
1647 break;
1648 }
1649 case PROP_FLOAT: {
1650 const float param = PyFloat_AsDouble(value);
1651 if (PyErr_Occurred()) {
1652 PyErr_Format(PyExc_TypeError,
1653 "%.200s %.200s.%.200s expected a float type, not %.200s",
1654 error_prefix,
1657 Py_TYPE(value)->tp_name);
1658 return -1;
1659 }
1660
1661 if (data) {
1662 RNA_property_float_clamp(ptr, prop, (float *)&param);
1663 *((float *)data) = param;
1664 }
1665 else {
1666 RNA_property_float_set(ptr, prop, param);
1667 }
1668
1669 break;
1670 }
1671 case PROP_STRING: {
1672 const int subtype = RNA_property_subtype(prop);
1673 const char *param;
1674
1675 if (value == Py_None) {
1676 if ((RNA_property_flag(prop) & PROP_NEVER_NULL) == 0) {
1677 if (data) {
1678 if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1679 *(char *)data = 0;
1680 }
1681 else {
1682 *((char **)data) = (char *)nullptr;
1683 }
1684 }
1685 else {
1686 RNA_property_string_set(ptr, prop, nullptr);
1687 }
1688 }
1689 else {
1690 PyErr_Format(PyExc_TypeError,
1691 "%.200s %.200s.%.200s doesn't support None from string types",
1692 error_prefix,
1695 return -1;
1696 }
1697 }
1698 else if (subtype == PROP_BYTESTRING) {
1699
1700 /* Byte String. */
1701
1702 param = PyBytes_AsString(value);
1703
1704 if (param == nullptr) {
1705 if (PyBytes_Check(value)) {
1706 /* there was an error assigning a string type,
1707 * rather than setting a new error, prefix the existing one
1708 */
1709 PyC_Err_Format_Prefix(PyExc_TypeError,
1710 "%.200s %.200s.%.200s error assigning bytes",
1711 error_prefix,
1714 }
1715 else {
1716 PyErr_Format(PyExc_TypeError,
1717 "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1718 error_prefix,
1721 Py_TYPE(value)->tp_name);
1722 }
1723
1724 return -1;
1725 }
1726
1727 if (data) {
1728 if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1729 BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
1730 }
1731 else {
1732 *((char **)data) = (char *)param;
1733 }
1734 }
1735 else {
1736 RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value));
1737 }
1738 }
1739 else {
1740/* Unicode String. */
1741#ifdef USE_STRING_COERCE
1742 PyObject *value_coerce = nullptr;
1743 if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1744 /* TODO: get size. */
1745 param = PyC_UnicodeAsBytes(value, &value_coerce);
1746 }
1747 else {
1748 param = PyUnicode_AsUTF8(value);
1749 }
1750#else /* USE_STRING_COERCE */
1751 param = PyUnicode_AsUTF8(value);
1752#endif /* USE_STRING_COERCE */
1753
1754 if (param == nullptr) {
1755 if (PyUnicode_Check(value)) {
1756 /* there was an error assigning a string type,
1757 * rather than setting a new error, prefix the existing one
1758 */
1759 PyC_Err_Format_Prefix(PyExc_TypeError,
1760 "%.200s %.200s.%.200s error assigning string",
1761 error_prefix,
1764 }
1765 else {
1766 PyErr_Format(PyExc_TypeError,
1767 "%.200s %.200s.%.200s expected a string type, not %.200s",
1768 error_prefix,
1771 Py_TYPE(value)->tp_name);
1772 }
1773
1774 return -1;
1775 }
1776
1777 /* Same as bytes. */
1778 /* XXX, this is suspect, but needed for function calls,
1779 * need to see if there's a better way. */
1780 if (data) {
1781 if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1782 BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
1783 }
1784 else {
1785 *((char **)data) = (char *)param;
1786 }
1787 }
1788 else {
1789 RNA_property_string_set(ptr, prop, param);
1790 }
1791
1792#ifdef USE_STRING_COERCE
1793 Py_XDECREF(value_coerce);
1794#endif /* USE_STRING_COERCE */
1795 }
1796 break;
1797 }
1798 case PROP_ENUM: {
1799 int val = 0;
1800
1801 /* Type checking is done by each function. */
1802 if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1803 /* Set of enum items, concatenate all values with OR. */
1804 if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
1805 return -1;
1806 }
1807 }
1808 else {
1809 /* Simple enum string. */
1810 if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
1811 return -1;
1812 }
1813 }
1814
1815 if (data) {
1816 *((int *)data) = val;
1817 }
1818 else {
1819 RNA_property_enum_set(ptr, prop, val);
1820 }
1821
1822 break;
1823 }
1824 case PROP_POINTER: {
1825 PyObject *value_new = nullptr;
1826
1827 StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
1828 const int flag = RNA_property_flag(prop);
1829 const int flag_parameter = RNA_parameter_flag(prop);
1830
1831 /* This is really nasty! Done so we can fake the operator having direct properties, eg:
1832 * layout.prop(self, "filepath")
1833 * ... which in fact should be:
1834 * layout.prop(self.properties, "filepath")
1835 *
1836 * we need to do this trick.
1837 * if the prop is not an operator type and the PyObject is an operator,
1838 * use its properties in place of itself.
1839 *
1840 * This is so bad that it is almost a good reason to do away with fake
1841 * 'self.properties -> self'
1842 * class mixing. If this causes problems in the future it should be removed.
1843 */
1844 if ((ptr_type == &RNA_AnyType) && BPy_StructRNA_Check(value)) {
1845 const StructRNA *base_type = RNA_struct_base_child_of(
1846 ((const BPy_StructRNA *)value)->ptr.type, nullptr);
1847 if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) {
1848 value = PyObject_GetAttr(value, bpy_intern_str_properties);
1849 value_new = value;
1850 }
1851 }
1852
1853 /* if property is an OperatorProperties/GizmoProperties pointer and value is a map,
1854 * forward back to pyrna_pydict_to_props */
1855 if (PyDict_Check(value)) {
1856 const StructRNA *base_type = RNA_struct_base_child_of(ptr_type, nullptr);
1857 if (base_type == &RNA_OperatorProperties) {
1859 return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
1860 }
1861 if (base_type == &RNA_GizmoProperties) {
1863 return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
1864 }
1865 }
1866
1867 /* Another exception, allow passing a collection as an RNA property. */
1868 if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */
1869 PointerRNA c_ptr;
1870 BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
1871 if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1872 value = pyrna_struct_CreatePyObject(&c_ptr);
1873 value_new = value;
1874 }
1875 else {
1876 PyErr_Format(PyExc_TypeError,
1877 "%.200s %.200s.%.200s collection has no type, "
1878 "can't be used as a %.200s type",
1879 error_prefix,
1882 RNA_struct_identifier(ptr_type));
1883 return -1;
1884 }
1885 }
1886
1887 BPy_StructRNA *param;
1888 if (value == Py_None) {
1889 if (flag & PROP_NEVER_NULL) {
1890 PyErr_Format(PyExc_TypeError,
1891 "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1892 error_prefix,
1895 RNA_struct_identifier(ptr_type));
1896 Py_XDECREF(value_new);
1897 return -1;
1898 }
1899 param = nullptr;
1900 }
1901 else {
1902 if (!BPy_StructRNA_Check(value)) {
1903 PyErr_Format(PyExc_TypeError,
1904 "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1905 error_prefix,
1908 RNA_struct_identifier(ptr_type),
1909 Py_TYPE(value)->tp_name);
1910 Py_XDECREF(value_new);
1911 return -1;
1912 }
1913 param = (BPy_StructRNA *)value;
1914
1915 const ID *value_owner_id = ((BPy_StructRNA *)value)->ptr.owner_id;
1916 if (value_owner_id != nullptr) {
1917 if ((flag & PROP_ID_SELF_CHECK) && (ptr->owner_id == value_owner_id)) {
1918 PyErr_Format(PyExc_TypeError,
1919 "%.200s %.200s.%.200s ID type does not support assignment to itself",
1920 error_prefix,
1923 Py_XDECREF(value_new);
1924 return -1;
1925 }
1926
1927 if (value_owner_id->tag & ID_TAG_TEMP_MAIN) {
1928 /* Allow passing temporary ID's to functions, but not attribute assignment. */
1929 if (ptr->type != &RNA_Function) {
1930 PyErr_Format(PyExc_TypeError,
1931 "%.200s %.200s.%.200s ID type assignment is temporary, can't assign",
1932 error_prefix,
1935 Py_XDECREF(value_new);
1936 return -1;
1937 }
1938 }
1939 }
1940 }
1941
1942 bool raise_error = false;
1943 if (data) {
1944
1945 if (flag_parameter & PARM_RNAPTR) {
1946 if (flag & PROP_THICK_WRAP) {
1947 if (param == nullptr) {
1948 memset(data, 0, sizeof(PointerRNA));
1949 }
1950 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1951 *((PointerRNA *)data) = param->ptr;
1952 }
1953 else {
1954 raise_error = true;
1955 }
1956 }
1957 else {
1958 /* For function calls, we sometimes want to pass the 'ptr' directly,
1959 * but watch out that it remains valid!
1960 * We could possibly support this later if needed. */
1961 BLI_assert(value_new == nullptr);
1962 if (param == nullptr) {
1963 *((void **)data) = nullptr;
1964 }
1965 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1966 *((PointerRNA **)data) = &param->ptr;
1967 }
1968 else {
1969 raise_error = true;
1970 }
1971 }
1972 }
1973 else if (param == nullptr) {
1974 *((void **)data) = nullptr;
1975 }
1976 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1977 *((void **)data) = param->ptr.data;
1978 }
1979 else {
1980 raise_error = true;
1981 }
1982 }
1983 else {
1984 /* Data == nullptr, assign to RNA. */
1985 if ((param == nullptr) || RNA_struct_is_a(param->ptr.type, ptr_type)) {
1986 ReportList reports;
1987 BKE_reports_init(&reports, RPT_STORE);
1989 ptr, prop, (param == nullptr) ? PointerRNA_NULL : param->ptr, &reports);
1990 const int err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true);
1991 if (err == -1) {
1992 Py_XDECREF(value_new);
1993 return -1;
1994 }
1995 }
1996 else {
1997 raise_error = true;
1998 }
1999 }
2000
2001 if (raise_error) {
2002 if (pyrna_struct_validity_check(param) == -1) {
2003 /* Error set. */
2004 }
2005 else {
2006 PointerRNA tmp = RNA_pointer_create(nullptr, ptr_type, nullptr);
2007 PyErr_Format(PyExc_TypeError,
2008 "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
2009 error_prefix,
2014 }
2015 Py_XDECREF(value_new);
2016 return -1;
2017 }
2018
2019 Py_XDECREF(value_new);
2020
2021 break;
2022 }
2023 case PROP_COLLECTION: {
2024 Py_ssize_t seq_len, i;
2025 PyObject *item;
2026 PointerRNA itemptr;
2027 CollectionVector *lb;
2028
2029 lb = (data) ? (CollectionVector *)data : nullptr;
2030
2031 /* Convert a sequence of dict's into a collection. */
2032 if (!PySequence_Check(value)) {
2033 PyErr_Format(
2034 PyExc_TypeError,
2035 "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
2036 error_prefix,
2039 Py_TYPE(value)->tp_name);
2040 return -1;
2041 }
2042
2043 seq_len = PySequence_Size(value);
2044 for (i = 0; i < seq_len; i++) {
2045 item = PySequence_GetItem(value, i);
2046
2047 if (item == nullptr) {
2048 PyErr_Format(
2049 PyExc_TypeError,
2050 "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
2051 error_prefix,
2054 i);
2055 Py_XDECREF(item);
2056 return -1;
2057 }
2058
2059 if (PyDict_Check(item) == 0) {
2060 PyErr_Format(PyExc_TypeError,
2061 "%.200s %.200s.%.200s expected a each sequence "
2062 "member to be a dict for an RNA collection, not %.200s",
2063 error_prefix,
2066 Py_TYPE(item)->tp_name);
2067 Py_XDECREF(item);
2068 return -1;
2069 }
2070
2071 if (lb) {
2072 lb->items.append(itemptr);
2073 }
2074 else {
2075 RNA_property_collection_add(ptr, prop, &itemptr);
2076 }
2077
2079 &itemptr, item, true, "Converting a Python list to an RNA collection") == -1)
2080 {
2081 PyObject *msg = PyC_ExceptionBuffer();
2082 const char *msg_char = PyUnicode_AsUTF8(msg);
2083 PyErr_Clear();
2084
2085 PyErr_Format(PyExc_TypeError,
2086 "%.200s %.200s.%.200s error converting a member of a collection "
2087 "from a dicts into an RNA collection, failed with: %s",
2088 error_prefix,
2091 msg_char);
2092
2093 Py_DECREF(item);
2094 Py_DECREF(msg);
2095 return -1;
2096 }
2097 Py_DECREF(item);
2098 }
2099
2100 break;
2101 }
2102 default:
2103 PyErr_Format(PyExc_AttributeError,
2104 "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
2105 error_prefix,
2108 return -1;
2109 }
2110 }
2111
2112 /* Run RNA property functions. */
2113 if (RNA_property_update_check(prop)) {
2115 }
2116
2117 return 0;
2118}
2119
2121{
2123 return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
2124}
2125
2126static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
2127{
2128 int ret = 0;
2129 PointerRNA *ptr = &self->ptr;
2130 PropertyRNA *prop = self->prop;
2131
2132 const int totdim = RNA_property_array_dimension(ptr, prop, nullptr);
2133
2134 if (totdim > 1) {
2135 // char error_str[512];
2137 &self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1)
2138 {
2139 /* Error is set. */
2140 ret = -1;
2141 }
2142 }
2143 else {
2144 /* See if we can coerce into a Python type - 'PropertyType'. */
2145 switch (RNA_property_type(prop)) {
2146 case PROP_BOOLEAN: {
2147 const int param = PyC_Long_AsBool(value);
2148
2149 if (param == -1) {
2150 /* Error is set. */
2151 ret = -1;
2152 }
2153 else {
2154 RNA_property_boolean_set_index(ptr, prop, index, param);
2155 }
2156 break;
2157 }
2158 case PROP_INT: {
2159 int param = PyC_Long_AsI32(value);
2160 if (param == -1 && PyErr_Occurred()) {
2161 PyErr_SetString(PyExc_TypeError, "expected an int type");
2162 ret = -1;
2163 }
2164 else {
2165 RNA_property_int_clamp(ptr, prop, &param);
2166 RNA_property_int_set_index(ptr, prop, index, param);
2167 }
2168 break;
2169 }
2170 case PROP_FLOAT: {
2171 float param = PyFloat_AsDouble(value);
2172 if (PyErr_Occurred()) {
2173 PyErr_SetString(PyExc_TypeError, "expected a float type");
2174 ret = -1;
2175 }
2176 else {
2177 RNA_property_float_clamp(ptr, prop, &param);
2178 RNA_property_float_set_index(ptr, prop, index, param);
2179 }
2180 break;
2181 }
2182 default:
2183 PyErr_SetString(PyExc_AttributeError, "not an array type");
2184 ret = -1;
2185 break;
2186 }
2187 }
2188
2189 /* Run RNA property functions. */
2190 if (RNA_property_update_check(prop)) {
2192 }
2193
2194 return ret;
2195}
2196
2197/* ---------------sequence------------------------------------------- */
2199{
2201
2202 if (RNA_property_array_dimension(&self->ptr, self->prop, nullptr) > 1) {
2203 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
2204 }
2205
2206 return RNA_property_array_length(&self->ptr, self->prop);
2207}
2208
2210{
2212
2213 return RNA_property_collection_length(&self->ptr, self->prop);
2214}
2215
2216/* bool functions are for speed, so we can avoid getting the length
2217 * of 1000's of items in a linked list for eg. */
2219{
2221
2222 return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
2223}
2224
2231
2232/* notice getting the length of the collection is avoided unless negative
2233 * index is used or to detect internal error with a valid index.
2234 * This is done for faster lookups. */
2235#define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
2236 if (keynum < 0) { \
2237 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2238 if (keynum_abs < 0) { \
2239 PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum); \
2240 return ret_err; \
2241 } \
2242 } \
2243 (void)0
2244
2249{
2250 if (value != Py_None) {
2252 const BPy_StructRNA *value_pyrna = (const BPy_StructRNA *)value;
2253 if (UNLIKELY(value_pyrna->ptr.type == nullptr)) {
2254 /* It's important to use a `TypeError` as that is what's returned when `__getitem__` is
2255 * called on an object that doesn't support item access. */
2256 PyErr_Format(PyExc_TypeError,
2257 "'%.200s' object is not subscriptable (only iteration is supported)",
2258 Py_TYPE(value)->tp_name);
2259 return -1;
2260 }
2261 }
2262 return 0;
2263}
2264
2266 const char *error_prefix)
2267{
2268 PyErr_Format(PyExc_TypeError,
2269 "%.200s: %.200s.%.200s does not support string lookups",
2270 error_prefix,
2271 RNA_struct_identifier(self->ptr.type),
2273}
2274
2276 const char *error_prefix)
2277{
2280 return 0;
2281 }
2283 return -1;
2284}
2285
2286/* Internal use only. */
2287static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2288{
2289 PointerRNA newptr;
2290 Py_ssize_t keynum_abs = keynum;
2291
2293
2295
2297 if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2298 return pyrna_struct_CreatePyObject(&newptr);
2299 }
2300 }
2301 else {
2302 /* No callback defined, just iterate and find the nth item. */
2303 const int key = int(keynum_abs);
2304 PyObject *result = nullptr;
2305 bool found = false;
2307 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
2308 for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
2309 if (i == key) {
2310 result = pyrna_struct_CreatePyObject(&iter.ptr);
2311 found = true;
2312 break;
2313 }
2314 }
2315 /* It's important to end the iterator after `result` has been created
2316 * so iterators may optionally invalidate items that were iterated over, see: #100286. */
2318 if (found) {
2319 if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) {
2320 Py_DECREF(result);
2321 result = nullptr; /* The exception has been set. */
2322 }
2323 return result;
2324 }
2325 }
2326
2327 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2328 if (keynum_abs >= len) {
2329 PyErr_Format(PyExc_IndexError,
2330 "bpy_prop_collection[index]: "
2331 "index %d out of range, size %d",
2332 keynum,
2333 len);
2334 }
2335 else {
2336 PyErr_Format(PyExc_RuntimeError,
2337 "bpy_prop_collection[index]: internal error, "
2338 "valid index %d given in %d sized collection, but value not found",
2339 keynum_abs,
2340 len);
2341 }
2342
2343 return nullptr;
2344}
2345
2346/* Values type must have been already checked. */
2348 Py_ssize_t keynum,
2349 PyObject *value)
2350{
2351 Py_ssize_t keynum_abs = keynum;
2352 const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2353
2355
2357
2358 if (!RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr)) {
2359 const int len = RNA_property_collection_length(&self->ptr, self->prop);
2360 if (keynum_abs >= len) {
2361 PyErr_Format(PyExc_IndexError,
2362 "bpy_prop_collection[index] = value: "
2363 "index %d out of range, size %d",
2364 keynum,
2365 len);
2366 }
2367 else {
2368 PyErr_Format(PyExc_IndexError,
2369 "bpy_prop_collection[index] = value: "
2370 "index %d failed assignment (unknown reason)",
2371 keynum);
2372 }
2373 return -1;
2374 }
2375
2376 return 0;
2377}
2378
2379static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum)
2380{
2381 int len;
2382
2384
2386
2387 if (keynum < 0) {
2388 keynum += len;
2389 }
2390
2391 if (keynum >= 0 && keynum < len) {
2392 return pyrna_prop_array_to_py_index(self, keynum);
2393 }
2394
2395 PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
2396 return nullptr;
2397}
2398
2399static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2400{
2401 PointerRNA newptr;
2402
2404
2406 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
2407 return pyrna_struct_CreatePyObject(&newptr);
2408 }
2409 }
2411 /* No callback defined, just iterate and find the nth item. */
2412 const int key_len = strlen(keyname);
2413 char name[256];
2414 int name_len;
2415 PyObject *result = nullptr;
2416 bool found = false;
2418 RNA_property_collection_begin(&self->ptr, self->prop, &iter);
2419 for (; iter.valid; RNA_property_collection_next(&iter)) {
2420 PropertyRNA *nameprop = RNA_struct_name_property(iter.ptr.type);
2421 /* The #RNA_property_collection_lookup_string_has_nameprop check should account for this.
2422 * Although it's technically possible a sub-type clears the name property,
2423 * this seems unlikely. */
2424 BLI_assert(nameprop != nullptr);
2425 char *name_ptr = RNA_property_string_get_alloc(
2426 &iter.ptr, nameprop, name, sizeof(name), &name_len);
2427 if ((key_len == name_len) && STREQ(name_ptr, keyname)) {
2428 found = true;
2429 }
2430 if (name != name_ptr) {
2431 MEM_freeN(name_ptr);
2432 }
2433 if (found) {
2434 result = pyrna_struct_CreatePyObject(&iter.ptr);
2435 break;
2436 }
2437 }
2438 /* It's important to end the iterator after `result` has been created
2439 * so iterators may optionally invalidate items that were iterated over, see: #100286. */
2441 if (found) {
2442 if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) {
2443 Py_DECREF(result);
2444 result = nullptr; /* The exception has been set. */
2445 }
2446 return result;
2447 }
2448 }
2449 else {
2451 return nullptr;
2452 }
2453
2454 PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2455 return nullptr;
2456}
2457// static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname)
2458
2471 PyObject *key,
2472 const char *err_prefix,
2473 const short err_not_found,
2474 PointerRNA *r_ptr)
2475{
2476 const char *keyname;
2477
2478 /* First validate the args, all we know is that they are a tuple. */
2479 if (PyTuple_GET_SIZE(key) != 2) {
2480 PyErr_Format(PyExc_KeyError,
2481 "%s: tuple key must be a pair, not size %d",
2482 err_prefix,
2483 PyTuple_GET_SIZE(key));
2484 return -1;
2485 }
2486 if (self->ptr.type != &RNA_BlendData) {
2487 PyErr_Format(PyExc_KeyError,
2488 "%s: is only valid for bpy.data collections, not %.200s",
2489 err_prefix,
2490 RNA_struct_identifier(self->ptr.type));
2491 return -1;
2492 }
2493 if ((keyname = PyUnicode_AsUTF8(PyTuple_GET_ITEM(key, 0))) == nullptr) {
2494 PyErr_Format(PyExc_KeyError,
2495 "%s: id must be a string, not %.200s",
2496 err_prefix,
2497 Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2498 return -1;
2499 }
2500
2501 PyObject *keylib = PyTuple_GET_ITEM(key, 1);
2502 Library *lib;
2503 bool found = false;
2504
2505 if (keylib == Py_None) {
2506 lib = nullptr;
2507 }
2508 else if (PyUnicode_Check(keylib)) {
2509 Main *bmain = static_cast<Main *>(self->ptr.data);
2510 const char *keylib_str = PyUnicode_AsUTF8(keylib);
2511 lib = static_cast<Library *>(
2512 BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath)));
2513 if (lib == nullptr) {
2514 if (err_not_found) {
2515 PyErr_Format(PyExc_KeyError,
2516 "%s: lib filepath '%.1024s' "
2517 "does not reference a valid library",
2518 err_prefix,
2519 keylib_str);
2520 return -1;
2521 }
2522
2523 return 0;
2524 }
2525 }
2526 else {
2527 PyErr_Format(PyExc_KeyError,
2528 "%s: lib must be a string or None, not %.200s",
2529 err_prefix,
2530 Py_TYPE(keylib)->tp_name);
2531 return -1;
2532 }
2533
2534 /* lib is either a valid pointer or nullptr,
2535 * either way can do direct comparison with id.lib */
2536
2537 RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
2538 ID *id = static_cast<ID *>(itemptr.data); /* Always an ID. */
2539 if (id->lib == lib && STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2)) {
2540 found = true;
2541 if (r_ptr) {
2542 *r_ptr = itemptr;
2543 }
2544 break;
2545 }
2546 }
2548
2549 /* We may want to fail silently as with collection.get(). */
2550 if ((found == false) && err_not_found) {
2551 /* Only runs for getitem access so use fixed string. */
2552 PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found");
2553 return -1;
2554 }
2555
2556 return found; /* 1 / 0, no exception. */
2557}
2558
2560 PyObject *key,
2561 const char *err_prefix,
2562 const bool err_not_found)
2563{
2566 self, key, err_prefix, err_not_found, &ptr);
2567
2568 if (contains == 1) {
2570 }
2571
2572 return nullptr;
2573}
2574
2576 Py_ssize_t start,
2577 Py_ssize_t stop)
2578{
2579 CollectionPropertyIterator rna_macro_iter;
2580 int count;
2581
2582 PyObject *list;
2583 PyObject *item;
2584
2586
2587 list = PyList_New(0);
2588
2589 /* Skip to start. */
2590 RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2591 RNA_property_collection_skip(&rna_macro_iter, start);
2592
2593 /* Add items until stop. */
2594 for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
2595 item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2596 PyList_APPEND(list, item);
2597
2598 count++;
2599 if (count == stop) {
2600 break;
2601 }
2602 }
2603
2604 RNA_property_collection_end(&rna_macro_iter);
2605
2606 return list;
2607}
2608
2615 PointerRNA *ptr,
2616 PropertyRNA *prop,
2617 Py_ssize_t start,
2618 Py_ssize_t stop,
2619 Py_ssize_t length)
2620{
2621 int count, totdim;
2622 PyObject *tuple;
2623
2624 /* Isn't needed, internal use only. */
2625 // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2626
2627 tuple = PyTuple_New(stop - start);
2628
2629 totdim = RNA_property_array_dimension(ptr, prop, nullptr);
2630
2631 if (totdim > 1) {
2632 for (count = start; count < stop; count++) {
2633 PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2634 }
2635 }
2636 else {
2637 switch (RNA_property_type(prop)) {
2638 case PROP_FLOAT: {
2639 float values_stack[PYRNA_STACK_ARRAY];
2640 float *values;
2641 if (length > PYRNA_STACK_ARRAY) {
2642 values = static_cast<float *>(PyMem_MALLOC(sizeof(float) * length));
2643 }
2644 else {
2645 values = values_stack;
2646 }
2647 RNA_property_float_get_array(ptr, prop, values);
2648
2649 for (count = start; count < stop; count++) {
2650 PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count]));
2651 }
2652
2653 if (values != values_stack) {
2654 PyMem_FREE(values);
2655 }
2656 break;
2657 }
2658 case PROP_BOOLEAN: {
2659 bool values_stack[PYRNA_STACK_ARRAY];
2660 bool *values;
2661 if (length > PYRNA_STACK_ARRAY) {
2662 values = static_cast<bool *>(PyMem_MALLOC(sizeof(bool) * length));
2663 }
2664 else {
2665 values = values_stack;
2666 }
2667
2668 RNA_property_boolean_get_array(ptr, prop, values);
2669 for (count = start; count < stop; count++) {
2670 PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count]));
2671 }
2672
2673 if (values != values_stack) {
2674 PyMem_FREE(values);
2675 }
2676 break;
2677 }
2678 case PROP_INT: {
2679 int values_stack[PYRNA_STACK_ARRAY];
2680 int *values;
2681 if (length > PYRNA_STACK_ARRAY) {
2682 values = static_cast<int *>(PyMem_MALLOC(sizeof(int) * length));
2683 }
2684 else {
2685 values = values_stack;
2686 }
2687
2688 RNA_property_int_get_array(ptr, prop, values);
2689 for (count = start; count < stop; count++) {
2690 PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count]));
2691 }
2692
2693 if (values != values_stack) {
2694 PyMem_FREE(values);
2695 }
2696 break;
2697 }
2698 default:
2699 BLI_assert_msg(0, "Invalid array type");
2700
2701 PyErr_SetString(PyExc_TypeError, "not an array type");
2702 Py_DECREF(tuple);
2703 tuple = nullptr;
2704 break;
2705 }
2706 }
2707 return tuple;
2708}
2709
2711{
2713
2714 if (PyUnicode_Check(key)) {
2715 return pyrna_prop_collection_subscript_str(self, PyUnicode_AsUTF8(key));
2716 }
2717 if (PyIndex_Check(key)) {
2718 const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2719 if (i == -1 && PyErr_Occurred()) {
2720 return nullptr;
2721 }
2722
2724 }
2725 if (PySlice_Check(key)) {
2726 PySliceObject *key_slice = (PySliceObject *)key;
2727 Py_ssize_t step = 1;
2728
2729 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2730 return nullptr;
2731 }
2732 if (step != 1) {
2733 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2734 return nullptr;
2735 }
2736 if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2737 return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2738 }
2739
2740 Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2741
2742 /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2743 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
2744 return nullptr;
2745 }
2746 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
2747 return nullptr;
2748 }
2749
2750 if (start < 0 || stop < 0) {
2751 /* Only get the length for negative values. */
2752 const Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2753 if (start < 0) {
2754 start += len;
2755 CLAMP_MIN(start, 0);
2756 }
2757 if (stop < 0) {
2758 stop += len;
2759 CLAMP_MIN(stop, 0);
2760 }
2761 }
2762
2763 if (stop - start <= 0) {
2764 return PyList_New(0);
2765 }
2766
2767 return pyrna_prop_collection_subscript_slice(self, start, stop);
2768 }
2769 if (PyTuple_Check(key)) {
2770 /* Special case, for ID datablocks we. */
2772 self, key, "bpy_prop_collection[id, lib]", true);
2773 }
2774
2775 PyErr_Format(PyExc_TypeError,
2776 "bpy_prop_collection[key]: invalid key, "
2777 "must be a string or an int, not %.200s",
2778 Py_TYPE(key)->tp_name);
2779 return nullptr;
2780}
2781
2782/* generic check to see if a PyObject is compatible with a collection
2783 * -1 on failure, 0 on success, sets the error */
2785{
2786 StructRNA *prop_srna;
2787
2788 if (value == Py_None) {
2789 if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2790 PyErr_Format(PyExc_TypeError,
2791 "bpy_prop_collection[key] = value: invalid, "
2792 "this collection doesn't support None assignment");
2793 return -1;
2794 }
2795
2796 return 0; /* None is OK. */
2797 }
2798 if (BPy_StructRNA_Check(value) == 0) {
2799 PyErr_Format(PyExc_TypeError,
2800 "bpy_prop_collection[key] = value: invalid, "
2801 "expected a StructRNA type or None, not a %.200s",
2802 Py_TYPE(value)->tp_name);
2803 return -1;
2804 }
2805 if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
2806 StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
2807 if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2808 PyErr_Format(PyExc_TypeError,
2809 "bpy_prop_collection[key] = value: invalid, "
2810 "expected a '%.200s' type or None, not a '%.200s'",
2811 RNA_struct_identifier(prop_srna),
2812 RNA_struct_identifier(value_srna));
2813 return -1;
2814 }
2815
2816 return 0; /* OK, this is the correct type! */
2817 }
2818
2819 PyErr_Format(PyExc_TypeError,
2820 "bpy_prop_collection[key] = value: internal error, "
2821 "failed to get the collection type");
2822 return -1;
2823}
2824
2825/* NOTE: currently this is a copy of 'pyrna_prop_collection_subscript' with
2826 * large blocks commented, we may support slice/key indices later */
2828 PyObject *key,
2829 PyObject *value)
2830{
2832
2833 /* Validate the assigned value. */
2834 if (value == nullptr) {
2835 PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported");
2836 return -1;
2837 }
2838 if (pyrna_prop_collection_type_check(self, value) == -1) {
2839 return -1; /* Exception is set. */
2840 }
2841
2842#if 0
2843 if (PyUnicode_Check(key)) {
2844 return pyrna_prop_collection_subscript_str(self, PyUnicode_AsUTF8(key));
2845 }
2846 else
2847#endif
2848 if (PyIndex_Check(key)) {
2849 const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2850 if (i == -1 && PyErr_Occurred()) {
2851 return -1;
2852 }
2853
2855 }
2856#if 0 /* TODO: fake slice assignment. */
2857 else if (PySlice_Check(key)) {
2858 PySliceObject *key_slice = (PySliceObject *)key;
2859 Py_ssize_t step = 1;
2860
2861 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2862 return nullptr;
2863 }
2864 else if (step != 1) {
2865 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2866 return nullptr;
2867 }
2868 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2869 return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2870 }
2871 else {
2872 Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2873
2874 /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2875 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
2876 return nullptr;
2877 }
2878 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
2879 return nullptr;
2880 }
2881
2882 if (start < 0 || stop < 0) {
2883 /* Only get the length for negative values. */
2884 Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2885 if (start < 0) {
2886 start += len;
2887 CLAMP_MIN(start, 0);
2888 }
2889 if (stop < 0) {
2890 stop += len;
2891 CLAMP_MIN(stop, 0);
2892 }
2893 }
2894
2895 if (stop - start <= 0) {
2896 return PyList_New(0);
2897 }
2898 else {
2899 return pyrna_prop_collection_subscript_slice(self, start, stop);
2900 }
2901 }
2902 }
2903#endif
2904
2905 PyErr_Format(PyExc_TypeError,
2906 "bpy_prop_collection[key]: invalid key, "
2907 "must be an int, not %.200s",
2908 Py_TYPE(key)->tp_name);
2909 return -1;
2910}
2911
2913{
2915
2916#if 0
2917 if (PyUnicode_Check(key)) {
2918 return pyrna_prop_array_subscript_str(self, PyUnicode_AsUTF8(key));
2919 }
2920 else
2921#endif
2922 if (PyIndex_Check(key)) {
2923 const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2924 if (i == -1 && PyErr_Occurred()) {
2925 return nullptr;
2926 }
2928 }
2929 if (PySlice_Check(key)) {
2930 Py_ssize_t step = 1;
2931 PySliceObject *key_slice = (PySliceObject *)key;
2932
2933 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2934 return nullptr;
2935 }
2936 if (step != 1) {
2937 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2938 return nullptr;
2939 }
2940 if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2941 /* NOTE: no significant advantage with optimizing [:] slice as with collections,
2942 * but include here for consistency with collection slice func */
2943 const Py_ssize_t len = pyrna_prop_array_length(self);
2944 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2945 }
2946
2947 const int len = pyrna_prop_array_length(self);
2948 Py_ssize_t start, stop, slicelength;
2949
2950 if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
2951 return nullptr;
2952 }
2953
2954 if (slicelength <= 0) {
2955 return PyTuple_New(0);
2956 }
2957
2958 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2959 }
2960
2961 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2962 return nullptr;
2963}
2964
2969static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, int length)
2970{
2971 PyObject *value_fast;
2972 if (!(value_fast = PySequence_Fast(value,
2973 "bpy_prop_array[slice] = value: "
2974 "element in assignment is not a sequence type")))
2975 {
2976 return nullptr;
2977 }
2978 if (PySequence_Fast_GET_SIZE(value_fast) != length) {
2979 Py_DECREF(value_fast);
2980 PyErr_SetString(PyExc_ValueError,
2981 "bpy_prop_array[slice] = value: "
2982 "re-sizing bpy_struct element in arrays isn't supported");
2983
2984 return nullptr;
2985 }
2986
2987 return value_fast;
2988}
2989
2991 PyObject **value_items, float *value, int totdim, const int dimsize[], const float range[2])
2992{
2993 const int length = dimsize[0];
2994 if (totdim > 1) {
2995 int index = 0;
2996 int i;
2997 for (i = 0; i != length; i++) {
2998 PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
2999 if (UNLIKELY(subvalue == nullptr)) {
3000 return 0;
3001 }
3002
3004 PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range);
3005
3006 Py_DECREF(subvalue);
3007 }
3008 return index;
3009 }
3010
3011 BLI_assert(totdim == 1);
3012 const float min = range[0], max = range[1];
3013 int i;
3014 for (i = 0; i != length; i++) {
3015 float v = PyFloat_AsDouble(value_items[i]);
3016 CLAMP(v, min, max);
3017 value[i] = v;
3018 }
3019 return i;
3020}
3021
3023 PyObject **value_items, int *value, int totdim, const int dimsize[], const int range[2])
3024{
3025 const int length = dimsize[0];
3026 if (totdim > 1) {
3027 int index = 0;
3028 int i;
3029 for (i = 0; i != length; i++) {
3030 PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
3031 if (UNLIKELY(subvalue == nullptr)) {
3032 return 0;
3033 }
3034
3036 PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range);
3037
3038 Py_DECREF(subvalue);
3039 }
3040 return index;
3041 }
3042
3043 BLI_assert(totdim == 1);
3044 const int min = range[0], max = range[1];
3045 int i;
3046 for (i = 0; i != length; i++) {
3047 int v = PyLong_AsLong(value_items[i]);
3048 CLAMP(v, min, max);
3049 value[i] = v;
3050 }
3051 return i;
3052}
3053
3054static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items,
3055 bool *value,
3056 int totdim,
3057 const int dimsize[])
3058{
3059 const int length = dimsize[0];
3060 if (totdim > 1) {
3061 int index = 0;
3062 int i;
3063 for (i = 0; i != length; i++) {
3064 PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
3065 if (UNLIKELY(subvalue == nullptr)) {
3066 return 0;
3067 }
3068
3070 PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1]);
3071
3072 Py_DECREF(subvalue);
3073 }
3074 return index;
3075 }
3076
3077 BLI_assert(totdim == 1);
3078 int i;
3079 for (i = 0; i != length; i++) {
3080 const int v = PyLong_AsLong(value_items[i]);
3081 value[i] = v;
3082 }
3083 return i;
3084}
3085
3086/* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */
3088 PropertyRNA *prop,
3089 int arraydim,
3090 int arrayoffset,
3091 int start,
3092 int stop,
3093 int length,
3094 PyObject *value_orig)
3095{
3096 const int length_flat = RNA_property_array_length(ptr, prop);
3097 PyObject *value;
3098 void *values_alloc = nullptr;
3099 int ret = 0;
3100
3101 if (value_orig == nullptr) {
3102 PyErr_SetString(
3103 PyExc_TypeError,
3104 "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
3105 return -1;
3106 }
3107
3108 if (!(value = PySequence_Fast(
3109 value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type")))
3110 {
3111 return -1;
3112 }
3113
3114 if (PySequence_Fast_GET_SIZE(value) != stop - start) {
3115 Py_DECREF(value);
3116 PyErr_SetString(PyExc_TypeError,
3117 "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported");
3118 return -1;
3119 }
3120
3121 int dimsize[3];
3122 const int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
3123 if (totdim > 1) {
3124 BLI_assert(dimsize[arraydim] == length);
3125 }
3126
3127 int span = 1;
3128 if (totdim > 1) {
3129 for (int i = arraydim + 1; i < totdim; i++) {
3130 span *= dimsize[i];
3131 }
3132 }
3133
3134 PyObject **value_items = PySequence_Fast_ITEMS(value);
3135 switch (RNA_property_type(prop)) {
3136 case PROP_FLOAT: {
3137 float values_stack[PYRNA_STACK_ARRAY];
3138 float *values = static_cast<float *>(
3139 (length_flat > PYRNA_STACK_ARRAY) ?
3140 (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) :
3141 values_stack);
3142 if (start != 0 || stop != length) {
3143 /* Partial assignment? - need to get the array. */
3144 RNA_property_float_get_array(ptr, prop, values);
3145 }
3146
3147 float range[2];
3148 RNA_property_float_range(ptr, prop, &range[0], &range[1]);
3149
3150 dimsize[arraydim] = stop - start;
3152 &values[arrayoffset + (start * span)],
3153 totdim - arraydim,
3154 &dimsize[arraydim],
3155 range);
3156
3157 if (PyErr_Occurred()) {
3158 ret = -1;
3159 }
3160 else {
3161 RNA_property_float_set_array(ptr, prop, values);
3162 }
3163 break;
3164 }
3165 case PROP_INT: {
3166 int values_stack[PYRNA_STACK_ARRAY];
3167 int *values = static_cast<int *>(
3168 (length_flat > PYRNA_STACK_ARRAY) ?
3169 (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) :
3170 values_stack);
3171 if (start != 0 || stop != length) {
3172 /* Partial assignment? - need to get the array. */
3173 RNA_property_int_get_array(ptr, prop, values);
3174 }
3175
3176 int range[2];
3177 RNA_property_int_range(ptr, prop, &range[0], &range[1]);
3178
3179 dimsize[arraydim] = stop - start;
3181 &values[arrayoffset + (start * span)],
3182 totdim - arraydim,
3183 &dimsize[arraydim],
3184 range);
3185
3186 if (PyErr_Occurred()) {
3187 ret = -1;
3188 }
3189 else {
3190 RNA_property_int_set_array(ptr, prop, values);
3191 }
3192 break;
3193 }
3194 case PROP_BOOLEAN: {
3195 bool values_stack[PYRNA_STACK_ARRAY];
3196 bool *values = static_cast<bool *>(
3197 (length_flat > PYRNA_STACK_ARRAY) ?
3198 (values_alloc = PyMem_MALLOC(sizeof(bool) * length_flat)) :
3199 values_stack);
3200
3201 if (start != 0 || stop != length) {
3202 /* Partial assignment? - need to get the array. */
3203 RNA_property_boolean_get_array(ptr, prop, values);
3204 }
3205
3206 dimsize[arraydim] = stop - start;
3208 &values[arrayoffset + (start * span)],
3209 totdim - arraydim,
3210 &dimsize[arraydim]);
3211
3212 if (PyErr_Occurred()) {
3213 ret = -1;
3214 }
3215 else {
3216 RNA_property_boolean_set_array(ptr, prop, values);
3217 }
3218 break;
3219 }
3220 default:
3221 PyErr_SetString(PyExc_TypeError, "not an array type");
3222 ret = -1;
3223 break;
3224 }
3225
3226 Py_DECREF(value);
3227
3228 if (values_alloc) {
3229 PyMem_FREE(values_alloc);
3230 }
3231
3232 return ret;
3233}
3234
3236 Py_ssize_t keynum,
3237 PyObject *value)
3238{
3240
3242
3243 if (keynum < 0) {
3244 keynum += len;
3245 }
3246
3247 if (keynum >= 0 && keynum < len) {
3248 return pyrna_py_to_prop_array_index(self, keynum, value);
3249 }
3250
3251 PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
3252 return -1;
3253}
3254
3256 PyObject *key,
3257 PyObject *value)
3258{
3259 // char *keyname = nullptr; /* Not supported yet. */
3260 int ret = -1;
3261
3263
3264 if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
3265 PyErr_Format(PyExc_AttributeError,
3266 "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
3268 RNA_struct_identifier(self->ptr.type));
3269 ret = -1;
3270 }
3271
3272 else if (PyIndex_Check(key)) {
3273 const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
3274 if (i == -1 && PyErr_Occurred()) {
3275 ret = -1;
3276 }
3277 else {
3279 }
3280 }
3281 else if (PySlice_Check(key)) {
3282 const Py_ssize_t len = pyrna_prop_array_length(self);
3283 Py_ssize_t start, stop, step, slicelength;
3284
3285 if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
3286 ret = -1;
3287 }
3288 else if (slicelength <= 0) {
3289 ret = 0; /* Do nothing. */
3290 }
3291 else if (step == 1) {
3293 &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value);
3294 }
3295 else {
3296 PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA");
3297 ret = -1;
3298 }
3299 }
3300 else {
3301 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
3302 ret = -1;
3303 }
3304
3305 if (ret != -1) {
3306 if (RNA_property_update_check(self->prop)) {
3308 }
3309 }
3310
3311 return ret;
3312}
3313
3314/* For slice only. */
3315static PyMappingMethods pyrna_prop_array_as_mapping = {
3316 /*mp_length*/ (lenfunc)pyrna_prop_array_length,
3317 /*mp_subscript*/ (binaryfunc)pyrna_prop_array_subscript,
3318 /*mp_ass_subscript*/ (objobjargproc)pyrna_prop_array_ass_subscript,
3319};
3320
3321static PyMappingMethods pyrna_prop_collection_as_mapping = {
3322 /*mp_length*/ (lenfunc)pyrna_prop_collection_length,
3323 /*mp_subscript*/ (binaryfunc)pyrna_prop_collection_subscript,
3324 /*mp_ass_subscript*/ (objobjargproc)pyrna_prop_collection_ass_subscript,
3325};
3326
3327/* Only for fast bool's, large structs, assign nb_bool on init. */
3328static PyNumberMethods pyrna_prop_array_as_number = {
3329 /*nb_add*/ nullptr,
3330 /*nb_subtract*/ nullptr,
3331 /*nb_multiply*/ nullptr,
3332 /*nb_remainder*/ nullptr,
3333 /*nb_divmod*/ nullptr,
3334 /*nb_power*/ nullptr,
3335 /*nb_negative*/ nullptr,
3336 /*nb_positive*/ nullptr,
3337 /*nb_absolute*/ nullptr,
3338 /*nb_bool*/ (inquiry)pyrna_prop_array_bool,
3339};
3340static PyNumberMethods pyrna_prop_collection_as_number = {
3341 /*nb_add*/ nullptr,
3342 /*nb_subtract*/ nullptr,
3343 /*nb_multiply*/ nullptr,
3344 /*nb_remainder*/ nullptr,
3345 /*nb_divmod*/ nullptr,
3346 /*nb_power*/ nullptr,
3347 /*nb_negative*/ nullptr,
3348 /*nb_positive*/ nullptr,
3349 /*nb_absolute*/ nullptr,
3350 /*nb_bool*/ (inquiry)pyrna_prop_collection_bool,
3351 /*nb_invert*/ nullptr,
3352 /*nb_lshift*/ nullptr,
3353 /*nb_rshift*/ nullptr,
3354 /*nb_and*/ nullptr,
3355 /*nb_xor*/ nullptr,
3356 /*nb_or*/ nullptr,
3357 /*nb_int*/ nullptr,
3358 /*nb_reserved*/ nullptr,
3359 /*nb_float*/ nullptr,
3360 /*nb_inplace_add*/ nullptr,
3361 /*nb_inplace_subtract*/ nullptr,
3362 /*nb_inplace_multiply*/ nullptr,
3363 /*nb_inplace_remainder*/ nullptr,
3364 /*nb_inplace_power*/ nullptr,
3365 /*nb_inplace_lshift*/ nullptr,
3366 /*nb_inplace_rshift*/ nullptr,
3367 /*nb_inplace_and*/ nullptr,
3368 /*nb_inplace_xor*/ nullptr,
3369 /*nb_inplace_or*/ nullptr,
3370 /*nb_floor_divide*/ nullptr,
3371 /*nb_true_divide*/ nullptr,
3372 /*nb_inplace_floor_divide*/ nullptr,
3373 /*nb_inplace_true_divide*/ nullptr,
3374 /*nb_index*/ nullptr,
3375 /*nb_matrix_multiply*/ nullptr,
3376 /*nb_inplace_matrix_multiply*/ nullptr,
3377};
3378
3380{
3381 return pyrna_array_contains_py(&self->ptr, self->prop, value);
3382}
3383
3385{
3386 PointerRNA newptr; /* Not used, just so RNA_property_collection_lookup_string runs. */
3387
3388 if (PyTuple_Check(key)) {
3389 /* Special case, for ID data-blocks. */
3391 self, key, "(id, lib) in bpy_prop_collection", false, nullptr);
3392 }
3393
3394 /* Key in dict style check. */
3395 const char *keyname = PyUnicode_AsUTF8(key);
3396
3397 if (keyname == nullptr) {
3398 PyErr_SetString(PyExc_TypeError,
3399 "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
3400 return -1;
3401 }
3402
3403 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
3404 return 1;
3405 }
3407 self, "bpy_prop_collection.__contains__") == -1)
3408 {
3409 return -1;
3410 }
3411
3412 return 0;
3413}
3414
3415static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
3416{
3417 const char *name = PyUnicode_AsUTF8(value);
3418
3420
3421 if (!name) {
3422 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
3423 return -1;
3424 }
3425
3426 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3427 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
3428 return -1;
3429 }
3430
3431 IDProperty *group = RNA_struct_idprops(&self->ptr, false);
3432
3433 if (!group) {
3434 return 0;
3435 }
3436
3437 return IDP_GetPropertyFromGroup(group, name) ? 1 : 0;
3438}
3439
3440static PySequenceMethods pyrna_prop_array_as_sequence = {
3441 /*sq_length*/ (lenfunc)pyrna_prop_array_length,
3442 /*sq_concat*/ nullptr,
3443 /*sq_repeat*/ nullptr,
3444 /* Only set this so `PySequence_Check()` returns True. */
3445 /*sq_item*/ (ssizeargfunc)pyrna_prop_array_subscript_int,
3446 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
3447 /*sq_ass_item*/ (ssizeobjargproc)prop_subscript_ass_array_int,
3448 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
3449 /*sq_contains*/ (objobjproc)pyrna_prop_array_contains,
3450 /*sq_inplace_concat*/ nullptr,
3451 /*sq_inplace_repeat*/ nullptr,
3452};
3453
3454static PySequenceMethods pyrna_prop_collection_as_sequence = {
3455 /*sq_length*/ (lenfunc)pyrna_prop_collection_length,
3456 /*sq_concat*/ nullptr,
3457 /*sq_repeat*/ nullptr,
3458 /* Only set this so PySequence_Check() returns True */
3459 /*sq_item*/ (ssizeargfunc)pyrna_prop_collection_subscript_int,
3460 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
3461 /* Let mapping take this one: #pyrna_prop_collection_ass_subscript_int */
3462 /*sq_ass_item*/ nullptr,
3463 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
3464 /*sq_contains*/ (objobjproc)pyrna_prop_collection_contains,
3465 /*sq_inplace_concat*/ nullptr,
3466 /*sq_inplace_repeat*/ nullptr,
3467};
3468
3469static PySequenceMethods pyrna_struct_as_sequence = {
3470 /*sq_length*/ nullptr, /* Can't set the len otherwise it can evaluate as false */
3471 /*sq_concat*/ nullptr,
3472 /*sq_repeat*/ nullptr,
3473 /* Only set this so `PySequence_Check()` returns True. */
3474 /*sq_item*/ nullptr,
3475 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
3476 /*sq_ass_item*/ nullptr,
3477 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
3478 /*sq_contains*/ (objobjproc)pyrna_struct_contains,
3479 /*sq_inplace_concat*/ nullptr,
3480 /*sq_inplace_repeat*/ nullptr,
3481};
3482
3483static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
3484{
3485 /* Mostly copied from BPy_IDGroup_Map_GetItem. */
3486 const char *name = PyUnicode_AsUTF8(key);
3487
3489
3490 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3491 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
3492 return nullptr;
3493 }
3494
3495 if (name == nullptr) {
3496 PyErr_SetString(PyExc_TypeError,
3497 "bpy_struct[key]: only strings are allowed as keys of ID properties");
3498 return nullptr;
3499 }
3500
3501 IDProperty *group = RNA_struct_idprops(&self->ptr, false);
3502
3503 if (group == nullptr) {
3504 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
3505 return nullptr;
3506 }
3507
3508 IDProperty *idprop = IDP_GetPropertyFromGroup(group, name);
3509
3510 if (idprop == nullptr) {
3511 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
3512 return nullptr;
3513 }
3514
3515 return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
3516}
3517
3518static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
3519{
3521
3522 IDProperty *group = RNA_struct_idprops(&self->ptr, true);
3523
3524#ifdef USE_PEDANTIC_WRITE
3525 if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
3526 return -1;
3527 }
3528#endif /* USE_PEDANTIC_WRITE */
3529
3530 if (group == nullptr) {
3531 PyErr_SetString(PyExc_TypeError,
3532 "bpy_struct[key] = val: id properties not supported for this type");
3533 return -1;
3534 }
3535
3536 if (value && BPy_StructRNA_Check(value)) {
3537 BPy_StructRNA *val = (BPy_StructRNA *)value;
3538 if (val && self->ptr.type && val->ptr.type) {
3541 {
3542 PyErr_SetString(
3543 PyExc_TypeError,
3544 "bpy_struct[key] = val: datablock id properties not supported for this type");
3545 return -1;
3546 }
3547 }
3548 }
3549
3550 return BPy_Wrap_SetMapItem(group, key, value);
3551}
3552
3553static PyMappingMethods pyrna_struct_as_mapping = {
3554 /*mp_length*/ (lenfunc) nullptr,
3555 /*mp_subscript*/ (binaryfunc)pyrna_struct_subscript,
3556 /*mp_ass_subscript*/ (objobjargproc)pyrna_struct_ass_subscript,
3557};
3558
3560 /* Wrap. */
3561 pyrna_struct_keys_doc,
3562 ".. method:: keys()\n"
3563 "\n"
3564 " Returns the keys of this objects custom properties (matches Python's\n"
3565 " dictionary function of the same name).\n"
3566 "\n"
3567 " :return: custom property keys.\n"
3568 " :rtype: :class:`idprop.types.IDPropertyGroupViewKeys`\n"
3571{
3573
3574 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3575 PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
3576 return nullptr;
3577 }
3578
3579 /* `group` may be nullptr. */
3580 IDProperty *group = RNA_struct_idprops(&self->ptr, false);
3581 return BPy_Wrap_GetKeys_View_WithID(self->ptr.owner_id, group);
3582}
3583
3585 /* Wrap. */
3586 pyrna_struct_items_doc,
3587 ".. method:: items()\n"
3588 "\n"
3589 " Returns the items of this objects custom properties (matches Python's\n"
3590 " dictionary function of the same name).\n"
3591 "\n"
3592 " :return: custom property key, value pairs.\n"
3593 " :rtype: :class:`idprop.types.IDPropertyGroupViewItems`\n"
3596{
3598
3599 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3600 PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
3601 return nullptr;
3602 }
3603
3604 /* `group` may be nullptr. */
3605 IDProperty *group = RNA_struct_idprops(&self->ptr, false);
3606 return BPy_Wrap_GetItems_View_WithID(self->ptr.owner_id, group);
3607}
3608
3610 /* Wrap. */
3611 pyrna_struct_values_doc,
3612 ".. method:: values()\n"
3613 "\n"
3614 " Returns the values of this objects custom properties (matches Python's\n"
3615 " dictionary function of the same name).\n"
3616 "\n"
3617 " :return: custom property values.\n"
3618 " :rtype: :class:`idprop.types.IDPropertyGroupViewValues`\n"
3621{
3623
3624 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3625 PyErr_SetString(PyExc_TypeError,
3626 "bpy_struct.values(): this type doesn't support IDProperties");
3627 return nullptr;
3628 }
3629
3630 /* `group` may be nullptr. */
3631 IDProperty *group = RNA_struct_idprops(&self->ptr, false);
3632 return BPy_Wrap_GetValues_View_WithID(self->ptr.owner_id, group);
3633}
3634
3636 /* Wrap. */
3637 pyrna_struct_is_property_set_doc,
3638 ".. method:: is_property_set(property, ghost=True)\n"
3639 "\n"
3640 " Check if a property is set, use for testing operator properties.\n"
3641 "\n"
3642 " :arg ghost: Used for operators that re-run with previous settings.\n"
3643 " In this case the property is not marked as set,\n"
3644 " yet the value from the previous execution is used.\n"
3645 "\n"
3646 " In rare cases you may want to set this option to false.\n"
3647 "\n"
3648 " :type ghost: bool\n"
3649 " :return: True when the property has been set.\n"
3650 " :rtype: bool\n");
3651static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args, PyObject *kw)
3652{
3653 PropertyRNA *prop;
3654 const char *name;
3655 bool use_ghost = true;
3656
3658
3659 static const char *_keywords[] = {"", "ghost", nullptr};
3660 static _PyArg_Parser _parser = {
3662 "s" /* `name` (positional). */
3663 "|$" /* Optional keyword only arguments. */
3664 "O&" /* `ghost` */
3665 ":is_property_set",
3666 _keywords,
3667 nullptr,
3668 };
3669 if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &name, PyC_ParseBool, &use_ghost)) {
3670 return nullptr;
3671 }
3672
3673 if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
3674 PyErr_Format(PyExc_TypeError,
3675 "%.200s.is_property_set(\"%.200s\") not found",
3676 RNA_struct_identifier(self->ptr.type),
3677 name);
3678 return nullptr;
3679 }
3680
3681 return PyBool_FromLong(RNA_property_is_set_ex(&self->ptr, prop, use_ghost));
3682}
3683
3685 /* Wrap. */
3686 pyrna_struct_property_unset_doc,
3687 ".. method:: property_unset(property)\n"
3688 "\n"
3689 " Unset a property, will use default value afterward.\n");
3690static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args)
3691{
3692 PropertyRNA *prop;
3693 const char *name;
3694
3696
3697 if (!PyArg_ParseTuple(args, "s:property_unset", &name)) {
3698 return nullptr;
3699 }
3700
3701 if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
3702 PyErr_Format(PyExc_TypeError,
3703 "%.200s.property_unset(\"%.200s\") not found",
3704 RNA_struct_identifier(self->ptr.type),
3705 name);
3706 return nullptr;
3707 }
3708
3709 RNA_property_unset(&self->ptr, prop);
3710
3711 Py_RETURN_NONE;
3712}
3713
3715 /* Wrap. */
3716 pyrna_struct_is_property_hidden_doc,
3717 ".. method:: is_property_hidden(property)\n"
3718 "\n"
3719 " Check if a property is hidden.\n"
3720 "\n"
3721 " :return: True when the property is hidden.\n"
3722 " :rtype: bool\n");
3723static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
3724{
3725 PropertyRNA *prop;
3726 const char *name;
3727
3729
3730 if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) {
3731 return nullptr;
3732 }
3733
3734 if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
3735 PyErr_Format(PyExc_TypeError,
3736 "%.200s.is_property_hidden(\"%.200s\") not found",
3737 RNA_struct_identifier(self->ptr.type),
3738 name);
3739 return nullptr;
3740 }
3741
3742 return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
3743}
3744
3746 /* Wrap. */
3747 pyrna_struct_is_property_readonly_doc,
3748 ".. method:: is_property_readonly(property)\n"
3749 "\n"
3750 " Check if a property is readonly.\n"
3751 "\n"
3752 " :return: True when the property is readonly (not writable).\n"
3753 " :rtype: bool\n");
3754static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args)
3755{
3756 PropertyRNA *prop;
3757 const char *name;
3758
3760
3761 if (!PyArg_ParseTuple(args, "s:is_property_readonly", &name)) {
3762 return nullptr;
3763 }
3764
3765 if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
3766 PyErr_Format(PyExc_TypeError,
3767 "%.200s.is_property_readonly(\"%.200s\") not found",
3768 RNA_struct_identifier(self->ptr.type),
3769 name);
3770 return nullptr;
3771 }
3772
3773 return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop));
3774}
3775
3777 /* Wrap. */
3778 pyrna_struct_is_property_overridable_library_doc,
3779 ".. method:: is_property_overridable_library(property)\n"
3780 "\n"
3781 " Check if a property is overridable.\n"
3782 "\n"
3783 " :return: True when the property is overridable.\n"
3784 " :rtype: bool\n");
3786{
3787 PropertyRNA *prop;
3788 const char *name;
3789
3791
3792 if (!PyArg_ParseTuple(args, "s:is_property_overridable_library", &name)) {
3793 return nullptr;
3794 }
3795
3796 if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
3797 PyErr_Format(PyExc_TypeError,
3798 "%.200s.is_property_overridable_library(\"%.200s\") not found",
3799 RNA_struct_identifier(self->ptr.type),
3800 name);
3801 return nullptr;
3802 }
3803
3804 return PyBool_FromLong(long(RNA_property_overridable_get(&self->ptr, prop)));
3805}
3806
3808 /* Wrap. */
3809 pyrna_struct_property_overridable_library_set_doc,
3810 ".. method:: property_overridable_library_set(property, overridable)\n"
3811 "\n"
3812 " Define a property as overridable or not (only for custom properties!).\n"
3813 "\n"
3814 " :return: True when the overridable status of the property was successfully set.\n"
3815 " :rtype: bool\n");
3817{
3818 PropertyRNA *prop;
3819 const char *name;
3820 int is_overridable;
3821
3823
3824 if (!PyArg_ParseTuple(args, "sp:property_overridable_library_set", &name, &is_overridable)) {
3825 return nullptr;
3826 }
3827
3828 if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
3829 PyErr_Format(PyExc_TypeError,
3830 "%.200s.property_overridable_library_set(\"%.200s\") not found",
3831 RNA_struct_identifier(self->ptr.type),
3832 name);
3833 return nullptr;
3834 }
3835
3836 return PyBool_FromLong(
3837 long(RNA_property_overridable_library_set(&self->ptr, prop, bool(is_overridable))));
3838}
3839
3841 /* Wrap. */
3842 pyrna_struct_path_resolve_doc,
3843 ".. method:: path_resolve(path, coerce=True)\n"
3844 "\n"
3845 " Returns the property from the path, raise an exception when not found.\n"
3846 "\n"
3847 " :arg path: path which this property resolves.\n"
3848 " :type path: str\n"
3849 " :arg coerce: optional argument, when True, the property will be converted\n"
3850 " into its Python representation.\n"
3851 " :type coerce: bool\n");
3852static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
3853{
3854 const char *path;
3855 PyObject *coerce = Py_True;
3856 PointerRNA r_ptr;
3857 PropertyRNA *r_prop;
3858 int index = -1;
3859
3861
3862 if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce)) {
3863 return nullptr;
3864 }
3865
3866 if (RNA_path_resolve_full_maybe_null(&self->ptr, path, &r_ptr, &r_prop, &index)) {
3867 if (r_prop) {
3868 if (index != -1) {
3869 if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
3870 PyErr_Format(PyExc_IndexError,
3871 "%.200s.path_resolve(\"%.200s\") index out of range",
3872 RNA_struct_identifier(self->ptr.type),
3873 path);
3874 return nullptr;
3875 }
3876
3877 return pyrna_array_index(&r_ptr, r_prop, index);
3878 }
3879
3880 if (coerce == Py_False) {
3881 return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
3882 }
3883
3884 return pyrna_prop_to_py(&r_ptr, r_prop);
3885 }
3886
3887 return pyrna_struct_CreatePyObject(&r_ptr);
3888 }
3889
3890 PyErr_Format(PyExc_ValueError,
3891 "%.200s.path_resolve(\"%.200s\") could not be resolved",
3892 RNA_struct_identifier(self->ptr.type),
3893 path);
3894 return nullptr;
3895}
3896
3898 /* Wrap. */
3899 pyrna_struct_path_from_id_doc,
3900 ".. method:: path_from_id(property=\"\")\n"
3901 "\n"
3902 " Returns the data path from the ID to this object (string).\n"
3903 "\n"
3904 " :arg property: Optional property name which can be used if the path is\n"
3905 " to a property of this object.\n"
3906 " :type property: str\n"
3907 " :return: The path from :class:`bpy.types.bpy_struct.id_data`\n"
3908 " to this struct and property (when given).\n"
3909 " :rtype: str\n");
3910static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
3911{
3912 const char *name = nullptr;
3913 PropertyRNA *prop;
3914 PyObject *ret;
3915
3917
3918 if (!PyArg_ParseTuple(args, "|s:path_from_id", &name)) {
3919 return nullptr;
3920 }
3921
3922 std::optional<std::string> path;
3923 if (name) {
3924 prop = RNA_struct_find_property(&self->ptr, name);
3925 if (prop == nullptr) {
3926 PyErr_Format(PyExc_AttributeError,
3927 "%.200s.path_from_id(\"%.200s\") not found",
3928 RNA_struct_identifier(self->ptr.type),
3929 name);
3930 return nullptr;
3931 }
3932
3933 path = RNA_path_from_ID_to_property(&self->ptr, prop);
3934 }
3935 else {
3936 path = RNA_path_from_ID_to_struct(&self->ptr);
3937 }
3938
3939 if (!path) {
3940 if (name) {
3941 PyErr_Format(PyExc_ValueError,
3942 "%.200s.path_from_id(\"%s\") found, but does not support path creation",
3943 RNA_struct_identifier(self->ptr.type),
3944 name);
3945 }
3946 else {
3947 PyErr_Format(PyExc_ValueError,
3948 "%.200s.path_from_id() does not support path creation for this type",
3949 RNA_struct_identifier(self->ptr.type));
3950 }
3951 return nullptr;
3952 }
3953
3954 ret = PyUnicode_FromString(path->c_str());
3955
3956 return ret;
3957}
3958
3960 /* Wrap. */
3961 pyrna_prop_path_from_id_doc,
3962 ".. method:: path_from_id()\n"
3963 "\n"
3964 " Returns the data path from the ID to this property (string).\n"
3965 "\n"
3966 " :return: The path from :class:`bpy.types.bpy_struct.id_data` to this property.\n"
3967 " :rtype: str\n");
3969{
3970 PropertyRNA *prop = self->prop;
3971 PyObject *ret;
3972
3973 const std::optional<std::string> path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
3974
3975 if (!path) {
3976 PyErr_Format(PyExc_ValueError,
3977 "%.200s.%.200s.path_from_id() does not support path creation for this type",
3978 RNA_struct_identifier(self->ptr.type),
3980 return nullptr;
3981 }
3982
3983 ret = PyUnicode_FromString(path->c_str());
3984
3985 return ret;
3986}
3987
3989 /* Wrap. */
3990 pyrna_prop_as_bytes_doc,
3991 ".. method:: as_bytes()\n"
3992 "\n"
3993 " Returns this string property as a byte rather than a Python string.\n"
3994 "\n"
3995 " :return: The string as bytes.\n"
3996 " :rtype: bytes\n");
3998{
3999
4000 if (RNA_property_type(self->prop) != PROP_STRING) {
4001 PyErr_Format(PyExc_TypeError,
4002 "%.200s.%.200s.as_bytes() must be a string",
4003 RNA_struct_identifier(self->ptr.type),
4005 return nullptr;
4006 }
4007
4008 PyObject *ret;
4009 char buf_fixed[256], *buf;
4010 int buf_len;
4011
4013 &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
4014
4015 ret = PyBytes_FromStringAndSize(buf, buf_len);
4016
4017 if (buf_fixed != buf) {
4018 MEM_freeN(buf);
4019 }
4020
4021 return ret;
4022}
4023
4025 /* Wrap. */
4026 pyrna_prop_update_doc,
4027 ".. method:: update()\n"
4028 "\n"
4029 " Execute the properties update callback.\n"
4030 "\n"
4031 " .. note::\n"
4032 " This is called when assigning a property,\n"
4033 " however in rare cases it's useful to call explicitly.\n");
4035{
4037 Py_RETURN_NONE;
4038}
4039
4041 /* Wrap. */
4042 pyrna_struct_type_recast_doc,
4043 ".. method:: type_recast()\n"
4044 "\n"
4045 " Return a new instance, this is needed because types\n"
4046 " such as textures can be changed at runtime.\n"
4047 "\n"
4048 " :return: a new instance of this object with the type initialized again.\n"
4049 " :rtype: :class:`bpy.types.bpy_struct`\n");
4051{
4052
4054
4055 PointerRNA r_ptr = RNA_pointer_recast(&self->ptr);
4056 return pyrna_struct_CreatePyObject(&r_ptr);
4057}
4058
4062static PyObject *pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, const char *id)
4063{
4064 PyObject *ret_test = nullptr;
4065 PyObject *subclasses = (PyObject *)((PyTypeObject *)cls)->tp_subclasses;
4066 if (subclasses) {
4067 /* Unfortunately we can't use the dict key because Python class names
4068 * don't match the bl_idname used internally. */
4069 BLI_assert(PyDict_CheckExact(subclasses));
4070 PyObject *key = nullptr;
4071 Py_ssize_t pos = 0;
4072 PyObject *value = nullptr;
4073 while (PyDict_Next(subclasses, &pos, &key, &value)) {
4074 BLI_assert(PyWeakref_CheckRef(value));
4075 PyObject *subcls = PyWeakref_GET_OBJECT(value);
4076 if (subcls != Py_None) {
4077 BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)subcls)->tp_dict,
4079 if (py_srna) {
4080 StructRNA *srna = static_cast<StructRNA *>(py_srna->ptr.data);
4081 if (STREQ(id, RNA_struct_identifier(srna))) {
4082 ret_test = subcls;
4083 break;
4084 }
4085 }
4086 ret_test = pyrna_struct_bl_rna_find_subclass_recursive(subcls, id);
4087 if (ret_test) {
4088 break;
4089 }
4090 }
4091 }
4092 }
4093 return ret_test;
4094}
4095
4097 /* Wrap. */
4098 pyrna_struct_bl_rna_get_subclass_py_doc,
4099 ".. classmethod:: bl_rna_get_subclass_py(id, default=None)\n"
4100 "\n"
4101 " :arg id: The RNA type identifier.\n"
4102 " :type id: str\n"
4103 " :return: The class or default when not found.\n"
4104 " :rtype: type\n");
4105static PyObject *pyrna_struct_bl_rna_get_subclass_py(PyObject *cls, PyObject *args)
4106{
4107 char *id;
4108 PyObject *ret_default = Py_None;
4109
4110 if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass_py", &id, &ret_default)) {
4111 return nullptr;
4112 }
4114 if (ret == nullptr) {
4115 ret = ret_default;
4116 }
4117 return Py_NewRef(ret);
4118}
4119
4121 /* Wrap. */
4122 pyrna_struct_bl_rna_get_subclass_doc,
4123 ".. classmethod:: bl_rna_get_subclass(id, default=None)\n"
4124 "\n"
4125 " :arg id: The RNA type identifier.\n"
4126 " :type id: str\n"
4127 " :return: The RNA type or default when not found.\n"
4128 " :rtype: :class:`bpy.types.Struct` subclass\n");
4129static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
4130{
4131 const char *id;
4132 PyObject *ret_default = Py_None;
4133
4134 if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) {
4135 return nullptr;
4136 }
4137
4138 const BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)cls)->tp_dict,
4140 if (py_srna == nullptr) {
4141 PyErr_SetString(PyExc_ValueError, "Not a registered class");
4142 return nullptr;
4143 }
4144 const StructRNA *srna_base = static_cast<const StructRNA *>(py_srna->ptr.data);
4145
4146 if (srna_base == &RNA_Node) {
4147 /* If the given idname is an alias, translate it to the proper idname. */
4149
4151 if (nt) {
4152 PointerRNA ptr = RNA_pointer_create(nullptr, &RNA_Struct, nt->rna_ext.srna);
4154 }
4155 }
4156 else {
4157 /* TODO: panels, menus etc. */
4158 PyErr_Format(
4159 PyExc_ValueError, "Class type \"%.200s\" not supported", RNA_struct_identifier(srna_base));
4160 return nullptr;
4161 }
4162
4163 return Py_NewRef(ret_default);
4164}
4165
4166static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict)
4167{
4168 PyObject *list_tmp;
4169
4170 list_tmp = PyDict_Keys(dict);
4171 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
4172 Py_DECREF(list_tmp);
4173}
4174
4175static void pyrna_dir_members_py(PyObject *list, PyObject *self)
4176{
4177 PyObject *dict;
4178 PyObject **dict_ptr;
4179
4180 dict_ptr = _PyObject_GetDictPtr((PyObject *)self);
4181
4182 if (dict_ptr && (dict = *dict_ptr)) {
4184 }
4185
4186 dict = ((PyTypeObject *)Py_TYPE(self))->tp_dict;
4187 if (dict) {
4189 }
4190
4191 /* Since this is least common case, handle it last. */
4193 BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self;
4194 if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) {
4195 PointerRNA r_ptr;
4196
4197 if (RNA_property_collection_type_get(&self_prop->ptr, self_prop->prop, &r_ptr)) {
4198 PyObject *cls = pyrna_struct_Subtype(&r_ptr); /* borrows */
4199 dict = ((PyTypeObject *)cls)->tp_dict;
4201 Py_DECREF(cls);
4202 }
4203 }
4204 }
4205}
4206
4207static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
4208{
4209 const char *idname;
4210
4211 /* For looping over attributes and functions. */
4212 PropertyRNA *iterprop;
4213
4214 {
4215 PointerRNA tptr = RNA_pointer_create(nullptr, &RNA_Struct, ptr->type);
4216 iterprop = RNA_struct_find_property(&tptr, "functions");
4217
4218 RNA_PROP_BEGIN (&tptr, itemptr, iterprop) {
4219 FunctionRNA *func = static_cast<FunctionRNA *>(itemptr.data);
4220 if (RNA_function_defined(func)) {
4221 idname = RNA_function_identifier(static_cast<FunctionRNA *>(itemptr.data));
4222 PyList_APPEND(list, PyUnicode_FromString(idname));
4223 }
4224 }
4226 }
4227
4228 {
4229 /*
4230 * Collect RNA attributes
4231 */
4232 char name[256], *name_ptr;
4233 int name_len;
4234
4236
4237 RNA_PROP_BEGIN (ptr, itemptr, iterprop) {
4238 /* Custom-properties are exposed using `__getitem__`, exclude from `__dir__`. */
4239 if (RNA_property_is_idprop(static_cast<const PropertyRNA *>(itemptr.data))) {
4240 continue;
4241 }
4242 name_ptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &name_len);
4243
4244 if (name_ptr) {
4245 PyList_APPEND(list, PyUnicode_FromStringAndSize(name_ptr, name_len));
4246
4247 if (name != name_ptr) {
4248 MEM_freeN(name_ptr);
4249 }
4250 }
4251 }
4253 }
4254}
4255
4257{
4258 PyObject *ret;
4259
4261
4262 /* Include this in case this instance is a subtype of a Python class
4263 * In these instances we may want to return a function or variable provided by the subtype. */
4264 ret = PyList_New(0);
4265
4267 pyrna_dir_members_py(ret, (PyObject *)self);
4268 }
4269
4271
4272 if (self->ptr.type == &RNA_Context) {
4273 ListBase lb = CTX_data_dir_get(static_cast<const bContext *>(self->ptr.data));
4274
4275 LISTBASE_FOREACH (LinkData *, link, &lb) {
4276 PyList_APPEND(ret, PyUnicode_FromString(static_cast<const char *>(link->data)));
4277 }
4278
4279 BLI_freelistN(&lb);
4280 }
4281
4282 {
4283 /* set(), this is needed to remove-doubles because the deferred
4284 * register-props will be in both the Python __dict__ and accessed as RNA */
4285
4286 PyObject *set = PySet_New(ret);
4287
4288 Py_DECREF(ret);
4289 ret = PySequence_List(set);
4290 Py_DECREF(set);
4291 }
4292
4293 return ret;
4294}
4295
4297 /* Wrap. */
4298 pyrna_struct_id_properties_ensure_doc,
4299 ".. method:: id_properties_ensure()\n"
4300 "\n"
4301 " :return: the parent group for an RNA struct's custom IDProperties.\n"
4302 " :rtype: :class:`idprop.types.IDPropertyGroup`\n");
4304{
4306
4307 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
4308 PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties");
4309 return nullptr;
4310 }
4311
4312 IDProperty *idprops = RNA_struct_idprops(&self->ptr, true);
4313
4314 /* This is a paranoid check that theoretically might not be necessary.
4315 * It allows the possibility that some structs can't ensure IDProperties. */
4316 if (idprops == nullptr) {
4317 return Py_None;
4318 }
4319
4320 BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type);
4321 group->owner_id = self->ptr.owner_id;
4322 group->prop = idprops;
4323 group->parent = nullptr;
4324 return (PyObject *)group;
4325}
4326
4328 /* Wrap. */
4329 pyrna_struct_id_properties_ui_doc,
4330 ".. method:: id_properties_ui(key)\n"
4331 "\n"
4332 " :return: Return an object used to manage an IDProperty's UI data.\n"
4333 " :arg key: String name of the property.\n"
4334 " :rtype: :class:`bpy.types.IDPropertyUIManager`\n");
4335static PyObject *pyrna_struct_id_properties_ui(BPy_StructRNA *self, PyObject *args)
4336{
4338
4339 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
4340 PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties");
4341 return nullptr;
4342 }
4343
4344 const char *key;
4345 if (!PyArg_ParseTuple(args, "s:ui_data", &key)) {
4346 return nullptr;
4347 }
4348
4349 IDProperty *parent_group = RNA_struct_idprops(&self->ptr, true);
4350
4351 /* This is a paranoid check that theoretically might not be necessary.
4352 * It allows the possibility that some structs can't ensure IDProperties. */
4353 if (parent_group == nullptr) {
4354 return Py_None;
4355 }
4356
4357 IDProperty *property = IDP_GetPropertyFromGroup(parent_group, key);
4358 if (property == nullptr) {
4359 PyErr_SetString(PyExc_KeyError, "Property not found in IDProperty group");
4360 return nullptr;
4361 }
4362
4363 if (!IDP_ui_data_supported(property)) {
4364 PyErr_Format(PyExc_TypeError, "IDProperty \"%s\" does not support UI data", property->name);
4365 return nullptr;
4366 }
4367
4368 BPy_IDPropertyUIManager *ui_manager = PyObject_New(BPy_IDPropertyUIManager,
4370 ui_manager->property = property;
4371 return (PyObject *)ui_manager;
4372}
4373
4375 /* Wrap. */
4376 pyrna_struct_id_properties_clear_doc,
4377 ".. method:: id_properties_clear()\n"
4378 "\n"
4379 " :return: Remove the parent group for an RNA struct's custom IDProperties.\n");
4381{
4383
4384 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
4385 PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties");
4386 return nullptr;
4387 }
4388
4389 IDProperty **idprops = RNA_struct_idprops_p(&self->ptr);
4390
4391 if (*idprops) {
4392 IDP_FreeProperty(*idprops);
4393 *idprops = nullptr;
4394 }
4395
4396 Py_RETURN_NONE;
4397}
4398
4399/* ---------------getattr-------------------------------------------- */
4400static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
4401{
4402 const char *name = PyUnicode_AsUTF8(pyname);
4403 PyObject *ret;
4404 PropertyRNA *prop;
4405 FunctionRNA *func;
4406
4407 /* Allow `__class__` so `isinstance(ob, cls)` can be used without raising an exception. */
4408 PYRNA_STRUCT_CHECK_OBJ_UNLESS(self, name && STREQ(name, "__class__"));
4409
4410 if (name == nullptr) {
4411 PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
4412 ret = nullptr;
4413 }
4414 else if (
4415 /* RNA can't start with a "_", so for __dict__ and similar we can skip using RNA lookups. */
4416 name[0] == '_')
4417 {
4418 /* Annoying exception, maybe we need to have different types for this... */
4419 if (STR_ELEM(name, "__getitem__", "__setitem__") && !RNA_struct_idprops_check(self->ptr.type))
4420 {
4421 PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
4422 ret = nullptr;
4423 }
4424 else {
4425 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4426 }
4427 }
4428 else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
4429 ret = pyrna_prop_to_py(&self->ptr, prop);
4430 }
4431 /* RNA function only if callback is declared (no optional functions). */
4432 else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) {
4433 ret = pyrna_func_to_py(&self->ptr, func);
4434 }
4435 else if (self->ptr.type == &RNA_Context) {
4436 bContext *C = static_cast<bContext *>(self->ptr.data);
4437 if (C == nullptr) {
4438 PyErr_Format(PyExc_AttributeError,
4439 "bpy_struct: Context is 'nullptr', can't get \"%.200s\" from context",
4440 name);
4441 ret = nullptr;
4442 }
4443 else {
4444 PointerRNA newptr;
4446 PropertyRNA *newprop;
4447 int newindex;
4448 blender::StringRef newstr;
4449 short newtype;
4450
4451 /* An empty string is used to implement #CTX_data_dir_get,
4452 * without this check `getattr(context, "")` succeeds. */
4453 eContextResult done;
4454 if (name[0]) {
4455 done = eContextResult(
4456 CTX_data_get(C, name, &newptr, &newlb, &newprop, &newindex, &newstr, &newtype));
4457 }
4458 else {
4459 /* Fall through to built-in `getattr`. */
4461 }
4462
4463 if (done == CTX_RESULT_OK) {
4464 switch (newtype) {
4466 if (newptr.data == nullptr) {
4467 ret = Py_None;
4468 Py_INCREF(ret);
4469 }
4470 else {
4472 }
4473 break;
4474 case CTX_DATA_TYPE_STRING: {
4475 if (newstr.is_empty()) {
4476 ret = Py_None;
4477 Py_INCREF(ret);
4478 }
4479 else {
4480 ret = PyUnicode_FromStringAndSize(newstr.data(), newstr.size());
4481 }
4482 break;
4483 }
4485 ret = PyList_New(0);
4486 for (PointerRNA &ptr : newlb) {
4487 PyList_APPEND(ret, pyrna_struct_CreatePyObject(&ptr));
4488 }
4489 break;
4490 }
4492 if (newprop != nullptr) {
4493 /* Create pointer to parent ID, and path from ID to property. */
4494 PointerRNA idptr;
4495
4496 PointerRNA *base_ptr;
4497 std::optional<std::string> path_str;
4498
4499 if (newptr.owner_id) {
4500 idptr = RNA_id_pointer_create(newptr.owner_id);
4501 path_str = RNA_path_from_ID_to_property(&idptr, newprop);
4502 base_ptr = &idptr;
4503 }
4504 else {
4505 path_str = RNA_path_from_ptr_to_property_index(&newptr, newprop, 0, -1);
4506 base_ptr = &newptr;
4507 }
4508
4509 if (path_str) {
4510 ret = PyTuple_New(3);
4513 PyUnicode_FromString(path_str->c_str()),
4514 PyLong_FromLong(newindex));
4515 }
4516 else {
4517 ret = Py_None;
4518 Py_INCREF(ret);
4519 }
4520 }
4521 else {
4522 ret = Py_None;
4523 Py_INCREF(ret);
4524 }
4525 break;
4526 }
4527 default:
4528 /* Should never happen. */
4529 BLI_assert_msg(0, "Invalid context type");
4530
4531 PyErr_Format(PyExc_AttributeError,
4532 "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context",
4533 newtype,
4534 name);
4535 ret = nullptr;
4536 break;
4537 }
4538 }
4539 else if (done == CTX_RESULT_NO_DATA) {
4540 ret = Py_None;
4541 Py_INCREF(ret);
4542 }
4543 else { /* Not found in the context. */
4544 /* Lookup the subclass. raise an error if it's not found. */
4545 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4546 }
4547 }
4548 }
4549 else {
4550#if 0
4551 PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
4552 ret = nullptr;
4553#endif
4554 /* Include this in case this instance is a subtype of a Python class
4555 * In these instances we may want to return a function or variable provided by the subtype
4556 *
4557 * Also needed to return methods when it's not a subtype.
4558 */
4559
4560 /* The error raised here will be displayed */
4561 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4562 }
4563
4564 return ret;
4565}
4566
4567#if 0
4568static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname)
4569{
4570 PyObject *dict = *(_PyObject_GetDictPtr((PyObject *)self));
4571 if (UNLIKELY(dict == nullptr)) {
4572 return 0;
4573 }
4574
4575 return PyDict_Contains(dict, pyname);
4576}
4577#endif
4578
4579/* --------------- setattr------------------------------------------- */
4580
4581#if 0
4582static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr)
4583{
4584 PyObject *ret = PyType_Type.tp_getattro(cls, attr);
4585
4586/* Allows:
4587 * >>> bpy.types.Scene.foo = BoolProperty()
4588 * >>> bpy.types.Scene.foo
4589 * <bpy_struct, BoolProperty("foo")>
4590 * ...rather than returning the deferred class register tuple
4591 * as checked by BPy_PropDeferred_CheckTypeExact()
4592 *
4593 * Disable for now,
4594 * this is faking internal behavior in a way that's too tricky to maintain well. */
4595# if 0
4596 if ((ret == nullptr) /* || BPy_PropDeferred_CheckTypeExact(ret) */) {
4597 PyErr_Clear(); /* Clear error from tp_getattro. */
4598 StructRNA *srna = srna_from_self(cls, "StructRNA.__getattr__");
4599 if (srna) {
4600 PropertyRNA *prop = RNA_struct_type_find_property_no_base(srna, PyUnicode_AsUTF8(attr));
4601 if (prop) {
4602 PointerRNA tptr = RNA_pointer_create(nullptr, &RNA_Property, prop);
4604 }
4605 }
4606 if (ret == nullptr) {
4607 PyErr_Format(PyExc_AttributeError,
4608 "StructRNA.__getattr__: attribute \"%.200s\" not found",
4609 PyUnicode_AsUTF8(attr));
4610 }
4611 }
4612# endif
4613
4614 return ret;
4615}
4616#endif
4617
4618static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
4619{
4620 StructRNA *srna = srna_from_self(cls, "StructRNA.__setattr__");
4621 const bool is_deferred_prop = (value && BPy_PropDeferred_CheckTypeExact(value));
4622 const char *attr_str = PyUnicode_AsUTF8(attr);
4623
4624 if (srna && !pyrna_write_check() &&
4625 (is_deferred_prop || RNA_struct_type_find_property_no_base(srna, attr_str)))
4626 {
4627 PyErr_Format(PyExc_AttributeError,
4628 "pyrna_struct_meta_idprop_setattro() "
4629 "can't set in readonly state '%.200s.%S'",
4630 ((PyTypeObject *)cls)->tp_name,
4631 attr);
4632 return -1;
4633 }
4634
4635 if (srna == nullptr) {
4636/* Allow setting on unregistered classes which can be registered later on. */
4637#if 0
4638 if (value && is_deferred_prop) {
4639 PyErr_Format(PyExc_AttributeError,
4640 "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'",
4641 ((PyTypeObject *)cls)->tp_name);
4642 return -1;
4643 }
4644#endif
4645 /* srna_from_self may set an error. */
4646 PyErr_Clear();
4647 return PyType_Type.tp_setattro(cls, attr, value);
4648 }
4649
4650 if (value) {
4651 /* Check if the value is a property. */
4652 if (is_deferred_prop) {
4653 const int ret = deferred_register_prop(srna, attr, value);
4654 if (ret == -1) {
4655 /* Error set. */
4656 return ret;
4657 }
4658
4659 /* pass through and assign to the classes __dict__ as well
4660 * so when the value isn't assigned it still creates the RNA property,
4661 * but gets confusing from script writers POV if the assigned value can't be read back. */
4662 }
4663 else {
4664 /* Remove existing property if it's set or we also end up with confusion. */
4665 RNA_def_property_free_identifier(srna, attr_str); /* Ignore on failure. */
4666 }
4667 }
4668 else { /* __delattr__ */
4669 /* First find if this is a registered property. */
4670 const int ret = RNA_def_property_free_identifier(srna, attr_str);
4671 if (ret == -1) {
4672 PyErr_Format(
4673 PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str);
4674 return -1;
4675 }
4676 }
4677
4678 /* Fallback to standard Python's `delattr/setattr`. */
4679 return PyType_Type.tp_setattro(cls, attr, value);
4680}
4681
4682static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject *value)
4683{
4684 const char *name = PyUnicode_AsUTF8(pyname);
4685 PropertyRNA *prop = nullptr;
4686
4688
4689#ifdef USE_PEDANTIC_WRITE
4690 if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
4691 return -1;
4692 }
4693#endif /* USE_PEDANTIC_WRITE */
4694
4695 if (name == nullptr) {
4696 PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
4697 return -1;
4698 }
4699 if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) {
4700 if (!RNA_property_editable_flag(&self->ptr, prop)) {
4701 PyErr_Format(PyExc_AttributeError,
4702 "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only",
4704 RNA_struct_identifier(self->ptr.type));
4705 return -1;
4706 }
4707 }
4708 else if (self->ptr.type == &RNA_Context) {
4709 /* Code just raises correct error, context prop's can't be set,
4710 * unless it's a part of the py class. */
4711 bContext *C = static_cast<bContext *>(self->ptr.data);
4712 if (C == nullptr) {
4713 PyErr_Format(PyExc_AttributeError,
4714 "bpy_struct: Context is 'nullptr', can't set \"%.200s\" from context",
4715 name);
4716 return -1;
4717 }
4718
4719 PointerRNA newptr;
4721 PropertyRNA *newprop;
4722 int newindex;
4723 blender::StringRef newstr;
4724 short newtype;
4725
4726 const eContextResult done = eContextResult(
4727 CTX_data_get(C, name, &newptr, &newlb, &newprop, &newindex, &newstr, &newtype));
4728
4729 if (done == CTX_RESULT_OK) {
4730 PyErr_Format(
4731 PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name);
4732 return -1;
4733 }
4734 }
4735
4736 /* pyrna_py_to_prop sets its own exceptions */
4737 if (prop) {
4738 if (value == nullptr) {
4739 PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
4740 return -1;
4741 }
4742 return pyrna_py_to_prop(&self->ptr, prop, nullptr, value, "bpy_struct: item.attr = val:");
4743 }
4744
4745 return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
4746}
4747
4749{
4750 PyObject *ret;
4751 PointerRNA r_ptr;
4752
4753 /* Include this in case this instance is a subtype of a Python class
4754 * In these instances we may want to return a function or variable provided by the subtype. */
4755 ret = PyList_New(0);
4756
4758 pyrna_dir_members_py(ret, (PyObject *)self);
4759 }
4760
4761 if (RNA_property_type(self->prop) == PROP_COLLECTION) {
4762 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4763 pyrna_dir_members_rna(ret, &r_ptr);
4764 }
4765 }
4766
4767 return ret;
4768}
4769
4770static PyObject *pyrna_prop_array_getattro(BPy_PropertyRNA *self, PyObject *pyname)
4771{
4772 return PyObject_GenericGetAttr((PyObject *)self, pyname);
4773}
4774
4775static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject *pyname)
4776{
4777 const char *name = PyUnicode_AsUTF8(pyname);
4778
4779 if (name == nullptr) {
4780 PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
4781 return nullptr;
4782 }
4783 if (name[0] != '_') {
4784 PyObject *ret;
4785 PropertyRNA *prop;
4786 FunctionRNA *func;
4787
4788 PointerRNA r_ptr;
4789 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4790 if ((prop = RNA_struct_find_property(&r_ptr, name))) {
4791 ret = pyrna_prop_to_py(&r_ptr, prop);
4792
4793 return ret;
4794 }
4795 if ((func = RNA_struct_find_function(r_ptr.type, name))) {
4796 PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr);
4797 ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func);
4798 Py_DECREF(self_collection);
4799
4800 return ret;
4801 }
4802 }
4803 }
4804
4805#if 0
4806 return PyObject_GenericGetAttr((PyObject *)self, pyname);
4807#else
4808 {
4809 /* Could just do this except for 1 awkward case.
4810 * `PyObject_GenericGetAttr((PyObject *)self, pyname);`
4811 * so as to support `bpy.data.libraries.load()` */
4812
4813 PyObject *ret = _PyObject_GenericGetAttrWithDict((PyObject *)self, pyname, nullptr, 1);
4814
4815 /* Check the '_' prefix to avoid inheriting `__call__` and similar. */
4816 if ((ret == nullptr) && (name[0] != '_')) {
4817 /* Since this is least common case, handle it last. */
4818 PointerRNA r_ptr;
4819 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4820 PyObject *cls = pyrna_struct_Subtype(&r_ptr);
4821 ret = _PyObject_GenericGetAttrWithDict(cls, pyname, nullptr, 1);
4822 Py_DECREF(cls);
4823
4824 if (ret != nullptr) {
4825 if (Py_TYPE(ret) == &PyMethodDescr_Type) {
4826 PyMethodDef *m = ((PyMethodDescrObject *)ret)->d_method;
4827 /* TODO: #METH_CLASS */
4828 if (m->ml_flags & METH_STATIC) {
4829 /* Keep 'ret' as-is. */
4830 }
4831 else {
4832 Py_DECREF(ret);
4833 ret = PyCMethod_New(m, (PyObject *)self, nullptr, nullptr);
4834 }
4835 }
4836 }
4837 }
4838 }
4839
4840 if (ret == nullptr) {
4841 PyErr_Format(
4842 PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
4843 }
4844
4845 return ret;
4846 }
4847#endif
4848}
4849
4850/* --------------- setattr------------------------------------------- */
4851static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pyname, PyObject *value)
4852{
4853 const char *name = PyUnicode_AsUTF8(pyname);
4854 PropertyRNA *prop;
4855 PointerRNA r_ptr;
4856
4857#ifdef USE_PEDANTIC_WRITE
4858 if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
4859 return -1;
4860 }
4861#endif /* USE_PEDANTIC_WRITE */
4862
4863 if (name == nullptr) {
4864 PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
4865 return -1;
4866 }
4867 if (value == nullptr) {
4868 PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
4869 return -1;
4870 }
4871 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4872 if ((prop = RNA_struct_find_property(&r_ptr, name))) {
4873 /* pyrna_py_to_prop sets its own exceptions. */
4874 return pyrna_py_to_prop(
4875 &r_ptr, prop, nullptr, value, "BPy_PropertyRNA - Attribute (setattr):");
4876 }
4877 }
4878
4879 PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
4880 return -1;
4881}
4882
4887{
4888 PointerRNA r_ptr;
4889
4890#ifdef USE_PEDANTIC_WRITE
4891 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
4892 return nullptr;
4893 }
4894#endif /* USE_PEDANTIC_WRITE */
4895
4896 RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
4897 if (!r_ptr.data) {
4898 PyErr_SetString(PyExc_TypeError,
4899 "bpy_prop_collection.add(): not supported for this collection");
4900 return nullptr;
4901 }
4902
4903 return pyrna_struct_CreatePyObject(&r_ptr);
4904}
4905
4907{
4908 const int key = PyLong_AsLong(value);
4909
4910#ifdef USE_PEDANTIC_WRITE
4911 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
4912 return nullptr;
4913 }
4914#endif /* USE_PEDANTIC_WRITE */
4915
4916 if (key == -1 && PyErr_Occurred()) {
4917 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument");
4918 return nullptr;
4919 }
4920
4921 if (!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
4922 PyErr_SetString(PyExc_TypeError,
4923 "bpy_prop_collection.remove() not supported for this collection");
4924 return nullptr;
4925 }
4926
4927 Py_RETURN_NONE;
4928}
4929
4931{
4932#ifdef USE_PEDANTIC_WRITE
4933 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
4934 return nullptr;
4935 }
4936#endif /* USE_PEDANTIC_WRITE */
4937
4939
4940 Py_RETURN_NONE;
4941}
4942
4944{
4945 int key = 0, pos = 0;
4946
4947#ifdef USE_PEDANTIC_WRITE
4948 if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
4949 return nullptr;
4950 }
4951#endif /* USE_PEDANTIC_WRITE */
4952
4953 if (!PyArg_ParseTuple(args, "ii", &key, &pos)) {
4954 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments");
4955 return nullptr;
4956 }
4957
4958 if (!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) {
4959 PyErr_SetString(PyExc_TypeError,
4960 "bpy_prop_collection.move() not supported for this collection");
4961 return nullptr;
4962 }
4963
4964 Py_RETURN_NONE;
4965}
4966
4968 /* Wrap. */
4969 pyrna_struct_get_id_data_doc,
4970 "The :class:`bpy.types.ID` object this datablock is from or None, (not available for "
4971 "all data types)");
4972static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self, void * /*closure*/)
4973{
4974 /* Used for struct and pointer since both have a ptr. */
4975 if (self->ptr.owner_id) {
4976 PointerRNA id_ptr = RNA_id_pointer_create((ID *)self->ptr.owner_id);
4977 return pyrna_struct_CreatePyObject(&id_ptr);
4978 }
4979
4980 Py_RETURN_NONE;
4981}
4982
4984 /* Wrap. */
4985 pyrna_struct_get_data_doc,
4986 "The data this property is using, *type* :class:`bpy.types.bpy_struct`");
4987static PyObject *pyrna_struct_get_data(BPy_DummyPointerRNA *self, void * /*closure*/)
4988{
4989 return pyrna_struct_CreatePyObject(&self->ptr);
4990}
4991
4993 /* Wrap. */
4994 pyrna_struct_get_rna_type_doc,
4995 "The property type for introspection");
4996static PyObject *pyrna_struct_get_rna_type(BPy_PropertyRNA *self, void * /*closure*/)
4997{
4998 PointerRNA tptr = RNA_pointer_create(nullptr, &RNA_Property, self->prop);
4999 return pyrna_struct_Subtype(&tptr);
5000}
5001
5002/*****************************************************************************/
5003/* Python attributes get/set structure: */
5004/*****************************************************************************/
5005
5006static PyGetSetDef pyrna_prop_getseters[] = {
5007 {"id_data",
5009 (setter) nullptr,
5010 pyrna_struct_get_id_data_doc,
5011 nullptr},
5012 {"data", (getter)pyrna_struct_get_data, (setter) nullptr, pyrna_struct_get_data_doc, nullptr},
5013 {"rna_type",
5015 (setter) nullptr,
5016 pyrna_struct_get_rna_type_doc,
5017 nullptr},
5018 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
5019};
5020
5021static PyGetSetDef pyrna_struct_getseters[] = {
5022 {"id_data",
5024 (setter) nullptr,
5025 pyrna_struct_get_id_data_doc,
5026 nullptr},
5027 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
5028};
5029
5030static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *closure);
5031
5032static PyGetSetDef pyrna_func_getseters[] = {
5033 {"__doc__", (getter)pyrna_func_doc_get, (setter) nullptr, nullptr, nullptr},
5034 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
5035};
5036
5038 /* Wrap. */
5039 pyrna_prop_collection_keys_doc,
5040 ".. method:: keys()\n"
5041 "\n"
5042 " Return the identifiers of collection members\n"
5043 " (matching Python's dict.keys() functionality).\n"
5044 "\n"
5045 " :return: the identifiers for each member of this collection.\n"
5046 " :rtype: list[str]\n");
5048{
5049 PyObject *ret = PyList_New(0);
5050 char name[256], *name_ptr;
5051 int name_len;
5052
5053 RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
5054 name_ptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &name_len);
5055
5056 if (name_ptr) {
5057 PyList_APPEND(ret, PyUnicode_FromStringAndSize(name_ptr, name_len));
5058
5059 if (name != name_ptr) {
5060 MEM_freeN(name_ptr);
5061 }
5062 }
5063 }
5065
5066 return ret;
5067}
5068
5070 /* Wrap. */
5071 pyrna_prop_collection_items_doc,
5072 ".. method:: items()\n"
5073 "\n"
5074 " Return the identifiers of collection members\n"
5075 " (matching Python's dict.items() functionality).\n"
5076 "\n"
5077 " :return: (key, value) pairs for each member of this collection.\n"
5078 " :rtype: list[tuple[str, :class:`bpy.types.bpy_struct`]]\n");
5080{
5081 PyObject *ret = PyList_New(0);
5082 PyObject *item;
5083 char name[256], *name_ptr;
5084 int name_len;
5085 int i = 0;
5086
5087 RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
5088 if (itemptr.data) {
5089 /* Add to Python list. */
5090 item = PyTuple_New(2);
5091 name_ptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &name_len);
5092 if (name_ptr) {
5093 PyTuple_SET_ITEM(item, 0, PyUnicode_FromStringAndSize(name_ptr, name_len));
5094 if (name != name_ptr) {
5095 MEM_freeN(name_ptr);
5096 }
5097 }
5098 else {
5099 /* A bit strange, but better than returning an empty list. */
5100 PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i));
5101 }
5102 PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
5103
5104 PyList_APPEND(ret, item);
5105
5106 i++;
5107 }
5108 }
5110
5111 return ret;
5112}
5113
5115 /* Wrap. */
5116 pyrna_prop_collection_values_doc,
5117 ".. method:: values()\n"
5118 "\n"
5119 " Return the values of collection\n"
5120 " (matching Python's dict.values() functionality).\n"
5121 "\n"
5122 " :return: The members of this collection.\n"
5123 " :rtype: list[:class:`bpy.types.bpy_struct`]\n");
5125{
5126 /* Re-use slice. */
5127 return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
5128}
5129
5131 /* Wrap. */
5132 pyrna_struct_get_doc,
5133 ".. method:: get(key, default=None)\n"
5134 "\n"
5135 " Returns the value of the custom property assigned to key or default\n"
5136 " when not found (matches Python's dictionary function of the same name).\n"
5137 "\n"
5138 " :arg key: The key associated with the custom property.\n"
5139 " :type key: str\n"
5140 " :arg default: Optional argument for the value to return if\n"
5141 " *key* is not found.\n"
5142 " :type default: Any\n"
5144static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
5145{
5146 IDProperty *group, *idprop;
5147
5148 const char *key;
5149 PyObject *def = Py_None;
5150
5152
5153 if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) {
5154 return nullptr;
5155 }
5156
5157 /* Mostly copied from BPy_IDGroup_Map_GetItem. */
5158 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
5159 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
5160 return nullptr;
5161 }
5162
5163 group = RNA_struct_idprops(&self->ptr, false);
5164 if (group) {
5165 idprop = IDP_GetPropertyFromGroup(group, key);
5166
5167 if (idprop) {
5168 return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
5169 }
5170 }
5171
5172 return Py_NewRef(def);
5173}
5174
5176 /* Wrap. */
5177 pyrna_struct_pop_doc,
5178 ".. method:: pop(key, default=None)\n"
5179 "\n"
5180 " Remove and return the value of the custom property assigned to key or default\n"
5181 " when not found (matches Python's dictionary function of the same name).\n"
5182 "\n"
5183 " :arg key: The key associated with the custom property.\n"
5184 " :type key: str\n"
5185 " :arg default: Optional argument for the value to return if\n"
5186 " *key* is not found.\n"
5187 " :type default: Any\n"
5189static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args)
5190{
5191 IDProperty *group, *idprop;
5192
5193 const char *key;
5194 PyObject *def = nullptr;
5195
5197
5198 if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) {
5199 return nullptr;
5200 }
5201
5202 /* Mostly copied from BPy_IDGroup_Map_GetItem. */
5203 if (RNA_struct_idprops_check(self->ptr.type) == 0) {
5204 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
5205 return nullptr;
5206 }
5207
5208 group = RNA_struct_idprops(&self->ptr, false);
5209 if (group) {
5210 idprop = IDP_GetPropertyFromGroup(group, key);
5211
5212 if (idprop) {
5213 /* Don't use #BPy_IDGroup_WrapData as the id-property is being removed from the ID. */
5214 PyObject *ret = BPy_IDGroup_MapDataToPy(idprop);
5215 /* Internal error. */
5216 if (UNLIKELY(ret == nullptr)) {
5217 return nullptr;
5218 }
5219 IDP_FreeFromGroup(group, idprop);
5220 return ret;
5221 }
5222 }
5223
5224 if (def == nullptr) {
5225 PyErr_SetString(PyExc_KeyError, "key not found");
5226 return nullptr;
5227 }
5228 return Py_NewRef(def);
5229}
5230
5232 /* Wrap. */
5233 pyrna_struct_as_pointer_doc,
5234 ".. method:: as_pointer()\n"
5235 "\n"
5236 " Returns the memory address which holds a pointer to Blender's internal data\n"
5237 "\n"
5238 " :return: int (memory address).\n"
5239 " :rtype: int\n"
5240 "\n"
5241 " .. note:: This is intended only for advanced script writers who need to\n"
5242 " pass blender data to their own C/Python modules.\n");
5244{
5245 return PyLong_FromVoidPtr(self->ptr.data);
5246}
5247
5249 /* Wrap. */
5250 pyrna_prop_collection_get_doc,
5251 ".. method:: get(key, default=None)\n"
5252 "\n"
5253 " Returns the value of the item assigned to key or default when not found\n"
5254 " (matches Python's dictionary function of the same name).\n"
5255 "\n"
5256 " :arg key: The identifier for the collection member.\n"
5257 " :type key: str\n"
5258 " :arg default: Optional argument for the value to return if\n"
5259 " *key* is not found.\n"
5260 " :type default: Any\n");
5261static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args)
5262{
5263 PointerRNA newptr;
5264
5265 PyObject *key_ob;
5266 PyObject *def = Py_None;
5267
5269
5270 if (!PyArg_ParseTuple(args, "O|O:get", &key_ob, &def)) {
5271 return nullptr;
5272 }
5273
5274 if (PyUnicode_Check(key_ob)) {
5275 const char *key = PyUnicode_AsUTF8(key_ob);
5276
5277 if (RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr)) {
5278 return pyrna_struct_CreatePyObject(&newptr);
5279 }
5281 "bpy_prop_collection.get") == -1)
5282 {
5283 return nullptr;
5284 }
5285 }
5286 else if (PyTuple_Check(key_ob)) {
5288 self, key_ob, "bpy_prop_collection.get((id, lib))", false);
5289 if (ret) {
5290 return ret;
5291 }
5292 }
5293 else {
5294 PyErr_Format(PyExc_KeyError,
5295 "bpy_prop_collection.get(key, ...): key must be a string or tuple, not %.200s",
5296 Py_TYPE(key_ob)->tp_name);
5297 }
5298
5299 return Py_NewRef(def);
5300}
5301
5303 /* Wrap. */
5304 pyrna_prop_collection_find_doc,
5305 ".. method:: find(key)\n"
5306 "\n"
5307 " Returns the index of a key in a collection or -1 when not found\n"
5308 " (matches Python's string find function of the same name).\n"
5309 "\n"
5310 " :arg key: The identifier for the collection member.\n"
5311 " :type key: str\n"
5312 " :return: index of the key.\n"
5313 " :rtype: int\n");
5314static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob)
5315{
5316 Py_ssize_t key_len_ssize;
5317 const char *key = PyUnicode_AsUTF8AndSize(key_ob, &key_len_ssize);
5318 const int key_len = int(key_len_ssize); /* Compare with same type. */
5319
5320 char name[256], *name_ptr;
5321 int name_len;
5322 int i = 0;
5323 int index = -1;
5324
5326
5327 RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
5328 name_ptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &name_len);
5329
5330 if (name_ptr) {
5331 if ((key_len == name_len) && memcmp(name_ptr, key, key_len) == 0) {
5332 index = i;
5333 break;
5334 }
5335
5336 if (name != name_ptr) {
5337 MEM_freeN(name_ptr);
5338 }
5339 }
5340
5341 i++;
5342 }
5344
5345 return PyLong_FromLong(index);
5346}
5347
5349 const char *attr,
5350 /* Values to assign. */
5351 RawPropertyType *r_raw_type,
5352 int *r_attr_tot,
5353 bool *r_attr_signed,
5354 bool *r_is_empty)
5355{
5356 PropertyRNA *prop;
5357 bool attr_ok = true;
5358 *r_raw_type = PROP_RAW_UNSET;
5359 *r_attr_tot = 0;
5360 *r_attr_signed = false;
5361 *r_is_empty = true;
5362
5363 /* NOTE: this is fail with zero length lists, so don't let this get called in that case. */
5364 RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
5365 prop = RNA_struct_find_property(&itemptr, attr);
5366 if (prop) {
5367 *r_raw_type = RNA_property_raw_type(prop);
5368 *r_attr_tot = RNA_property_array_length(&itemptr, prop);
5369 *r_attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED);
5370 }
5371 else {
5372 attr_ok = false;
5373 }
5374 *r_is_empty = false;
5375 break;
5376 }
5378
5379 return attr_ok;
5380}
5381
5382/* pyrna_prop_collection_foreach_get/set both use this. */
5384 PyObject *args,
5385 const char *function_name,
5386
5387 /* Values to assign. */
5388 const char **r_attr,
5389 PyObject **r_seq,
5390 int *r_tot,
5391 size_t *r_size,
5392 RawPropertyType *r_raw_type,
5393 int *r_attr_tot,
5394 bool *r_attr_signed)
5395{
5396 *r_size = *r_attr_tot = 0;
5397 *r_attr_signed = false;
5398 *r_raw_type = PROP_RAW_UNSET;
5399
5400 if (!PyArg_ParseTuple(args, "sO:foreach_get/set", r_attr, r_seq)) {
5401 return -1;
5402 }
5403
5404 if (!PySequence_Check(*r_seq) && PyObject_CheckBuffer(*r_seq)) {
5405 PyErr_Format(PyExc_TypeError,
5406 "%s(..) expected second argument to be a sequence or buffer, not a %.200s",
5407 function_name,
5408 Py_TYPE(*r_seq)->tp_name);
5409 return -1;
5410 }
5411
5412 /* TODO: buffer may not be a sequence! array.array() is though. */
5413 *r_tot = PySequence_Size(*r_seq);
5414
5415 if (*r_tot > 0) {
5416#if 0
5417 /* Avoid a full collection count when all that's needed is to check it's empty. */
5418 int array_tot;
5419
5420 if (RNA_property_type(self->prop) == PROP_COLLECTION) {
5421 array_tot = RNA_property_collection_length(&self->ptr, self->prop);
5422 }
5423 else {
5424 array_tot = RNA_property_array_length(&self->ptr, self->prop);
5425 }
5426 if (array_tot == 0) {
5427 PyErr_Format(PyExc_TypeError,
5428 "%s(..) sequence length mismatch given %d, needed 0",
5429 function_name,
5430 *r_tot);
5431 return -1;
5432 }
5433#endif
5434
5435 bool is_empty = false; /* `array_tot == 0`. */
5436 if (!foreach_attr_type(self, *r_attr, r_raw_type, r_attr_tot, r_attr_signed, &is_empty)) {
5437 PyErr_Format(PyExc_AttributeError,
5438 "%s(..) '%.200s.%200s[...]' elements have no attribute '%.200s'",
5439 function_name,
5440 RNA_struct_identifier(self->ptr.type),
5442 *r_attr);
5443 return -1;
5444 }
5445
5446 if (is_empty) {
5447 PyErr_Format(PyExc_TypeError,
5448 "%s(..) sequence length mismatch given %d, needed 0",
5449 function_name,
5450 *r_tot);
5451 return -1;
5452 }
5453
5454 *r_size = RNA_raw_type_sizeof(*r_raw_type);
5455
5456#if 0
5457 /* This size check does not work as the size check is based on the size of the
5458 * first element and elements in the collection/array can have different sizes
5459 * (i.e. for mixed quad/triangle meshes). See for example issue #111117. */
5460
5461 if ((*r_attr_tot) < 1) {
5462 *r_attr_tot = 1;
5463 }
5464
5465 const int target_tot = array_tot * (*r_attr_tot);
5466
5467 /* rna_access.cc - rna_raw_access(...) uses this same method. */
5468 if (target_tot != (*r_tot)) {
5469 PyErr_Format(PyExc_TypeError,
5470 "%s(..) sequence length mismatch given %d, needed %d",
5471 function_name,
5472 *r_tot,
5473 target_tot);
5474 return -1;
5475 }
5476#endif
5477 }
5478
5479 /* Check 'r_attr_tot' otherwise we don't know if any values were set.
5480 * This isn't ideal because it means running on an empty list may
5481 * fail silently when it's not compatible. */
5482 if (*r_size == 0 && *r_attr_tot != 0) {
5483 PyErr_Format(
5484 PyExc_AttributeError, "%s(..): attribute does not support foreach method", function_name);
5485 return -1;
5486 }
5487 return 0;
5488}
5489
5490static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
5491{
5492 const char f = format ? *format : 'B'; /* B is assumed when not set */
5493
5494 switch (raw_type) {
5495 case PROP_RAW_INT8:
5496 if (attr_signed) {
5497 return (f == 'b') ? true : false;
5498 }
5499 else {
5500 return (f == 'B') ? true : false;
5501 }
5502 case PROP_RAW_CHAR:
5503 case PROP_RAW_UINT8:
5504 return (f == 'B') ? true : false;
5505 case PROP_RAW_SHORT:
5506 if (attr_signed) {
5507 return (f == 'h') ? true : false;
5508 }
5509 else {
5510 return (f == 'H') ? true : false;
5511 }
5512 case PROP_RAW_UINT16:
5513 return (f == 'H') ? true : false;
5514 case PROP_RAW_INT:
5515 if (attr_signed) {
5516 return (f == 'i') ? true : false;
5517 }
5518 else {
5519 return (f == 'I') ? true : false;
5520 }
5521 case PROP_RAW_BOOLEAN:
5522 return (f == '?') ? true : false;
5523 case PROP_RAW_FLOAT:
5524 return (f == 'f') ? true : false;
5525 case PROP_RAW_DOUBLE:
5526 return (f == 'd') ? true : false;
5527 case PROP_RAW_INT64:
5528 if (attr_signed) {
5529 return (f == 'q') ? true : false;
5530 }
5531 else {
5532 return (f == 'Q') ? true : false;
5533 }
5534 case PROP_RAW_UINT64:
5535 return (f == 'Q') ? true : false;
5536 case PROP_RAW_UNSET:
5537 return false;
5538 }
5539
5540 return false;
5541}
5542
5543static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
5544{
5545 PyObject *item = nullptr;
5546 int i = 0, ok = 0;
5547 bool buffer_is_compat;
5548 void *array = nullptr;
5549
5550 /* Get/set both take the same args currently. */
5551 const char *attr;
5552 PyObject *seq;
5553 int tot, attr_tot;
5554 size_t size;
5555 bool attr_signed;
5556 RawPropertyType raw_type;
5557
5559 args,
5560 set ? "foreach_set" : "foreach_get",
5561 &attr,
5562 &seq,
5563 &tot,
5564 &size,
5565 &raw_type,
5566 &attr_tot,
5567 &attr_signed) == -1)
5568 {
5569 return nullptr;
5570 }
5571
5572 if (tot == 0) {
5573 Py_RETURN_NONE;
5574 }
5575
5576 if (set) { /* Get the array from python. */
5577 buffer_is_compat = false;
5578 if (PyObject_CheckBuffer(seq)) {
5579 Py_buffer buf;
5580 if (PyObject_GetBuffer(seq, &buf, PyBUF_ND | PyBUF_FORMAT) == -1) {
5581 /* Request failed. A `PyExc_BufferError` will have been raised,
5582 * so clear it to silently fall back to accessing as a sequence. */
5583 PyErr_Clear();
5584 }
5585 else {
5586 /* Check if the buffer matches. */
5587
5588 buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format);
5589
5590 if (buffer_is_compat) {
5592 nullptr, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
5593 }
5594
5595 PyBuffer_Release(&buf);
5596 }
5597 }
5598
5599 /* Could not use the buffer, fallback to sequence. */
5600 if (!buffer_is_compat) {
5601 array = PyMem_Malloc(size * tot);
5602
5603 for (; i < tot; i++) {
5604 item = PySequence_GetItem(seq, i);
5605 switch (raw_type) {
5606 case PROP_RAW_CHAR:
5607 ((char *)array)[i] = char(PyC_Long_AsU8(item));
5608 break;
5609 case PROP_RAW_INT8:
5610 ((int8_t *)array)[i] = PyC_Long_AsI8(item);
5611 break;
5612 case PROP_RAW_UINT8:
5613 ((uint8_t *)array)[i] = PyC_Long_AsU8(item);
5614 break;
5615 case PROP_RAW_SHORT:
5616 ((short *)array)[i] = short(PyC_Long_AsI16(item));
5617 break;
5618 case PROP_RAW_UINT16:
5619 ((uint16_t *)array)[i] = PyC_Long_AsU16(item);
5620 break;
5621 case PROP_RAW_INT:
5622 ((int *)array)[i] = int(PyC_Long_AsI32(item));
5623 break;
5624 case PROP_RAW_BOOLEAN:
5625 ((bool *)array)[i] = bool(PyC_Long_AsBool(item));
5626 break;
5627 case PROP_RAW_FLOAT:
5628 ((float *)array)[i] = float(PyFloat_AsDouble(item));
5629 break;
5630 case PROP_RAW_DOUBLE:
5631 ((double *)array)[i] = double(PyFloat_AsDouble(item));
5632 break;
5633 case PROP_RAW_INT64:
5634 ((int64_t *)array)[i] = PyC_Long_AsI64(item);
5635 break;
5636 case PROP_RAW_UINT64:
5637 ((uint64_t *)array)[i] = PyC_Long_AsU64(item);
5638 break;
5639 case PROP_RAW_UNSET:
5640 /* Should never happen. */
5641 BLI_assert_msg(0, "Invalid array type - set");
5642 break;
5643 }
5644
5645 Py_DECREF(item);
5646 }
5647
5649 nullptr, &self->ptr, self->prop, attr, array, raw_type, tot);
5650 }
5651 }
5652 else {
5653 buffer_is_compat = false;
5654 if (PyObject_CheckBuffer(seq)) {
5655 Py_buffer buf;
5656 if (PyObject_GetBuffer(seq, &buf, PyBUF_ND | PyBUF_FORMAT) == -1) {
5657 /* Request failed. A `PyExc_BufferError` will have been raised,
5658 * so clear it to silently fall back to accessing as a sequence. */
5659 PyErr_Clear();
5660 }
5661 else {
5662 /* Check if the buffer matches. */
5663
5664 buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format);
5665
5666 if (buffer_is_compat) {
5668 nullptr, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
5669 }
5670
5671 PyBuffer_Release(&buf);
5672 }
5673 }
5674
5675 /* Could not use the buffer, fallback to sequence. */
5676 if (!buffer_is_compat) {
5677 array = PyMem_Malloc(size * tot);
5678
5680 nullptr, &self->ptr, self->prop, attr, array, raw_type, tot);
5681
5682 if (!ok) {
5683 /* Skip the loop. */
5684 i = tot;
5685 }
5686
5687 for (; i < tot; i++) {
5688
5689 switch (raw_type) {
5690 case PROP_RAW_CHAR:
5691 item = PyLong_FromLong(long(((char *)array)[i]));
5692 break;
5693 case PROP_RAW_INT8:
5694 item = PyLong_FromLong(long(((int8_t *)array)[i]));
5695 break;
5696 case PROP_RAW_UINT8:
5697 item = PyLong_FromLong(long(((uint8_t *)array)[i]));
5698 break;
5699 case PROP_RAW_SHORT:
5700 item = PyLong_FromLong(long(((short *)array)[i]));
5701 break;
5702 case PROP_RAW_UINT16:
5703 item = PyLong_FromLong(long(((uint16_t *)array)[i]));
5704 break;
5705 case PROP_RAW_INT:
5706 item = PyLong_FromLong(long(((int *)array)[i]));
5707 break;
5708 case PROP_RAW_FLOAT:
5709 item = PyFloat_FromDouble(double(((float *)array)[i]));
5710 break;
5711 case PROP_RAW_DOUBLE:
5712 item = PyFloat_FromDouble(double(((double *)array)[i]));
5713 break;
5714 case PROP_RAW_BOOLEAN:
5715 item = PyBool_FromLong(long(((bool *)array)[i]));
5716 break;
5717 case PROP_RAW_INT64:
5718 item = PyLong_FromLongLong(((int64_t *)array)[i]);
5719 break;
5720 case PROP_RAW_UINT64:
5721 item = PyLong_FromUnsignedLongLong(((uint64_t *)array)[i]);
5722 break;
5723 default: /* PROP_RAW_UNSET */
5724 /* Should never happen. */
5725 BLI_assert_msg(0, "Invalid array type - get");
5726 item = Py_None;
5727 Py_INCREF(item);
5728 break;
5729 }
5730
5731 PySequence_SetItem(seq, i, item);
5732 Py_DECREF(item);
5733 }
5734 }
5735 }
5736
5737 if (array) {
5738 PyMem_Free(array);
5739 }
5740
5741 if (PyErr_Occurred()) {
5742 /* Maybe we could make our own error. */
5743 PyErr_Print();
5744 PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence");
5745 return nullptr;
5746 }
5747 if (!ok) {
5748 PyErr_SetString(PyExc_RuntimeError, "internal error setting the array");
5749 return nullptr;
5750 }
5751
5752 if (set) {
5754 }
5755 Py_RETURN_NONE;
5756}
5757
5759 /* Wrap. */
5760 pyrna_prop_collection_foreach_get_doc,
5761 ".. method:: foreach_get(attr, seq)\n"
5762 "\n"
5763 " This is a function to give fast access to attributes within a collection.\n");
5765{
5767
5768 return foreach_getset(self, args, 0);
5769}
5770
5772 /* Wrap. */
5773 pyrna_prop_collection_foreach_set_doc,
5774 ".. method:: foreach_set(attr, seq)\n"
5775 "\n"
5776 " This is a function to give fast access to attributes within a collection.\n");
5778{
5780
5781 return foreach_getset(self, args, 1);
5782}
5783
5785 PyObject *args,
5786 const bool do_set)
5787{
5788 PyObject *item = nullptr;
5789 Py_ssize_t i, seq_size, size;
5790 void *array = nullptr;
5791 const PropertyType prop_type = RNA_property_type(self->prop);
5792
5793 /* Get/set both take the same args currently. */
5794 PyObject *seq;
5795
5796 if (!ELEM(prop_type, PROP_INT, PROP_FLOAT)) {
5797 PyErr_Format(PyExc_TypeError, "foreach_get/set available only for int and float");
5798 return nullptr;
5799 }
5800
5801 if (!PyArg_ParseTuple(args, "O:foreach_get/set", &seq)) {
5802 return nullptr;
5803 }
5804
5805 if (!PySequence_Check(seq) && PyObject_CheckBuffer(seq)) {
5806 PyErr_Format(
5807 PyExc_TypeError,
5808 "foreach_get/set expected second argument to be a sequence or buffer, not a %.200s",
5809 Py_TYPE(seq)->tp_name);
5810 return nullptr;
5811 }
5812
5813 /* NOTE: in this case it's important to use the flat-array size and *not* the result of
5814 * `len()`, which uses #pyrna_prop_array_length, see !116457 for details. */
5815 size = RNA_property_array_length(&self->ptr, self->prop);
5816 seq_size = PySequence_Size(seq);
5817
5818 if (size != seq_size) {
5819 PyErr_Format(PyExc_TypeError, "expected sequence size %d, got %d", size, seq_size);
5820 return nullptr;
5821 }
5822
5823 Py_buffer buf;
5824 if (PyObject_GetBuffer(seq, &buf, PyBUF_ND | PyBUF_FORMAT) == -1) {
5825 PyErr_Clear();
5826
5827 switch (prop_type) {
5828 case PROP_INT:
5829 array = PyMem_Malloc(sizeof(int) * size);
5830 if (do_set) {
5831 for (i = 0; i < size; i++) {
5832 item = PySequence_GetItem(seq, i);
5833 ((int *)array)[i] = int(PyLong_AsLong(item));
5834 Py_DECREF(item);
5835 }
5836
5837 RNA_property_int_set_array(&self->ptr, self->prop, static_cast<const int *>(array));
5838 }
5839 else {
5840 RNA_property_int_get_array(&self->ptr, self->prop, static_cast<int *>(array));
5841
5842 for (i = 0; i < size; i++) {
5843 item = PyLong_FromLong(long(((int *)array)[i]));
5844 PySequence_SetItem(seq, i, item);
5845 Py_DECREF(item);
5846 }
5847 }
5848
5849 break;
5850 case PROP_FLOAT:
5851 array = PyMem_Malloc(sizeof(float) * size);
5852 if (do_set) {
5853 for (i = 0; i < size; i++) {
5854 item = PySequence_GetItem(seq, i);
5855 ((float *)array)[i] = float(PyFloat_AsDouble(item));
5856 Py_DECREF(item);
5857 }
5858
5859 RNA_property_float_set_array(&self->ptr, self->prop, static_cast<const float *>(array));
5860 }
5861 else {
5862 RNA_property_float_get_array(&self->ptr, self->prop, static_cast<float *>(array));
5863
5864 for (i = 0; i < size; i++) {
5865 item = PyFloat_FromDouble(double(((float *)array)[i]));
5866 PySequence_SetItem(seq, i, item);
5867 Py_DECREF(item);
5868 }
5869 }
5870 break;
5871 case PROP_BOOLEAN:
5872 case PROP_STRING:
5873 case PROP_ENUM:
5874 case PROP_POINTER:
5875 case PROP_COLLECTION:
5876 /* Should never happen. */
5878 break;
5879 }
5880
5881 PyMem_Free(array);
5882
5883 if (PyErr_Occurred()) {
5884 /* Maybe we could make our own error. */
5885 PyErr_Print();
5886 PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence");
5887 return nullptr;
5888 }
5889 }
5890 else {
5891 const char f = buf.format ? buf.format[0] : 0;
5892 if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || !ELEM(f, 'l', 'i'))) ||
5893 (prop_type == PROP_FLOAT && (buf.itemsize != sizeof(float) || f != 'f')))
5894 {
5895 PyBuffer_Release(&buf);
5896 PyErr_Format(PyExc_TypeError, "incorrect sequence item type: %s", buf.format);
5897 return nullptr;
5898 }
5899
5900 switch (prop_type) {
5901 case PROP_INT:
5902 if (do_set) {
5903 RNA_property_int_set_array(&self->ptr, self->prop, static_cast<const int *>(buf.buf));
5904 }
5905 else {
5906 RNA_property_int_get_array(&self->ptr, self->prop, static_cast<int *>(buf.buf));
5907 }
5908 break;
5909 case PROP_FLOAT:
5910 if (do_set) {
5912 &self->ptr, self->prop, static_cast<const float *>(buf.buf));
5913 }
5914 else {
5915 RNA_property_float_get_array(&self->ptr, self->prop, static_cast<float *>(buf.buf));
5916 }
5917 break;
5918 case PROP_BOOLEAN:
5919 case PROP_STRING:
5920 case PROP_ENUM:
5921 case PROP_POINTER:
5922 case PROP_COLLECTION:
5923 /* Should never happen. */
5925 break;
5926 }
5927
5928 PyBuffer_Release(&buf);
5929 }
5930
5931 Py_RETURN_NONE;
5932}
5933
5935 /* Wrap. */
5936 pyrna_prop_array_foreach_get_doc,
5937 ".. method:: foreach_get(seq)\n"
5938 "\n"
5939 " This is a function to give fast access to array data.\n");
5941{
5943
5944 return pyprop_array_foreach_getset(self, args, false);
5945}
5946
5948 /* Wrap. */
5949 pyrna_prop_array_foreach_set_doc,
5950 ".. method:: foreach_set(seq)\n"
5951 "\n"
5952 " This is a function to give fast access to array data.\n");
5954{
5956
5957 return pyprop_array_foreach_getset(self, args, true);
5958}
5959
5960/* A bit of a kludge, make a list out of a collection or array,
5961 * then return the list's iter function, not especially fast, but convenient for now. */
5963{
5964 /* Try get values from a collection. */
5965 PyObject *ret;
5966 PyObject *iter = nullptr;
5967 int len;
5968
5970
5973
5974 /* we know this is a list so no need to PyIter_Check
5975 * otherwise it could be nullptr (unlikely) if conversion failed */
5976 if (ret) {
5977 iter = PyObject_GetIter(ret);
5978 Py_DECREF(ret);
5979 }
5980
5981 return iter;
5982}
5983
5985
5986#ifndef USE_PYRNA_ITER
5988{
5989 /* Try get values from a collection. */
5990 PyObject *ret;
5991 PyObject *iter = nullptr;
5993
5994 /* we know this is a list so no need to PyIter_Check
5995 * otherwise it could be nullptr (unlikely) if conversion failed */
5996 if (ret) {
5997 iter = PyObject_GetIter(ret);
5998 Py_DECREF(ret);
5999 }
6000
6001 return iter;
6002}
6003#endif /* # !USE_PYRNA_ITER */
6004
6005#if (defined(__GNUC__) && !defined(__clang__))
6006# pragma GCC diagnostic push
6007# pragma GCC diagnostic ignored "-Wcast-function-type"
6008#endif
6009
6010static PyMethodDef pyrna_struct_methods[] = {
6011
6012 /* Only for PointerRNA's with ID'props. */
6013 {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc},
6014 {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, pyrna_struct_values_doc},
6015 {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, pyrna_struct_items_doc},
6016
6017 {"get", (PyCFunction)pyrna_struct_get, METH_VARARGS, pyrna_struct_get_doc},
6018 {"pop", (PyCFunction)pyrna_struct_pop, METH_VARARGS, pyrna_struct_pop_doc},
6019
6020 {"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc},
6021
6022 /* `bpy_rna_anim.cc` */
6023 {"keyframe_insert",
6024 (PyCFunction)pyrna_struct_keyframe_insert,
6025 METH_VARARGS | METH_KEYWORDS,
6027 {"keyframe_delete",
6028 (PyCFunction)pyrna_struct_keyframe_delete,
6029 METH_VARARGS | METH_KEYWORDS,
6031 {"driver_add",
6032 (PyCFunction)pyrna_struct_driver_add,
6033 METH_VARARGS,
6035 {"driver_remove",
6036 (PyCFunction)pyrna_struct_driver_remove,
6037 METH_VARARGS,
6039
6040 {"is_property_set",
6041 (PyCFunction)pyrna_struct_is_property_set,
6042 METH_VARARGS | METH_KEYWORDS,
6043 pyrna_struct_is_property_set_doc},
6044 {"property_unset",
6045 (PyCFunction)pyrna_struct_property_unset,
6046 METH_VARARGS,
6047 pyrna_struct_property_unset_doc},
6048 {"is_property_hidden",
6050 METH_VARARGS,
6051 pyrna_struct_is_property_hidden_doc},
6052 {"is_property_readonly",
6054 METH_VARARGS,
6055 pyrna_struct_is_property_readonly_doc},
6056 {"is_property_overridable_library",
6058 METH_VARARGS,
6059 pyrna_struct_is_property_overridable_library_doc},
6060 {"property_overridable_library_set",
6062 METH_VARARGS,
6063 pyrna_struct_property_overridable_library_set_doc},
6064 {"path_resolve",
6065 (PyCFunction)pyrna_struct_path_resolve,
6066 METH_VARARGS,
6067 pyrna_struct_path_resolve_doc},
6068 {"path_from_id",
6069 (PyCFunction)pyrna_struct_path_from_id,
6070 METH_VARARGS,
6071 pyrna_struct_path_from_id_doc},
6072 {"type_recast",
6073 (PyCFunction)pyrna_struct_type_recast,
6074 METH_NOARGS,
6075 pyrna_struct_type_recast_doc},
6076 {"bl_rna_get_subclass_py",
6078 METH_VARARGS | METH_CLASS,
6079 pyrna_struct_bl_rna_get_subclass_py_doc},
6080 {"bl_rna_get_subclass",
6082 METH_VARARGS | METH_CLASS,
6083 pyrna_struct_bl_rna_get_subclass_doc},
6084 {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, nullptr},
6085 {"id_properties_ensure",
6087 METH_NOARGS,
6088 pyrna_struct_id_properties_ensure_doc},
6089 {"id_properties_clear",
6091 METH_NOARGS,
6092 pyrna_struct_id_properties_clear_doc},
6093 {"id_properties_ui",
6094 (PyCFunction)pyrna_struct_id_properties_ui,
6095 METH_VARARGS,
6096 pyrna_struct_id_properties_ui_doc},
6097
6098/* experimental */
6099/* unused for now */
6100#if 0
6101 {"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, nullptr},
6102 {"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, nullptr},
6103
6104 {"callback_add",
6105 (PyCFunction)pyrna_callback_classmethod_add,
6106 METH_VARARGS | METH_CLASS,
6107 nullptr},
6108 {"callback_remove",
6110 METH_VARARGS | METH_CLASS,
6111 nullptr},
6112#endif
6113 {nullptr, nullptr, 0, nullptr},
6114};
6115
6116static PyMethodDef pyrna_prop_methods[] = {
6117 {"path_from_id",
6118 (PyCFunction)pyrna_prop_path_from_id,
6119 METH_NOARGS,
6120 pyrna_prop_path_from_id_doc},
6121 {"as_bytes", (PyCFunction)pyrna_prop_as_bytes, METH_NOARGS, pyrna_prop_as_bytes_doc},
6122 {"update", (PyCFunction)pyrna_prop_update, METH_NOARGS, pyrna_prop_update_doc},
6123 {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, nullptr},
6124 {nullptr, nullptr, 0, nullptr},
6125};
6126
6127static PyMethodDef pyrna_prop_array_methods[] = {
6128 {"foreach_get",
6129 (PyCFunction)pyrna_prop_array_foreach_get,
6130 METH_VARARGS,
6131 pyrna_prop_array_foreach_get_doc},
6132 {"foreach_set",
6133 (PyCFunction)pyrna_prop_array_foreach_set,
6134 METH_VARARGS,
6135 pyrna_prop_array_foreach_set_doc},
6136
6137 {nullptr, nullptr, 0, nullptr},
6138};
6139
6140static PyMethodDef pyrna_prop_collection_methods[] = {
6141 {"foreach_get",
6143 METH_VARARGS,
6144 pyrna_prop_collection_foreach_get_doc},
6145 {"foreach_set",
6147 METH_VARARGS,
6148 pyrna_prop_collection_foreach_set_doc},
6149
6150 {"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, pyrna_prop_collection_keys_doc},
6151 {"items",
6152 (PyCFunction)pyrna_prop_collection_items,
6153 METH_NOARGS,
6154 pyrna_prop_collection_items_doc},
6155 {"values",
6156 (PyCFunction)pyrna_prop_collection_values,
6157 METH_NOARGS,
6158 pyrna_prop_collection_values_doc},
6159
6160 {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc},
6161 {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc},
6162 {nullptr, nullptr, 0, nullptr},
6163};
6164
6166 {"add", (PyCFunction)pyrna_prop_collection_idprop_add, METH_NOARGS, nullptr},
6167 {"remove", (PyCFunction)pyrna_prop_collection_idprop_remove, METH_O, nullptr},
6168 {"clear", (PyCFunction)pyrna_prop_collection_idprop_clear, METH_NOARGS, nullptr},
6169 {"move", (PyCFunction)pyrna_prop_collection_idprop_move, METH_VARARGS, nullptr},
6170 {nullptr, nullptr, 0, nullptr},
6171};
6172
6173#if (defined(__GNUC__) && !defined(__clang__))
6174# pragma GCC diagnostic pop
6175#endif
6176
6181static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
6182{
6183 if (PyTuple_GET_SIZE(args) == 1) {
6184 BPy_StructRNA *base = (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0);
6185 if (Py_TYPE(base) == type) {
6186 Py_INCREF(base);
6187 return (PyObject *)base;
6188 }
6189 if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
6190 /* this almost never runs, only when using user defined subclasses of built-in object.
6191 * this isn't common since it's NOT related to registerable subclasses. eg:
6192 *
6193 * >>> class MyObSubclass(bpy.types.Object):
6194 * ... def test_func(self):
6195 * ... print(100)
6196 * ...
6197 * >>> myob = MyObSubclass(bpy.context.object)
6198 * >>> myob.test_func()
6199 * 100
6200 *
6201 * Keep this since it could be useful.
6202 */
6204 if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) {
6205 ret->ptr = base->ptr;
6206#ifdef USE_PYRNA_STRUCT_REFERENCE
6207 /* #PyType_GenericAlloc will have set tracking.
6208 * We only want tracking when `StructRNA.reference` has been set. */
6209 PyObject_GC_UnTrack(ret);
6210#endif
6211 }
6212 /* Pass on exception & nullptr if tp_alloc fails. */
6213 return (PyObject *)ret;
6214 }
6215
6216 /* Error, invalid type given. */
6217 PyErr_Format(PyExc_TypeError,
6218 "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct",
6219 type->tp_name);
6220 return nullptr;
6221 }
6222
6223 PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument");
6224 return nullptr;
6225}
6226
6231static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
6232{
6233 BPy_PropertyRNA *base;
6234
6235 if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base)) {
6236 return nullptr;
6237 }
6238
6239 if (type == Py_TYPE(base)) {
6240 return Py_NewRef(base);
6241 }
6242 if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
6243 BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0);
6244 ret->ptr = base->ptr;
6245 ret->prop = base->prop;
6246 return (PyObject *)ret;
6247 }
6248
6249 PyErr_Format(PyExc_TypeError,
6250 "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop",
6251 type->tp_name);
6252 return nullptr;
6253}
6254
6255static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
6256{
6257 PyObject *ret;
6258 const int type = RNA_property_type(prop);
6259 const int flag = RNA_property_flag(prop);
6260 const int flag_parameter = RNA_parameter_flag(prop);
6261
6262 if (RNA_property_array_check(prop)) {
6263 int a, len;
6264
6265 if (flag & PROP_DYNAMIC) {
6266 ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(data);
6267 len = data_alloc->array_tot;
6268 data = data_alloc->array;
6269 }
6270 else {
6272 }
6273
6274 /* Resolve the array from a new Python type. */
6275
6276 /* TODO(Kazanbas): make multi-dimensional sequences here. */
6277
6278 switch (type) {
6279 case PROP_BOOLEAN:
6280 ret = PyTuple_New(len);
6281 for (a = 0; a < len; a++) {
6282 PyTuple_SET_ITEM(ret, a, PyBool_FromLong(((bool *)data)[a]));
6283 }
6284 break;
6285 case PROP_INT:
6286 ret = PyTuple_New(len);
6287 for (a = 0; a < len; a++) {
6288 PyTuple_SET_ITEM(ret, a, PyLong_FromLong(((int *)data)[a]));
6289 }
6290 break;
6291 case PROP_FLOAT:
6292 switch (RNA_property_subtype(prop)) {
6293#ifdef USE_MATHUTILS
6295 ret = Vector_CreatePyObject(static_cast<const float *>(data), len, nullptr);
6296 break;
6297 case PROP_MATRIX:
6298 if (len == 16) {
6299 ret = Matrix_CreatePyObject(static_cast<const float *>(data), 4, 4, nullptr);
6300 break;
6301 }
6302 else if (len == 9) {
6303 ret = Matrix_CreatePyObject(static_cast<const float *>(data), 3, 3, nullptr);
6304 break;
6305 }
6307#endif
6308 default:
6309 ret = PyTuple_New(len);
6310 for (a = 0; a < len; a++) {
6311 PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble(((float *)data)[a]));
6312 }
6313 break;
6314 }
6315 break;
6316 default:
6317 PyErr_Format(
6318 PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
6319 ret = nullptr;
6320 break;
6321 }
6322 }
6323 else {
6324 /* See if we can coerce into a python type - PropertyType. */
6325 switch (type) {
6326 case PROP_BOOLEAN:
6327 ret = PyBool_FromLong(*(bool *)data);
6328 break;
6329 case PROP_INT:
6330 ret = PyLong_FromLong(*(int *)data);
6331 break;
6332 case PROP_FLOAT:
6333 ret = PyFloat_FromDouble(*(float *)data);
6334 break;
6335 case PROP_STRING: {
6336 const char *data_ch;
6337 const int subtype = RNA_property_subtype(prop);
6338 size_t data_ch_len;
6339
6340 if (flag & PROP_DYNAMIC) {
6341 ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(data);
6342 data_ch = static_cast<const char *>(data_alloc->array);
6343 data_ch_len = data_alloc->array_tot;
6344 BLI_assert((data_ch == nullptr) || strlen(data_ch) == data_ch_len);
6345 }
6346 else {
6347 data_ch = (flag & PROP_THICK_WRAP) ? (char *)data : *(char **)data;
6348 data_ch_len = data_ch ? strlen(data_ch) : 0;
6349 }
6350
6351 if (UNLIKELY(data_ch == nullptr)) {
6353 ret = Py_None;
6354 Py_INCREF(ret);
6355 }
6356#ifdef USE_STRING_COERCE
6357 else if (subtype == PROP_BYTESTRING) {
6358 ret = PyBytes_FromStringAndSize(data_ch, data_ch_len);
6359 }
6360 else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
6361 ret = PyC_UnicodeFromBytesAndSize(data_ch, data_ch_len);
6362 }
6363 else {
6364 ret = PyUnicode_FromStringAndSize(data_ch, data_ch_len);
6365 }
6366#else
6367 else if (subtype == PROP_BYTESTRING) {
6368 ret = PyBytes_FromString(buf);
6369 }
6370 else {
6371 ret = PyUnicode_FromString(data_ch);
6372 }
6373#endif
6374
6375 break;
6376 }
6377 case PROP_ENUM: {
6378 ret = pyrna_enum_to_py(ptr, prop, *(int *)data);
6379 break;
6380 }
6381 case PROP_POINTER: {
6382 PointerRNA newptr;
6383 StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
6384
6385 if (flag_parameter & PARM_RNAPTR) {
6386 /* In this case we get the full ptr. */
6387 newptr = *(PointerRNA *)data;
6388 }
6389 else {
6390 if (RNA_struct_is_ID(ptype)) {
6391 newptr = RNA_id_pointer_create(static_cast<ID *>(*(void **)data));
6392 }
6393 else {
6394 /* NOTE: this is taken from the function's ID pointer
6395 * and will break if a function returns a pointer from
6396 * another ID block, watch this! - it should at least be
6397 * easy to debug since they are all ID's */
6398 newptr = RNA_pointer_create(ptr->owner_id, ptype, *(void **)data);
6399 }
6400 }
6401
6402 if (newptr.data) {
6404 }
6405 else {
6406 ret = Py_None;
6407 Py_INCREF(ret);
6408 }
6409 break;
6410 }
6411 case PROP_COLLECTION: {
6412 CollectionVector *lb = (CollectionVector *)data;
6413 ret = PyList_New(0);
6414 for (PointerRNA &ptr_iter : lb->items) {
6415 PyList_APPEND(ret, pyrna_struct_CreatePyObject(&ptr_iter));
6416 }
6417 break;
6418 }
6419 default:
6420 PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
6421 ret = nullptr;
6422 break;
6423 }
6424 }
6425
6426 return ret;
6427}
6428
6434static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup)
6435{
6436 /* Comparing the size then `memcmp` the string gives ~20-30% speedup. */
6437 const Py_ssize_t key_lookup_len = strlen(key_lookup);
6438 PyObject *key = nullptr;
6439 Py_ssize_t pos = 0;
6440 PyObject *value = nullptr;
6441
6442 while (PyDict_Next(dict, &pos, &key, &value)) {
6443 if (PyUnicode_Check(key)) {
6444 Py_ssize_t key_buf_len;
6445 const char *key_buf = PyUnicode_AsUTF8AndSize(key, &key_buf_len);
6446 if ((key_lookup_len == key_buf_len) && (memcmp(key_lookup, key_buf, key_lookup_len) == 0)) {
6447 return value;
6448 }
6449 }
6450 }
6451
6452 return nullptr;
6453}
6454
6459 PropertyRNA *parm,
6460 const int parm_index,
6461 char *error,
6462 const size_t error_size)
6463{
6464 PointerRNA *self_ptr = &self->ptr;
6465 FunctionRNA *self_func = self->func;
6466 if (parm_index == -1) {
6468 error_size,
6469 "%.200s.%.200s(): error with keyword argument \"%.200s\" - ",
6470 RNA_struct_identifier(self_ptr->type),
6471 RNA_function_identifier(self_func),
6473 }
6474 else {
6476 error_size,
6477 "%.200s.%.200s(): error with argument %d, \"%.200s\" - ",
6478 RNA_struct_identifier(self_ptr->type),
6479 RNA_function_identifier(self_func),
6480 parm_index + 1,
6482 }
6483}
6484
6485static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw)
6486{
6487 /* NOTE: both BPy_StructRNA and BPy_PropertyRNA can be used here. */
6488 PointerRNA *self_ptr = &self->ptr;
6489 FunctionRNA *self_func = self->func;
6490
6491 ParameterList parms;
6492 ParameterIterator iter;
6493 PropertyRNA *parm;
6494 PyObject *ret, *item;
6495 int i, pyargs_len, pykw_len, parms_len, ret_len, flag_parameter, err = 0, kw_tot = 0;
6496 bool kw_arg;
6497
6498 PropertyRNA *pret_single = nullptr;
6499 void *retdata_single = nullptr;
6500
6501 /* enable this so all strings are copied and freed after calling.
6502 * this exposes bugs where the pointer to the string is held and re-used */
6503 // #define DEBUG_STRING_FREE
6504
6505#ifdef DEBUG_STRING_FREE
6506 PyObject *string_free_ls = PyList_New(0);
6507#endif
6508
6509 /* Should never happen, but it does in rare cases. */
6510 BLI_assert(self_ptr != nullptr);
6511
6512 if (self_ptr == nullptr) {
6513 PyErr_SetString(PyExc_RuntimeError,
6514 "RNA functions internal RNA pointer is nullptr, this is a bug. aborting");
6515 return nullptr;
6516 }
6517
6518 if (self_func == nullptr) {
6519 PyErr_Format(
6520 PyExc_RuntimeError,
6521 "%.200s.<unknown>(): RNA function internal function is nullptr, this is a bug. aborting",
6522 RNA_struct_identifier(self_ptr->type));
6523 return nullptr;
6524 }
6525
6526/* For testing. */
6527#if 0
6528 {
6529 const char *fn;
6530 int lineno;
6531 PyC_FileAndNum(&fn, &lineno);
6532 printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n",
6533 RNA_struct_identifier(self_ptr->type),
6534 RNA_function_identifier(self_func),
6535 fn,
6536 lineno);
6537 }
6538#endif
6539
6540 /* include the ID pointer for pyrna_param_to_py() so we can include the
6541 * ID pointer on return values, this only works when returned values have
6542 * the same ID as the functions. */
6543 PointerRNA funcptr = RNA_pointer_create(self_ptr->owner_id, &RNA_Function, self_func);
6544
6545 pyargs_len = PyTuple_GET_SIZE(args);
6546 pykw_len = kw ? PyDict_Size(kw) : 0;
6547
6548 RNA_parameter_list_create(&parms, self_ptr, self_func);
6549 RNA_parameter_list_begin(&parms, &iter);
6550 parms_len = RNA_parameter_list_arg_count(&parms);
6551 ret_len = 0;
6552
6553 if (pyargs_len + pykw_len > parms_len) {
6555 PyErr_Format(PyExc_TypeError,
6556 "%.200s.%.200s(): takes at most %d arguments, got %d",
6557 RNA_struct_identifier(self_ptr->type),
6558 RNA_function_identifier(self_func),
6559 parms_len,
6560 pyargs_len + pykw_len);
6561 err = -1;
6562 }
6563
6564 /* Parse function parameters. */
6565 for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) {
6566 parm = iter.parm;
6567 flag_parameter = RNA_parameter_flag(parm);
6568
6569 /* Only useful for single argument returns, we'll need another list loop for multiple. */
6570 if (flag_parameter & PARM_OUTPUT) {
6571 ret_len++;
6572 if (pret_single == nullptr) {
6573 pret_single = parm;
6574 retdata_single = iter.data;
6575 }
6576
6577 continue;
6578 }
6579
6580 item = nullptr;
6581
6582 if (i < pyargs_len) {
6583 /* New in 2.8x, optional arguments must be keywords. */
6584 if (UNLIKELY((flag_parameter & PARM_REQUIRED) == 0)) {
6585 PyErr_Format(PyExc_TypeError,
6586 "%.200s.%.200s(): required parameter \"%.200s\" to be a keyword argument!",
6587 RNA_struct_identifier(self_ptr->type),
6588 RNA_function_identifier(self_func),
6590 err = -1;
6591 break;
6592 }
6593
6594 item = PyTuple_GET_ITEM(args, i);
6595 kw_arg = false;
6596 }
6597 else if (kw != nullptr) {
6598#if 0
6599 item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* Borrow reference. */
6600#else
6601 item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* Borrow reference. */
6602#endif
6603 if (item) {
6604 kw_tot++; /* Make sure invalid keywords are not given. */
6605 }
6606
6607 kw_arg = true;
6608 }
6609
6610 if (item == nullptr) {
6611 if (flag_parameter & PARM_REQUIRED) {
6612 PyErr_Format(PyExc_TypeError,
6613 "%.200s.%.200s(): required parameter \"%.200s\" not specified",
6614 RNA_struct_identifier(self_ptr->type),
6615 RNA_function_identifier(self_func),
6617 err = -1;
6618 break;
6619 }
6620 /* PyDict_GetItemString won't raise an error. */
6621 }
6622 else {
6623
6624#ifdef DEBUG_STRING_FREE
6625 if (item) {
6626 if (PyUnicode_Check(item)) {
6627 PyList_APPEND(string_free_ls, PyUnicode_FromString(PyUnicode_AsUTF8(item)));
6628 }
6629 }
6630#endif
6631
6632 /* the error generated isn't that useful, so generate it again with a useful prefix
6633 * could also write a function to prepend to error messages */
6634 char error_prefix[512];
6635
6636 err = pyrna_py_to_prop(&funcptr, parm, iter.data, item, "");
6637
6638 if (err != 0) {
6639 PyErr_Clear(); /* Re-raise. */
6640 pyrna_func_error_prefix(self, parm, kw_arg ? -1 : i, error_prefix, sizeof(error_prefix));
6641 pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix);
6642
6643 break;
6644 }
6645 }
6646
6647 i++; /* Current argument. */
6648 }
6649
6651
6652 /* Check if we gave args that don't exist in the function
6653 * Printing the error is slow, but it should only happen when developing.
6654 * The "if" below is quick check to make sure less keyword args were passed than we gave.
6655 * (Don't overwrite the error if we have one,
6656 * otherwise can skip important messages and confuse with args).
6657 */
6658 if (err == 0 && kw && (pykw_len > kw_tot)) {
6659 PyObject *key, *value;
6660 Py_ssize_t pos = 0;
6661
6662 DynStr *bad_args = BLI_dynstr_new();
6663 DynStr *good_args = BLI_dynstr_new();
6664
6665 const char *arg_name, *bad_args_str, *good_args_str;
6666 bool found = false, first = true;
6667
6668 while (PyDict_Next(kw, &pos, &key, &value)) {
6669
6670 arg_name = PyUnicode_AsUTF8(key);
6671 found = false;
6672
6673 if (arg_name == nullptr)
6674 { /* Unlikely the `arg_name` is not a string, but ignore if it is. */
6675 PyErr_Clear();
6676 }
6677 else {
6678 /* Search for arg_name. */
6679 RNA_parameter_list_begin(&parms, &iter);
6680 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6681 parm = iter.parm;
6682 if (STREQ(arg_name, RNA_property_identifier(parm))) {
6683 found = true;
6684 break;
6685 }
6686 }
6687
6689
6690 if (found == false) {
6691 BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
6692 first = false;
6693 }
6694 }
6695 }
6696
6697 /* List good args. */
6698 first = true;
6699
6700 RNA_parameter_list_begin(&parms, &iter);
6701 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6702 parm = iter.parm;
6703 if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
6704 continue;
6705 }
6706
6707 BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
6708 first = false;
6709 }
6711
6712 bad_args_str = BLI_dynstr_get_cstring(bad_args);
6713 good_args_str = BLI_dynstr_get_cstring(good_args);
6714
6715 PyErr_Format(
6716 PyExc_TypeError,
6717 "%.200s.%.200s(): was called with invalid keyword argument(s) (%s), expected (%s)",
6718 RNA_struct_identifier(self_ptr->type),
6719 RNA_function_identifier(self_func),
6720 bad_args_str,
6721 good_args_str);
6722
6723 BLI_dynstr_free(bad_args);
6724 BLI_dynstr_free(good_args);
6725 MEM_freeN((void *)bad_args_str);
6726 MEM_freeN((void *)good_args_str);
6727
6728 err = -1;
6729 }
6730
6731 ret = nullptr;
6732 if (err == 0) {
6733 /* Call function. */
6734 ReportList reports;
6736
6737 BKE_reports_init(&reports, RPT_STORE);
6738 RNA_function_call(C, &reports, self_ptr, self_func, &parms);
6739
6740 err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true);
6741
6742 /* Return value. */
6743 if (err != -1) {
6744 if (ret_len > 0) {
6745 if (ret_len > 1) {
6746 ret = PyTuple_New(ret_len);
6747 i = 0; /* Arg index. */
6748
6749 RNA_parameter_list_begin(&parms, &iter);
6750
6751 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6752 parm = iter.parm;
6753
6754 if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
6755 PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data));
6756 }
6757 }
6758
6760 }
6761 else {
6762 ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single);
6763 }
6764
6765 /* Possible there is an error in conversion. */
6766 if (ret == nullptr) {
6767 err = -1;
6768 }
6769 }
6770 }
6771 }
6772
6773#ifdef DEBUG_STRING_FREE
6774# if 0
6775 if (PyList_GET_SIZE(string_free_ls)) {
6776 printf("%.200s.%.200s(): has %d strings\n",
6777 RNA_struct_identifier(self_ptr->type),
6778 RNA_function_identifier(self_func),
6779 int(PyList_GET_SIZE(string_free_ls)));
6780 }
6781# endif
6782 Py_DECREF(string_free_ls);
6783# undef DEBUG_STRING_FREE
6784#endif
6785
6786 /* Cleanup. */
6789
6790 if (ret) {
6791 return ret;
6792 }
6793
6794 if (err == -1) {
6795 return nullptr;
6796 }
6797
6798 Py_RETURN_NONE;
6799}
6800
6801static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void * /*closure*/)
6802{
6803 PyObject *ret;
6804
6805 std::string args = RNA_function_as_string_keywords(nullptr, self->func, true, true, INT_MAX);
6806
6807 ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
6808 RNA_struct_identifier(self->ptr.type),
6810 args.c_str(),
6812
6813 return ret;
6814}
6815
6817 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
6818 /*tp_name*/ "bpy_struct_meta_idprop",
6819 /* NOTE: would be `sizeof(PyTypeObject)`,
6820 * but sub-types of Type must be #PyHeapTypeObject's. */
6821 /*tp_basicsize*/ sizeof(PyHeapTypeObject),
6822 /*tp_itemsize*/ 0,
6823 /*tp_dealloc*/ nullptr,
6824 /*tp_vectorcall_offset*/ 0,
6825 /*tp_getattr*/ nullptr,
6826 /*tp_setattr*/ nullptr,
6827 /*tp_as_async*/ nullptr,
6828 /*tp_repr*/ nullptr,
6829 /*tp_as_number*/ nullptr,
6830 /*tp_as_sequence*/ nullptr,
6831 /*tp_as_mapping*/ nullptr,
6832 /*tp_hash*/ nullptr,
6833 /*tp_call*/ nullptr,
6834 /*tp_str*/ nullptr,
6835 /*tp_getattro*/ nullptr, /* Sub-classed: #pyrna_struct_meta_idprop_getattro. */
6836 /*tp_setattro*/ (setattrofunc)pyrna_struct_meta_idprop_setattro,
6837 /*tp_as_buffer*/ nullptr,
6838 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
6839 /*tp_doc*/ nullptr,
6840 /*tp_traverse*/ nullptr,
6841 /*tp_clear*/ nullptr,
6842 /*tp_richcompare*/ nullptr,
6843 /*tp_weaklistoffset*/ 0,
6844 /*tp_iter*/ nullptr,
6845 /*tp_iternext*/ nullptr,
6846 /*tp_methods*/ nullptr,
6847 /*tp_members*/ nullptr,
6848 /*tp_getset*/ nullptr,
6849#if defined(_MSC_VER)
6850 /*tp_base*/ nullptr, /* Defer assignment. */
6851#else
6852 /*tp_base*/ &PyType_Type,
6853#endif
6854 /*tp_dict*/ nullptr,
6855 /*tp_descr_get*/ nullptr,
6856 /*tp_descr_set*/ nullptr,
6857 /*tp_dictoffset*/ 0,
6858 /*tp_init*/ nullptr,
6859 /*tp_alloc*/ nullptr,
6860 /*tp_new*/ nullptr,
6861 /*tp_free*/ nullptr,
6862 /*tp_is_gc*/ nullptr,
6863 /*tp_bases*/ nullptr,
6864 /*tp_mro*/ nullptr,
6865 /*tp_cache*/ nullptr,
6866 /*tp_subclasses*/ nullptr,
6867 /*tp_weaklist*/ nullptr,
6868 /*tp_del*/ nullptr,
6869 /*tp_version_tag*/ 0,
6870 /*tp_finalize*/ nullptr,
6871 /*tp_vectorcall*/ nullptr,
6872};
6873
6874/*-----------------------BPy_StructRNA method def------------------------------*/
6875
6876PyTypeObject pyrna_struct_Type = {
6877 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
6878 /*tp_name*/ "bpy_struct",
6879 /*tp_basicsize*/ sizeof(BPy_StructRNA),
6880 /*tp_itemsize*/ 0,
6881 /*tp_dealloc*/ (destructor)pyrna_struct_dealloc,
6882 /*tp_vectorcall_offset*/ 0,
6883 /*tp_getattr*/ nullptr,
6884 /*tp_setattr*/ nullptr,
6885 /*tp_as_async*/ nullptr,
6886 /*tp_repr*/ (reprfunc)pyrna_struct_repr,
6887 /*tp_as_number*/ nullptr,
6888 /*tp_as_sequence*/ &pyrna_struct_as_sequence,
6889 /*tp_as_mapping*/ &pyrna_struct_as_mapping,
6890 /*tp_hash*/ (hashfunc)pyrna_struct_hash,
6891 /*tp_call*/ nullptr,
6892 /*tp_str*/ (reprfunc)pyrna_struct_str,
6893 /*tp_getattro*/ (getattrofunc)pyrna_struct_getattro,
6894 /*tp_setattro*/ (setattrofunc)pyrna_struct_setattro,
6895 /*tp_as_buffer*/ nullptr,
6896 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
6897#ifdef USE_PYRNA_STRUCT_REFERENCE
6898 | Py_TPFLAGS_HAVE_GC
6899#endif
6900 ,
6901 /*tp_doc*/ nullptr,
6902#ifdef USE_PYRNA_STRUCT_REFERENCE
6903 /*tp_traverse*/ (traverseproc)pyrna_struct_traverse,
6904 /*tp_clear*/ (inquiry)pyrna_struct_clear,
6905#else
6906 /*tp_traverse*/ nullptr,
6907 /*tp_clear*/ nullptr,
6908#endif /* !USE_PYRNA_STRUCT_REFERENCE */
6909 /*tp_richcompare*/ (richcmpfunc)pyrna_struct_richcmp,
6910#ifdef USE_WEAKREFS
6911 /*tp_weaklistoffset*/ offsetof(BPy_StructRNA, in_weakreflist),
6912#else
6913 0,
6914#endif
6915 /*tp_iter*/ nullptr,
6916 /*tp_iternext*/ nullptr,
6917 /*tp_methods*/ pyrna_struct_methods,
6918 /*tp_members*/ nullptr,
6919 /*tp_getset*/ pyrna_struct_getseters,
6920 /*tp_base*/ nullptr,
6921 /*tp_dict*/ nullptr,
6922 /*tp_descr_get*/ nullptr,
6923 /*tp_descr_set*/ nullptr,
6924 /*tp_dictoffset*/ 0,
6925 /*tp_init*/ nullptr,
6926 /*tp_alloc*/ nullptr,
6927 /*tp_new*/ pyrna_struct_new,
6928 /*tp_free*/ nullptr,
6929 /*tp_is_gc*/ nullptr,
6930 /*tp_bases*/ nullptr,
6931 /*tp_mro*/ nullptr,
6932 /*tp_cache*/ nullptr,
6933 /*tp_subclasses*/ nullptr,
6934 /*tp_weaklist*/ nullptr,
6935 /*tp_del*/ nullptr,
6936 /*tp_version_tag*/ 0,
6937 /*tp_finalize*/ nullptr,
6938 /*tp_vectorcall*/ nullptr,
6939};
6940
6941/*-----------------------BPy_PropertyRNA method def------------------------------*/
6942
6943PyTypeObject pyrna_prop_Type = {
6944 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
6945 /*tp_name*/ "bpy_prop",
6946 /*tp_basicsize*/ sizeof(BPy_PropertyRNA),
6947 /*tp_itemsize*/ 0,
6948 /*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
6949 /*tp_vectorcall_offset*/ 0,
6950 /*tp_getattr*/ nullptr,
6951 /*tp_setattr*/ nullptr,
6952 /*tp_as_async*/ nullptr,
6953 /*tp_repr*/ (reprfunc)pyrna_prop_repr,
6954 /*tp_as_number*/ nullptr,
6955 /*tp_as_sequence*/ nullptr,
6956 /*tp_as_mapping*/ nullptr,
6957 /*tp_hash*/ (hashfunc)pyrna_prop_hash,
6958 /*tp_call*/ nullptr,
6959 /*tp_str*/ (reprfunc)pyrna_prop_str,
6960 /*tp_getattro*/ nullptr,
6961 /*tp_setattro*/ nullptr,
6962 /*tp_as_buffer*/ nullptr,
6963 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
6964 /*tp_doc*/ nullptr,
6965 /*tp_traverse*/ nullptr,
6966 /*tp_clear*/ nullptr,
6967 /*tp_richcompare*/ (richcmpfunc)pyrna_prop_richcmp,
6968#ifdef USE_WEAKREFS
6969 /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
6970#else
6971 /*tp_weaklistoffset*/ 0,
6972#endif
6973 /*tp_iter*/ nullptr,
6974 /*tp_iternext*/ nullptr,
6975 /*tp_methods*/ pyrna_prop_methods,
6976 /*tp_members*/ nullptr,
6977 /*tp_getset*/ pyrna_prop_getseters,
6978 /*tp_base*/ nullptr,
6979 /*tp_dict*/ nullptr,
6980 /*tp_descr_get*/ nullptr,
6981 /*tp_descr_set*/ nullptr,
6982 /*tp_dictoffset*/ 0,
6983 /*tp_init*/ nullptr,
6984 /*tp_alloc*/ nullptr,
6985 /*tp_new*/ pyrna_prop_new,
6986 /*tp_free*/ nullptr,
6987 /*tp_is_gc*/ nullptr,
6988 /*tp_bases*/ nullptr,
6989 /*tp_mro*/ nullptr,
6990 /*tp_cache*/ nullptr,
6991 /*tp_subclasses*/ nullptr,
6992 /*tp_weaklist*/ nullptr,
6993 /*tp_del*/ nullptr,
6994 /*tp_version_tag*/ 0,
6995 /*tp_finalize*/ nullptr,
6996 /*tp_vectorcall*/ nullptr,
6997};
6998
7000 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
7001 /*tp_name*/ "bpy_prop_array",
7002 /*tp_basicsize*/ sizeof(BPy_PropertyArrayRNA),
7003 /*tp_itemsize*/ 0,
7004 /*tp_dealloc*/ (destructor)pyrna_prop_array_dealloc,
7005 /*tp_vectorcall_offset*/ 0,
7006 /*tp_getattr*/ nullptr,
7007 /*tp_setattr*/ nullptr,
7008 /*tp_as_async*/ nullptr,
7009 /*tp_repr*/ (reprfunc)pyrna_prop_array_repr,
7010 /*tp_as_number*/ &pyrna_prop_array_as_number,
7011 /*tp_as_sequence*/ &pyrna_prop_array_as_sequence,
7012 /*tp_as_mapping*/ &pyrna_prop_array_as_mapping,
7013 /*tp_hash*/ nullptr,
7014 /*tp_call*/ nullptr,
7015 /*tp_str*/ nullptr,
7016 /*tp_getattro*/ (getattrofunc)pyrna_prop_array_getattro,
7017 /*tp_setattro*/ nullptr,
7018 /*tp_as_buffer*/ nullptr,
7019 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
7020 /*tp_doc*/ nullptr,
7021 /*tp_traverse*/ nullptr,
7022 /*tp_clear*/ nullptr,
7023 /*tp_richcompare*/ nullptr,
7024#ifdef USE_WEAKREFS
7025 /*tp_weaklistoffset*/ offsetof(BPy_PropertyArrayRNA, in_weakreflist),
7026#else
7027 /*tp_weaklistoffset*/ 0,
7028#endif
7029 /*tp_iter*/ (getiterfunc)pyrna_prop_array_iter,
7030 /*tp_iternext*/ nullptr,
7031 /*tp_methods*/ pyrna_prop_array_methods,
7032 /*tp_members*/ nullptr,
7033 /*tp_getset*/ nullptr /* Sub-classed: #pyrna_prop_getseters. */,
7034 /*tp_base*/ &pyrna_prop_Type,
7035 /*tp_dict*/ nullptr,
7036 /*tp_descr_get*/ nullptr,
7037 /*tp_descr_set*/ nullptr,
7038 /*tp_dictoffset*/ 0,
7039 /*tp_init*/ nullptr,
7040 /*tp_alloc*/ nullptr,
7041 /*tp_new*/ nullptr,
7042 /*tp_free*/ nullptr,
7043 /*tp_is_gc*/ nullptr,
7044 /*tp_bases*/ nullptr,
7045 /*tp_mro*/ nullptr,
7046 /*tp_cache*/ nullptr,
7047 /*tp_subclasses*/ nullptr,
7048 /*tp_weaklist*/ nullptr,
7049 /*tp_del*/ nullptr,
7050 /*tp_version_tag*/ 0,
7051 /*tp_finalize*/ nullptr,
7052 /*tp_vectorcall*/ nullptr,
7053};
7054
7056 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
7057 /*tp_name*/ "bpy_prop_collection",
7058 /*tp_basicsize*/ sizeof(BPy_PropertyRNA),
7059 /*tp_itemsize*/ 0,
7060 /*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
7061 /*tp_vectorcall_offset*/ 0,
7062 /*tp_getattr*/ nullptr,
7063 /*tp_setattr*/ nullptr,
7064 /*tp_as_async*/ nullptr,
7065 /*tp_repr*/ nullptr, /* Sub-classed, no need to define. */
7066 /*tp_as_number*/ &pyrna_prop_collection_as_number,
7067 /*tp_as_sequence*/ &pyrna_prop_collection_as_sequence,
7068 /*tp_as_mapping*/ &pyrna_prop_collection_as_mapping,
7069 /*tp_hash*/ nullptr,
7070 /*tp_call*/ nullptr,
7071 /*tp_str*/ nullptr,
7072 /*tp_getattro*/ (getattrofunc)pyrna_prop_collection_getattro,
7073 /*tp_setattro*/ (setattrofunc)pyrna_prop_collection_setattro,
7074 /*tp_as_buffer*/ nullptr,
7075 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
7076 /*tp_doc*/ nullptr,
7077 /*tp_traverse*/ nullptr,
7078 /*tp_clear*/ nullptr,
7079 /*tp_richcompare*/ nullptr,
7080#ifdef USE_WEAKREFS
7081 /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
7082#else
7083 /*tp_weaklistoffset*/ 0,
7084#endif
7085 /*tp_iter*/ (getiterfunc)pyrna_prop_collection_iter,
7086 /*tp_iternext*/ nullptr,
7087 /*tp_methods*/ pyrna_prop_collection_methods,
7088 /*tp_members*/ nullptr,
7089 /*tp_getset*/ nullptr /*Sub-classed: see #pyrna_prop_getseters. */,
7090 /*tp_base*/ &pyrna_prop_Type,
7091 /*tp_dict*/ nullptr,
7092 /*tp_descr_get*/ nullptr,
7093 /*tp_descr_set*/ nullptr,
7094 /*tp_dictoffset*/ 0,
7095 /*tp_init*/ nullptr,
7096 /*tp_alloc*/ nullptr,
7097 /*tp_new*/ nullptr,
7098 /*tp_free*/ nullptr,
7099 /*tp_is_gc*/ nullptr,
7100 /*tp_bases*/ nullptr,
7101 /*tp_mro*/ nullptr,
7102 /*tp_cache*/ nullptr,
7103 /*tp_subclasses*/ nullptr,
7104 /*tp_weaklist*/ nullptr,
7105 /*tp_del*/ nullptr,
7106 /*tp_version_tag*/ 0,
7107 /*tp_finalize*/ nullptr,
7108 /*tp_vectorcall*/ nullptr,
7109};
7110
7111/* only for add/remove/move methods */
7113 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
7114 /*tp_name*/ "bpy_prop_collection_idprop",
7115 /*tp_basicsize*/ sizeof(BPy_PropertyRNA),
7116 /*tp_itemsize*/ 0,
7117 /*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
7118 /*tp_vectorcall_offset*/ 0,
7119 /*tp_getattr*/ nullptr,
7120 /*tp_setattr*/ nullptr,
7121 /*tp_compare*/ nullptr, /* DEPRECATED. */
7122 /*tp_repr*/ nullptr, /* Sub-classed, no need to define. */
7123 /*tp_as_number*/ nullptr,
7124 /*tp_as_sequence*/ nullptr,
7125 /*tp_as_mapping*/ nullptr,
7126 /*tp_hash*/ nullptr,
7127 /*tp_call*/ nullptr,
7128 /*tp_str*/ nullptr,
7129 /*tp_getattro*/ nullptr,
7130 /*tp_setattro*/ nullptr,
7131 /*tp_as_buffer*/ nullptr,
7132 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
7133 /*tp_doc*/ nullptr,
7134 /*tp_traverse*/ nullptr,
7135 /*tp_clear*/ nullptr,
7136 /*tp_richcompare*/ nullptr,
7137#ifdef USE_WEAKREFS
7138 /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
7139#else
7140 /*tp_weaklistoffset*/ 0,
7141#endif
7142 /*tp_iter*/ nullptr,
7143 /*tp_iternext*/ nullptr,
7145 /*tp_members*/ nullptr,
7146 /*tp_getset*/ nullptr /* Sub-classed: #pyrna_prop_getseters. */,
7147 /*tp_base*/ &pyrna_prop_collection_Type,
7148 /*tp_dict*/ nullptr,
7149 /*tp_descr_get*/ nullptr,
7150 /*tp_descr_set*/ nullptr,
7151 /*tp_dictoffset*/ 0,
7152 /*tp_init*/ nullptr,
7153 /*tp_alloc*/ nullptr,
7154 /*tp_new*/ nullptr,
7155 /*tp_free*/ nullptr,
7156 /*tp_is_gc*/ nullptr,
7157 /*tp_bases*/ nullptr,
7158 /*tp_mro*/ nullptr,
7159 /*tp_cache*/ nullptr,
7160 /*tp_subclasses*/ nullptr,
7161 /*tp_weaklist*/ nullptr,
7162 /*tp_del*/ nullptr,
7163 /*tp_version_tag*/ 0,
7164 /*tp_finalize*/ nullptr,
7165 /*tp_vectorcall*/ nullptr,
7166};
7167
7168/*-----------------------BPy_PropertyRNA method def------------------------------*/
7169
7170PyTypeObject pyrna_func_Type = {
7171 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
7172 /*tp_name*/ "bpy_func",
7173 /*tp_basicsize*/ sizeof(BPy_FunctionRNA),
7174 /*tp_itemsize*/ 0,
7175 /*tp_dealloc*/ nullptr,
7176 /*tp_vectorcall_offset*/ 0,
7177 /*tp_getattr*/ nullptr,
7178 /*tp_setattr*/ nullptr,
7179 /*tp_as_async*/ nullptr,
7180 /*tp_repr*/ (reprfunc)pyrna_func_repr,
7181 /*tp_as_number*/ nullptr,
7182 /*tp_as_sequence*/ nullptr,
7183 /*tp_as_mapping*/ nullptr,
7184 /*tp_hash*/ nullptr,
7185 /*tp_call*/ (ternaryfunc)pyrna_func_call,
7186 /*tp_str*/ nullptr,
7187 /*tp_getattro*/ nullptr,
7188 /*tp_setattro*/ nullptr,
7189 /*tp_as_buffer*/ nullptr,
7190 /*tp_flags*/ Py_TPFLAGS_DEFAULT,
7191 /*tp_doc*/ nullptr,
7192 /*tp_traverse*/ nullptr,
7193 /*tp_clear*/ nullptr,
7194 /*tp_richcompare*/ nullptr,
7195#ifdef USE_WEAKREFS
7196 /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
7197#else
7198 /*tp_weaklistoffset*/ 0,
7199#endif
7200 /*tp_iter*/ nullptr,
7201 /*tp_iternext*/ nullptr,
7202 /*tp_methods*/ nullptr,
7203 /*tp_members*/ nullptr,
7204 /*tp_getset*/ pyrna_func_getseters,
7205 /*tp_base*/ nullptr,
7206 /*tp_dict*/ nullptr,
7207 /*tp_descr_get*/ nullptr,
7208 /*tp_descr_set*/ nullptr,
7209 /*tp_dictoffset*/ 0,
7210 /*tp_init*/ nullptr,
7211 /*tp_alloc*/ nullptr,
7212 /*tp_new*/ nullptr,
7213 /*tp_free*/ nullptr,
7214 /*tp_is_gc*/ nullptr,
7215 /*tp_bases*/ nullptr,
7216 /*tp_mro*/ nullptr,
7217 /*tp_cache*/ nullptr,
7218 /*tp_subclasses*/ nullptr,
7219 /*tp_weaklist*/ nullptr,
7220 /*tp_del*/ nullptr,
7221 /*tp_version_tag*/ 0,
7222 /*tp_finalize*/ nullptr,
7223 /*tp_vectorcall*/ nullptr,
7224};
7225
7226#ifdef USE_PYRNA_ITER
7227/* --- collection iterator: start --- */
7228/* wrap RNA collection iterator functions */
7229/*
7230 * RNA_property_collection_begin(...)
7231 * RNA_property_collection_next(...)
7232 * RNA_property_collection_end(...)
7233 */
7234
7237
7238static PyTypeObject pyrna_prop_collection_iter_Type = {
7239 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
7240 /*tp_name*/ "bpy_prop_collection_iter",
7241 /*tp_basicsize*/ sizeof(BPy_PropertyCollectionIterRNA),
7242 /*tp_itemsize*/ 0,
7243 /*tp_dealloc*/ (destructor)pyrna_prop_collection_iter_dealloc,
7244 /*tp_vectorcall_offset*/ 0,
7245 /*tp_getattr*/ nullptr,
7246 /*tp_setattr*/ nullptr,
7247 /*tp_as_async*/ nullptr,
7248 /*tp_repr*/ nullptr, /* No need to define, sub-classed. */
7249 /*tp_as_number*/ nullptr,
7250 /*tp_as_sequence*/ nullptr,
7251 /*tp_as_mapping*/ nullptr,
7252 /*tp_hash*/ nullptr,
7253 /*tp_call*/ nullptr,
7254 /*tp_str*/ nullptr,
7255 /*tp_getattro*/ PyObject_GenericGetAttr,
7256 /*tp_setattro*/ nullptr,
7257 /*tp_as_buffer*/ nullptr,
7258 /*tp_flags*/ Py_TPFLAGS_DEFAULT,
7259 /*tp_doc*/ nullptr,
7260 /*tp_traverse*/ nullptr,
7261 /*tp_clear*/ nullptr,
7262 /*tp_richcompare*/ nullptr,
7263# ifdef USE_WEAKREFS
7264 /*tp_weaklistoffset*/ offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist),
7265# else
7266 /*tp_weaklistoffset*/ 0,
7267# endif
7268 /*tp_iter*/ PyObject_SelfIter,
7269 /*tp_iternext*/ (iternextfunc)pyrna_prop_collection_iter_next,
7270 /*tp_methods*/ nullptr,
7271 /*tp_members*/ nullptr,
7272 /*tp_getset*/ nullptr,
7273 /*tp_base*/ nullptr,
7274 /*tp_dict*/ nullptr,
7275 /*tp_descr_get*/ nullptr,
7276 /*tp_descr_set*/ nullptr,
7277 /*tp_dictoffset*/ 0,
7278 /*tp_init*/ nullptr,
7279 /*tp_alloc*/ nullptr,
7280 /*tp_new*/ nullptr,
7281 /*tp_free*/ nullptr,
7282 /*tp_is_gc*/ nullptr,
7283 /*tp_bases*/ nullptr,
7284 /*tp_mro*/ nullptr,
7285 /*tp_cache*/ nullptr,
7286 /*tp_subclasses*/ nullptr,
7287 /*tp_weaklist*/ nullptr,
7288 /*tp_del*/ nullptr,
7289 /*tp_version_tag*/ 0,
7290 /*tp_finalize*/ nullptr,
7291 /*tp_vectorcall*/ nullptr,
7292};
7293
7295{
7298
7299# ifdef USE_WEAKREFS
7300 self->in_weakreflist = nullptr;
7301# endif
7302
7303 RNA_property_collection_begin(ptr, prop, &self->iter);
7304
7305 return (PyObject *)self;
7306}
7307
7312
7314{
7315 if (self->iter.valid == false) {
7316 PyErr_SetNone(PyExc_StopIteration);
7317 return nullptr;
7318 }
7319
7321
7322# ifdef USE_PYRNA_STRUCT_REFERENCE
7323 if (pyrna) { /* Unlikely, but may fail. */
7324 if ((PyObject *)pyrna != Py_None) {
7325 /* hold a reference to the iterator since it may have
7326 * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's. */
7327 /* TODO: we could have an api call to know if this is
7328 * needed since most collections don't */
7329 pyrna_struct_reference_set(pyrna, (PyObject *)self);
7330 }
7331 }
7332# endif /* !USE_PYRNA_STRUCT_REFERENCE */
7333
7335
7336 return (PyObject *)pyrna;
7337}
7338
7340{
7341# ifdef USE_WEAKREFS
7342 if (self->in_weakreflist != nullptr) {
7343 PyObject_ClearWeakRefs((PyObject *)self);
7344 }
7345# endif
7346
7348
7349 PyObject_DEL(self);
7350}
7351
7352/* --- collection iterator: end --- */
7353#endif /* !USE_PYRNA_ITER */
7354
7355static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
7356{
7357 Py_INCREF(newclass);
7358
7359 if (PyObject *oldclass = static_cast<PyObject *>(RNA_struct_py_type_get(srna))) {
7360 PyC_ObSpit("RNA WAS SET - ", oldclass);
7361 Py_DECREF(oldclass);
7362 }
7363 RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */
7364
7365 /* Not 100% needed, but useful,
7366 * having an instance within a type looks wrong, but this instance _is_ an RNA type. */
7367
7368 /* Python deals with the circular reference. */
7369 PointerRNA ptr = RNA_pointer_create(nullptr, &RNA_Struct, srna);
7370
7371 /* NOTE: using `pyrna_struct_CreatePyObject(&ptr)` is close to what is needed,
7372 * however the it isn't correct because the result of:
7373 * `type(bpy.types.Object.bl_rna) == bpy.types.Object`.
7374 * In this case the type of `bl_rna` should be `bpy.types.Struct`.
7375 * This is passed in explicitly, while #pyrna_struct_CreatePyObject could
7376 * take this as an argument it's such a corner case that using a lower level
7377 * function that takes the type is preferable. */
7378 {
7379 BLI_assert(RNA_struct_instance(&ptr) == nullptr);
7380 PyTypeObject *tp = (PyTypeObject *)pyrna_srna_Subtype(&RNA_Struct);
7381 PyObject *item = pyrna_struct_CreatePyObject_from_type(&ptr, tp, nullptr);
7382 Py_DECREF(tp); /* `srna` owns, can't hold a reference. */
7383
7384 /* NOTE: must set the class not the `__dict__`
7385 * else the internal slots are not updated correctly. */
7386 PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
7387 Py_DECREF(item);
7388 }
7389
7390 /* Add `staticmethod` and `classmethod` functions. */
7391 {
7392 const PointerRNA func_ptr = {nullptr, srna, nullptr};
7393 const ListBase *lb;
7394
7395 lb = RNA_struct_type_functions(srna);
7396 LISTBASE_FOREACH (Link *, link, lb) {
7397 FunctionRNA *func = (FunctionRNA *)link;
7398 const int flag = RNA_function_flag(func);
7399 if ((flag & FUNC_NO_SELF) && /* Is `staticmethod` or `classmethod`. */
7400 (flag & FUNC_REGISTER) == false) /* Is not for registration. */
7401 {
7402 /* We may want to set the type of this later. */
7403 PyObject *func_py = pyrna_func_to_py(&func_ptr, func);
7404 PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py);
7405 Py_DECREF(func_py);
7406 }
7407 }
7408 }
7409
7410 /* Done with RNA instance. */
7411}
7412
7413/* Return a borrowed reference. */
7414static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict)
7415{
7416 /* Assume RNA_struct_py_type_get(srna) was already checked. */
7417 StructRNA *base;
7418
7419 PyObject *py_base = nullptr;
7420
7421 /* Get the base type. */
7422 base = RNA_struct_base(srna);
7423
7424 if (base && base != srna) {
7425 // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna);
7426 py_base = pyrna_srna_Subtype(base); //, bpy_types_dict);
7427 Py_DECREF(py_base); /* `srna` owns, this is only to pass as an argument. */
7428 }
7429
7430 if (py_base == nullptr) {
7431 py_base = (PyObject *)&pyrna_struct_Type;
7432 }
7433
7434 return py_base;
7435}
7436
7437/* Check if we have a native Python subclass, use it when it exists
7438 * return a borrowed reference. */
7439static PyObject *bpy_types_dict = nullptr;
7440
7441static PyObject *pyrna_srna_ExternalType(StructRNA *srna)
7442{
7443 const char *idname = RNA_struct_identifier(srna);
7444 PyObject *newclass;
7445
7446 if (bpy_types_dict == nullptr) {
7447 PyObject *bpy_types = PyImport_ImportModuleLevel("bpy_types", nullptr, nullptr, nullptr, 0);
7448
7449 if (bpy_types == nullptr) {
7450 PyErr_Print();
7451 PyErr_Clear();
7452 CLOG_ERROR(BPY_LOG_RNA, "failed to find 'bpy_types' module");
7453 return nullptr;
7454 }
7455 bpy_types_dict = PyModule_GetDict(bpy_types); /* Borrow. */
7456 Py_DECREF(bpy_types); /* Fairly safe to assume the dict is kept. */
7457 }
7458
7459 newclass = PyDict_GetItemString(bpy_types_dict, idname);
7460
7461 /* Sanity check, could skip this unless in debug mode. */
7462 if (newclass) {
7463 PyObject *base_compare = pyrna_srna_PyBase(srna);
7464 /* Can't do this because it gets super-classes values! */
7465 // PyObject *slots = PyObject_GetAttrString(newclass, "__slots__");
7466 /* Can do this, but faster not to. */
7467 // PyObject *bases = PyObject_GetAttrString(newclass, "__bases__");
7468 PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases;
7469 PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict,
7471
7472 if (tp_slots == nullptr) {
7473 CLOG_ERROR(
7474 BPY_LOG_RNA, "expected class '%s' to have __slots__ defined, see bpy_types.py", idname);
7475 newclass = nullptr;
7476 }
7477 else if (PyTuple_GET_SIZE(tp_bases)) {
7478 PyObject *base = PyTuple_GET_ITEM(tp_bases, 0);
7479
7480 if (base_compare != base) {
7481 char pyob_info[256];
7482 PyC_ObSpitStr(pyob_info, sizeof(pyob_info), base_compare);
7484 "incorrect subclassing of SRNA '%s', expected '%s', see bpy_types.py",
7485 idname,
7486 pyob_info);
7487 newclass = nullptr;
7488 }
7489 else {
7490 CLOG_INFO(BPY_LOG_RNA, 2, "SRNA sub-classed: '%s'", idname);
7491 }
7492 }
7493 }
7494
7495 return newclass;
7496}
7497
7498static PyObject *pyrna_srna_Subtype(StructRNA *srna)
7499{
7500 PyObject *newclass = nullptr;
7501
7502 /* Stupid/simple case. */
7503 if (srna == nullptr) {
7504 newclass = nullptr; /* Nothing to do. */
7505 } /* The class may have already been declared & allocated. */
7506 else if ((newclass = static_cast<PyObject *>(RNA_struct_py_type_get(srna)))) {
7507 Py_INCREF(newclass);
7508 } /* Check if bpy_types.py module has the class defined in it. */
7509 else if ((newclass = pyrna_srna_ExternalType(srna))) {
7510 pyrna_subtype_set_rna(newclass, srna);
7511 Py_INCREF(newclass);
7512 } /* create a new class instance with the C api
7513 * mainly for the purposing of matching the C/RNA type hierarchy */
7514 else {
7515 /* subclass equivalents
7516 * - class myClass(myBase):
7517 * some = 'value' # or ...
7518 * - myClass = type(
7519 * name='myClass',
7520 * bases=(myBase,), dict={'__module__': 'bpy.types', '__slots__': ()}
7521 * )
7522 */
7523
7524 /* Assume RNA_struct_py_type_get(srna) was already checked. */
7525 PyObject *py_base = pyrna_srna_PyBase(srna);
7526 PyObject *metaclass;
7527 const char *idname = RNA_struct_identifier(srna);
7528
7529/* Remove `__doc__` for now because we don't need it to generate docs. */
7530#if 0
7531 const char *descr = RNA_struct_ui_description(srna);
7532 if (!descr) {
7533 descr = "(no docs)";
7534 }
7535#endif
7536
7537 if (RNA_struct_idprops_check(srna) &&
7538 !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type))
7539 {
7540 metaclass = (PyObject *)&pyrna_struct_meta_idprop_Type;
7541 }
7542 else {
7543 metaclass = (PyObject *)&PyType_Type;
7544 }
7545
7546/* Always use O not N when calling, N causes refcount errors. */
7547#if 0
7548 newclass = PyObject_CallFunction(
7549 metaclass, "s(O) {sss()}", idname, py_base, "__module__", "bpy.types", "__slots__");
7550#else
7551 {
7552 /* Longhand of the call above. */
7553 PyObject *args, *item, *value;
7554 int ok;
7555
7556 args = PyTuple_New(3);
7557
7558 /* arg[0] (name=...) */
7559 PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(idname));
7560
7561 /* arg[1] (bases=...) */
7562 PyTuple_SET_ITEM(args, 1, item = PyTuple_New(1));
7563 PyTuple_SET_ITEM(item, 0, Py_NewRef(py_base));
7564
7565 /* arg[2] (dict=...) */
7566 PyTuple_SET_ITEM(args, 2, item = PyDict_New());
7567 ok = PyDict_SetItem(item, bpy_intern_str___module__, bpy_intern_str_bpy_types);
7568 BLI_assert(ok != -1);
7569 ok = PyDict_SetItem(item, bpy_intern_str___slots__, value = PyTuple_New(0));
7570 Py_DECREF(value);
7571 BLI_assert(ok != -1);
7572
7573 newclass = PyObject_CallObject(metaclass, args);
7574 Py_DECREF(args);
7575
7576 (void)ok;
7577 }
7578#endif
7579
7580 /* Newclass will now have 2 ref's, ???,
7581 * probably 1 is internal since #Py_DECREF here segfaults. */
7582
7583 // PyC_ObSpit("new class ref", newclass);
7584
7585 if (newclass) {
7586 /* srna owns one, and the other is owned by the caller. */
7587 pyrna_subtype_set_rna(newclass, srna);
7588
7589 /* XXX, adding this back segfaults Blender on load. */
7590 // Py_DECREF(newclass); /* let srna own */
7591 }
7592 else {
7593 /* This should not happen. */
7594 CLOG_ERROR(BPY_LOG_RNA, "failed to register '%s'", idname);
7595 PyErr_Print();
7596 PyErr_Clear();
7597 }
7598 }
7599
7600 return newclass;
7601}
7602
7607{
7608 if (ptr->type == &RNA_Struct) {
7609 return static_cast<StructRNA *>(ptr->data);
7610 }
7611
7612 return ptr->type;
7613}
7614
7615/* Always returns a new ref, be sure to decref when done. */
7617{
7619}
7620
7621/*-----------------------CreatePyObject---------------------------------*/
7622
7628 PyTypeObject *tp,
7629 void **instance)
7630{
7631 BPy_StructRNA *pyrna = nullptr;
7632 if (tp) {
7633 pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
7634#ifdef USE_PYRNA_STRUCT_REFERENCE
7635 /* #PyType_GenericAlloc will have set tracking.
7636 * We only want tracking when `StructRNA.reference` has been set. */
7637 if (pyrna != nullptr) {
7638 PyObject_GC_UnTrack(pyrna);
7639 }
7640#endif
7641 }
7642 else {
7643 CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
7644
7645#ifdef USE_PYRNA_STRUCT_REFERENCE
7646 pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
7647#else
7648 pyrna = (BPy_StructRNA *)PyObject_New(BPy_StructRNA, &pyrna_struct_Type);
7649#endif
7650
7651#ifdef USE_PYRNA_STRUCT_REFERENCE
7652 /* #PyType_GenericAlloc will have set tracking.
7653 * We only want tracking when `StructRNA.reference` has been set. */
7654 PyObject_GC_UnTrack(pyrna);
7655#endif
7656
7657#ifdef USE_WEAKREFS
7658 if (pyrna != nullptr) {
7659 pyrna->in_weakreflist = nullptr;
7660 }
7661#endif
7662 }
7663
7664 if (pyrna == nullptr) {
7665 PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_struct object");
7666 return nullptr;
7667 }
7668
7669 /* Blender's instance owns a reference (to avoid Python freeing it). */
7670 if (instance) {
7671 *instance = pyrna;
7672 Py_INCREF(pyrna);
7673 }
7674
7675 pyrna->ptr = *ptr;
7676#ifdef PYRNA_FREE_SUPPORT
7677 pyrna->freeptr = false;
7678#endif
7679
7680#ifdef USE_PYRNA_STRUCT_REFERENCE
7681 pyrna->reference = nullptr;
7682#endif
7683
7684 // PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna);
7685
7686#ifdef USE_PYRNA_INVALIDATE_WEAKREF
7687 if (ptr->owner_id) {
7688 id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna);
7689 }
7690#endif
7691 return (PyObject *)pyrna;
7692}
7693
7695{
7696 BPy_StructRNA *pyrna = nullptr;
7697
7698 /* NOTE: don't rely on this to return None since nullptr data with a valid type can often crash.
7699 */
7700 if (ptr->data == nullptr && ptr->type == nullptr) { /* Operator RNA has nullptr data. */
7701 Py_RETURN_NONE;
7702 }
7703
7704 /* New in 2.8x, since not many types support instancing
7705 * we may want to use a flag to avoid looping over all classes. - campbell */
7706 void **instance = ptr->data ? RNA_struct_instance(ptr) : nullptr;
7707 if (instance && *instance) {
7708 pyrna = static_cast<BPy_StructRNA *>(*instance);
7709
7710 /* Refine may have changed types after the first instance was created. */
7711 if (ptr->type == pyrna->ptr.type) {
7712 Py_INCREF(pyrna);
7713 return (PyObject *)pyrna;
7714 }
7715
7716 /* Existing users will need to use 'type_recast' method. */
7717 Py_DECREF(pyrna);
7718 *instance = nullptr;
7719/* Continue as if no instance was made. */
7720#if 0 /* No need to assign, will be written to next... */
7721 pyrna = nullptr;
7722#endif
7723 }
7724
7725 PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
7727 Py_XDECREF(tp); /* `srna` owns, can't hold a reference. */
7728 return (PyObject *)pyrna;
7729}
7730
7732{
7733 if (ptr->type == &RNA_PrimitiveString) {
7734 const PrimitiveStringRNA *data = static_cast<const PrimitiveStringRNA *>(ptr->data);
7735 return PyC_UnicodeFromBytes(data->value);
7736 }
7737 if (ptr->type == &RNA_PrimitiveInt) {
7738 const PrimitiveIntRNA *data = static_cast<const PrimitiveIntRNA *>(ptr->data);
7739 return PyLong_FromLong(data->value);
7740 }
7741 if (ptr->type == &RNA_PrimitiveFloat) {
7742 const PrimitiveFloatRNA *data = static_cast<const PrimitiveFloatRNA *>(ptr->data);
7743 return PyFloat_FromDouble(data->value);
7744 }
7745 if (ptr->type == &RNA_PrimitiveBoolean) {
7746 const PrimitiveBooleanRNA *data = static_cast<const PrimitiveBooleanRNA *>(ptr->data);
7747 return PyBool_FromLong(data->value);
7748 }
7750}
7751
7753{
7754 BPy_PropertyRNA *pyrna;
7755
7756 if (RNA_property_array_check(prop) == 0) {
7757 PyTypeObject *type;
7758
7759 if (RNA_property_type(prop) != PROP_COLLECTION) {
7760 type = &pyrna_prop_Type;
7761 }
7762 else {
7763 if ((RNA_property_flag(prop) & PROP_IDPROPERTY) == 0) {
7765 }
7766 else {
7768 }
7769 }
7770
7771 pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyRNA, type);
7772#ifdef USE_WEAKREFS
7773 pyrna->in_weakreflist = nullptr;
7774#endif
7775 }
7776 else {
7778 ((BPy_PropertyArrayRNA *)pyrna)->arraydim = 0;
7779 ((BPy_PropertyArrayRNA *)pyrna)->arrayoffset = 0;
7780#ifdef USE_WEAKREFS
7781 ((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist = nullptr;
7782#endif
7783 }
7784
7785 if (pyrna == nullptr) {
7786 PyErr_SetString(PyExc_MemoryError, "couldn't create BPy_rna object");
7787 return nullptr;
7788 }
7789
7790 pyrna->ptr = *ptr;
7791 pyrna->prop = prop;
7792
7793#ifdef USE_PYRNA_INVALIDATE_WEAKREF
7794 if (ptr->owner_id) {
7795 id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna);
7796 }
7797#endif
7798
7799 return (PyObject *)pyrna;
7800}
7801
7803{
7804 if (id) {
7807 }
7808
7809 Py_RETURN_NONE;
7810}
7811
7812bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
7813{
7814 if (pyrna_id_CheckPyObject(obj)) {
7815 *id = ((BPy_StructRNA *)obj)->ptr.owner_id;
7816 return true;
7817 }
7818
7819 *id = nullptr;
7820 return false;
7821}
7822
7823bool pyrna_id_CheckPyObject(PyObject *obj)
7824{
7825 return BPy_StructRNA_Check(obj) && RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type);
7826}
7827
7829{
7830#ifdef USE_MATHUTILS /* Register mathutils callbacks, ok to run more than once. */
7833#endif
7834
7835/* For some reason MSVC complains of these. */
7836#if defined(_MSC_VER)
7837 pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type;
7838#endif
7839
7840 /* metaclass */
7841 if (PyType_Ready(&pyrna_struct_meta_idprop_Type) < 0) {
7842 return;
7843 }
7844
7845 if (PyType_Ready(&pyrna_struct_Type) < 0) {
7846 return;
7847 }
7848
7849 if (PyType_Ready(&pyrna_prop_Type) < 0) {
7850 return;
7851 }
7852
7853 if (PyType_Ready(&pyrna_prop_array_Type) < 0) {
7854 return;
7855 }
7856
7857 if (PyType_Ready(&pyrna_prop_collection_Type) < 0) {
7858 return;
7859 }
7860
7861 if (PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0) {
7862 return;
7863 }
7864
7865 if (PyType_Ready(&pyrna_func_Type) < 0) {
7866 return;
7867 }
7868
7869#ifdef USE_PYRNA_ITER
7870 if (PyType_Ready(&pyrna_prop_collection_iter_Type) < 0) {
7871 return;
7872 }
7873#endif
7874
7875#ifdef USE_PYRNA_INVALIDATE_WEAKREF
7876 BLI_assert(id_weakref_pool == nullptr);
7877 id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool");
7878#endif
7879}
7880
7882{
7883#ifdef USE_PYRNA_INVALIDATE_WEAKREF
7884 /* This can help track down which kinds of data were not released.
7885 * If they were in fact freed by Blender, printing their names
7886 * will crash giving a useful error with address sanitizer. The likely cause
7887 * for this list not being empty is a missing call to: #BKE_libblock_free_data_py. */
7888 const int id_weakref_pool_len = BLI_ghash_len(id_weakref_pool);
7889 if (id_weakref_pool_len != 0) {
7890 printf("Found %d unreleased ID's\n", id_weakref_pool_len);
7891 GHashIterator gh_iter;
7892 GHASH_ITER (gh_iter, id_weakref_pool) {
7893 ID *id = static_cast<ID *>(BLI_ghashIterator_getKey(&gh_iter));
7894 printf("ID: %s\n", id->name);
7895 }
7896 }
7897 BLI_ghash_free(id_weakref_pool, nullptr, id_weakref_pool_free_value_fn);
7898 id_weakref_pool = nullptr;
7899#endif
7900}
7901
7902/* 'bpy.data' from Python. */
7903static PointerRNA *rna_module_ptr = nullptr;
7905{
7906 BPy_StructRNA *pyrna;
7907
7908 /* For now, return the base RNA type rather than a real module. */
7911
7912 rna_module_ptr = &pyrna->ptr;
7913 return (PyObject *)pyrna;
7914}
7915
7917{
7918 if (rna_module_ptr) {
7919#if 0
7921#else
7922 rna_module_ptr->data = G_MAIN; /* Just set data is enough. */
7923#endif
7924 }
7925}
7926
7927#if 0
7928/* This is a way we can access doc-strings for RNA types
7929 * without having the data-types in Blender. */
7930PyObject *BPY_rna_doc()
7931{
7932
7933 /* For now, return the base RNA type rather than a real module. */
7935
7937}
7938#endif
7939
7940/* -------------------------------------------------------------------- */
7956
7957static PyObject *bpy_types_module_getattro(PyObject *self, PyObject *pyname)
7958{
7959 BPy_TypesModule_State *state = static_cast<BPy_TypesModule_State *>(PyModule_GetState(self));
7960 PointerRNA newptr;
7961 PyObject *ret;
7962 const char *name = PyUnicode_AsUTF8(pyname);
7963
7964 if (name == nullptr) {
7965 PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string");
7966 ret = nullptr;
7967 }
7968 else if (RNA_property_collection_lookup_string(&state->ptr, state->prop, name, &newptr)) {
7969 ret = pyrna_struct_Subtype(&newptr);
7970 if (ret == nullptr) {
7971 PyErr_Format(PyExc_RuntimeError,
7972 "bpy.types.%.200s subtype could not be generated, this is a bug!",
7973 PyUnicode_AsUTF8(pyname));
7974 }
7975 }
7976 else {
7977#if 0
7978 PyErr_Format(PyExc_AttributeError,
7979 "bpy.types.%.200s RNA_Struct does not exist",
7980 PyUnicode_AsUTF8(pyname));
7981 return nullptr;
7982#endif
7983 /* The error raised here will be displayed. */
7984 ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
7985 }
7986
7987 return ret;
7988}
7989
7990static PyObject *bpy_types_module_dir(PyObject *self)
7991{
7992 BPy_TypesModule_State *state = static_cast<BPy_TypesModule_State *>(PyModule_GetState(self));
7993 PyObject *ret = PyList_New(0);
7994
7995 RNA_PROP_BEGIN (&state->ptr, itemptr, state->prop) {
7996 StructRNA *srna = static_cast<StructRNA *>(itemptr.data);
7997 PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna)));
7998 }
8000
8001 /* Include the modules `__dict__` for Python only types. */
8002 PyObject *submodule_dict = PyModule_GetDict(self);
8003 PyObject *key, *value;
8004 Py_ssize_t pos = 0;
8005 while (PyDict_Next(submodule_dict, &pos, &key, &value)) {
8006 PyList_Append(ret, key);
8007 }
8008 return ret;
8009}
8010
8011#if (defined(__GNUC__) && !defined(__clang__))
8012# pragma GCC diagnostic push
8013# pragma GCC diagnostic ignored "-Wcast-function-type"
8014#endif
8015
8016static PyMethodDef bpy_types_module_methods[] = {
8017 {"__getattr__", (PyCFunction)bpy_types_module_getattro, METH_O, nullptr},
8018 {"__dir__", (PyCFunction)bpy_types_module_dir, METH_NOARGS, nullptr},
8019 {nullptr, nullptr, 0, nullptr},
8020};
8021
8022#if (defined(__GNUC__) && !defined(__clang__))
8023# pragma GCC diagnostic pop
8024#endif
8025
8027 /* Wrap. */
8028 bpy_types_module_doc,
8029 "Access to internal Blender types");
8030static PyModuleDef bpy_types_module_def = {
8031 /*m_base*/ PyModuleDef_HEAD_INIT,
8032 /*m_name*/ "bpy.types",
8033 /*m_doc*/ bpy_types_module_doc,
8034 /*m_size*/ sizeof(BPy_TypesModule_State),
8035 /*m_methods*/ bpy_types_module_methods,
8036 /*m_slots*/ nullptr,
8037 /*m_traverse*/ nullptr,
8038 /*m_clear*/ nullptr,
8039 /*m_free*/ nullptr,
8040};
8041
8042PyObject *BPY_rna_types()
8043{
8044 PyObject *submodule = PyModule_Create(&bpy_types_module_def);
8046 PyModule_GetState(submodule));
8047
8049 state->prop = RNA_struct_find_property(&state->ptr, "structs");
8050
8051 /* Internal base types we have no other accessors for. */
8052 {
8053 static PyTypeObject *pyrna_types[] = {
8060 };
8061
8062 PyObject *submodule_dict = PyModule_GetDict(submodule);
8063 for (int i = 0; i < ARRAY_SIZE(pyrna_types); i += 1) {
8064 PyDict_SetItemString(submodule_dict, pyrna_types[i]->tp_name, (PyObject *)pyrna_types[i]);
8065 }
8066 }
8067
8068 return submodule;
8069}
8070
8072{
8073 /* NOTE: Blender is generally functional without running this logic
8074 * however failure set the classes `bl_rna` (via `pyrna_subtype_set_rna`)
8075 * means *partially* initialized classes exist.
8076 * It's simpler to avoid this altogether as it's a corner case Python developers should
8077 * not have to concern themselves with as it could cause errors with RNA introspection.
8078 *
8079 * If the classes are accessed via `bpy.types` they will be initialized correctly
8080 * however classes can also be accessed via `bpy.types.ID.__subclasses__()`
8081 * which doesn't ensure the `bl_rna` is set. See: #127127. */
8082
8084 PyModule_GetState(submodule));
8085
8086 PyObject *arg_key, *arg_value;
8087 Py_ssize_t arg_pos = 0;
8088 while (PyDict_Next(bpy_types_dict, &arg_pos, &arg_key, &arg_value)) {
8089 const char *key_str = PyUnicode_AsUTF8(arg_key);
8090 if (key_str[0] == '_') {
8091 continue;
8092 }
8093
8095 PyObject_IsSubclass(arg_value, (PyObject *)&pyrna_struct_Type),
8096 "Members of bpy_types.py which are not StructRNA sub-classes must use a \"_\" prefix!");
8097
8098 PointerRNA newptr;
8099 if (RNA_property_collection_lookup_string(&state->ptr, state->prop, key_str, &newptr)) {
8100 StructRNA *srna = srna_from_ptr(&newptr);
8101 /* Within the Python logic of `./scripts/modules/bpy_types.py`
8102 * it's possible this was already initialized. */
8103 if (RNA_struct_py_type_get(srna) == nullptr) {
8104 pyrna_subtype_set_rna(arg_value, srna);
8105 }
8106 }
8107#ifndef NDEBUG
8108 else {
8109 /* Avoid noisy warnings based on build-options. */
8110# ifndef WITH_USD
8111 if (STREQ(key_str, "USDHook")) {
8112 continue;
8113 }
8114# endif
8115 CLOG_WARN(
8116 BPY_LOG_RNA, "bpy_types.py defines \"%.200s\" which is not a known RNA type!", key_str);
8117 }
8118#endif
8119 }
8120}
8121
8124StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
8125{
8126 BPy_StructRNA *py_srna = nullptr;
8127 StructRNA *srna;
8128
8129 /* Unfortunately PyObject_GetAttrString won't look up this types tp_dict first :/ */
8130 if (PyType_Check(self)) {
8131 py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict,
8133 Py_XINCREF(py_srna);
8134 }
8135
8136 if (parent) {
8137 /* be very careful with this since it will return a parent classes srna.
8138 * modifying this will do confusing stuff! */
8139 if (py_srna == nullptr) {
8140 py_srna = (BPy_StructRNA *)PyObject_GetAttr(self, bpy_intern_str_bl_rna);
8141 }
8142 }
8143
8144 if (py_srna == nullptr) {
8145 PyErr_Format(PyExc_RuntimeError,
8146 "%.200s, missing bl_rna attribute from '%.200s' instance (may not be registered)",
8147 error_prefix,
8148 Py_TYPE(self)->tp_name);
8149 return nullptr;
8150 }
8151
8152 if (!BPy_StructRNA_Check(py_srna)) {
8153 PyErr_Format(PyExc_TypeError,
8154 "%.200s, bl_rna attribute wrong type '%.200s' on '%.200s'' instance",
8155 error_prefix,
8156 Py_TYPE(py_srna)->tp_name,
8157 Py_TYPE(self)->tp_name);
8158 Py_DECREF(py_srna);
8159 return nullptr;
8160 }
8161
8162 if (py_srna->ptr.type != &RNA_Struct) {
8163 PyErr_Format(PyExc_TypeError,
8164 "%.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance",
8165 error_prefix,
8166 Py_TYPE(self)->tp_name);
8167 Py_DECREF(py_srna);
8168 return nullptr;
8169 }
8170
8171 srna = static_cast<StructRNA *>(py_srna->ptr.data);
8172 Py_DECREF(py_srna);
8173
8174 return srna;
8175}
8176
8177const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna)
8178{
8179 BPy_StructRNA *bpy_srna = (BPy_StructRNA *)py_obj;
8180 if (!BPy_StructRNA_Check(py_obj) || !RNA_struct_is_a(bpy_srna->ptr.type, srna)) {
8181 PyErr_Format(PyExc_TypeError,
8182 "Expected a \"bpy.types.%.200s\" not a \"%.200s\"",
8184 Py_TYPE(py_obj)->tp_name);
8185 return nullptr;
8186 }
8187 PYRNA_STRUCT_CHECK_OBJ(bpy_srna);
8188 return &bpy_srna->ptr;
8189}
8190
8191const PointerRNA *pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna)
8192{
8193 if (py_obj == Py_None) {
8194 return &PointerRNA_NULL;
8195 }
8196 return pyrna_struct_as_ptr(py_obj, srna);
8197}
8198
8199int pyrna_struct_as_ptr_parse(PyObject *o, void *p)
8200{
8201 BPy_StructRNA_Parse *srna_parse = static_cast<BPy_StructRNA_Parse *>(p);
8202 BLI_assert(srna_parse->type != nullptr);
8203 srna_parse->ptr = pyrna_struct_as_ptr(o, srna_parse->type);
8204 if (srna_parse->ptr == nullptr) {
8205 return 0;
8206 }
8207 return 1;
8208}
8209
8210int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p)
8211{
8212 BPy_StructRNA_Parse *srna_parse = static_cast<BPy_StructRNA_Parse *>(p);
8213 BLI_assert(srna_parse->type != nullptr);
8214 srna_parse->ptr = pyrna_struct_as_ptr_or_null(o, srna_parse->type);
8215 if (srna_parse->ptr == nullptr) {
8216 return 0;
8217 }
8218 return 1;
8219}
8220
8221/* Orphan functions, not sure where they should go. */
8222
8223StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
8224{
8225 if (self == nullptr) {
8226 return nullptr;
8227 }
8228 if (PyCapsule_CheckExact(self)) {
8229 return static_cast<StructRNA *>(PyCapsule_GetPointer(self, nullptr));
8230 }
8231 if (PyType_Check(self) == 0) {
8232 return nullptr;
8233 }
8234
8235 /* These cases above not errors, they just mean the type was not compatible
8236 * After this any errors will be raised in the script. */
8237 return pyrna_struct_as_srna(self, false, error_prefix);
8238}
8239
8240static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item)
8241{
8243 /* No error, ignoring. */
8244 return 0;
8245 }
8246
8247 /* We only care about results from C which
8248 * are for sure types, save some time with error */
8249 PyObject *py_func = static_cast<PyObject *>(((BPy_PropDeferred *)item)->fn);
8250 PyObject *py_kw = ((BPy_PropDeferred *)item)->kw;
8251 PyObject *py_srna_cobject, *py_ret;
8252
8253 /* Show the function name in errors to help give context. */
8254 BLI_assert(PyCFunction_CheckExact(py_func));
8255 PyMethodDef *py_func_method_def = ((PyCFunctionObject *)py_func)->m_ml;
8256 const char *func_name = py_func_method_def->ml_name;
8257
8258 PyObject *args_fake;
8259 const char *key_str = PyUnicode_AsUTF8(key);
8260
8261 if (*key_str == '_') {
8262 PyErr_Format(PyExc_ValueError,
8263 "bpy_struct \"%.200s\" registration error: "
8264 "'%.200s' %.200s could not register because it starts with an '_'",
8266 key_str,
8267 func_name);
8268 return -1;
8269 }
8270 py_srna_cobject = PyCapsule_New(srna, nullptr, nullptr);
8271
8272 /* Not 100% nice :/, modifies the dict passed, should be ok. */
8273 PyDict_SetItem(py_kw, bpy_intern_str_attr, key);
8274
8275 args_fake = PyTuple_New(1);
8276 PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
8277
8278 PyObject *type = PyDict_GetItemString(py_kw, "type");
8279 StructRNA *type_srna = srna_from_self(type, "");
8280 if (type_srna) {
8282 PyCFunctionWithKeywords py_func_ref = *(
8283 PyCFunctionWithKeywords)(void *)PyCFunction_GET_FUNCTION(py_func);
8284 if (ELEM(py_func_ref, BPy_PointerProperty, BPy_CollectionProperty)) {
8286
8287 PyErr_Format(PyExc_ValueError,
8288 "bpy_struct \"%.200s\" registration error: "
8289 "'%.200s' %.200s could not register because "
8290 "this type doesn't support data-block properties",
8292 key_str,
8293 func_name);
8294 return -1;
8295 }
8296 }
8297 }
8298 }
8299
8300 py_ret = PyObject_Call(py_func, args_fake, py_kw);
8301
8302 if (py_ret) {
8303 Py_DECREF(py_ret);
8304 Py_DECREF(args_fake); /* Free's py_srna_cobject too. */
8305 }
8306 else {
8307 /* _must_ print before decrefing args_fake. */
8308 PyErr_Print();
8309 PyErr_Clear();
8310
8311 Py_DECREF(args_fake); /* Free's py_srna_cobject too. */
8312
8313 PyErr_Format(PyExc_ValueError,
8314 "bpy_struct \"%.200s\" registration error: "
8315 "'%.200s' %.200s could not register (see previous error)",
8317 key_str,
8318 func_name);
8319 return -1;
8320 }
8321
8322 return 0;
8323}
8324
8328static int pyrna_deferred_register_class_from_type_hints(StructRNA *srna, PyTypeObject *py_class)
8329{
8330 PyObject *annotations_dict = nullptr;
8331
8332 /* `typing.get_type_hints(py_class)` */
8333 {
8334 PyObject *typing_mod = PyImport_ImportModuleLevel("typing", nullptr, nullptr, nullptr, 0);
8335 if (typing_mod != nullptr) {
8336 PyObject *get_type_hints_fn = PyObject_GetAttrString(typing_mod, "get_type_hints");
8337 if (get_type_hints_fn != nullptr) {
8338 PyObject *args = PyTuple_New(1);
8339
8340 PyTuple_SET_ITEM(args, 0, (PyObject *)py_class);
8341 Py_INCREF(py_class);
8342
8343 annotations_dict = PyObject_CallObject(get_type_hints_fn, args);
8344
8345 Py_DECREF(args);
8346 Py_DECREF(get_type_hints_fn);
8347 }
8348 Py_DECREF(typing_mod);
8349 }
8350 }
8351
8352 int ret = 0;
8353 if (annotations_dict != nullptr) {
8354 if (PyDict_CheckExact(annotations_dict)) {
8355 PyObject *item, *key;
8356 Py_ssize_t pos = 0;
8357
8358 while (PyDict_Next(annotations_dict, &pos, &key, &item)) {
8359 ret = deferred_register_prop(srna, key, item);
8360 if (ret != 0) {
8361 break;
8362 }
8363 }
8364 }
8365 else {
8366 /* Should never happen, an error won't have been raised, so raise one. */
8367 PyErr_Format(PyExc_TypeError,
8368 "typing.get_type_hints returned: %.200s, expected dict\n",
8369 Py_TYPE(annotations_dict)->tp_name);
8370 ret = -1;
8371 }
8372
8373 Py_DECREF(annotations_dict);
8374 }
8375 else {
8376 BLI_assert(PyErr_Occurred());
8377 fprintf(stderr, "typing.get_type_hints failed with: %.200s\n", py_class->tp_name);
8378 ret = -1;
8379 }
8380
8381 return ret;
8382}
8383
8384static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
8385{
8386 PyObject *annotations_dict;
8387 PyObject *item, *key;
8388 Py_ssize_t pos = 0;
8389 int ret = 0;
8390
8391 /* in both cases PyDict_CheckExact(class_dict) will be true even
8392 * though Operators have a metaclass dict namespace */
8393 if ((annotations_dict = PyDict_GetItem(class_dict, bpy_intern_str___annotations__)) &&
8394 PyDict_CheckExact(annotations_dict))
8395 {
8396 while (PyDict_Next(annotations_dict, &pos, &key, &item)) {
8397 ret = deferred_register_prop(srna, key, item);
8398
8399 if (ret != 0) {
8400 break;
8401 }
8402 }
8403 }
8404
8405 return ret;
8406}
8407
8408static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject *py_class)
8409{
8410 const int len = PyTuple_GET_SIZE(py_class->tp_bases);
8411 int i, ret;
8412
8413 /* First scan base classes for registerable properties. */
8414 for (i = 0; i < len; i++) {
8415 PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i);
8416
8417 /* the rules for using these base classes are not clear,
8418 * 'object' is of course not worth looking into and
8419 * existing subclasses of RNA would cause a lot more dictionary
8420 * looping then is needed (SomeOperator would scan Operator.__dict__)
8421 * which is harmless, but not at all useful.
8422 *
8423 * So only scan base classes which are not subclasses if blender types.
8424 * This best fits having 'mix-in' classes for operators and render engines.
8425 */
8426 if (py_superclass != &PyBaseObject_Type &&
8427 !PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type))
8428 {
8429 ret = pyrna_deferred_register_class_recursive(srna, py_superclass);
8430
8431 if (ret != 0) {
8432 return ret;
8433 }
8434 }
8435 }
8436
8437 /* Not register out own properties. */
8438 /* getattr(..., "__dict__") returns a proxy. */
8439 return pyrna_deferred_register_props(srna, py_class->tp_dict);
8440}
8441
8442int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class)
8443{
8444 /* Panels and Menus don't need this
8445 * save some time and skip the checks here */
8447 return 0;
8448 }
8449
8450#ifdef USE_POSTPONED_ANNOTATIONS
8451 const bool use_postponed_annotations = true;
8452#else
8453 const bool use_postponed_annotations = false;
8454#endif
8455
8456 if (use_postponed_annotations) {
8457 return pyrna_deferred_register_class_from_type_hints(srna, py_class);
8458 }
8459 return pyrna_deferred_register_class_recursive(srna, py_class);
8460}
8461
8462/*-------------------- Type Registration ------------------------*/
8463
8464static int rna_function_arg_count(FunctionRNA *func, int *min_count)
8465{
8466 const ListBase *lb = RNA_function_defined_parameters(func);
8467 PropertyRNA *parm;
8468 const int flag = RNA_function_flag(func);
8469 const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
8470 int count = is_staticmethod ? 0 : 1;
8471 bool done_min_count = false;
8472
8473 LISTBASE_FOREACH (Link *, link, lb) {
8474 parm = (PropertyRNA *)link;
8475 if (!(RNA_parameter_flag(parm) & PARM_OUTPUT)) {
8476 if (!done_min_count && (RNA_parameter_flag(parm) & PARM_PYFUNC_OPTIONAL)) {
8477 /* From now on, the following parameters are optional in a Python function. */
8478 if (min_count) {
8479 *min_count = count;
8480 }
8481 done_min_count = true;
8482 }
8483 count++;
8484 }
8485 }
8486
8487 if (!done_min_count && min_count) {
8488 *min_count = count;
8489 }
8490 return count;
8491}
8492
8494 StructRNA *srna,
8495 void *py_data,
8496 bool *have_function)
8497{
8498 const ListBase *lb;
8499 const char *class_type = RNA_struct_identifier(srna);
8500 StructRNA *srna_base = RNA_struct_base(srna);
8501 PyObject *py_class = (PyObject *)py_data;
8502 PyObject *base_class = static_cast<PyObject *>(RNA_struct_py_type_get(srna));
8503 PyObject *item;
8504 int i, arg_count, func_arg_count, func_arg_min_count = 0;
8505 const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */
8506
8507 if (srna_base) {
8508 if (bpy_class_validate_recursive(dummy_ptr, srna_base, py_data, have_function) != 0) {
8509 return -1;
8510 }
8511 }
8512
8513 if (base_class) {
8514 if (!PyObject_IsSubclass(py_class, base_class)) {
8515 PyErr_Format(PyExc_TypeError,
8516 "expected %.200s subclass of class \"%.200s\"",
8517 class_type,
8518 py_class_name);
8519 return -1;
8520 }
8521 }
8522
8523 /* Verify callback functions. */
8524 lb = RNA_struct_type_functions(srna);
8525 i = 0;
8526 LISTBASE_FOREACH (Link *, link, lb) {
8527 FunctionRNA *func = (FunctionRNA *)link;
8528 const int flag = RNA_function_flag(func);
8529 if (!(flag & FUNC_REGISTER)) {
8530 continue;
8531 }
8532
8533 item = PyObject_GetAttrString(py_class, RNA_function_identifier(func));
8534 have_function[i] = (item != nullptr);
8535 i++;
8536
8537 if (item == nullptr) {
8538 if ((flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER)) == 0) {
8539 PyErr_Format(PyExc_AttributeError,
8540 "expected %.200s, %.200s class to have an \"%.200s\" attribute",
8541 class_type,
8542 py_class_name,
8544 return -1;
8545 }
8546 PyErr_Clear();
8547
8548 continue;
8549 }
8550
8551 /* TODO(@ideasman42): this is used for classmethod's too,
8552 * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg.
8553 * Keep this as-is since it's working, but we should be using
8554 * 'FUNC_USE_SELF_TYPE' for many functions. */
8555 const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
8556
8557 /* Store original so we can decrement its reference before returning. */
8558 PyObject *item_orig = item;
8559
8560 if (is_staticmethod) {
8561 if (PyMethod_Check(item) == 0) {
8562 PyErr_Format(PyExc_TypeError,
8563 "expected %.200s, %.200s class \"%.200s\" "
8564 "attribute to be a static/class method, not a %.200s",
8565 class_type,
8566 py_class_name,
8568 Py_TYPE(item)->tp_name);
8569 Py_DECREF(item_orig);
8570 return -1;
8571 }
8572 item = ((PyMethodObject *)item)->im_func;
8573 }
8574 else {
8575 if (PyFunction_Check(item) == 0) {
8576 PyErr_Format(PyExc_TypeError,
8577 "expected %.200s, %.200s class \"%.200s\" "
8578 "attribute to be a function, not a %.200s",
8579 class_type,
8580 py_class_name,
8582 Py_TYPE(item)->tp_name);
8583 Py_DECREF(item_orig);
8584 return -1;
8585 }
8586 }
8587
8588 func_arg_count = rna_function_arg_count(func, &func_arg_min_count);
8589
8590 if (func_arg_count >= 0) { /* -1 if we don't care. */
8591 arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
8592
8593 /* NOTE: the number of args we check for and the number of args we give to
8594 * '@staticmethods' are different (quirk of Python),
8595 * this is why rna_function_arg_count() doesn't return the value -1. */
8596 if (is_staticmethod) {
8597 func_arg_count++;
8598 func_arg_min_count++;
8599 }
8600
8601 if (arg_count < func_arg_min_count || arg_count > func_arg_count) {
8602 if (func_arg_min_count != func_arg_count) {
8603 PyErr_Format(
8604 PyExc_ValueError,
8605 "expected %.200s, %.200s class \"%.200s\" function to have between %d and %d "
8606 "args, found %d",
8607 class_type,
8608 py_class_name,
8610 func_arg_count,
8611 func_arg_min_count,
8612 arg_count);
8613 }
8614 else {
8615 PyErr_Format(
8616 PyExc_ValueError,
8617 "expected %.200s, %.200s class \"%.200s\" function to have %d args, found %d",
8618 class_type,
8619 py_class_name,
8621 func_arg_count,
8622 arg_count);
8623 }
8624 Py_DECREF(item_orig);
8625 return -1;
8626 }
8627 }
8628 Py_DECREF(item_orig);
8629 }
8630
8631 /* Verify properties. */
8632 lb = RNA_struct_type_properties(srna);
8633 LISTBASE_FOREACH (Link *, link, lb) {
8634 const char *identifier;
8635 PropertyRNA *prop = (PropertyRNA *)link;
8636 const int flag = RNA_property_flag(prop);
8637
8638 if (!(flag & PROP_REGISTER)) {
8639 continue;
8640 }
8641
8642 /* TODO(@ideasman42): Use Python3.7x _PyObject_LookupAttr(), also in the macro below. */
8643 identifier = RNA_property_identifier(prop);
8644 item = PyObject_GetAttrString(py_class, identifier);
8645
8646 if (item == nullptr) {
8647 PyErr_Clear();
8648 /* Sneaky workaround to use the class name as the bl_idname. */
8649
8650#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
8651 else if (STREQ(identifier, rna_attr)) { \
8652 if ((item = PyObject_GetAttr(py_class, py_attr))) { \
8653 if (item != Py_None) { \
8654 if (pyrna_py_to_prop(dummy_ptr, prop, nullptr, item, "validating class:") != 0) { \
8655 Py_DECREF(item); \
8656 return -1; \
8657 } \
8658 } \
8659 Py_DECREF(item); \
8660 } \
8661 else { \
8662 PyErr_Clear(); \
8663 } \
8664 } /* Intentionally allow else here. */
8665
8666 if (false) {
8667 } /* Needed for macro. */
8670
8671#undef BPY_REPLACEMENT_STRING
8672
8673 if (item == nullptr && ((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL)) {
8674 PyErr_Format(PyExc_AttributeError,
8675 "expected %.200s, %.200s class to have an \"%.200s\" attribute",
8676 class_type,
8677 py_class_name,
8678 identifier);
8679 return -1;
8680 }
8681
8682 PyErr_Clear();
8683 }
8684 else {
8685 if (pyrna_py_to_prop(dummy_ptr, prop, nullptr, item, "validating class:") != 0) {
8686 Py_DECREF(item);
8687 return -1;
8688 }
8689 Py_DECREF(item);
8690 }
8691 }
8692
8693 return 0;
8694}
8695
8696static int bpy_class_validate(PointerRNA *dummy_ptr, void *py_data, bool *have_function)
8697{
8698 return bpy_class_validate_recursive(dummy_ptr, dummy_ptr->type, py_data, have_function);
8699}
8700
8701/* TODO: multiple return values like with RNA functions. */
8703{
8704 PyObject *args;
8705 PyObject *ret = nullptr, *py_srna = nullptr, *py_class_instance = nullptr, *parmitem;
8706 PyTypeObject *py_class;
8707 PropertyRNA *parm;
8708 ParameterIterator iter;
8709 PointerRNA funcptr;
8710 int err = 0, i, ret_len = 0, arg_count;
8711 const int flag = RNA_function_flag(func);
8712 const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
8713 const bool is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE);
8714
8715 PropertyRNA *pret_single = nullptr;
8716 void *retdata_single = nullptr;
8717
8718 PyGILState_STATE gilstate;
8719
8720#ifdef USE_PEDANTIC_WRITE
8721 const bool is_readonly_init = !(RNA_struct_is_a(ptr->type, &RNA_Operator) ||
8722 RNA_struct_is_a(ptr->type, &RNA_Gizmo));
8723 // const char *func_id = RNA_function_identifier(func); /* UNUSED */
8724 /* Testing, for correctness, not operator and not draw function. */
8725 const bool is_readonly = !(RNA_function_flag(func) & FUNC_ALLOW_WRITE);
8726#endif
8727
8728 py_class = static_cast<PyTypeObject *>(RNA_struct_py_type_get(ptr->type));
8729 /* Rare case. can happen when registering subclasses. */
8730 if (py_class == nullptr) {
8732 "unable to get Python class for RNA struct '%.200s'",
8734 return -1;
8735 }
8736
8737 /* XXX, this is needed because render engine calls without a context
8738 * this should be supported at some point, but at the moment it's not! */
8739 if (C == nullptr) {
8740 C = BPY_context_get();
8741 }
8742
8743 /* Annoying! We need to check if the screen gets set to nullptr which is a
8744 * hint that the file was actually re-loaded. */
8745 const bool is_valid_wm = (CTX_wm_manager(C) != nullptr);
8746
8747 bpy_context_set(C, &gilstate);
8748
8749 if (!(is_staticmethod || is_classmethod)) {
8750 /* Some data-types (operator, render engine) can store PyObjects for re-use. */
8751 if (ptr->data) {
8752 void **instance = RNA_struct_instance(ptr);
8753
8754 if (instance) {
8755 if (*instance) {
8756 py_class_instance = static_cast<PyObject *>(*instance);
8757 Py_INCREF(py_class_instance);
8758 }
8759 }
8760 }
8761 /* End exception. */
8762
8763 if (py_class_instance == nullptr) {
8765 }
8766
8767 if (py_class_instance) {
8768 /* Special case, instance is cached. */
8769 }
8770 else if (py_srna == nullptr) {
8771 py_class_instance = nullptr;
8772 }
8773 else if (py_srna == Py_None) { /* Probably won't ever happen, but possible. */
8774 Py_DECREF(py_srna);
8775 py_class_instance = nullptr;
8776 }
8777 else {
8778#if 1
8779 /* Skip the code below and call init directly on the allocated 'py_srna'
8780 * otherwise __init__() always needs to take a second self argument, see pyrna_struct_new().
8781 * Although this is annoying to have to implement a part of Python's
8782 * typeobject.c:type_call().
8783 */
8784 if (py_class->tp_init) {
8785# ifdef USE_PEDANTIC_WRITE
8786 const int prev_write = rna_disallow_writes;
8787 rna_disallow_writes = is_readonly_init ? false :
8788 true; /* Only operators can write on __init__. */
8789# endif
8790
8791 /* True in most cases even when the class itself doesn't define an __init__ function. */
8792 args = PyTuple_New(0);
8793 if (py_class->tp_init(py_srna, args, nullptr) < 0) {
8794 Py_DECREF(py_srna);
8795 py_srna = nullptr;
8796 /* Err set below. */
8797 }
8798 Py_DECREF(args);
8799# ifdef USE_PEDANTIC_WRITE
8800 rna_disallow_writes = prev_write;
8801# endif
8802 }
8803 py_class_instance = py_srna;
8804
8805#else
8806 const int prev_write = rna_disallow_writes;
8807 rna_disallow_writes = true;
8808
8809/* 'almost' all the time calling the class isn't needed.
8810 * We could just do... */
8811# if 0
8812 py_class_instance = py_srna;
8813 Py_INCREF(py_class_instance);
8814# endif
8815 /*
8816 * This would work fine, but means __init__ functions wouldn't run.
8817 * None of Blender's default scripts use __init__ but it's nice to call it
8818 * for general correctness. just to note why this is here when it could be safely removed.
8819 */
8820 args = PyTuple_New(1);
8821 PyTuple_SET_ITEM(args, 0, py_srna);
8822 py_class_instance = PyObject_Call(py_class, args, nullptr);
8823 Py_DECREF(args);
8824
8825 rna_disallow_writes = prev_write;
8826
8827#endif
8828
8829 if (py_class_instance == nullptr) {
8830 err = -1; /* So the error is not overridden below. */
8831 }
8832 }
8833 }
8834
8835 /* Initializing the class worked, now run its invoke function. */
8836 if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) {
8837 PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func));
8838
8839 const bool item_type_valid = (item != nullptr) &&
8840 (is_staticmethod ? PyMethod_Check(item) : PyFunction_Check(item));
8841 if (item_type_valid) {
8842 funcptr = RNA_pointer_create(nullptr, &RNA_Function, func);
8843
8844 if (is_staticmethod) {
8845 arg_count =
8846 ((PyCodeObject *)PyFunction_GET_CODE(((PyMethodObject *)item)->im_func))->co_argcount -
8847 1;
8848 }
8849 else {
8850 arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
8851 }
8852#if 0
8853 /* First arg is included in 'item'. */
8854 args = PyTuple_New(rna_function_arg_count(func));
8855#endif
8856 args = PyTuple_New(arg_count); /* First arg is included in 'item'. */
8857
8858 if (is_staticmethod) {
8859 i = 0;
8860 }
8861 else if (is_classmethod) {
8862 PyTuple_SET_ITEM(args, 0, (PyObject *)py_class);
8863 i = 1;
8864 }
8865 else {
8866 PyTuple_SET_ITEM(args, 0, py_class_instance);
8867 i = 1;
8868 }
8869
8870 RNA_parameter_list_begin(parms, &iter);
8871
8872 /* Parse function parameters. */
8873 for (; iter.valid; RNA_parameter_list_next(&iter)) {
8874 parm = iter.parm;
8875
8876 /* Only useful for single argument returns, we'll need another list loop for multiple. */
8877 if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
8878 ret_len++;
8879 if (pret_single == nullptr) {
8880 pret_single = parm;
8881 retdata_single = iter.data;
8882 }
8883
8884 continue;
8885 }
8886
8887 if (i < arg_count) {
8888 parmitem = pyrna_param_to_py(&funcptr, parm, iter.data);
8889 PyTuple_SET_ITEM(args, i, parmitem);
8890 i++;
8891 }
8892 }
8893
8894#ifdef USE_PEDANTIC_WRITE
8895 /* Handle nested draw calls, see: #89253. */
8896 const bool rna_disallow_writes_prev = rna_disallow_writes;
8897 rna_disallow_writes = is_readonly ? true : false;
8898#endif
8899 /* *** Main Caller *** */
8900
8901 ret = PyObject_Call(item, args, nullptr);
8902
8903 /* *** Done Calling *** */
8904
8905#ifdef USE_PEDANTIC_WRITE
8906 rna_disallow_writes = rna_disallow_writes_prev;
8907#endif
8908
8910 Py_DECREF(item);
8911 Py_DECREF(args);
8912 }
8913 else {
8914 PyErr_Print();
8915 PyErr_Clear();
8916 PyErr_Format(PyExc_TypeError,
8917 "could not find function %.200s in %.200s to execute callback",
8920 err = -1;
8921 }
8922 }
8923 else {
8924 /* The error may be already set if the class instance couldn't be created. */
8925 if (err != -1) {
8926 PyErr_Format(PyExc_RuntimeError,
8927 "could not create instance of %.200s to call callback function %.200s",
8930 err = -1;
8931 }
8932 }
8933
8934 if (ret == nullptr) { /* Covers py_class_instance failing too. */
8935 err = -1;
8936 }
8937 else {
8938 if (ret_len == 0 && ret != Py_None) {
8939 PyErr_Format(PyExc_RuntimeError,
8940 "expected class %.200s, function %.200s to return None, not %.200s",
8943 Py_TYPE(ret)->tp_name);
8944 err = -1;
8945 }
8946 else if (ret_len == 1) {
8947 err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, "");
8948
8949 /* When calling operator functions only gives `Function.result` with no line number
8950 * since the function has finished calling on error, re-raise the exception with more
8951 * information since it would be slow to create prefix on every call
8952 * (when there are no errors). */
8953 if (err == -1) {
8954 PyC_Err_Format_Prefix(PyExc_RuntimeError,
8955 "class %.200s, function %.200s: incompatible return value ",
8958 }
8959 }
8960 else if (ret_len > 1) {
8961
8962 if (PyTuple_Check(ret) == 0) {
8963 PyErr_Format(
8964 PyExc_RuntimeError,
8965 "expected class %.200s, function %.200s to return a tuple of size %d, not %.200s",
8968 ret_len,
8969 Py_TYPE(ret)->tp_name);
8970 err = -1;
8971 }
8972 else if (PyTuple_GET_SIZE(ret) != ret_len) {
8973 PyErr_Format(PyExc_RuntimeError,
8974 "class %.200s, function %.200s to returned %d items, expected %d",
8977 PyTuple_GET_SIZE(ret),
8978 ret_len);
8979 err = -1;
8980 }
8981 else {
8982
8983 RNA_parameter_list_begin(parms, &iter);
8984
8985 /* Parse function parameters. */
8986 for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) {
8987 parm = iter.parm;
8988
8989 /* Only useful for single argument returns, we'll need another list loop for multiple. */
8990 if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
8991 err = pyrna_py_to_prop(
8992 &funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:");
8993 if (err) {
8994 break;
8995 }
8996 }
8997 }
8998
9000 }
9001 }
9002 Py_DECREF(ret);
9003 }
9004
9005 if (err != 0) {
9006 ReportList *reports;
9007 /* Alert the user, else they won't know unless they see the console. */
9008 if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) &&
9009 RNA_struct_is_a(ptr->type, &RNA_Operator) &&
9010 (is_valid_wm == (CTX_wm_manager(C) != nullptr)))
9011 {
9012 wmOperator *op = static_cast<wmOperator *>(ptr->data);
9013 reports = op->reports;
9014 }
9015 else {
9016 /* Won't alert users, but they can view in 'info' space. */
9017 reports = CTX_wm_reports(C);
9018 }
9019
9020 if (reports) {
9021 BPy_errors_to_report(reports);
9022 }
9023
9024 /* Also print in the console for Python. */
9025 PyErr_Print();
9026 PyErr_Clear();
9027 }
9028
9029 bpy_context_clear(C, &gilstate);
9030
9031 return err;
9032}
9033
9034static void bpy_class_free(void *pyob_ptr)
9035{
9036 PyObject *self = (PyObject *)pyob_ptr;
9037 PyGILState_STATE gilstate;
9038
9039 gilstate = PyGILState_Ensure();
9040
9041 /* Breaks re-registering classes. */
9042 // PyDict_Clear(((PyTypeObject *)self)->tp_dict);
9043
9044 /* Remove the RNA attribute instead. */
9045
9046 /* NOTE: it's important to use `delattr` instead of `PyDict_DelItem`
9047 * to ensure the internal slots are updated (which is also used for assignment). */
9048 if (PyObject_DelAttr(self, bpy_intern_str_bl_rna) == -1) {
9049 PyErr_Clear();
9050 }
9051
9052#if 0 /* Needs further investigation, too annoying so quiet for now. */
9053 if (G.debug & G_DEBUG_PYTHON) {
9054 if (self->ob_refcnt > 1) {
9055 PyC_ObSpit("zombie class - reference should be 1", self);
9056 }
9057 }
9058#endif
9059 Py_DECREF((PyObject *)pyob_ptr);
9060
9061 PyGILState_Release(gilstate);
9062}
9063
9065{
9066 /* NOTE: This isn't essential to run on startup, since sub-types will lazy initialize.
9067 * But keep running in debug mode so we get immediate notification of bad class hierarchy
9068 * or any errors in "bpy_types.py" at load time, so errors don't go unnoticed. */
9069
9070#ifndef NDEBUG
9071 PyGILState_STATE gilstate;
9072
9073 PropertyRNA *prop;
9074
9075 gilstate = PyGILState_Ensure();
9076
9077 /* Avoid doing this lookup for every getattr. */
9079 prop = RNA_struct_find_property(&ptr, "structs");
9080
9081 RNA_PROP_BEGIN (&ptr, itemptr, prop) {
9082 PyObject *item = pyrna_struct_Subtype(&itemptr);
9083 if (item == nullptr) {
9084 if (PyErr_Occurred()) {
9085 PyErr_Print();
9086 PyErr_Clear();
9087 }
9088 }
9089 else {
9090 Py_DECREF(item);
9091 }
9092 }
9094
9095 PyGILState_Release(gilstate);
9096#endif /* !NDEBUG */
9097}
9098
9100{
9101 PropertyRNA *prop;
9102
9103 /* Avoid doing this lookup for every getattr. */
9105 prop = RNA_struct_find_property(&ptr, "structs");
9106
9107 RNA_PROP_BEGIN (&ptr, itemptr, prop) {
9108 StructRNA *srna = srna_from_ptr(&itemptr);
9109 void *py_ptr = RNA_struct_py_type_get(srna);
9110
9111 if (py_ptr) {
9112#if 0 /* XXX: should be able to do this, but makes Python crash on exit. */
9113 bpy_class_free(py_ptr);
9114#endif
9115 RNA_struct_py_type_set(srna, nullptr);
9116 }
9117 }
9119}
9120
9133 /* Wrap. */
9134 pyrna_register_class_doc,
9135 ".. function:: register_class(cls)\n"
9136 "\n"
9137 " Register a subclass of a Blender type class.\n"
9138 "\n"
9139 " :arg cls: Blender type class in:\n"
9140 " :class:`bpy.types.Panel`, :class:`bpy.types.UIList`,\n"
9141 " :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
9142 " :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
9143 " :class:`bpy.types.RenderEngine`, :class:`bpy.types.AssetShelf`,\n"
9144 " :class:`bpy.types.FileHandler`\n"
9145 " :type cls: type\n"
9146 " :raises ValueError:\n"
9147 " if the class is not a subclass of a registerable blender class.\n"
9148 "\n"
9149 " .. note::\n"
9150 "\n"
9151 " If the class has a *register* class method it will be called\n"
9152 " before registration.\n");
9154 "register_class", pyrna_register_class, METH_O, pyrna_register_class_doc};
9155static PyObject *pyrna_register_class(PyObject * /*self*/, PyObject *py_class)
9156{
9157 bContext *C = nullptr;
9158 ReportList reports;
9160 StructRNA *srna;
9161 StructRNA *srna_new;
9162 const char *identifier;
9163 PyObject *py_cls_meth;
9164 const char *error_prefix = "register_class(...):";
9165
9166 if (!PyType_Check(py_class)) {
9167 PyErr_Format(PyExc_ValueError,
9168 "register_class(...): "
9169 "expected a class argument, not '%.200s'",
9170 Py_TYPE(py_class)->tp_name);
9171 return nullptr;
9172 }
9173
9174 if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna)) {
9175 PyErr_Format(PyExc_ValueError,
9176 "register_class(...): "
9177 "already registered as a subclass '%.200s'",
9178 ((PyTypeObject *)py_class)->tp_name);
9179 return nullptr;
9180 }
9181
9182 if (!pyrna_write_check()) {
9183 PyErr_Format(PyExc_RuntimeError,
9184 "register_class(...): "
9185 "can't run in readonly state '%.200s'",
9186 ((PyTypeObject *)py_class)->tp_name);
9187 return nullptr;
9188 }
9189
9190 /* WARNING: gets parent classes srna, only for the register function. */
9191 srna = pyrna_struct_as_srna(py_class, true, "register_class(...):");
9192 if (srna == nullptr) {
9193 return nullptr;
9194 }
9195
9196/* Fails in some cases, so can't use this check, but would like to :| */
9197#if 0
9198 if (RNA_struct_py_type_get(srna)) {
9199 PyErr_Format(PyExc_ValueError,
9200 "register_class(...): %.200s's parent class %.200s is already registered, this "
9201 "is not allowed",
9202 ((PyTypeObject *)py_class)->tp_name,
9203 RNA_struct_identifier(srna));
9204 return nullptr;
9205 }
9206#endif
9207
9208 /* Check that we have a register callback for this type. */
9209 reg = RNA_struct_register(srna);
9210
9211 if (!reg) {
9212 PyErr_Format(PyExc_ValueError,
9213 "register_class(...): expected a subclass of a registerable "
9214 "RNA type (%.200s does not support registration)",
9215 RNA_struct_identifier(srna));
9216 return nullptr;
9217 }
9218
9219 /* Get the context, so register callback can do necessary refreshes. */
9220 C = BPY_context_get();
9221
9222 /* Call the register callback with reports & identifier. */
9223 BKE_reports_init(&reports, RPT_STORE);
9224
9225 identifier = ((PyTypeObject *)py_class)->tp_name;
9226
9227 srna_new = reg(CTX_data_main(C),
9228 &reports,
9229 py_class,
9230 identifier,
9234
9235 if (!BLI_listbase_is_empty(&reports.list)) {
9236 const bool has_error = (BPy_reports_to_error(&reports, PyExc_RuntimeError, false) == -1);
9237 if (!has_error) {
9239 BPy_reports_write_stdout(&reports, error_prefix);
9240 }
9241 if (has_error) {
9242 BKE_reports_free(&reports);
9243 return nullptr;
9244 }
9245 }
9246 BKE_reports_free(&reports);
9247
9248 /* Python errors validating are not converted into reports so the check above will fail.
9249 * the cause for returning nullptr will be printed as an error */
9250 if (srna_new == nullptr) {
9251 return nullptr;
9252 }
9253
9254 /* Takes a reference to 'py_class'. */
9255 pyrna_subtype_set_rna(py_class, srna_new);
9256
9257 /* Old srna still references us, keep the check in case registering somehow can free it. */
9258 if (RNA_struct_py_type_get(srna)) {
9259 RNA_struct_py_type_set(srna, nullptr);
9260#if 0
9261 /* Should be able to do this XXX since the old RNA adds a new ref. */
9262 Py_DECREF(py_class);
9263#endif
9264 }
9265
9266 /* Can't use this because it returns a dict proxy
9267 *
9268 * item = PyObject_GetAttrString(py_class, "__dict__");
9269 */
9270 if (pyrna_deferred_register_class(srna_new, (PyTypeObject *)py_class) != 0) {
9271 return nullptr;
9272 }
9273
9274 /* Call classed register method.
9275 * Note that zero falls through, no attribute, no error. */
9276 switch (_PyObject_LookupAttr(py_class, bpy_intern_str_register, &py_cls_meth)) {
9277 case 1: {
9278 PyObject *ret = PyObject_CallObject(py_cls_meth, nullptr);
9279 Py_DECREF(py_cls_meth);
9280 if (ret) {
9281 Py_DECREF(ret);
9282 }
9283 else {
9284 return nullptr;
9285 }
9286 break;
9287 }
9288 case -1: {
9289 return nullptr;
9290 }
9291 }
9292
9293 Py_RETURN_NONE;
9294}
9295
9297 StructRNA *srna,
9298 const char **r_prop_identifier)
9299{
9300 PropertyRNA *prop;
9301
9302 /* Verify properties. */
9303 const ListBase *lb = RNA_struct_type_properties(srna);
9304
9305 LISTBASE_FOREACH (LinkData *, link, lb) {
9306 prop = (PropertyRNA *)link;
9307 if (RNA_property_type(prop) == PROP_POINTER && !RNA_property_builtin(prop)) {
9308 PointerRNA tptr = RNA_pointer_create(nullptr, &RNA_Struct, srna_props);
9309
9310 if (RNA_property_pointer_type(&tptr, prop) == srna) {
9311 *r_prop_identifier = RNA_property_identifier(prop);
9312 return 1;
9313 }
9314 }
9315 }
9316
9317 return 0;
9318}
9319
9321 /* Wrap. */
9322 pyrna_unregister_class_doc,
9323 ".. function:: unregister_class(cls)\n"
9324 "\n"
9325 " Unload the Python class from blender.\n"
9326 "\n"
9327 " :arg cls: Blender type class, \n"
9328 " see :mod:`bpy.utils.register_class` for classes which can \n"
9329 " be registered.\n"
9330 " :type cls: type\n"
9331 "\n"
9332 " .. note::\n"
9333 "\n"
9334 " If the class has an *unregister* class method it will be called\n"
9335 " before unregistering.\n");
9337 "unregister_class",
9339 METH_O,
9340 pyrna_unregister_class_doc,
9341};
9342static PyObject *pyrna_unregister_class(PyObject * /*self*/, PyObject *py_class)
9343{
9344 bContext *C = nullptr;
9346 StructRNA *srna;
9347 PyObject *py_cls_meth;
9348
9349 if (!PyType_Check(py_class)) {
9350 PyErr_Format(PyExc_ValueError,
9351 "register_class(...): "
9352 "expected a class argument, not '%.200s'",
9353 Py_TYPE(py_class)->tp_name);
9354 return nullptr;
9355 }
9356
9357#if 0
9358 if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna) == nullptr) {
9359 PWM_cursor_wait(false);
9360 PyErr_SetString(PyExc_ValueError, "unregister_class(): not a registered as a subclass");
9361 return nullptr;
9362 }
9363#endif
9364
9365 if (!pyrna_write_check()) {
9366 PyErr_Format(PyExc_RuntimeError,
9367 "unregister_class(...): "
9368 "can't run in readonly state '%.200s'",
9369 ((PyTypeObject *)py_class)->tp_name);
9370 return nullptr;
9371 }
9372
9373 srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):");
9374 if (srna == nullptr) {
9375 return nullptr;
9376 }
9377
9378 /* Check that we have a unregister callback for this type. */
9379 unreg = RNA_struct_unregister(srna);
9380
9381 if (!unreg) {
9382 PyErr_SetString(
9383 PyExc_ValueError,
9384 "unregister_class(...): "
9385 "expected a Type subclassed from a registerable RNA type (no unregister supported)");
9386 return nullptr;
9387 }
9388
9389 /* Call classed unregister method.
9390 * Note that zero falls through, no attribute, no error. */
9391 switch (_PyObject_LookupAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) {
9392 case 1: {
9393 PyObject *ret = PyObject_CallObject(py_cls_meth, nullptr);
9394 Py_DECREF(py_cls_meth);
9395 if (ret) {
9396 Py_DECREF(ret);
9397 }
9398 else {
9399 return nullptr;
9400 }
9401 break;
9402 }
9403 case -1: {
9404 return nullptr;
9405 }
9406 }
9407
9408 /* Should happen all the time, however it's very slow. */
9409 if (G.debug & G_DEBUG_PYTHON) {
9410 /* Remove all properties using this class. */
9411 StructRNA *srna_iter;
9412 PropertyRNA *prop_rna;
9413 const char *prop_identifier = nullptr;
9414
9416 prop_rna = RNA_struct_find_property(&ptr_rna, "structs");
9417
9418 /* Loop over all structs. */
9419 RNA_PROP_BEGIN (&ptr_rna, itemptr, prop_rna) {
9420 srna_iter = static_cast<StructRNA *>(itemptr.data);
9421 if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) {
9422 break;
9423 }
9424 }
9426
9427 if (prop_identifier) {
9428 PyErr_Format(PyExc_RuntimeError,
9429 "unregister_class(...): can't unregister %s because %s.%s pointer property is "
9430 "using this",
9432 RNA_struct_identifier(srna_iter),
9433 prop_identifier);
9434 return nullptr;
9435 }
9436 }
9437
9438 /* Get the context, so register callback can do necessary refreshes. */
9439 C = BPY_context_get();
9440
9441 /* Call unregister. */
9442 unreg(CTX_data_main(C), srna); /* Calls bpy_class_free, this decref's py_class. */
9443
9444 /* Typically `bpy_class_free` will have removed, remove here just in case. */
9445 if (UNLIKELY(PyDict_Contains(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna))) {
9446 if (PyDict_DelItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna) == -1) {
9447 PyErr_Clear();
9448 }
9449 }
9450
9451 Py_RETURN_NONE;
9452}
9453
9454void pyrna_struct_type_extend_capi(StructRNA *srna, PyMethodDef *method, PyGetSetDef *getset)
9455{
9456 /* See 'add_methods' in Python's 'typeobject.c'. */
9457 PyTypeObject *type = (PyTypeObject *)pyrna_srna_Subtype(srna);
9458 PyObject *dict = type->tp_dict;
9459 if (method != nullptr) {
9460 for (; method->ml_name != nullptr; method++) {
9461 PyObject *py_method;
9462
9463 if (method->ml_flags & METH_CLASS) {
9464 PyObject *cfunc = PyCFunction_New(method, (PyObject *)type);
9465 py_method = PyClassMethod_New(cfunc);
9466 Py_DECREF(cfunc);
9467 }
9468 else if (method->ml_flags & METH_STATIC) {
9469 py_method = PyCFunction_New(method, nullptr);
9470 }
9471 else {
9472 py_method = PyDescr_NewMethod(type, method);
9473 }
9474
9475 const int err = PyDict_SetItemString(dict, method->ml_name, py_method);
9476 Py_DECREF(py_method);
9477 BLI_assert(!(err < 0));
9478 UNUSED_VARS_NDEBUG(err);
9479 }
9480 }
9481
9482 if (getset != nullptr) {
9483 for (; getset->name != nullptr; getset++) {
9484 PyObject *descr = PyDescr_NewGetSet(type, getset);
9485 /* Ensure we're not overwriting anything that already exists. */
9486 BLI_assert(PyDict_GetItem(dict, PyDescr_NAME(descr)) == nullptr);
9487 PyDict_SetItem(dict, PyDescr_NAME(descr), descr);
9488 Py_DECREF(descr);
9489 }
9490 }
9491 Py_DECREF(type);
9492}
9493
9494/* Access to 'owner_id' internal global. */
9495
9496static PyObject *pyrna_bl_owner_id_get(PyObject * /*self*/)
9497{
9498 const char *name = RNA_struct_state_owner_get();
9499 if (name) {
9500 return PyUnicode_FromString(name);
9501 }
9502 Py_RETURN_NONE;
9503}
9504
9505static PyObject *pyrna_bl_owner_id_set(PyObject * /*self*/, PyObject *value)
9506{
9507 const char *name;
9508 if (value == Py_None) {
9509 name = nullptr;
9510 }
9511 else if (PyUnicode_Check(value)) {
9512 name = PyUnicode_AsUTF8(value);
9513 }
9514 else {
9515 PyErr_Format(PyExc_ValueError,
9516 "owner_set(...): "
9517 "expected None or a string, not '%.200s'",
9518 Py_TYPE(value)->tp_name);
9519 return nullptr;
9520 }
9522 Py_RETURN_NONE;
9523}
9524
9525#if (defined(__GNUC__) && !defined(__clang__))
9526# pragma GCC diagnostic push
9527# pragma GCC diagnostic ignored "-Wcast-function-type"
9528#endif
9529
9531 "_bl_owner_id_get",
9532 (PyCFunction)pyrna_bl_owner_id_get,
9533 METH_NOARGS,
9534 nullptr,
9535};
9537 "_bl_owner_id_set",
9538 (PyCFunction)pyrna_bl_owner_id_set,
9539 METH_O,
9540 nullptr,
9541};
9542
9543#if (defined(__GNUC__) && !defined(__clang__))
9544# pragma GCC diagnostic pop
9545#endif
ReportList * CTX_wm_reports(const bContext *C)
ListBase CTX_data_dir_get(const bContext *C)
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, blender::Vector< PointerRNA > *r_lb, PropertyRNA **r_prop, int *r_index, blender::StringRef *r_str, short *r_type)
eContextResult
@ CTX_RESULT_MEMBER_NOT_FOUND
@ CTX_RESULT_OK
@ CTX_RESULT_NO_DATA
Main * CTX_data_main(const bContext *C)
@ CTX_DATA_TYPE_PROPERTY
@ CTX_DATA_TYPE_POINTER
@ CTX_DATA_TYPE_COLLECTION
@ CTX_DATA_TYPE_STRING
wmWindowManager * CTX_wm_manager(const bContext *C)
#define G_MAIN
@ G_DEBUG_PYTHON
void IDP_FreeFromGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:757
bool IDP_ui_data_supported(const IDProperty *prop)
Definition idprop.cc:1687
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:763
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1227
const char * BKE_idtype_idcode_to_name(short idcode)
Definition idtype.cc:168
const char * BKE_idtype_idcode_to_name_plural(short idcode)
Definition idtype.cc:175
void BKE_reports_free(ReportList *reports)
Definition report.cc:69
void BKE_report_print_level_set(ReportList *reports, eReportType level)
Definition report.cc:237
void BKE_reports_init(ReportList *reports, int flag)
Definition report.cc:54
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define ATTR_FALLTHROUGH
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition BLI_dynstr.c:149
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.c:37
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition BLI_dynstr.c:174
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.h:299
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition BLI_ghash.c:911
#define GHASH_ITER(gh_iter_, ghash_)
Definition BLI_ghash.h:322
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:702
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:787
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
Definition BLI_ghash.c:895
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.h:311
void BLI_kdtree_nd_ free(KDTree *tree)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
@ EULER_ORDER_XYZ
@ EULER_ORDER_ZYX
#define STR_ELEM(...)
Definition BLI_string.h:653
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_str_tolower_ascii(char *str, size_t len) ATTR_NONNULL(1)
Definition string.c:952
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned char uchar
unsigned int uint
#define CLAMP(a, b, c)
#define ARRAY_SIZE(arr)
#define STREQLEN(a, b, n)
#define STRINGIFY(x)
#define UNUSED_VARS_NDEBUG(...)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define CLAMP_MIN(a, b)
struct CLG_LogRef * BPY_LOG_RNA
typedef double(DMatrix)[4][4]
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
#define CLOG_INFO(clg_ref, level,...)
Definition CLG_log.h:179
ID * DEG_get_original_id(ID *id)
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:725
@ ID_TAG_TEMP_MAIN
Definition DNA_ID.h:938
@ ID_WM
@ ID_WS
@ ID_SCR
Read Guarded memory(de)allocation.
#define RNA_PROP_END
#define RNA_STRUCT_BEGIN(sptr, prop)
#define RNA_STRUCT_END
#define RNA_POINTER_INVALIDATE(ptr)
#define RNA_PROP_BEGIN(sptr, itemptr, prop)
int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier)
@ PARM_RNAPTR
Definition RNA_types.hh:399
@ PARM_PYFUNC_OPTIONAL
Definition RNA_types.hh:407
@ PARM_REQUIRED
Definition RNA_types.hh:397
@ PARM_OUTPUT
Definition RNA_types.hh:398
@ FUNC_USE_SELF_TYPE
Definition RNA_types.hh:675
@ FUNC_NO_SELF
Definition RNA_types.hh:673
@ FUNC_REGISTER
Definition RNA_types.hh:687
@ FUNC_REGISTER_OPTIONAL
Definition RNA_types.hh:689
@ FUNC_ALLOW_WRITE
Definition RNA_types.hh:695
#define RNA_ENUM_BITFLAG_SIZE
Definition RNA_types.hh:125
PropertyType
Definition RNA_types.hh:64
@ PROP_FLOAT
Definition RNA_types.hh:67
@ PROP_BOOLEAN
Definition RNA_types.hh:65
@ PROP_ENUM
Definition RNA_types.hh:69
@ PROP_INT
Definition RNA_types.hh:66
@ PROP_STRING
Definition RNA_types.hh:68
@ PROP_POINTER
Definition RNA_types.hh:70
@ PROP_COLLECTION
Definition RNA_types.hh:71
bool(*)(Main *bmain, StructRNA *type) StructUnregisterFunc
Definition RNA_types.hh:760
StructRNA *(*)(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) StructRegisterFunc
Definition RNA_types.hh:752
RawPropertyType
Definition RNA_types.hh:471
@ PROP_RAW_INT8
Definition RNA_types.hh:483
@ PROP_RAW_UINT64
Definition RNA_types.hh:482
@ PROP_RAW_INT
Definition RNA_types.hh:473
@ PROP_RAW_INT64
Definition RNA_types.hh:481
@ PROP_RAW_UNSET
Definition RNA_types.hh:472
@ PROP_RAW_BOOLEAN
Definition RNA_types.hh:476
@ PROP_RAW_CHAR
Definition RNA_types.hh:475
@ PROP_RAW_FLOAT
Definition RNA_types.hh:478
@ PROP_RAW_DOUBLE
Definition RNA_types.hh:477
@ PROP_RAW_UINT8
Definition RNA_types.hh:479
@ PROP_RAW_UINT16
Definition RNA_types.hh:480
@ PROP_RAW_SHORT
Definition RNA_types.hh:474
@ PROP_THICK_WRAP
Definition RNA_types.hh:312
@ PROP_DYNAMIC
Definition RNA_types.hh:317
@ PROP_ENUM_FLAG
Definition RNA_types.hh:293
@ PROP_REGISTER_OPTIONAL
Definition RNA_types.hh:301
@ PROP_NEVER_NULL
Definition RNA_types.hh:266
@ PROP_REGISTER
Definition RNA_types.hh:300
@ PROP_ID_SELF_CHECK
Definition RNA_types.hh:259
@ PROP_HIDDEN
Definition RNA_types.hh:239
@ PROP_IDPROPERTY
Definition RNA_types.hh:315
@ PROP_MATRIX
Definition RNA_types.hh:168
@ PROP_BYTESTRING
Definition RNA_types.hh:143
@ PROP_FILENAME
Definition RNA_types.hh:141
@ PROP_COLOR
Definition RNA_types.hh:163
@ PROP_EULER
Definition RNA_types.hh:169
@ PROP_DIRPATH
Definition RNA_types.hh:140
@ PROP_COLOR_GAMMA
Definition RNA_types.hh:175
@ PROP_UNSIGNED
Definition RNA_types.hh:152
@ PROP_QUATERNION
Definition RNA_types.hh:170
@ PROP_FILEPATH
Definition RNA_types.hh:139
constexpr PointerRNA PointerRNA_NULL
Definition RNA_types.hh:45
ATTR_WARN_UNUSED_RESULT const BMVert * v
void BPy_reports_write_stdout(const ReportList *reports, const char *header)
short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
bool BPy_errors_to_report(ReportList *reports)
void bpy_context_clear(struct bContext *C, const PyGILState_STATE *gilstate)
void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate)
struct bContext * BPY_context_get(void)
PyObject * self
PyObject * bpy_intern_str_bpy_types
PyObject * bpy_intern_str___name__
PyObject * bpy_intern_str_register
PyObject * bpy_intern_str_bl_rna
PyObject * bpy_intern_str___module__
PyObject * bpy_intern_str___doc__
PyObject * bpy_intern_str_attr
PyObject * bpy_intern_str___annotations__
PyObject * bpy_intern_str_unregister
PyObject * bpy_intern_str___slots__
PyObject * bpy_intern_str_properties
PyObject * BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject * BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
#define BPy_PropDeferred_CheckTypeExact(v)
Definition bpy_props.hh:33
#define PYRNA_STACK_ARRAY
Definition bpy_props.hh:35
static PyModuleDef bpy_types_module_def
Definition bpy_rna.cc:8030
static PyTypeObject pyrna_prop_collection_iter_Type
Definition bpy_rna.cc:7238
static PyObject * pyrna_struct_is_property_overridable_library(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3785
const PointerRNA * pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna)
Definition bpy_rna.cc:8177
static PyObject * pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
Definition bpy_rna.cc:2575
static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
Definition bpy_rna.cc:448
static PyObject * pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args)
Definition bpy_rna.cc:5261
PyDoc_STRVAR(pyrna_struct_keys_doc, ".. method:: keys()\n" "\n" " Returns the keys of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property keys.\n" " :rtype: :class:`idprop.types.IDPropertyGroupViewKeys`\n" "\n" BPY_DOC_ID_PROP_TYPE_NOTE)
static void pyrna_struct_dealloc(BPy_StructRNA *self)
Definition bpy_rna.cc:1163
PyTypeObject pyrna_struct_meta_idprop_Type
Definition bpy_rna.cc:6816
PyTypeObject pyrna_prop_Type
Definition bpy_rna.cc:6943
static PyObject * pyrna_register_class(PyObject *self, PyObject *py_class)
Definition bpy_rna.cc:9155
static PyObject * pyrna_bl_owner_id_get(PyObject *)
Definition bpy_rna.cc:9496
void pyrna_invalidate(BPy_DummyPointerRNA *self)
Definition bpy_rna.cc:147
static PyObject * pyrna_struct_dir(BPy_StructRNA *self)
Definition bpy_rna.cc:4256
StructRNA * pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
Definition bpy_rna.cc:8124
static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
Definition bpy_rna.cc:818
static PyObject * pyrna_prop_array_repr(BPy_PropertyArrayRNA *self)
Definition bpy_rna.cc:1106
static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
Definition bpy_rna.cc:3379
static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
Definition bpy_rna.cc:2126
static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
Definition bpy_rna.cc:2198
static PointerRNA * rna_module_ptr
Definition bpy_rna.cc:7903
static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
Definition bpy_rna.cc:3255
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr)
static PyObject * pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
Definition bpy_rna.cc:2912
static PyObject * pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
Definition bpy_rna.cc:2710
static PyObject * pyrna_struct_type_recast(BPy_StructRNA *self)
Definition bpy_rna.cc:4050
static int rna_function_arg_count(FunctionRNA *func, int *min_count)
Definition bpy_rna.cc:8464
PyMethodDef meth_bpy_owner_id_set
Definition bpy_rna.cc:9536
bool pyrna_id_CheckPyObject(PyObject *obj)
Definition bpy_rna.cc:7823
static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject *py_class)
Definition bpy_rna.cc:8408
static PyObject * pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
Definition bpy_rna.cc:7313
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
Definition bpy_rna.cc:2209
static PyObject * pyrna_srna_Subtype(StructRNA *srna)
Definition bpy_rna.cc:7498
static PyObject * pyrna_prop_array_foreach_set(BPy_PropertyArrayRNA *self, PyObject *args)
Definition bpy_rna.cc:5953
static PyObject * pyrna_struct_get_id_data(BPy_DummyPointerRNA *self, void *)
Definition bpy_rna.cc:4972
static PyObject * pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3910
PyObject * BPY_rna_module()
Definition bpy_rna.cc:7904
static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
Definition bpy_rna.cc:823
#define MATHUTILS_CB_SUBTYPE_COLOR
Definition bpy_rna.cc:415
static int prop_subscript_ass_array_slice__int_recursive(PyObject **value_items, int *value, int totdim, const int dimsize[], const int range[2])
Definition bpy_rna.cc:3022
static PyObject * pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3690
static bool rna_disallow_writes
Definition bpy_rna.cc:333
#define PROP_ALL_VECTOR_SUBTYPES
Definition bpy_rna.cc:642
static PyObject * pyrna_struct_id_properties_ensure(BPy_StructRNA *self)
Definition bpy_rna.cc:4303
static const char * pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_rna.cc:1238
static PyObject * pyrna_srna_PyBase(StructRNA *srna)
Definition bpy_rna.cc:7414
static long pyrna_prop_hash(BPy_PropertyRNA *self)
Definition bpy_rna.cc:1125
static PyObject * pyrna_struct_get_data(BPy_DummyPointerRNA *self, void *)
Definition bpy_rna.cc:4987
static PyMethodDef pyrna_struct_methods[]
Definition bpy_rna.cc:6010
static PyObject * pyrna_struct_as_pointer(BPy_StructRNA *self)
Definition bpy_rna.cc:5243
void BPY_id_release(ID *id)
Definition bpy_rna.cc:312
static PyMethodDef pyrna_prop_collection_idprop_methods[]
Definition bpy_rna.cc:6165
static PyObject * pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject *pyname)
Definition bpy_rna.cc:4775
PyObject * pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_rna.cc:651
static PyObject * pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
Definition bpy_rna.cc:2120
static PyObject * pyrna_struct_id_properties_clear(BPy_StructRNA *self)
Definition bpy_rna.cc:4380
static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
Definition bpy_rna.cc:2347
static PyObject * pyrna_struct_items(BPy_StructRNA *self)
Definition bpy_rna.cc:3595
static PyObject * pyrna_bl_owner_id_set(PyObject *, PyObject *value)
Definition bpy_rna.cc:9505
void pyrna_struct_type_extend_capi(StructRNA *srna, PyMethodDef *method, PyGetSetDef *getset)
Definition bpy_rna.cc:9454
static PyObject * pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
Definition bpy_rna.cc:830
static PyMappingMethods pyrna_struct_as_mapping
Definition bpy_rna.cc:3553
static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item)
Definition bpy_rna.cc:8240
static PyObject * pyrna_prop_dir(BPy_PropertyRNA *self)
Definition bpy_rna.cc:4748
static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict)
Definition bpy_rna.cc:4166
static PyTypeObject pyrna_prop_collection_idprop_Type
Definition bpy_rna.cc:7112
static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
Definition bpy_rna.cc:3384
static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
Definition bpy_rna.cc:1216
static PyObject * pyrna_struct_property_overridable_library_set(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3816
#define BPY_DOC_ID_PROP_TYPE_NOTE
Definition bpy_rna.cc:106
static PyObject * pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
Definition bpy_rna.cc:2614
static PyMappingMethods pyrna_prop_array_as_mapping
Definition bpy_rna.cc:3315
static void pyrna_dir_members_py(PyObject *list, PyObject *self)
Definition bpy_rna.cc:4175
PyMethodDef meth_bpy_owner_id_get
Definition bpy_rna.cc:9530
static PyObject * pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
Definition bpy_rna.cc:2399
static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
Definition bpy_rna.cc:2827
static PyObject * pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args)
Definition bpy_rna.cc:5764
static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *r_value, const char *error_prefix)
Definition bpy_rna.cc:1259
static PyObject * pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
Definition bpy_rna.cc:861
static PyObject * pyrna_prop_as_bytes(BPy_PropertyRNA *self)
Definition bpy_rna.cc:3997
static PyObject * pyrna_prop_collection_iter(BPy_PropertyRNA *self)
Definition bpy_rna.cc:7308
static PyObject * pyrna_struct_id_properties_ui(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:4335
static int pyrna_prop_collection_string_subscript_supported_or_error(BPy_PropertyRNA *self, const char *error_prefix)
Definition bpy_rna.cc:2275
static PyObject * pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
Definition bpy_rna.cc:1330
static int bpy_class_validate_recursive(PointerRNA *dummy_ptr, StructRNA *srna, void *py_data, bool *have_function)
Definition bpy_rna.cc:8493
static PyObject * pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
Definition bpy_rna.cc:5777
static PyObject * pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum)
Definition bpy_rna.cc:2379
bool pyrna_write_check()
Definition bpy_rna.cc:369
static PyObject * pyrna_prop_update(BPy_PropertyRNA *self)
Definition bpy_rna.cc:4034
static PyObject * pyrna_prop_path_from_id(BPy_PropertyRNA *self)
Definition bpy_rna.cc:3968
void pyrna_struct_validity_exception_only(const BPy_StructRNA *pysrna)
Definition bpy_rna.cc:120
static PyNumberMethods pyrna_prop_collection_as_number
Definition bpy_rna.cc:3340
static PyObject * pyrna_struct_get_rna_type(BPy_PropertyRNA *self, void *)
Definition bpy_rna.cc:4996
static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int start, int stop, int length, PyObject *value_orig)
Definition bpy_rna.cc:3087
static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
Definition bpy_rna.cc:8384
void BPY_rna_init()
Definition bpy_rna.cc:7828
static PyObject * pyrna_prop_collection_values(BPy_PropertyRNA *self)
Definition bpy_rna.cc:5124
static PyObject * pyrna_srna_ExternalType(StructRNA *srna)
Definition bpy_rna.cc:7441
void BPY_rna_types_finalize_external_types(PyObject *submodule)
Definition bpy_rna.cc:8071
static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
Definition bpy_rna.cc:2784
static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
Definition bpy_rna.cc:4618
int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p)
Definition bpy_rna.cc:8210
int pyrna_struct_as_ptr_parse(PyObject *o, void *p)
Definition bpy_rna.cc:8199
static PyObject * pyrna_unregister_class(PyObject *self, PyObject *py_class)
Definition bpy_rna.cc:9342
static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject *value)
Definition bpy_rna.cc:4682
static uchar mathutils_rna_array_cb_index
Definition bpy_rna.cc:409
static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
Definition bpy_rna.cc:8702
static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int, int index)
Definition bpy_rna.cc:502
static PyObject * small_dict_get_item_string(PyObject *dict, const char *key_lookup)
Definition bpy_rna.cc:6434
StructRNA * srna_from_self(PyObject *self, const char *error_prefix)
Definition bpy_rna.cc:8223
static PySequenceMethods pyrna_struct_as_sequence
Definition bpy_rna.cc:3469
static PyObject * pyrna_func_doc_get(BPy_FunctionRNA *self, void *closure)
Definition bpy_rna.cc:6801
static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
Definition bpy_rna.cc:2218
#define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err)
Definition bpy_rna.cc:2235
PyObject * pyrna_id_CreatePyObject(ID *id)
Definition bpy_rna.cc:7802
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
Definition bpy_rna.cc:7355
int pyrna_struct_validity_check(const BPy_StructRNA *pysrna)
Definition bpy_rna.cc:126
static int pyrna_prop_collection_subscript_is_valid_or_error(const PyObject *value)
Definition bpy_rna.cc:2248
static PyObject * pyrna_prop_array_foreach_get(BPy_PropertyArrayRNA *self, PyObject *args)
Definition bpy_rna.cc:5940
int pyrna_prop_validity_check(const BPy_PropertyRNA *self)
Definition bpy_rna.cc:135
static int mathutils_rna_generic_check(BaseMathObject *bmo)
Definition bpy_rna.cc:417
void pyrna_free_types()
Definition bpy_rna.cc:9099
static PyObject * pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3852
int pyrna_struct_validity_check_only(const BPy_StructRNA *pysrna)
Definition bpy_rna.cc:112
static PyObject * pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3723
static PyObject * pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:3754
static PyObject * pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key, const char *err_prefix, const bool err_not_found)
Definition bpy_rna.cc:2559
const PointerRNA * pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna)
Definition bpy_rna.cc:8191
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self)
Definition bpy_rna.cc:7339
static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
Definition bpy_rna.cc:4207
static PyObject * pyrna_prop_array_getattro(BPy_PropertyRNA *self, PyObject *pyname)
Definition bpy_rna.cc:4770
PyTypeObject pyrna_prop_array_Type
Definition bpy_rna.cc:6999
static void pyrna_func_error_prefix(BPy_FunctionRNA *self, PropertyRNA *parm, const int parm_index, char *error, const size_t error_size)
Definition bpy_rna.cc:6458
static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items, bool *value, int totdim, const int dimsize[])
Definition bpy_rna.cc:3054
static PyNumberMethods pyrna_prop_array_as_number
Definition bpy_rna.cc:3328
static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
Definition bpy_rna.cc:3235
static PyObject * foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
Definition bpy_rna.cc:5543
static PySequenceMethods pyrna_prop_collection_as_sequence
Definition bpy_rna.cc:3454
static PyObject * pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:5144
static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self)
Definition bpy_rna.cc:1119
static PyObject * pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, const char *id)
Definition bpy_rna.cc:4062
static PyGetSetDef pyrna_prop_getseters[]
Definition bpy_rna.cc:5006
PyTypeObject pyrna_struct_Type
Definition bpy_rna.cc:6876
static PyObject * pyrna_prop_collection_idprop_clear(BPy_PropertyRNA *self)
Definition bpy_rna.cc:4930
static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
Definition bpy_rna.cc:426
static PyObject * pyrna_struct_pop(BPy_StructRNA *self, PyObject *args)
Definition bpy_rna.cc:5189
static PyObject * pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw)
Definition bpy_rna.cc:6485
static PyObject * prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, int length)
Definition bpy_rna.cc:2969
static void bpy_class_free(void *pyob_ptr)
Definition bpy_rna.cc:9034
static uchar mathutils_rna_matrix_cb_index
Definition bpy_rna.cc:559
static PySequenceMethods pyrna_prop_array_as_sequence
Definition bpy_rna.cc:3440
static PyObject * pyrna_struct_Subtype(PointerRNA *ptr)
Definition bpy_rna.cc:7616
static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
Definition bpy_rna.cc:5490
static PyMethodDef pyrna_prop_methods[]
Definition bpy_rna.cc:6116
static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, StructRNA *srna, const char **r_prop_identifier)
Definition bpy_rna.cc:9296
static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
Definition bpy_rna.cc:3415
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_rna.cc:1405
PyTypeObject pyrna_func_Type
Definition bpy_rna.cc:7170
static PyObject * pyrna_struct_str(BPy_StructRNA *self)
Definition bpy_rna.cc:893
int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class)
Definition bpy_rna.cc:8442
static PyGetSetDef pyrna_struct_getseters[]
Definition bpy_rna.cc:5021
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const bool all_args, const char *error_prefix)
Definition bpy_rna.cc:1486
static PyObject * pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
Definition bpy_rna.cc:4400
static PyMethodDef pyrna_prop_collection_methods[]
Definition bpy_rna.cc:6140
static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, const char *function_name, const char **r_attr, PyObject **r_seq, int *r_tot, size_t *r_size, RawPropertyType *r_raw_type, int *r_attr_tot, bool *r_attr_signed)
Definition bpy_rna.cc:5383
static PyObject * pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
Definition bpy_rna.cc:1556
static PyObject * pyrna_struct_CreatePyObject_from_type(const PointerRNA *ptr, PyTypeObject *tp, void **instance)
Definition bpy_rna.cc:7627
static Mathutils_Callback mathutils_rna_array_cb
Definition bpy_rna.cc:550
static void pyrna_prop_collection_string_subscript_unsupported_error(BPy_PropertyRNA *self, const char *error_prefix)
Definition bpy_rna.cc:2265
static PyObject * pyrna_struct_values(BPy_StructRNA *self)
Definition bpy_rna.cc:3620
void BPY_rna_exit()
Definition bpy_rna.cc:7881
static PyObject * pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
Definition bpy_rna.cc:6255
static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
Definition bpy_rna.cc:2225
static PyObject * pyrna_struct_bl_rna_get_subclass_py(PyObject *cls, PyObject *args)
Definition bpy_rna.cc:4105
PyObject * BPY_rna_types()
Definition bpy_rna.cc:8042
static bool foreach_attr_type(BPy_PropertyRNA *self, const char *attr, RawPropertyType *r_raw_type, int *r_attr_tot, bool *r_attr_signed, bool *r_is_empty)
Definition bpy_rna.cc:5348
PyMethodDef meth_bpy_unregister_class
Definition bpy_rna.cc:9336
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, const short order_fallback, PropertyRNA **r_prop_eul_order)
Definition bpy_rna.cc:616
static PyObject * bpy_types_dict
Definition bpy_rna.cc:7439
static int prop_subscript_ass_array_slice__float_recursive(PyObject **value_items, float *value, int totdim, const int dimsize[], const float range[2])
Definition bpy_rna.cc:2990
PyObject * pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_rna.cc:7752
static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
Definition bpy_rna.cc:1227
void pyrna_write_set(bool val)
Definition bpy_rna.cc:374
static PyObject * pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index)
Definition bpy_rna.cc:1055
static PyObject * pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
Definition bpy_rna.cc:4886
PyMethodDef meth_bpy_register_class
Definition bpy_rna.cc:9153
static int bpy_class_validate(PointerRNA *dummy_ptr, void *py_data, bool *have_function)
Definition bpy_rna.cc:8696
static PyObject * pyrna_struct_repr(BPy_StructRNA *self)
Definition bpy_rna.cc:929
#define MATHUTILS_CB_SUBTYPE_VEC
Definition bpy_rna.cc:413
static int pyrna_deferred_register_class_from_type_hints(StructRNA *srna, PyTypeObject *py_class)
Definition bpy_rna.cc:8328
void pyrna_alloc_types()
Definition bpy_rna.cc:9064
static PyObject * pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob)
Definition bpy_rna.cc:5314
static int mathutils_rna_matrix_set(BaseMathObject *bmo, int)
Definition bpy_rna.cc:575
static PyObject * pyrna_prop_collection_keys(BPy_PropertyRNA *self)
Definition bpy_rna.cc:5047
#define MATHUTILS_CB_SUBTYPE_EUL
Definition bpy_rna.cc:412
static PyObject * pyrna_prop_repr(BPy_PropertyRNA *self)
Definition bpy_rna.cc:1101
static PyGetSetDef pyrna_func_getseters[]
Definition bpy_rna.cc:5032
void BPY_update_rna_module()
Definition bpy_rna.cc:7916
static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pyname, PyObject *value)
Definition bpy_rna.cc:4851
static PyObject * pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
Definition bpy_rna.cc:4129
static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
Definition bpy_rna.cc:1286
static PyObject * pyrna_func_repr(BPy_FunctionRNA *self)
Definition bpy_rna.cc:1111
static PyMappingMethods pyrna_prop_collection_as_mapping
Definition bpy_rna.cc:3321
bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
Definition bpy_rna.cc:7812
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:7694
static PyMethodDef bpy_types_module_methods[]
Definition bpy_rna.cc:8016
static PyObject * bpy_types_module_getattro(PyObject *self, PyObject *pyname)
Definition bpy_rna.cc:7957
static PyObject * pyrna_prop_str(BPy_PropertyRNA *self)
Definition bpy_rna.cc:986
static PyObject * pyrna_prop_collection_items(BPy_PropertyRNA *self)
Definition bpy_rna.cc:5079
static PyObject * pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self, PyObject *args, const bool do_set)
Definition bpy_rna.cc:5784
static int mathutils_rna_matrix_get(BaseMathObject *bmo, int)
Definition bpy_rna.cc:561
static PyObject * bpy_types_module_dir(PyObject *self)
Definition bpy_rna.cc:7990
static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int, int index)
Definition bpy_rna.cc:516
static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *)
Definition bpy_rna.cc:6181
static PyObject * pyrna_struct_keys(BPy_StructRNA *self)
Definition bpy_rna.cc:3570
static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, PyObject *key, const char *err_prefix, const short err_not_found, PointerRNA *r_ptr)
Definition bpy_rna.cc:2470
static PyObject * pyrna_prop_array_iter(BPy_PropertyArrayRNA *self)
Definition bpy_rna.cc:5962
#define MATHUTILS_CB_SUBTYPE_QUAT
Definition bpy_rna.cc:414
static PyObject * pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
Definition bpy_rna.cc:2287
static PyObject * pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args)
Definition bpy_rna.cc:4943
static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *)
Definition bpy_rna.cc:6231
static PyMethodDef pyrna_prop_array_methods[]
Definition bpy_rna.cc:6127
BPy_StructRNA * bpy_context_module
Definition bpy_rna.cc:91
PyObject * pyrna_struct_CreatePyObject_with_primitive_support(PointerRNA *ptr)
Definition bpy_rna.cc:7731
static PyObject * pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
Definition bpy_rna.cc:4906
static PyObject * pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
Definition bpy_rna.cc:3483
static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
Definition bpy_rna.cc:3518
static PyObject * pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_rna.cc:7294
static StructRNA * srna_from_ptr(PointerRNA *ptr)
Definition bpy_rna.cc:7606
static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
Definition bpy_rna.cc:335
static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
Definition bpy_rna.cc:1564
PyTypeObject pyrna_prop_collection_Type
Definition bpy_rna.cc:7055
static PyObject * pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args, PyObject *kw)
Definition bpy_rna.cc:3651
static Mathutils_Callback mathutils_rna_matrix_cb
Definition bpy_rna.cc:608
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix)
PyObject * pyrna_array_index(PointerRNA *ptr, PropertyRNA *prop, int index)
#define PYRNA_STRUCT_IS_VALID(pysrna)
Definition bpy_rna.hh:106
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
#define BPy_StructRNA_CheckExact(v)
Definition bpy_rna.hh:70
#define PYRNA_STRUCT_CHECK_OBJ(obj)
Definition bpy_rna.hh:74
int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix)
#define PYRNA_STRUCT_CHECK_INT(obj)
Definition bpy_rna.hh:79
#define PYRNA_STRUCT_CHECK_OBJ_UNLESS(obj, unless)
Definition bpy_rna.hh:96
#define PYRNA_PROP_CHECK_OBJ(obj)
Definition bpy_rna.hh:85
#define PYRNA_PROP_CHECK_INT(obj)
Definition bpy_rna.hh:90
#define BPy_PropertyRNA_CheckExact(v)
Definition bpy_rna.hh:72
#define BPy_StructRNA_Check(v)
Definition bpy_rna.hh:69
#define BPy_PropertyRNA_Check(v)
Definition bpy_rna.hh:71
PyObject * pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int index)
PyObject * pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop)
char pyrna_struct_driver_add_doc[]
char pyrna_struct_keyframe_insert_doc[]
PyObject * pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
PyObject * pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
PyObject * pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
char pyrna_struct_driver_remove_doc[]
char pyrna_struct_keyframe_delete_doc[]
PyObject * pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
PyObject * pyrna_callback_classmethod_remove(PyObject *, PyObject *args)
PyObject * pyrna_callback_classmethod_add(PyObject *, PyObject *args)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr const char * data() const
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
#define printf
#define offsetof(t, d)
int len
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
uint col
PyObject * BPy_Wrap_GetKeys_View_WithID(ID *id, IDProperty *prop)
int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val)
PyObject * BPy_Wrap_GetItems_View_WithID(ID *id, IDProperty *prop)
PyTypeObject BPy_IDGroup_Type
PyObject * BPy_IDGroup_MapDataToPy(IDProperty *prop)
PyObject * BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent)
PyObject * BPy_Wrap_GetValues_View_WithID(ID *id, IDProperty *prop)
PyTypeObject BPy_IDPropertyUIManager_Type
int count
#define GS(x)
Definition iris.cc:202
format
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
Definition mathutils.cc:522
int(* BaseMathGetFunc)(BaseMathObject *, int)
Definition mathutils.hh:95
int(* BaseMathGetIndexFunc)(BaseMathObject *, int, int)
Definition mathutils.hh:99
int(* BaseMathSetIndexFunc)(BaseMathObject *, int, int)
Definition mathutils.hh:101
int(* BaseMathSetFunc)(BaseMathObject *, int)
Definition mathutils.hh:97
int(* BaseMathCheckFunc)(BaseMathObject *)
Definition mathutils.hh:93
PyObject * Color_CreatePyObject(const float col[3], PyTypeObject *base_type)
PyObject * Color_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar cb_subtype)
PyObject * Euler_CreatePyObject(const float eul[3], const short order, PyTypeObject *base_type)
PyObject * Euler_CreatePyObject_cb(PyObject *cb_user, const short order, uchar cb_type, uchar cb_subtype)
PyObject * Matrix_CreatePyObject_cb(PyObject *cb_user, const ushort col_num, const ushort row_num, uchar cb_type, uchar cb_subtype)
PyObject * Matrix_CreatePyObject(const float *mat, const ushort col_num, const ushort row_num, PyTypeObject *base_type)
PyObject * Quaternion_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar cb_subtype)
PyObject * Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
PyObject * Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
static ulong state[N]
#define G(x, y, z)
static void error(const char *str)
const char * node_type_find_alias(const char *idname)
Definition node.cc:1679
bNodeType * node_type_find(const char *idname)
Definition node.cc:1667
int pyrna_enum_bitfield_from_set(const EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
char * pyrna_enum_repr(const EnumPropertyItem *item)
int16_t PyC_Long_AsI16(PyObject *value)
uint8_t PyC_Long_AsU8(PyObject *value)
PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format,...)
void PyC_ObSpit(const char *name, PyObject *var)
int8_t PyC_Long_AsI8(PyObject *value)
PyObject * PyC_UnicodeFromBytesAndSize(const char *str, Py_ssize_t size)
PyObject * PyC_UnicodeFromBytes(const char *str)
uint64_t PyC_Long_AsU64(PyObject *value)
void PyC_ObSpitStr(char *result, size_t result_maxncpy, PyObject *var)
PyObject * PyC_ExceptionBuffer()
int PyC_Long_AsBool(PyObject *value)
void PyC_FileAndNum(const char **r_filename, int *r_lineno)
uint16_t PyC_Long_AsU16(PyObject *value)
int PyC_ParseBool(PyObject *o, void *p)
const char * PyC_UnicodeAsBytes(PyObject *py_str, PyObject **r_coerce)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
header-only utilities
#define PyTuple_SET_ITEMS(op_arg,...)
return ret
StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_collection_lookup_int_has_fn(PropertyRNA *prop)
bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
StructRegisterFunc RNA_struct_register(StructRNA *type)
bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_identifier)
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
const StructRNA * RNA_struct_base_child_of(const StructRNA *type, const StructRNA *parent_type)
bool RNA_property_update_check(PropertyRNA *prop)
bool RNA_property_array_check(PropertyRNA *prop)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
const char * RNA_function_identifier(FunctionRNA *func)
void RNA_parameter_list_end(ParameterIterator *)
void RNA_struct_state_owner_set(const char *name)
void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
IDProperty ** RNA_struct_idprops_p(PointerRNA *ptr)
int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_identifier)
bool RNA_struct_is_ID(const StructRNA *type)
const ListBase * RNA_struct_type_properties(StructRNA *srna)
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
const ListBase * RNA_struct_type_functions(StructRNA *srna)
bool RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr)
bool RNA_property_collection_is_empty(PointerRNA *ptr, PropertyRNA *prop)
int RNA_function_defined(FunctionRNA *func)
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num)
bool RNA_property_collection_lookup_string_has_nameprop(PropertyRNA *prop)
int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost)
bool RNA_property_collection_lookup_string_supported(PropertyRNA *prop)
void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
PropertyType RNA_property_type(PropertyRNA *prop)
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
void ** RNA_struct_instance(PointerRNA *ptr)
void RNA_parameter_list_free(ParameterList *parms)
IDProperty * RNA_struct_idprops(PointerRNA *ptr, bool create)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
size_t RNA_raw_type_sizeof(RawPropertyType type)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_struct_identifier(const StructRNA *type)
bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
bool RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **r_identifier)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_collection_next(CollectionPropertyIterator *iter)
void RNA_parameter_list_next(ParameterIterator *iter)
const char * RNA_function_ui_description(FunctionRNA *func)
int RNA_property_array_dimension(const PointerRNA *ptr, PropertyRNA *prop, int length[])
PropertyRNA * RNA_struct_type_find_property_no_base(StructRNA *srna, const char *identifier)
int RNA_function_flag(FunctionRNA *func)
std::string RNA_function_as_string_keywords(bContext *C, FunctionRNA *func, const bool as_function, const bool all_args, const int max_prop_length)
int RNA_property_flag(PropertyRNA *prop)
RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
bool RNA_property_builtin(PropertyRNA *prop)
const char * RNA_struct_ui_description(const StructRNA *type)
int RNA_parameter_list_arg_count(const ParameterList *parms)
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
bool RNA_struct_idprops_register_check(const StructRNA *type)
void RNA_property_string_set_bytes(PointerRNA *ptr, PropertyRNA *prop, const char *value, int len)
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
StructRNA * RNA_struct_base(StructRNA *type)
FunctionRNA * RNA_struct_find_function(StructRNA *srna, const char *identifier)
bool RNA_property_is_idprop(const PropertyRNA *prop)
int RNA_property_string_maxlength(PropertyRNA *prop)
const char * RNA_struct_state_owner_get()
bool RNA_struct_idprops_datablock_allowed(const StructRNA *type)
bool RNA_property_editable(const PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
PointerRNA RNA_pointer_recast(PointerRNA *ptr)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
PointerRNA RNA_main_pointer_create(Main *main)
void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
bool RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
ParameterList * RNA_parameter_list_create(ParameterList *parms, PointerRNA *, FunctionRNA *func)
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
void RNA_property_collection_end(CollectionPropertyIterator *iter)
bool RNA_property_collection_lookup_string_has_fn(PropertyRNA *prop)
bool RNA_struct_idprops_check(StructRNA *srna)
PointerRNA RNA_blender_rna_pointer_create()
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
PropertyRNA * RNA_struct_iterator_property(StructRNA *type)
void RNA_property_enum_items_ex(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const bool use_static, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
int RNA_parameter_flag(PropertyRNA *prop)
void * RNA_struct_py_type_get(StructRNA *srna)
bool RNA_property_editable_flag(const PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
const char * RNA_property_identifier(const PropertyRNA *prop)
const ListBase * RNA_function_defined_parameters(FunctionRNA *func)
int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
PointerRNA RNA_id_pointer_create(ID *id)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
bool RNA_property_overridable_library_set(PointerRNA *, PropertyRNA *prop, const bool is_overridable)
bool RNA_property_overridable_get(const PointerRNA *ptr, PropertyRNA *prop)
std::optional< std::string > RNA_path_from_ID_to_struct(const PointerRNA *ptr)
Definition rna_path.cc:1007
std::optional< std::string > RNA_path_from_real_ID_to_struct(Main *bmain, const PointerRNA *ptr, ID **r_real)
Definition rna_path.cc:1049
std::optional< std::string > RNA_path_from_real_ID_to_property_index(Main *bmain, const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index, ID **r_real_id)
Definition rna_path.cc:1171
bool RNA_path_resolve_full_maybe_null(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
Definition rna_path.cc:547
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition rna_path.cc:1166
std::string RNA_path_from_ptr_to_property_index(const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index)
Definition rna_path.cc:1141
const EnumPropertyItem rna_enum_property_type_items[]
Definition rna_rna.cc:46
const EnumPropertyItem rna_enum_dummy_NULL_items[]
Definition rna_rna.cc:29
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
unsigned short uint16_t
Definition stdint.h:79
__int64 int64_t
Definition stdint.h:89
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
signed char int8_t
Definition stdint.h:75
PyObject_HEAD PointerRNA ptr
Definition bpy_rna.hh:116
PyObject_HEAD PointerRNA ptr
Definition bpy_rna.hh:176
FunctionRNA * func
Definition bpy_rna.hh:177
PyObject_VAR_HEAD IDProperty * property
PropertyRNA * prop
Definition bpy_rna.hh:143
PyObject_HEAD PointerRNA ptr
Definition bpy_rna.hh:142
StructRNA * type
Definition bpy_rna.hh:216
const PointerRNA * ptr
Definition bpy_rna.hh:218
PyObject_HEAD PointerRNA ptr
Definition bpy_rna.hh:124
PropertyRNA * prop
Definition bpy_rna.cc:7954
blender::Vector< PointerRNA > items
Definition RNA_types.hh:468
unsigned char order
StructRNA * srna
Definition RNA_types.hh:780
Definition DNA_ID.h:413
int tag
Definition DNA_ID.h:434
char name[66]
Definition DNA_ID.h:425
ListBase libraries
Definition BKE_main.hh:211
PropertyRNA * parm
Definition RNA_types.hh:636
ID * owner_id
Definition RNA_types.hh:40
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
Defines a node type.
Definition BKE_node.hh:218
struct ReportList * reports
float max
static DynamicLibrary lib
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138