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