Blender V4.3
bpy_props.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
13/* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
14#define PY_SSIZE_T_CLEAN
15
16#include <algorithm>
17
18#include <Python.h>
19
20#include "RNA_types.hh"
21
22#include "BLI_array.hh"
23#include "BLI_listbase.h"
24#include "BLI_utildefines.h"
25
26#include "bpy_capi_utils.hh"
27#include "bpy_props.hh"
28#include "bpy_rna.hh"
29
30#include "RNA_access.hh"
31#include "RNA_define.hh" /* for defining our own rna */
32#include "RNA_enum_types.hh"
33#include "RNA_prototypes.hh"
34
35#include "MEM_guardedalloc.h"
36
37#include "DNA_ID.h" /* MAX_IDPROP_NAME */
38
42
43using blender::Array;
44
45/* Disabled duplicating strings because the array can still be freed and
46 * the strings from it referenced, for now we can't support dynamically
47 * created strings from Python. */
48// #define USE_ENUM_COPY_STRINGS
49
50/* -------------------------------------------------------------------- */
54#define BPY_PROPDEF_OPTIONS_DOC \
55 " :arg options: Enumerator in :ref:`rna_enum_property_flag_items`.\n" \
56 " :type options: set[str]\n"
57
58#define BPY_PROPDEF_OPTIONS_ENUM_DOC \
59 " :arg options: Enumerator in :ref:`rna_enum_property_flag_enum_items`.\n" \
60 " :type options: set[str]\n"
61
62#define BPY_PROPDEF_OPTIONS_OVERRIDE_DOC \
63 " :arg override: Enumerator in :ref:`rna_enum_property_override_flag_items`.\n" \
64 " :type override: set[str]\n"
65
66#define BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC \
67 " :arg override: Enumerator in :ref:`rna_enum_property_override_flag_collection_items`.\n" \
68 " :type override: set[str]\n"
69
70#define BPY_PROPDEF_SUBTYPE_STRING_DOC \
71 " :arg subtype: Enumerator in :ref:`rna_enum_property_subtype_string_items`.\n" \
72 " :type subtype: str\n"
73
74#define BPY_PROPDEF_SUBTYPE_NUMBER_DOC \
75 " :arg subtype: Enumerator in :ref:`rna_enum_property_subtype_number_items`.\n" \
76 " :type subtype: str\n"
77
78#define BPY_PROPDEF_SUBTYPE_NUMBER_ARRAY_DOC \
79 " :arg subtype: Enumerator in :ref:`rna_enum_property_subtype_number_array_items`.\n" \
80 " :type subtype: str\n"
81
84/* -------------------------------------------------------------------- */
124
129 struct {
131 PyObject *get_fn;
132 PyObject *set_fn;
134 PyObject *update_fn;
135
137 union {
139 struct {
141 PyObject *itemf_fn;
144 struct {
146 PyObject *poll_fn;
149 struct {
151 PyObject *search_fn;
153 };
155};
156
157#define BPY_PROP_STORE_PY_DATA_SIZE (sizeof(BPyPropStore::py_data) / sizeof(PyObject *))
158
159#define ASSIGN_PYOBJECT_INCREF(a, b) \
160 { \
161 BLI_assert((a) == nullptr); \
162 Py_INCREF(b); \
163 a = b; \
164 } \
165 ((void)0)
166
171static ListBase g_bpy_prop_store_list = {nullptr, nullptr};
172
174{
175 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
176 if (prop_store == nullptr) {
177 prop_store = static_cast<BPyPropStore *>(MEM_callocN(sizeof(*prop_store), __func__));
178 RNA_def_py_data(prop, prop_store);
180 }
181 return prop_store;
182}
183
188{
189 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
190 if (prop_store == nullptr) {
191 return;
192 }
193
194 PyObject **py_data = (PyObject **)&prop_store->py_data;
195 for (int i = 0; i < BPY_PROP_STORE_PY_DATA_SIZE; i++) {
196 Py_XDECREF(py_data[i]);
197 }
199}
200
203/* -------------------------------------------------------------------- */
212{
213 PyObject_GC_UnTrack(self);
214 Py_CLEAR(self->kw);
215 PyObject_GC_Del(self);
216}
217
218static int bpy_prop_deferred_traverse(BPy_PropDeferred *self, visitproc visit, void *arg)
219{
220 Py_VISIT(self->kw);
221 return 0;
222}
223
225{
226 Py_CLEAR(self->kw);
227 return 0;
228}
229
231{
232 return PyUnicode_FromFormat("<%.200s, %R, %R>", Py_TYPE(self)->tp_name, self->fn, self->kw);
233}
234
241static PyObject *bpy_prop_deferred_call(BPy_PropDeferred * /*self*/,
242 PyObject * /*args*/,
243 PyObject * /*kw*/)
244{
245 /* Dummy value. */
246 Py_RETURN_NONE;
247}
248
249/* Get/Set Items. */
250
255static PyObject *bpy_prop_deferred_function_get(BPy_PropDeferred *self, void * /*closure*/)
256{
257 PyObject *ret = static_cast<PyObject *>(self->fn);
258 Py_IncRef(ret);
259 return ret;
260}
261
266static PyObject *bpy_prop_deferred_keywords_get(BPy_PropDeferred *self, void * /*closure*/)
267{
268 PyObject *ret = self->kw;
269 Py_IncRef(ret);
270 return ret;
271}
272
273static PyGetSetDef bpy_prop_deferred_getset[] = {
274 {"function", (getter)bpy_prop_deferred_function_get, (setter) nullptr, nullptr, nullptr},
275 {"keywords", (getter)bpy_prop_deferred_keywords_get, (setter) nullptr, nullptr, nullptr},
276 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
277};
278
280 /* Wrap. */
281 bpy_prop_deferred_doc,
282 "Intermediate storage for properties before registration.\n"
283 "\n"
284 ".. note::\n"
285 "\n"
286 " This is not part of the stable API and may change between releases.");
287
289 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
290 /*tp_name*/ "_PropertyDeferred",
291 /*tp_basicsize*/ sizeof(BPy_PropDeferred),
292 /*tp_itemsize*/ 0,
293 /*tp_dealloc*/ (destructor)bpy_prop_deferred_dealloc,
294 /*tp_vectorcall_offset*/ 0,
295 /*tp_getattr*/ nullptr,
296 /*tp_setattr*/ nullptr,
297 /*tp_as_async*/ nullptr,
298 /*tp_repr*/ (reprfunc)bpy_prop_deferred_repr,
299 /*tp_as_number*/ nullptr,
300 /*tp_as_sequence*/ nullptr,
301 /*tp_as_mapping*/ nullptr,
302 /*tp_hash*/ nullptr,
303 /*tp_call*/ (ternaryfunc)bpy_prop_deferred_call,
304 /*tp_str*/ nullptr,
305 /*tp_getattro*/ nullptr,
306 /*tp_setattro*/ nullptr,
307 /*tp_as_buffer*/ nullptr,
308 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
309 /*tp_doc*/ bpy_prop_deferred_doc,
310 /*tp_traverse*/ (traverseproc)bpy_prop_deferred_traverse,
311 /*tp_clear*/ (inquiry)bpy_prop_deferred_clear,
312 /*tp_richcompare*/ nullptr,
313 /*tp_weaklistoffset*/ 0,
314 /*tp_iter*/ nullptr,
315 /*tp_iternext*/ nullptr,
316 /*tp_methods*/ nullptr,
317 /*tp_members*/ nullptr,
318 /*tp_getset*/ bpy_prop_deferred_getset,
319 /*tp_base*/ nullptr,
320 /*tp_dict*/ nullptr,
321 /*tp_descr_get*/ nullptr,
322 /*tp_descr_set*/ nullptr,
323 /*tp_dictoffset*/ 0,
324 /*tp_init*/ nullptr,
325 /*tp_alloc*/ nullptr,
326 /*tp_new*/ nullptr,
327 /*tp_free*/ nullptr,
328 /*tp_is_gc*/ nullptr,
329 /*tp_bases*/ nullptr,
330 /*tp_mro*/ nullptr,
331 /*tp_cache*/ nullptr,
332 /*tp_subclasses*/ nullptr,
333 /*tp_weaklist*/ nullptr,
334 /*tp_del*/ nullptr,
335 /*tp_version_tag*/ 0,
336 /*tp_finalize*/ nullptr,
337 /*tp_vectorcall*/ nullptr,
338};
339
340static PyObject *bpy_prop_deferred_data_CreatePyObject(PyObject *fn, PyObject *kw)
341{
343 self->fn = fn;
344 if (kw == nullptr) {
345 kw = PyDict_New();
346 }
347 else {
348 Py_INCREF(kw);
349 }
350 self->kw = kw;
351 BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
352 PyObject_GC_Track(self);
353 return (PyObject *)self;
354}
355
358/* -------------------------------------------------------------------- */
362/* PyObject's */
363static PyObject *pymeth_BoolProperty = nullptr;
364static PyObject *pymeth_BoolVectorProperty = nullptr;
365static PyObject *pymeth_IntProperty = nullptr;
366static PyObject *pymeth_IntVectorProperty = nullptr;
367static PyObject *pymeth_FloatProperty = nullptr;
368static PyObject *pymeth_FloatVectorProperty = nullptr;
369static PyObject *pymeth_StringProperty = nullptr;
370static PyObject *pymeth_EnumProperty = nullptr;
371static PyObject *pymeth_PointerProperty = nullptr;
372static PyObject *pymeth_CollectionProperty = nullptr;
373static PyObject *pymeth_RemoveProperty = nullptr;
374
376{
377 PyObject *self = nullptr;
378 /* first get self */
379 /* operators can store their own instance for later use */
380 if (ptr->data) {
381 void **instance = RNA_struct_instance(ptr);
382
383 if (instance) {
384 if (*instance) {
385 self = static_cast<PyObject *>(*instance);
386 Py_INCREF(self);
387 }
388 }
389 }
390
391 /* in most cases this will run */
392 if (self == nullptr) {
394 }
395
396 return self;
397}
398
399static void bpy_prop_assign_flag(PropertyRNA *prop, const int flag)
400{
401 const int flag_mask = ((PROP_ANIMATABLE) & ~flag);
402
403 if (flag) {
405 }
406
407 if (flag_mask) {
409 }
410}
411
412static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_override)
413{
415}
416
419/* -------------------------------------------------------------------- */
429
433static int bpy_prop_array_length_parse(PyObject *o, void *p)
434{
435 BPyPropArrayLength *array_len_info = static_cast<BPyPropArrayLength *>(p);
436
437 if (PyLong_CheckExact(o)) {
438 int size;
439 if ((size = PyLong_AsLong(o)) == -1) {
440 PyErr_Format(
441 PyExc_ValueError, "expected number or sequence of numbers, got %s", Py_TYPE(o)->tp_name);
442 return 0;
443 }
445 PyErr_Format(
446 PyExc_TypeError, "(size=%d) must be between 1 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
447 return 0;
448 }
449 array_len_info->len_total = size;
450
451 /* Don't use this value. */
452 array_len_info->dims_len = 0;
453 }
454 else {
455 PyObject *seq_fast;
456 if (!(seq_fast = PySequence_Fast(o, "size must be a number of a sequence of numbers"))) {
457 return 0;
458 }
459 const int seq_len = PySequence_Fast_GET_SIZE(seq_fast);
460 if (seq_len < 1 || seq_len > RNA_MAX_ARRAY_DIMENSION) {
461 PyErr_Format(
462 PyExc_TypeError,
463 "(len(size)=%d) length must be between 1 and " STRINGIFY(RNA_MAX_ARRAY_DIMENSION),
464 seq_len);
465 Py_DECREF(seq_fast);
466 return 0;
467 }
468
469 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
470 array_len_info->len_total = 1;
471 for (int i = 0; i < seq_len; i++) {
472 int size;
473 if ((size = PyLong_AsLong(seq_items[i])) == -1) {
474 Py_DECREF(seq_fast);
475 PyErr_Format(PyExc_ValueError,
476 "expected number in sequence, got %s at index %d",
477 Py_TYPE(o)->tp_name,
478 i);
479 return 0;
480 }
482 Py_DECREF(seq_fast);
483 PyErr_Format(PyExc_TypeError,
484 "(size[%d]=%d) must be between 1 and " STRINGIFY(PYRNA_STACK_ARRAY),
485 i,
486 size);
487 return 0;
488 }
489
490 array_len_info->dims[i] = size;
491 array_len_info->dims_len = seq_len;
492 array_len_info->len_total *= size;
493 }
494 }
495 return 1;
496}
497
501static int bpy_prop_array_from_py_with_dims(void *values,
502 size_t values_elem_size,
503 PyObject *py_values,
504 const BPyPropArrayLength *array_len_info,
505 const PyTypeObject *type,
506 const char *error_str)
507{
508 if (array_len_info->dims_len == 0) {
509 return PyC_AsArray(
510 values, values_elem_size, py_values, array_len_info->len_total, type, error_str);
511 }
512 const int *dims = array_len_info->dims;
513 const int dims_len = array_len_info->dims_len;
514 return PyC_AsArray_Multi(values, values_elem_size, py_values, dims, dims_len, type, error_str);
515}
516
518 const BPyPropArrayLength *array_len_info)
519{
520 return ((subtype == PROP_MATRIX) && (array_len_info->dims_len == 2) &&
521 ((array_len_info->dims[0] >= 2) && (array_len_info->dims[0] >= 4)) &&
522 ((array_len_info->dims[1] >= 2) && (array_len_info->dims[1] >= 4)));
523}
524
526 const BPyPropArrayLength *array_len_info)
527{
530}
531
536 const float *values_src,
537 const BPyPropArrayLength *array_len_info)
538{
539 BLI_assert(values_dst != values_src);
540 const int dim0 = array_len_info->dims[0], dim1 = array_len_info->dims[1];
541 BLI_assert(dim0 <= 4 && dim1 <= 4);
542 for (int i = 0; i < dim0; i++) {
543 for (int j = 0; j < dim1; j++) {
544 values_dst[(j * dim0) + i] = values_src[(i * dim1) + j];
545 }
546 }
547}
548
550 const BPyPropArrayLength *array_len_info)
551{
552 const int dim0 = array_len_info->dims[0], dim1 = array_len_info->dims[1];
553 BLI_assert(dim0 <= 4 && dim1 <= 4);
554 float values_orig[4 * 4];
555 memcpy(values_orig, values, sizeof(float) * (dim0 * dim1));
556 bpy_prop_array_matrix_swap_row_column_vn_vn(values, values_orig, array_len_info);
557}
558
561/* -------------------------------------------------------------------- */
567/* callbacks */
569{
570 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
571 PyGILState_STATE gilstate;
572 PyObject *py_func;
573 PyObject *args;
574 PyObject *self;
575 PyObject *ret;
576 const bool is_write_ok = pyrna_write_check();
577
578 BLI_assert(prop_store != nullptr);
579
580 if (!is_write_ok) {
581 pyrna_write_set(true);
582 }
583
584 bpy_context_set(C, &gilstate);
585
586 py_func = prop_store->py_data.update_fn;
587
588 args = PyTuple_New(2);
590 PyTuple_SET_ITEM(args, 0, self);
591
592 PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
593 Py_INCREF(bpy_context_module);
594
595 ret = PyObject_CallObject(py_func, args);
596
597 Py_DECREF(args);
598
599 if (ret == nullptr) {
600 PyC_Err_PrintWithFunc(py_func);
601 }
602 else {
603 if (ret != Py_None) {
604 PyErr_SetString(PyExc_ValueError, "the return value must be None");
605 PyC_Err_PrintWithFunc(py_func);
606 }
607
608 Py_DECREF(ret);
609 }
610
611 bpy_context_clear(C, &gilstate);
612
613 if (!is_write_ok) {
614 pyrna_write_set(false);
615 }
616}
617
620/* -------------------------------------------------------------------- */
625{
626 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
627 PyObject *py_func;
628 PyObject *args;
629 PyObject *self;
630 PyObject *ret;
631 PyGILState_STATE gilstate;
632 bool use_gil;
633 const bool is_write_ok = pyrna_write_check();
634 bool value;
635
636 BLI_assert(prop_store != nullptr);
637
638 if (!is_write_ok) {
639 pyrna_write_set(true);
640 }
641
642 use_gil = true; /* !PyC_IsInterpreterActive(); */
643
644 if (use_gil) {
645 gilstate = PyGILState_Ensure();
646 }
647
648 py_func = prop_store->py_data.get_fn;
649
650 args = PyTuple_New(1);
652 PyTuple_SET_ITEM(args, 0, self);
653
654 ret = PyObject_CallObject(py_func, args);
655
656 Py_DECREF(args);
657
658 if (ret == nullptr) {
659 PyC_Err_PrintWithFunc(py_func);
660 value = false;
661 }
662 else {
663 const int value_i = PyC_Long_AsBool(ret);
664
665 if (value_i == -1 && PyErr_Occurred()) {
666 PyC_Err_PrintWithFunc(py_func);
667 value = false;
668 }
669 else {
670 value = bool(value_i);
671 }
672
673 Py_DECREF(ret);
674 }
675
676 if (use_gil) {
677 PyGILState_Release(gilstate);
678 }
679
680 if (!is_write_ok) {
681 pyrna_write_set(false);
682 }
683
684 return value;
685}
686
687static void bpy_prop_boolean_set_fn(PointerRNA *ptr, PropertyRNA *prop, bool value)
688{
689 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
690 PyObject *py_func;
691 PyObject *args;
692 PyObject *self;
693 PyObject *ret;
694 PyGILState_STATE gilstate;
695 bool use_gil;
696 const bool is_write_ok = pyrna_write_check();
697
698 BLI_assert(prop_store != nullptr);
699
700 if (!is_write_ok) {
701 pyrna_write_set(true);
702 }
703
704 use_gil = true; /* !PyC_IsInterpreterActive(); */
705
706 if (use_gil) {
707 gilstate = PyGILState_Ensure();
708 }
709
710 py_func = prop_store->py_data.set_fn;
711
712 args = PyTuple_New(2);
714 PyTuple_SET_ITEM(args, 0, self);
715
716 PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value));
717
718 ret = PyObject_CallObject(py_func, args);
719
720 Py_DECREF(args);
721
722 if (ret == nullptr) {
723 PyC_Err_PrintWithFunc(py_func);
724 }
725 else {
726 if (ret != Py_None) {
727 PyErr_SetString(PyExc_ValueError, "the return value must be None");
728 PyC_Err_PrintWithFunc(py_func);
729 }
730
731 Py_DECREF(ret);
732 }
733
734 if (use_gil) {
735 PyGILState_Release(gilstate);
736 }
737
738 if (!is_write_ok) {
739 pyrna_write_set(false);
740 }
741}
742
743static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bool *values)
744{
745 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
746 PyObject *py_func;
747 PyObject *args;
748 PyObject *self;
749 PyObject *ret;
750 PyGILState_STATE gilstate;
751 bool use_gil;
752 const bool is_write_ok = pyrna_write_check();
753 bool is_values_set = false;
754 int i, len = RNA_property_array_length(ptr, prop);
755 BPyPropArrayLength array_len_info{};
756 array_len_info.len_total = len;
757 array_len_info.dims_len = RNA_property_array_dimension(ptr, prop, array_len_info.dims);
758
759 BLI_assert(prop_store != nullptr);
760
761 if (!is_write_ok) {
762 pyrna_write_set(true);
763 }
764
765 use_gil = true; /* !PyC_IsInterpreterActive(); */
766
767 if (use_gil) {
768 gilstate = PyGILState_Ensure();
769 }
770
771 py_func = prop_store->py_data.get_fn;
772
773 args = PyTuple_New(1);
775 PyTuple_SET_ITEM(args, 0, self);
776
777 ret = PyObject_CallObject(py_func, args);
778
779 Py_DECREF(args);
780
781 if (ret != nullptr) {
783 sizeof(*values),
784 ret,
785 &array_len_info,
786 &PyBool_Type,
787 "BoolVectorProperty get callback") == -1)
788 {
789 PyC_Err_PrintWithFunc(py_func);
790 }
791 else {
792 is_values_set = true;
793 }
794 Py_DECREF(ret);
795 }
796
797 if (is_values_set == false) {
798 /* This is the flattened length for multi-dimensional arrays. */
799 for (i = 0; i < len; i++) {
800 values[i] = false;
801 }
802 }
803
804 if (use_gil) {
805 PyGILState_Release(gilstate);
806 }
807
808 if (!is_write_ok) {
809 pyrna_write_set(false);
810 }
811}
812
813static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
814{
815 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
816 PyObject *py_func;
817 PyObject *args;
818 PyObject *self;
819 PyObject *ret;
820 PyObject *py_values;
821 PyGILState_STATE gilstate;
822 bool use_gil;
823 const bool is_write_ok = pyrna_write_check();
824 const int len = RNA_property_array_length(ptr, prop);
825 BPyPropArrayLength array_len_info{};
826 array_len_info.len_total = len;
827 array_len_info.dims_len = RNA_property_array_dimension(ptr, prop, array_len_info.dims);
828
829 BLI_assert(prop_store != nullptr);
830
831 if (!is_write_ok) {
832 pyrna_write_set(true);
833 }
834
835 use_gil = true; /* !PyC_IsInterpreterActive(); */
836
837 if (use_gil) {
838 gilstate = PyGILState_Ensure();
839 }
840
841 py_func = prop_store->py_data.set_fn;
842
843 args = PyTuple_New(2);
845 PyTuple_SET_ITEM(args, 0, self);
846
847 if (array_len_info.dims_len == 0) {
848 py_values = PyC_Tuple_PackArray_Bool(values, len);
849 }
850 else {
852 values, array_len_info.dims, array_len_info.dims_len);
853 }
854 PyTuple_SET_ITEM(args, 1, py_values);
855
856 ret = PyObject_CallObject(py_func, args);
857
858 Py_DECREF(args);
859
860 if (ret == nullptr) {
861 PyC_Err_PrintWithFunc(py_func);
862 }
863 else {
864 if (ret != Py_None) {
865 PyErr_SetString(PyExc_ValueError, "the return value must be None");
866 PyC_Err_PrintWithFunc(py_func);
867 }
868
869 Py_DECREF(ret);
870 }
871
872 if (use_gil) {
873 PyGILState_Release(gilstate);
874 }
875
876 if (!is_write_ok) {
877 pyrna_write_set(false);
878 }
879}
880
883/* -------------------------------------------------------------------- */
888{
889 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
890 PyObject *py_func;
891 PyObject *args;
892 PyObject *self;
893 PyObject *ret;
894 PyGILState_STATE gilstate;
895 bool use_gil;
896 const bool is_write_ok = pyrna_write_check();
897 int value;
898
899 BLI_assert(prop_store != nullptr);
900
901 if (!is_write_ok) {
902 pyrna_write_set(true);
903 }
904
905 use_gil = true; /* !PyC_IsInterpreterActive(); */
906
907 if (use_gil) {
908 gilstate = PyGILState_Ensure();
909 }
910
911 py_func = prop_store->py_data.get_fn;
912
913 args = PyTuple_New(1);
915 PyTuple_SET_ITEM(args, 0, self);
916
917 ret = PyObject_CallObject(py_func, args);
918
919 Py_DECREF(args);
920
921 if (ret == nullptr) {
922 PyC_Err_PrintWithFunc(py_func);
923 value = 0.0f;
924 }
925 else {
926 value = PyC_Long_AsI32(ret);
927
928 if (value == -1 && PyErr_Occurred()) {
929 PyC_Err_PrintWithFunc(py_func);
930 value = 0;
931 }
932
933 Py_DECREF(ret);
934 }
935
936 if (use_gil) {
937 PyGILState_Release(gilstate);
938 }
939
940 if (!is_write_ok) {
941 pyrna_write_set(false);
942 }
943
944 return value;
945}
946
947static void bpy_prop_int_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
948{
949 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
950 PyObject *py_func;
951 PyObject *args;
952 PyObject *self;
953 PyObject *ret;
954 PyGILState_STATE gilstate;
955 bool use_gil;
956 const bool is_write_ok = pyrna_write_check();
957
958 BLI_assert(prop_store != nullptr);
959
960 if (!is_write_ok) {
961 pyrna_write_set(true);
962 }
963
964 use_gil = true; /* !PyC_IsInterpreterActive(); */
965
966 if (use_gil) {
967 gilstate = PyGILState_Ensure();
968 }
969
970 py_func = prop_store->py_data.set_fn;
971
972 args = PyTuple_New(2);
974 PyTuple_SET_ITEM(args, 0, self);
975
976 PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
977
978 ret = PyObject_CallObject(py_func, args);
979
980 Py_DECREF(args);
981
982 if (ret == nullptr) {
983 PyC_Err_PrintWithFunc(py_func);
984 }
985 else {
986 if (ret != Py_None) {
987 PyErr_SetString(PyExc_ValueError, "the return value must be None");
988 PyC_Err_PrintWithFunc(py_func);
989 }
990
991 Py_DECREF(ret);
992 }
993
994 if (use_gil) {
995 PyGILState_Release(gilstate);
996 }
997
998 if (!is_write_ok) {
999 pyrna_write_set(false);
1000 }
1001}
1002
1003static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *values)
1004{
1005 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1006 PyObject *py_func;
1007 PyObject *args;
1008 PyObject *self;
1009 PyObject *ret;
1010 PyGILState_STATE gilstate;
1011 bool use_gil;
1012 const bool is_write_ok = pyrna_write_check();
1013 bool is_values_set = false;
1014 int i, len = RNA_property_array_length(ptr, prop);
1015 BPyPropArrayLength array_len_info{};
1016 array_len_info.len_total = len;
1017 array_len_info.dims_len = RNA_property_array_dimension(ptr, prop, array_len_info.dims);
1018
1019 BLI_assert(prop_store != nullptr);
1020
1021 if (!is_write_ok) {
1022 pyrna_write_set(true);
1023 }
1024
1025 use_gil = true; /* !PyC_IsInterpreterActive(); */
1026
1027 if (use_gil) {
1028 gilstate = PyGILState_Ensure();
1029 }
1030
1031 py_func = prop_store->py_data.get_fn;
1032
1033 args = PyTuple_New(1);
1035 PyTuple_SET_ITEM(args, 0, self);
1036
1037 ret = PyObject_CallObject(py_func, args);
1038
1039 Py_DECREF(args);
1040
1041 if (ret != nullptr) {
1043 sizeof(*values),
1044 ret,
1045 &array_len_info,
1046 &PyLong_Type,
1047 "IntVectorProperty get callback") == -1)
1048 {
1049 PyC_Err_PrintWithFunc(py_func);
1050 }
1051 else {
1052 is_values_set = true;
1053 }
1054 Py_DECREF(ret);
1055 }
1056
1057 if (is_values_set == false) {
1058 /* This is the flattened length for multi-dimensional arrays. */
1059 for (i = 0; i < len; i++) {
1060 values[i] = 0;
1061 }
1062 }
1063
1064 if (use_gil) {
1065 PyGILState_Release(gilstate);
1066 }
1067
1068 if (!is_write_ok) {
1069 pyrna_write_set(false);
1070 }
1071}
1072
1073static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1074{
1075 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1076 PyObject *py_func;
1077 PyObject *args;
1078 PyObject *self;
1079 PyObject *ret;
1080 PyObject *py_values;
1081 PyGILState_STATE gilstate;
1082 bool use_gil;
1083 const bool is_write_ok = pyrna_write_check();
1084 const int len = RNA_property_array_length(ptr, prop);
1085 BPyPropArrayLength array_len_info{};
1086 array_len_info.len_total = len;
1087 array_len_info.dims_len = RNA_property_array_dimension(ptr, prop, array_len_info.dims);
1088
1089 BLI_assert(prop_store != nullptr);
1090
1091 if (!is_write_ok) {
1092 pyrna_write_set(true);
1093 }
1094
1095 use_gil = true; /* !PyC_IsInterpreterActive(); */
1096
1097 if (use_gil) {
1098 gilstate = PyGILState_Ensure();
1099 }
1100
1101 py_func = prop_store->py_data.set_fn;
1102
1103 args = PyTuple_New(2);
1105 PyTuple_SET_ITEM(args, 0, self);
1106
1107 if (array_len_info.dims_len == 0) {
1108 py_values = PyC_Tuple_PackArray_I32(values, len);
1109 }
1110 else {
1112 values, array_len_info.dims, array_len_info.dims_len);
1113 }
1114
1115 PyTuple_SET_ITEM(args, 1, py_values);
1116
1117 ret = PyObject_CallObject(py_func, args);
1118
1119 Py_DECREF(args);
1120
1121 if (ret == nullptr) {
1122 PyC_Err_PrintWithFunc(py_func);
1123 }
1124 else {
1125 if (ret != Py_None) {
1126 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1127 PyC_Err_PrintWithFunc(py_func);
1128 }
1129
1130 Py_DECREF(ret);
1131 }
1132
1133 if (use_gil) {
1134 PyGILState_Release(gilstate);
1135 }
1136
1137 if (!is_write_ok) {
1138 pyrna_write_set(false);
1139 }
1140}
1141
1144/* -------------------------------------------------------------------- */
1149{
1150 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1151 PyObject *py_func;
1152 PyObject *args;
1153 PyObject *self;
1154 PyObject *ret;
1155 PyGILState_STATE gilstate;
1156 bool use_gil;
1157 const bool is_write_ok = pyrna_write_check();
1158 float value;
1159
1160 BLI_assert(prop_store != nullptr);
1161
1162 if (!is_write_ok) {
1163 pyrna_write_set(true);
1164 }
1165
1166 use_gil = true; /* !PyC_IsInterpreterActive(); */
1167
1168 if (use_gil) {
1169 gilstate = PyGILState_Ensure();
1170 }
1171
1172 py_func = prop_store->py_data.get_fn;
1173
1174 args = PyTuple_New(1);
1176 PyTuple_SET_ITEM(args, 0, self);
1177
1178 ret = PyObject_CallObject(py_func, args);
1179
1180 Py_DECREF(args);
1181
1182 if (ret == nullptr) {
1183 PyC_Err_PrintWithFunc(py_func);
1184 value = 0.0f;
1185 }
1186 else {
1187 value = PyFloat_AsDouble(ret);
1188
1189 if (value == -1.0f && PyErr_Occurred()) {
1190 PyC_Err_PrintWithFunc(py_func);
1191 value = 0.0f;
1192 }
1193
1194 Py_DECREF(ret);
1195 }
1196
1197 if (use_gil) {
1198 PyGILState_Release(gilstate);
1199 }
1200
1201 if (!is_write_ok) {
1202 pyrna_write_set(false);
1203 }
1204
1205 return value;
1206}
1207
1208static void bpy_prop_float_set_fn(PointerRNA *ptr, PropertyRNA *prop, float value)
1209{
1210 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1211 PyObject *py_func;
1212 PyObject *args;
1213 PyObject *self;
1214 PyObject *ret;
1215 PyGILState_STATE gilstate;
1216 bool use_gil;
1217 const bool is_write_ok = pyrna_write_check();
1218
1219 BLI_assert(prop_store != nullptr);
1220
1221 if (!is_write_ok) {
1222 pyrna_write_set(true);
1223 }
1224
1225 use_gil = true; /* !PyC_IsInterpreterActive(); */
1226
1227 if (use_gil) {
1228 gilstate = PyGILState_Ensure();
1229 }
1230
1231 py_func = prop_store->py_data.set_fn;
1232
1233 args = PyTuple_New(2);
1235 PyTuple_SET_ITEM(args, 0, self);
1236
1237 PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value));
1238
1239 ret = PyObject_CallObject(py_func, args);
1240
1241 Py_DECREF(args);
1242
1243 if (ret == nullptr) {
1244 PyC_Err_PrintWithFunc(py_func);
1245 }
1246 else {
1247 if (ret != Py_None) {
1248 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1249 PyC_Err_PrintWithFunc(py_func);
1250 }
1251
1252 Py_DECREF(ret);
1253 }
1254
1255 if (use_gil) {
1256 PyGILState_Release(gilstate);
1257 }
1258
1259 if (!is_write_ok) {
1260 pyrna_write_set(false);
1261 }
1262}
1263
1264static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, float *values)
1265{
1266 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1267 PyObject *py_func;
1268 PyObject *args;
1269 PyObject *self;
1270 PyObject *ret;
1271 PyGILState_STATE gilstate;
1272 bool use_gil;
1273 const bool is_write_ok = pyrna_write_check();
1274 bool is_values_set = false;
1275 int i, len = RNA_property_array_length(ptr, prop);
1276 BPyPropArrayLength array_len_info{};
1277 array_len_info.len_total = len;
1278 array_len_info.dims_len = RNA_property_array_dimension(ptr, prop, array_len_info.dims);
1279
1280 BLI_assert(prop_store != nullptr);
1281
1282 if (!is_write_ok) {
1283 pyrna_write_set(true);
1284 }
1285
1286 use_gil = true; /* !PyC_IsInterpreterActive(); */
1287
1288 if (use_gil) {
1289 gilstate = PyGILState_Ensure();
1290 }
1291
1292 py_func = prop_store->py_data.get_fn;
1293
1294 args = PyTuple_New(1);
1296 PyTuple_SET_ITEM(args, 0, self);
1297
1298 ret = PyObject_CallObject(py_func, args);
1299
1300 Py_DECREF(args);
1301
1302 if (ret != nullptr) {
1304 sizeof(*values),
1305 ret,
1306 &array_len_info,
1307 &PyFloat_Type,
1308 "FloatVectorProperty get callback") == -1)
1309 {
1310 PyC_Err_PrintWithFunc(py_func);
1311 }
1312 else {
1313 /* Only for float types. */
1314 if (bpy_prop_array_is_matrix_compatible(prop, &array_len_info)) {
1315 bpy_prop_array_matrix_swap_row_column_vn(values, &array_len_info);
1316 }
1317 is_values_set = true;
1318 }
1319 Py_DECREF(ret);
1320 }
1321
1322 if (is_values_set == false) {
1323 /* This is the flattened length for multi-dimensional arrays. */
1324 for (i = 0; i < len; i++) {
1325 values[i] = 0.0f;
1326 }
1327 }
1328
1329 if (use_gil) {
1330 PyGILState_Release(gilstate);
1331 }
1332
1333 if (!is_write_ok) {
1334 pyrna_write_set(false);
1335 }
1336}
1337
1338static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1339{
1340 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1341 PyObject *py_func;
1342 PyObject *args;
1343 PyObject *self;
1344 PyObject *ret;
1345 PyObject *py_values;
1346 PyGILState_STATE gilstate;
1347 bool use_gil;
1348 const bool is_write_ok = pyrna_write_check();
1349 const int len = RNA_property_array_length(ptr, prop);
1350 BPyPropArrayLength array_len_info{};
1351 array_len_info.len_total = len;
1352 array_len_info.dims_len = RNA_property_array_dimension(ptr, prop, array_len_info.dims);
1353
1354 BLI_assert(prop_store != nullptr);
1355
1356 if (!is_write_ok) {
1357 pyrna_write_set(true);
1358 }
1359
1360 use_gil = true; /* !PyC_IsInterpreterActive(); */
1361
1362 if (use_gil) {
1363 gilstate = PyGILState_Ensure();
1364 }
1365
1366 py_func = prop_store->py_data.set_fn;
1367
1368 args = PyTuple_New(2);
1370 PyTuple_SET_ITEM(args, 0, self);
1371
1372 if (array_len_info.dims_len == 0) {
1373 py_values = PyC_Tuple_PackArray_F32(values, len);
1374 }
1375 else {
1376 /* No need for matrix column/row swapping here unless the matrix data is read directly. */
1378 values, array_len_info.dims, array_len_info.dims_len);
1379 }
1380 PyTuple_SET_ITEM(args, 1, py_values);
1381
1382 ret = PyObject_CallObject(py_func, args);
1383
1384 Py_DECREF(args);
1385
1386 if (ret == nullptr) {
1387 PyC_Err_PrintWithFunc(py_func);
1388 }
1389 else {
1390 if (ret != Py_None) {
1391 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1392 PyC_Err_PrintWithFunc(py_func);
1393 }
1394
1395 Py_DECREF(ret);
1396 }
1397
1398 if (use_gil) {
1399 PyGILState_Release(gilstate);
1400 }
1401
1402 if (!is_write_ok) {
1403 pyrna_write_set(false);
1404 }
1405}
1406
1409/* -------------------------------------------------------------------- */
1413static void bpy_prop_string_get_fn(PointerRNA *ptr, PropertyRNA *prop, char *value)
1414{
1415 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1416 PyObject *py_func;
1417 PyObject *args;
1418 PyObject *self;
1419 PyObject *ret;
1420 PyGILState_STATE gilstate;
1421 bool use_gil;
1422 const bool is_write_ok = pyrna_write_check();
1423
1424 BLI_assert(prop_store != nullptr);
1425
1426 if (!is_write_ok) {
1427 pyrna_write_set(true);
1428 }
1429
1430 use_gil = true; /* !PyC_IsInterpreterActive(); */
1431
1432 if (use_gil) {
1433 gilstate = PyGILState_Ensure();
1434 }
1435
1436 py_func = prop_store->py_data.get_fn;
1437
1438 args = PyTuple_New(1);
1440 PyTuple_SET_ITEM(args, 0, self);
1441
1442 ret = PyObject_CallObject(py_func, args);
1443
1444 Py_DECREF(args);
1445
1446 if (ret == nullptr) {
1447 PyC_Err_PrintWithFunc(py_func);
1448 value[0] = '\0';
1449 }
1450 else if (!PyUnicode_Check(ret)) {
1451 PyErr_Format(
1452 PyExc_TypeError, "return value must be a string, not %.200s", Py_TYPE(ret)->tp_name);
1453 PyC_Err_PrintWithFunc(py_func);
1454 value[0] = '\0';
1455 Py_DECREF(ret);
1456 }
1457 else {
1458 Py_ssize_t length;
1459 const char *buffer = PyUnicode_AsUTF8AndSize(ret, &length);
1460 memcpy(value, buffer, length + 1);
1461 Py_DECREF(ret);
1462 }
1463
1464 if (use_gil) {
1465 PyGILState_Release(gilstate);
1466 }
1467
1468 if (!is_write_ok) {
1469 pyrna_write_set(false);
1470 }
1471}
1472
1474{
1475 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1476 PyObject *py_func;
1477 PyObject *args;
1478 PyObject *self;
1479 PyObject *ret;
1480 PyGILState_STATE gilstate;
1481 bool use_gil;
1482 const bool is_write_ok = pyrna_write_check();
1483 int length;
1484
1485 BLI_assert(prop_store != nullptr);
1486
1487 if (!is_write_ok) {
1488 pyrna_write_set(true);
1489 }
1490
1491 use_gil = true; /* !PyC_IsInterpreterActive(); */
1492
1493 if (use_gil) {
1494 gilstate = PyGILState_Ensure();
1495 }
1496
1497 py_func = prop_store->py_data.get_fn;
1498
1499 args = PyTuple_New(1);
1501 PyTuple_SET_ITEM(args, 0, self);
1502
1503 ret = PyObject_CallObject(py_func, args);
1504
1505 Py_DECREF(args);
1506
1507 if (ret == nullptr) {
1508 PyC_Err_PrintWithFunc(py_func);
1509 length = 0;
1510 }
1511 else if (!PyUnicode_Check(ret)) {
1512 PyErr_Format(
1513 PyExc_TypeError, "return value must be a string, not %.200s", Py_TYPE(ret)->tp_name);
1514 PyC_Err_PrintWithFunc(py_func);
1515 length = 0;
1516 Py_DECREF(ret);
1517 }
1518 else {
1519 Py_ssize_t length_ssize = 0;
1520 PyUnicode_AsUTF8AndSize(ret, &length_ssize);
1521 length = length_ssize;
1522 Py_DECREF(ret);
1523 }
1524
1525 if (use_gil) {
1526 PyGILState_Release(gilstate);
1527 }
1528
1529 if (!is_write_ok) {
1530 pyrna_write_set(false);
1531 }
1532
1533 return length;
1534}
1535
1536static void bpy_prop_string_set_fn(PointerRNA *ptr, PropertyRNA *prop, const char *value)
1537{
1538 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1539 PyObject *py_func;
1540 PyObject *args;
1541 PyObject *self;
1542 PyObject *ret;
1543 PyGILState_STATE gilstate;
1544 bool use_gil;
1545 const bool is_write_ok = pyrna_write_check();
1546 PyObject *py_value;
1547
1548 BLI_assert(prop_store != nullptr);
1549
1550 if (!is_write_ok) {
1551 pyrna_write_set(true);
1552 }
1553
1554 use_gil = true; /* !PyC_IsInterpreterActive(); */
1555
1556 if (use_gil) {
1557 gilstate = PyGILState_Ensure();
1558 }
1559
1560 py_func = prop_store->py_data.set_fn;
1561
1562 args = PyTuple_New(2);
1564 PyTuple_SET_ITEM(args, 0, self);
1565
1566 py_value = PyUnicode_FromString(value);
1567 if (!py_value) {
1568 PyErr_SetString(PyExc_ValueError, "the return value must be a string");
1569 PyC_Err_PrintWithFunc(py_func);
1570 }
1571 else {
1572 PyTuple_SET_ITEM(args, 1, py_value);
1573 }
1574
1575 ret = PyObject_CallObject(py_func, args);
1576
1577 Py_DECREF(args);
1578
1579 if (ret == nullptr) {
1580 PyC_Err_PrintWithFunc(py_func);
1581 }
1582 else {
1583 if (ret != Py_None) {
1584 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1585 PyC_Err_PrintWithFunc(py_func);
1586 }
1587
1588 Py_DECREF(ret);
1589 }
1590
1591 if (use_gil) {
1592 PyGILState_Release(gilstate);
1593 }
1594
1595 if (!is_write_ok) {
1596 pyrna_write_set(false);
1597 }
1598}
1599
1601 PyObject *py_func,
1602 PyObject *item,
1604{
1605 const char *text;
1606 const char *info = nullptr;
1607
1608 if (PyTuple_CheckExact(item)) {
1609 /* Positional only. */
1610 static const char *_keywords[] = {
1611 "",
1612 "",
1613 nullptr,
1614 };
1615 static _PyArg_Parser _parser = {
1617 "s" /* `text` */
1618 "s" /* `info` */
1619 ":search",
1620 _keywords,
1621 nullptr,
1622 };
1623 if (!_PyArg_ParseTupleAndKeywordsFast(item, nullptr, &_parser, &text, &info)) {
1624 PyC_Err_PrintWithFunc(py_func);
1625 return false;
1626 }
1627 }
1628 else {
1629 text = PyUnicode_AsUTF8(item);
1630 if (UNLIKELY(text == nullptr)) {
1631 PyErr_Clear();
1632 PyErr_Format(PyExc_TypeError,
1633 "expected sequence of strings or tuple pairs of strings, not %.200s",
1634 Py_TYPE(item)->tp_name);
1635 PyC_Err_PrintWithFunc(py_func);
1636 return false;
1637 }
1638 }
1639
1640 StringPropertySearchVisitParams visit_params{};
1641 visit_params.text = text;
1642 visit_params.info = info ? info : "";
1643 visit_fn(visit_params);
1644 return true;
1645}
1646
1648 const bContext *C,
1649 PointerRNA *ptr,
1650 PropertyRNA *prop,
1651 const char *edit_text,
1653{
1654 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1655 PyObject *py_func;
1656 PyObject *args;
1657 PyObject *self;
1658 PyObject *ret;
1659 PyGILState_STATE gilstate;
1660 PyObject *py_edit_text;
1661
1662 BLI_assert(prop_store != nullptr);
1663
1664 if (C) {
1665 bpy_context_set((bContext *)C, &gilstate);
1666 }
1667 else {
1668 gilstate = PyGILState_Ensure();
1669 }
1670
1671 py_func = prop_store->py_data.string_data.search_fn;
1672
1673 args = PyTuple_New(3);
1675 PyTuple_SET_ITEM(args, 0, self);
1676
1677 Py_INCREF(bpy_context_module);
1678 PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
1679
1680 py_edit_text = PyUnicode_FromString(edit_text);
1681 PyTuple_SET_ITEM(args, 2, py_edit_text);
1682
1683 ret = PyObject_CallObject(py_func, args);
1684
1685 Py_DECREF(args);
1686
1687 if (ret == nullptr) {
1688 PyC_Err_PrintWithFunc(py_func);
1689 }
1690 else {
1691 if (PyIter_Check(ret)) {
1692 /* Iterators / generator types. */
1693 PyObject *it;
1694 PyObject *(*iternext)(PyObject *);
1695 it = PyObject_GetIter(ret);
1696 if (it == nullptr) {
1697 PyC_Err_PrintWithFunc(py_func);
1698 }
1699 else {
1700 iternext = *Py_TYPE(it)->tp_iternext;
1701 for (;;) {
1702 PyObject *py_text = iternext(it);
1703 if (py_text == nullptr) {
1704 break;
1705 }
1706 const bool ok = bpy_prop_string_visit_fn_call(py_func, py_text, visit_fn);
1707 Py_DECREF(py_text);
1708 if (!ok) {
1709 break;
1710 }
1711 }
1712 Py_DECREF(it);
1713 if (PyErr_Occurred()) {
1714 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
1715 PyErr_Clear();
1716 }
1717 else {
1718 PyC_Err_PrintWithFunc(py_func);
1719 }
1720 }
1721 }
1722 }
1723 else {
1724 /* Sequence (typically list/tuple). */
1725 PyObject *ret_fast = PySequence_Fast(
1726 ret,
1727 "StringProperty(...): "
1728 "return value from search callback was not a sequence, iterator or generator");
1729 if (ret_fast == nullptr) {
1730 PyC_Err_PrintWithFunc(py_func);
1731 }
1732 else {
1733 const Py_ssize_t ret_num = PySequence_Fast_GET_SIZE(ret_fast);
1734 PyObject **ret_fast_items = PySequence_Fast_ITEMS(ret_fast);
1735 for (Py_ssize_t i = 0; i < ret_num; i++) {
1736 const bool ok = bpy_prop_string_visit_fn_call(py_func, ret_fast_items[i], visit_fn);
1737 if (!ok) {
1738 break;
1739 }
1740 }
1741 Py_DECREF(ret_fast);
1742 }
1743 }
1744
1745 Py_DECREF(ret);
1746 }
1747
1748 if (C) {
1749 bpy_context_clear((bContext *)C, &gilstate);
1750 }
1751 else {
1752 PyGILState_Release(gilstate);
1753 }
1754}
1755
1758/* -------------------------------------------------------------------- */
1763{
1764 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1765 PyObject *py_self;
1766 PyObject *py_candidate;
1767 PyObject *py_func;
1768 PyObject *args;
1769 PyObject *ret;
1770 bool result;
1771 const int is_write_ok = pyrna_write_check();
1772 const PyGILState_STATE gilstate = PyGILState_Ensure();
1773
1774 BLI_assert(self != nullptr);
1775
1776 py_self = pyrna_struct_as_instance(self);
1777 py_candidate = pyrna_struct_as_instance(&candidate);
1778 py_func = prop_store->py_data.pointer_data.poll_fn;
1779
1780 if (!is_write_ok) {
1781 pyrna_write_set(true);
1782 }
1783
1784 args = PyTuple_New(2);
1785 PyTuple_SET_ITEM(args, 0, py_self);
1786 PyTuple_SET_ITEM(args, 1, py_candidate);
1787
1788 ret = PyObject_CallObject(py_func, args);
1789
1790 Py_DECREF(args);
1791
1792 if (ret == nullptr) {
1793 PyC_Err_PrintWithFunc(py_func);
1794 result = false;
1795 }
1796 else {
1797 result = PyObject_IsTrue(ret);
1798 Py_DECREF(ret);
1799 }
1800
1801 PyGILState_Release(gilstate);
1802 if (!is_write_ok) {
1803 pyrna_write_set(false);
1804 }
1805
1806 return result;
1807}
1808
1811/* -------------------------------------------------------------------- */
1816{
1817 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1818 PyObject *py_func;
1819 PyObject *args;
1820 PyObject *self;
1821 PyObject *ret;
1822 PyGILState_STATE gilstate;
1823 bool use_gil;
1824 const bool is_write_ok = pyrna_write_check();
1825 int value;
1826
1827 BLI_assert(prop_store != nullptr);
1828
1829 if (!is_write_ok) {
1830 pyrna_write_set(true);
1831 }
1832
1833 use_gil = true; /* !PyC_IsInterpreterActive(); */
1834
1835 if (use_gil) {
1836 gilstate = PyGILState_Ensure();
1837 }
1838
1839 py_func = prop_store->py_data.get_fn;
1840
1841 args = PyTuple_New(1);
1843 PyTuple_SET_ITEM(args, 0, self);
1844
1845 ret = PyObject_CallObject(py_func, args);
1846
1847 Py_DECREF(args);
1848
1849 if (ret == nullptr) {
1850 PyC_Err_PrintWithFunc(py_func);
1851 value = RNA_property_enum_get_default(ptr, prop);
1852 }
1853 else {
1854 value = PyC_Long_AsI32(ret);
1855
1856 if (value == -1 && PyErr_Occurred()) {
1857 PyC_Err_PrintWithFunc(py_func);
1858 value = RNA_property_enum_get_default(ptr, prop);
1859 }
1860
1861 Py_DECREF(ret);
1862 }
1863
1864 if (use_gil) {
1865 PyGILState_Release(gilstate);
1866 }
1867
1868 if (!is_write_ok) {
1869 pyrna_write_set(false);
1870 }
1871
1872 return value;
1873}
1874
1875static void bpy_prop_enum_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
1876{
1877 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1878 PyObject *py_func;
1879 PyObject *args;
1880 PyObject *self;
1881 PyObject *ret;
1882 PyGILState_STATE gilstate;
1883 bool use_gil;
1884 const bool is_write_ok = pyrna_write_check();
1885
1886 BLI_assert(prop_store != nullptr);
1887
1888 if (!is_write_ok) {
1889 pyrna_write_set(true);
1890 }
1891
1892 use_gil = true; /* !PyC_IsInterpreterActive(); */
1893
1894 if (use_gil) {
1895 gilstate = PyGILState_Ensure();
1896 }
1897
1898 py_func = prop_store->py_data.set_fn;
1899
1900 args = PyTuple_New(2);
1902 PyTuple_SET_ITEM(args, 0, self);
1903
1904 PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
1905
1906 ret = PyObject_CallObject(py_func, args);
1907
1908 Py_DECREF(args);
1909
1910 if (ret == nullptr) {
1911 PyC_Err_PrintWithFunc(py_func);
1912 }
1913 else {
1914 if (ret != Py_None) {
1915 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1916 PyC_Err_PrintWithFunc(py_func);
1917 }
1918
1919 Py_DECREF(ret);
1920 }
1921
1922 if (use_gil) {
1923 PyGILState_Release(gilstate);
1924 }
1925
1926 if (!is_write_ok) {
1927 pyrna_write_set(false);
1928 }
1929}
1930
1931/* utility function we need for parsing int's in an if statement */
1932static bool py_long_as_int(PyObject *py_long, int *r_int)
1933{
1934 if (PyLong_CheckExact(py_long)) {
1935 *r_int = int(PyLong_AS_LONG(py_long));
1936 return true;
1937 }
1938
1939 return false;
1940}
1941
1942#ifdef USE_ENUM_COPY_STRINGS
1943/* copies orig to buf, then sets orig to buf, returns copy length */
1944static size_t strswapbufcpy(char *buf, const char **orig)
1945{
1946 const char *src = *orig;
1947 char *dst = buf;
1948 size_t i = 0;
1949 *orig = buf;
1950 while ((*dst = *src)) {
1951 dst++;
1952 src++;
1953 i++;
1954 }
1955 return i + 1; /* include '\0' */
1956}
1957#endif
1958
1959static int icon_id_from_name(const char *name)
1960{
1961 const EnumPropertyItem *item;
1962 int id;
1963
1964 if (name[0]) {
1965 for (item = rna_enum_icon_items, id = 0; item->identifier; item++, id++) {
1966 if (STREQ(item->name, name)) {
1967 return item->value;
1968 }
1969 }
1970 }
1971
1972 return 0;
1973}
1974
1975static const EnumPropertyItem *enum_items_from_py(PyObject *seq_fast,
1976 const bool is_enum_flag,
1977 PyObject *default_py,
1978 int *r_default_value)
1979{
1980 EnumPropertyItem *items;
1981 PyObject *item;
1982 const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
1983 PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
1984 int i;
1985#ifdef USE_ENUM_COPY_STRINGS
1986 Py_ssize_t totbuf = 0;
1987#endif
1988 short default_used = 0;
1989 const char *default_str_cmp = nullptr;
1990 int default_int_cmp = 0;
1991
1992 if (is_enum_flag) {
1993 if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
1994 PyErr_SetString(PyExc_TypeError,
1995 "EnumProperty(...): maximum " STRINGIFY(
1996 RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property");
1997 return nullptr;
1998 }
1999 if (default_py && !PySet_Check(default_py)) {
2000 PyErr_Format(PyExc_TypeError,
2001 "EnumProperty(...): default option must be a 'set' "
2002 "type when ENUM_FLAG is enabled, not a '%.200s'",
2003 Py_TYPE(default_py)->tp_name);
2004 return nullptr;
2005 }
2006 }
2007 else {
2008 if (default_py) {
2009 if (!py_long_as_int(default_py, &default_int_cmp)) {
2010 default_str_cmp = PyUnicode_AsUTF8(default_py);
2011 if (default_str_cmp == nullptr) {
2012 PyErr_Format(PyExc_TypeError,
2013 "EnumProperty(...): default option must be a 'str' or 'int' "
2014 "type when ENUM_FLAG is disabled, not a '%.200s'",
2015 Py_TYPE(default_py)->tp_name);
2016 return nullptr;
2017 }
2018 }
2019 }
2020 }
2021
2022 /* blank value */
2023 *r_default_value = 0;
2024
2025 items = static_cast<EnumPropertyItem *>(
2026 MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"));
2027
2028 for (i = 0; i < seq_len; i++) {
2029 EnumPropertyItem tmp = {0, "", 0, "", ""};
2030 const char *tmp_icon = nullptr;
2031 Py_ssize_t item_size;
2032 Py_ssize_t id_str_len;
2033 Py_ssize_t name_str_len;
2034 Py_ssize_t desc_str_len;
2035
2036 item = seq_fast_items[i];
2037
2038 if (PyTuple_CheckExact(item) && (item_size = PyTuple_GET_SIZE(item)) &&
2039 (item_size >= 3 && item_size <= 5) &&
2040 (tmp.identifier = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 0), &id_str_len)) &&
2041 (tmp.name = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 1), &name_str_len)) &&
2042 (tmp.description = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 2), &desc_str_len)) &&
2043 /* TODO: number isn't ensured to be unique from the script author. */
2044 (item_size != 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value)) &&
2045 (item_size != 5 || ((py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.icon) ||
2046 (tmp_icon = PyUnicode_AsUTF8(PyTuple_GET_ITEM(item, 3)))) &&
2047 py_long_as_int(PyTuple_GET_ITEM(item, 4), &tmp.value))))
2048 {
2049 if (is_enum_flag) {
2050 if (item_size < 4) {
2051 tmp.value = 1 << i;
2052 }
2053
2054 if (default_py && PySet_Contains(default_py, PyTuple_GET_ITEM(item, 0))) {
2055 *r_default_value |= tmp.value;
2056 default_used++;
2057 }
2058 }
2059 else {
2060 if (item_size < 4) {
2061 tmp.value = i;
2062 }
2063
2064 if (default_py && default_used == 0) {
2065 if ((default_str_cmp != nullptr && STREQ(default_str_cmp, tmp.identifier)) ||
2066 (default_str_cmp == nullptr && default_int_cmp == tmp.value))
2067 {
2068 *r_default_value = tmp.value;
2069 default_used++; /* only ever 1 */
2070 }
2071 }
2072 }
2073
2074 if (tmp_icon) {
2075 tmp.icon = icon_id_from_name(tmp_icon);
2076 }
2077
2078 items[i] = tmp;
2079
2080#ifdef USE_ENUM_COPY_STRINGS
2081 /* Calculate combine string length. */
2082 totbuf += id_str_len + name_str_len + desc_str_len + 3; /* 3 is for '\0's */
2083#endif
2084 }
2085 else if (item == Py_None) {
2086 /* Only set since the rest is cleared. */
2087 items[i].identifier = "";
2088 }
2089 else {
2090 MEM_freeN(items);
2091 PyErr_SetString(PyExc_TypeError,
2092 "EnumProperty(...): expected a tuple containing "
2093 "(identifier, name, description) and optionally an "
2094 "icon name and unique number");
2095 return nullptr;
2096 }
2097 }
2098
2099 if (is_enum_flag) {
2100 /* strict check that all set members were used */
2101 if (default_py && default_used != PySet_GET_SIZE(default_py)) {
2102 MEM_freeN(items);
2103
2104 PyErr_Format(PyExc_TypeError,
2105 "EnumProperty(..., default={...}): set has %d unused member(s)",
2106 PySet_GET_SIZE(default_py) - default_used);
2107 return nullptr;
2108 }
2109 }
2110 else {
2111 if (default_py && default_used == 0) {
2112 MEM_freeN(items);
2113
2114 if (default_str_cmp) {
2115 PyErr_Format(PyExc_TypeError,
2116 "EnumProperty(..., default=\'%s\'): not found in enum members",
2117 default_str_cmp);
2118 }
2119 else {
2120 PyErr_Format(PyExc_TypeError,
2121 "EnumProperty(..., default=%d): not found in enum members",
2122 default_int_cmp);
2123 }
2124 return nullptr;
2125 }
2126 }
2127
2128#ifdef USE_ENUM_COPY_STRINGS
2129 /* This would all work perfectly _but_ the python strings may be freed immediately after use,
2130 * so we need to duplicate them, ugh. annoying because it works most of the time without this. */
2131 {
2132 EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) +
2133 (sizeof(char) * totbuf),
2134 "enum_items_from_py2");
2135 EnumPropertyItem *items_ptr = items_dup;
2136 char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
2137 memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
2138 for (i = 0; i < seq_len; i++, items_ptr++) {
2139 buf += strswapbufcpy(buf, &items_ptr->identifier);
2140 buf += strswapbufcpy(buf, &items_ptr->name);
2141 buf += strswapbufcpy(buf, &items_ptr->description);
2142 }
2143 MEM_freeN(items);
2144 items = items_dup;
2145 }
2146/* end string duplication */
2147#endif
2148
2149 return items;
2150}
2151
2153 PointerRNA *ptr,
2154 PropertyRNA *prop,
2155 bool *r_free)
2156{
2157 PyGILState_STATE gilstate;
2158 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2159 PyObject *py_func = prop_store->py_data.enum_data.itemf_fn;
2160 PyObject *self = nullptr;
2161 PyObject *args;
2162 PyObject *items; /* returned from the function call */
2163
2164 const EnumPropertyItem *eitems = nullptr;
2165 int err = 0;
2166
2167 if (C) {
2168 bpy_context_set(C, &gilstate);
2169 }
2170 else {
2171 gilstate = PyGILState_Ensure();
2172 }
2173
2174 args = PyTuple_New(2);
2176 PyTuple_SET_ITEM(args, 0, self);
2177
2178 /* now get the context */
2179 if (C) {
2180 PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
2181 Py_INCREF(bpy_context_module);
2182 }
2183 else {
2184 PyTuple_SET_ITEM(args, 1, Py_None);
2185 Py_INCREF(Py_None);
2186 }
2187
2188 items = PyObject_CallObject(py_func, args);
2189
2190 Py_DECREF(args);
2191
2192 if (items == nullptr) {
2193 err = -1;
2194 }
2195 else {
2196 PyObject *items_fast;
2197 int default_value_dummy = 0;
2198
2199 if (!(items_fast = PySequence_Fast(items,
2200 "EnumProperty(...): "
2201 "return value from the callback was not a sequence")))
2202 {
2203 err = -1;
2204 }
2205 else {
2206 eitems = enum_items_from_py(items_fast,
2207 (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0,
2208 nullptr,
2209 &default_value_dummy);
2210
2211 Py_DECREF(items_fast);
2212
2213 if (!eitems) {
2214 err = -1;
2215 }
2216 }
2217
2218 Py_DECREF(items);
2219 }
2220
2221 if (err != -1) { /* worked */
2222 *r_free = true;
2223 }
2224 else {
2225 PyC_Err_PrintWithFunc(py_func);
2226
2228 }
2229
2230 if (C) {
2231 bpy_context_clear(C, &gilstate);
2232 }
2233 else {
2234 PyGILState_Release(gilstate);
2235 }
2236
2237 return eitems;
2238}
2239
2240static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
2241{
2242 if (py_func && py_func != Py_None) {
2243 if (!PyFunction_Check(py_func)) {
2244 PyErr_Format(PyExc_TypeError,
2245 "%s keyword: expected a function type, not a %.200s",
2246 keyword,
2247 Py_TYPE(py_func)->tp_name);
2248 return -1;
2249 }
2250
2251 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
2252 if (f_code->co_argcount != argcount) {
2253 PyErr_Format(PyExc_TypeError,
2254 "%s keyword: expected a function taking %d arguments, not %d",
2255 keyword,
2256 argcount,
2257 f_code->co_argcount);
2258 return -1;
2259 }
2260 }
2261
2262 return 0;
2263}
2264
2267/* -------------------------------------------------------------------- */
2271static void bpy_prop_callback_assign_update(PropertyRNA *prop, PyObject *update_fn)
2272{
2273 /* assume this is already checked for type and arg length */
2274 if (update_fn && update_fn != Py_None) {
2275 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2276
2278 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.update_fn, update_fn);
2279 }
2280}
2281
2282static void bpy_prop_callback_assign_pointer(PropertyRNA *prop, PyObject *poll_fn)
2283{
2284 if (poll_fn && poll_fn != Py_None) {
2285 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2286
2287 RNA_def_property_poll_runtime(prop, reinterpret_cast<const void *>(bpy_prop_pointer_poll_fn));
2288 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.pointer_data.poll_fn, poll_fn);
2289 }
2290}
2291
2292static void bpy_prop_callback_assign_boolean(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
2293{
2294 BooleanPropertyGetFunc rna_get_fn = nullptr;
2295 BooleanPropertySetFunc rna_set_fn = nullptr;
2296
2297 if (get_fn && get_fn != Py_None) {
2298 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2299
2300 rna_get_fn = bpy_prop_boolean_get_fn;
2301 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2302 }
2303
2304 if (set_fn && set_fn != Py_None) {
2305 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2306
2307 rna_set_fn = bpy_prop_boolean_set_fn;
2308 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2309 }
2310
2311 RNA_def_property_boolean_funcs_runtime(prop, rna_get_fn, rna_set_fn);
2312}
2313
2315 PyObject *get_fn,
2316 PyObject *set_fn)
2317{
2318 BooleanArrayPropertyGetFunc rna_get_fn = nullptr;
2319 BooleanArrayPropertySetFunc rna_set_fn = nullptr;
2320
2321 if (get_fn && get_fn != Py_None) {
2322 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2323
2324 rna_get_fn = bpy_prop_boolean_array_get_fn;
2325 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2326 }
2327
2328 if (set_fn && set_fn != Py_None) {
2329 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2330
2331 rna_set_fn = bpy_prop_boolean_array_set_fn;
2332 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2333 }
2334
2335 RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_fn, rna_set_fn);
2336}
2337
2338static void bpy_prop_callback_assign_int(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
2339{
2340 IntPropertyGetFunc rna_get_fn = nullptr;
2341 IntPropertySetFunc rna_set_fn = nullptr;
2342
2343 if (get_fn && get_fn != Py_None) {
2344 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2345
2346 rna_get_fn = bpy_prop_int_get_fn;
2347 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2348 }
2349
2350 if (set_fn && set_fn != Py_None) {
2351 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2352
2353 rna_set_fn = bpy_prop_int_set_fn;
2354 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2355 }
2356
2357 RNA_def_property_int_funcs_runtime(prop, rna_get_fn, rna_set_fn, nullptr);
2358}
2359
2361 PyObject *get_fn,
2362 PyObject *set_fn)
2363{
2364 IntArrayPropertyGetFunc rna_get_fn = nullptr;
2365 IntArrayPropertySetFunc rna_set_fn = nullptr;
2366
2367 if (get_fn && get_fn != Py_None) {
2368 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2369
2370 rna_get_fn = bpy_prop_int_array_get_fn;
2371 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2372 }
2373
2374 if (set_fn && set_fn != Py_None) {
2375 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2376
2377 rna_set_fn = bpy_prop_int_array_set_fn;
2378 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2379 }
2380
2381 RNA_def_property_int_array_funcs_runtime(prop, rna_get_fn, rna_set_fn, nullptr);
2382}
2383
2384static void bpy_prop_callback_assign_float(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
2385{
2386 FloatPropertyGetFunc rna_get_fn = nullptr;
2387 FloatPropertySetFunc rna_set_fn = nullptr;
2388
2389 if (get_fn && get_fn != Py_None) {
2390 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2391
2392 rna_get_fn = bpy_prop_float_get_fn;
2393 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2394 }
2395
2396 if (set_fn && set_fn != Py_None) {
2397 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2398
2399 rna_set_fn = bpy_prop_float_set_fn;
2400 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2401 }
2402
2403 RNA_def_property_float_funcs_runtime(prop, rna_get_fn, rna_set_fn, nullptr);
2404}
2405
2407 PyObject *get_fn,
2408 PyObject *set_fn)
2409{
2410 FloatArrayPropertyGetFunc rna_get_fn = nullptr;
2411 FloatArrayPropertySetFunc rna_set_fn = nullptr;
2412
2413 if (get_fn && get_fn != Py_None) {
2414 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2415
2416 rna_get_fn = bpy_prop_float_array_get_fn;
2417 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2418 }
2419
2420 if (set_fn && set_fn != Py_None) {
2421 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2422
2423 rna_set_fn = bpy_prop_float_array_set_fn;
2424 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2425 }
2426
2427 RNA_def_property_float_array_funcs_runtime(prop, rna_get_fn, rna_set_fn, nullptr);
2428}
2429
2431 PyObject *get_fn,
2432 PyObject *set_fn,
2433 PyObject *search_fn,
2434 const eStringPropertySearchFlag search_flag)
2435{
2436 StringPropertyGetFunc rna_get_fn = nullptr;
2437 StringPropertyLengthFunc rna_length_fn = nullptr;
2438 StringPropertySetFunc rna_set_fn = nullptr;
2439 StringPropertySearchFunc rna_search_fn = nullptr;
2440
2441 if (get_fn && get_fn != Py_None) {
2442 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2443
2444 rna_get_fn = bpy_prop_string_get_fn;
2445 rna_length_fn = bpy_prop_string_length_fn;
2446 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2447 }
2448
2449 if (set_fn && set_fn != Py_None) {
2450 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2451
2452 rna_set_fn = bpy_prop_string_set_fn;
2453 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2454 }
2455 if (search_fn) {
2456 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2457
2459 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.string_data.search_fn, search_fn);
2460 }
2461
2462 RNA_def_property_string_funcs_runtime(prop, rna_get_fn, rna_length_fn, rna_set_fn);
2463 if (rna_search_fn) {
2464 RNA_def_property_string_search_func_runtime(prop, rna_search_fn, search_flag);
2465 }
2466}
2467
2469 PyObject *get_fn,
2470 PyObject *set_fn,
2471 PyObject *itemf_fn)
2472{
2473 EnumPropertyGetFunc rna_get_fn = nullptr;
2474 EnumPropertyItemFunc rna_itemf_fn = nullptr;
2475 EnumPropertySetFunc rna_set_fn = nullptr;
2476
2477 if (get_fn && get_fn != Py_None) {
2478 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2479
2480 rna_get_fn = bpy_prop_enum_get_fn;
2481 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2482 }
2483
2484 if (set_fn && set_fn != Py_None) {
2485 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2486
2487 rna_set_fn = bpy_prop_enum_set_fn;
2488 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2489 }
2490
2491 if (itemf_fn && itemf_fn != Py_None) {
2492 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2493 rna_itemf_fn = bpy_prop_enum_itemf_fn;
2494 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.enum_data.itemf_fn, itemf_fn);
2495 }
2496
2497 RNA_def_property_enum_funcs_runtime(prop, rna_get_fn, rna_set_fn, rna_itemf_fn);
2498}
2499
2502/* -------------------------------------------------------------------- */
2520 PyObject *args,
2521 PyObject *kw,
2522 PyObject *method_object,
2523 PyObject **r_deferred_result)
2524{
2525 /* This must be the methods of one of the main property types defined in this file. */
2526 BLI_assert(PyCFunction_CheckExact(method_object));
2527
2528 const int args_len = PyTuple_GET_SIZE(args);
2529 PyMethodDef *method_def = ((PyCFunctionObject *)method_object)->m_ml;
2530
2531 /* Call this function with the first argument set to `self`. */
2532 if (args_len == 1) {
2533 self = PyTuple_GET_ITEM(args, 0);
2534 args = PyTuple_New(0);
2535
2536 /* This will be #BPy_BoolProperty` or one of the functions that define a type. */
2537 PyCFunctionWithKeywords method_fn = (PyCFunctionWithKeywords)(void *)method_def->ml_meth;
2538 *r_deferred_result = method_fn(self, args, kw);
2539 Py_DECREF(args);
2540 /* May be an error (depending on `r_deferred_result`). */
2541 return nullptr;
2542 }
2543
2544 const char *error_prefix = method_def->ml_name;
2545 if (args_len > 1) {
2546 PyErr_Format(PyExc_ValueError, "%s: all args must be keywords", error_prefix);
2547 *r_deferred_result = nullptr;
2548 /* An error. */
2549 return nullptr;
2550 }
2551
2552 StructRNA *srna = srna_from_self(self, error_prefix);
2553 if (srna == nullptr) {
2554 *r_deferred_result = PyErr_Occurred() ?
2555 nullptr :
2556 bpy_prop_deferred_data_CreatePyObject(method_object, kw);
2557 /* May be an error (depending on `r_deferred_result`). */
2558 return nullptr;
2559 }
2560
2561/* Crash if this is ever used by accident! */
2562#ifndef NDEBUG
2563 *r_deferred_result = (PyObject *)intptr_t(1);
2564#endif
2565
2566 /* No error or deferred result, perform registration immediately. */
2567 return srna;
2568}
2569
2581
2585static int bpy_prop_arg_parse_id(PyObject *o, void *p)
2586{
2587 BPy_PropIDParse *parse_data = static_cast<BPy_PropIDParse *>(p);
2588 StructRNA *srna = parse_data->srna;
2589
2590 if (!PyUnicode_Check(o)) {
2591 PyErr_Format(PyExc_TypeError, "expected a string (got %.200s)", Py_TYPE(o)->tp_name);
2592 return 0;
2593 }
2594
2595 Py_ssize_t id_len;
2596 const char *id;
2597
2598 id = PyUnicode_AsUTF8AndSize(o, &id_len);
2599 if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) {
2600 PyErr_Format(PyExc_TypeError, "'%.200s' too long, max length is %d", id, MAX_IDPROP_NAME - 1);
2601 return 0;
2602 }
2603
2604 parse_data->prop_free_handle = nullptr;
2606 srna, id, &parse_data->prop_free_handle) == -1))
2607 {
2608 PyErr_Format(PyExc_TypeError,
2609 "'%s' is defined as a non-dynamic type for '%s'",
2610 id,
2611 RNA_struct_identifier(srna));
2612 return 0;
2613 }
2614 parse_data->value = id;
2615 return 1;
2616}
2617
2625
2630static int bpy_prop_arg_parse_tag_defines(PyObject *o, void *p)
2631{
2633 parse_data->base.items = RNA_struct_property_tag_defines(parse_data->srna);
2634 if (parse_data->base.items == nullptr) {
2635 PyErr_Format(PyExc_TypeError,
2636 "property-tags not available for '%s'",
2637 RNA_struct_identifier(parse_data->srna));
2638 return 0;
2639 }
2640 return pyrna_enum_bitfield_parse_set(o, &parse_data->base);
2641}
2642
2645/* -------------------------------------------------------------------- */
2649#define BPY_PROPDEF_NAME_DOC \
2650 " :arg name: Name used in the user interface.\n" \
2651 " :type name: str\n"
2652
2653#define BPY_PROPDEF_DESC_DOC \
2654 " :arg description: Text used for the tooltip and api documentation.\n" \
2655 " :type description: str\n"
2656
2657#define BPY_PROPDEF_CTXT_DOC \
2658 " :arg translation_context: Text used as context to disambiguate translations.\n" \
2659 " :type translation_context: str\n"
2660
2661#define BPY_PROPDEF_UNIT_DOC \
2662 " :arg unit: Enumerator in :ref:`rna_enum_property_unit_items`.\n" \
2663 " :type unit: str\n"
2664
2665#define BPY_PROPDEF_NUM_MIN_DOC_(ty) \
2666 " :arg min: Hard minimum, trying to assign a value below will silently assign this minimum " \
2667 "instead.\n" \
2668 " :type min: " ty "\n"
2669
2670#define BPY_PROPDEF_NUM_MAX_DOC_(ty) \
2671 " :arg max: Hard maximum, trying to assign a value above will silently assign this maximum " \
2672 "instead.\n" \
2673 " :type max: " ty "\n"
2674
2675#define BPY_PROPDEF_NUM_MINMAX_DOC(ty) BPY_PROPDEF_NUM_MIN_DOC_(ty) BPY_PROPDEF_NUM_MAX_DOC_(ty)
2676
2677#define BPY_PROPDEF_NUM_SOFT_MIN_DOC_(ty) \
2678 " :arg soft_min: Soft minimum (>= *min*), " \
2679 "user won't be able to drag the widget below this value in the UI.\n" \
2680 " :type soft_min: " ty "\n"
2681
2682#define BPY_PROPDEF_NUM_SOFT_MAX_DOC_(ty) \
2683 " :arg soft_max: Soft maximum (<= *max*), " \
2684 "user won't be able to drag the widget above this value in the UI.\n" \
2685 " :type soft_max: " ty "\n"
2686
2687#define BPY_PROPDEF_NUM_SOFT_MINMAX_DOC(ty) \
2688 BPY_PROPDEF_NUM_SOFT_MIN_DOC_(ty) BPY_PROPDEF_NUM_SOFT_MAX_DOC_(ty)
2689
2690#define BPY_PROPDEF_VECSIZE_DOC \
2691 " :arg size: Vector dimensions in [1, " STRINGIFY(PYRNA_STACK_ARRAY) "]. " \
2692"An int sequence can be used to define multi-dimension arrays.\n" \
2693" :type size: int | Sequence[int]\n"
2694
2695#define BPY_PROPDEF_INT_STEP_DOC \
2696 " :arg step: Step of increment/decrement in UI, in [1, 100], defaults to 1 (WARNING: unused " \
2697 "currently!).\n" \
2698 " :type step: int\n"
2699
2700#define BPY_PROPDEF_FLOAT_STEP_DOC \
2701 " :arg step: Step of increment/decrement in UI, in [1, 100], defaults to 3 (WARNING: actual " \
2702 "value is /100).\n" \
2703 " :type step: int\n"
2704
2705#define BPY_PROPDEF_FLOAT_PREC_DOC \
2706 " :arg precision: Maximum number of decimal digits to display, in [0, 6]. Fraction is " \
2707 "automatically hidden for exact integer values of fields with unit 'NONE' or 'TIME' (frame " \
2708 "count) and step divisible by 100.\n" \
2709 " :type precision: int\n"
2710
2711#define BPY_PROPDEF_UPDATE_DOC \
2712 " :arg update: Function to be called when this value is modified,\n" \
2713 " This function must take 2 values (self, context) and return None.\n" \
2714 " *Warning* there are no safety checks to avoid infinite recursion.\n" \
2715 " :type update: Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.Context`], " \
2716 "None]\n"
2717
2718#define BPY_PROPDEF_POLL_DOC \
2719 " :arg poll: function to be called to determine whether an item is valid for this " \
2720 "property.\n" \
2721 " The function must take 2 values (self, object) and return Bool.\n" \
2722 " :type poll: Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.bpy_struct`], " \
2723 "bool]\n"
2724
2725#define BPY_PROPDEF_GET_DOC(ty) \
2726 " :arg get: Function to be called when this value is 'read',\n" \
2727 " This function must take 1 value (self) and return the value of the property.\n" \
2728 " :type get: Callable[[:class:`bpy.types.bpy_struct`], " ty "]\n"
2729
2730#define BPY_PROPDEF_SET_DOC(ty) \
2731 " :arg set: Function to be called when this value is 'written',\n" \
2732 " This function must take 2 values (self, value) and return None.\n" \
2733 " :type set: Callable[[:class:`bpy.types.bpy_struct`, " ty "], None]\n"
2734
2735#define BPY_PROPDEF_SEARCH_DOC \
2736 " :arg search: Function to be called to show candidates for this string (shown in the UI).\n" \
2737 " This function must take 3 values (self, context, edit_text)\n" \
2738 " and return a sequence, iterator or generator where each item must be:\n" \
2739 "\n" \
2740 " - A single string (representing a candidate to display).\n" \
2741 " - A tuple-pair of strings, where the first is a candidate and the second\n" \
2742 " is additional information about the candidate.\n" \
2743 " :type search: Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.Context`, str], " \
2744 "Iterable[str | tuple[str, str]]" \
2745 "]\n" \
2746 " :arg search_options: Set of strings in:\n" \
2747 "\n" \
2748 " - 'SORT' sorts the resulting items.\n" \
2749 " - 'SUGGESTION' lets the user enter values not found in search candidates.\n" \
2750 " **WARNING** disabling this flag causes the search callback to run on redraw,\n" \
2751 " so only disable this flag if it's not likely to cause performance issues.\n" \
2752 "\n" \
2753 " :type search_options: set[str]\n"
2754
2755#define BPY_PROPDEF_POINTER_TYPE_DOC \
2756 " :arg type: A subclass of a property group or ID types.\n" \
2757 " :type type: :class:`bpy.types.PropertyGroup` | :class:`bpy.types.ID`\n"
2758
2759#define BPY_PROPDEF_COLLECTION_TYPE_DOC \
2760 " :arg type: A subclass of a property group.\n" \
2761 " :type type: :class:`bpy.types.PropertyGroup`\n"
2762
2763#define BPY_PROPDEF_TAGS_DOC \
2764 " :arg tags: Enumerator of tags that are defined by parent class.\n" \
2765 " :type tags: set[str]\n"
2766
2767#if 0
2768static int bpy_struct_id_used(StructRNA *srna, char *identifier)
2769{
2770 PointerRNA ptr = RNA_pointer_create(nullptr, srna, nullptr);
2771 return (RNA_struct_find_property(&ptr, identifier) != nullptr);
2772}
2773#endif
2774
2777/* -------------------------------------------------------------------- */
2789 /* Wrap. */
2790 BPy_BoolProperty_doc,
2791 ".. function:: BoolProperty("
2792 "*, "
2793 "name=\"\", "
2794 "description=\"\", "
2795 "translation_context=\"*\", "
2796 "default=False, "
2797 "options={'ANIMATABLE'}, "
2798 "override=set(), "
2799 "tags=set(), "
2800 "subtype='NONE', "
2801 "update=None, "
2802 "get=None, "
2803 "set=None)\n"
2804 "\n"
2805 " Returns a new boolean property definition.\n"
2809static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
2810{
2811 StructRNA *srna;
2812 { /* Keep this block first. */
2813 PyObject *deferred_result;
2814 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_BoolProperty, &deferred_result);
2815 if (srna == nullptr) {
2816 return deferred_result;
2817 }
2818 }
2819
2820 BPy_PropIDParse id_data{};
2821 id_data.srna = srna;
2822
2823 const char *name = nullptr, *description = "";
2824 const char *translation_context = nullptr;
2825 bool default_value = false;
2826 PropertyRNA *prop;
2827 BPy_EnumProperty_Parse options_enum{};
2828 options_enum.items = rna_enum_property_flag_items;
2829 options_enum.value = 0;
2830
2831 BPy_EnumProperty_Parse override_enum{};
2833 override_enum.value = 0;
2834
2836 tags_enum.srna = srna;
2837
2838 BPy_EnumProperty_Parse subtype_enum{};
2840 subtype_enum.value = PROP_NONE;
2841
2842 PyObject *update_fn = nullptr;
2843 PyObject *get_fn = nullptr;
2844 PyObject *set_fn = nullptr;
2845
2846 static const char *_keywords[] = {
2847 "attr",
2848 "name",
2849 "description",
2850 "translation_context",
2851 "default",
2852 "options",
2853 "override",
2854 "tags",
2855 "subtype",
2856 "update",
2857 "get",
2858 "set",
2859 nullptr,
2860 };
2861 static _PyArg_Parser _parser = {
2863 "O&" /* `attr` */
2864 "|$" /* Optional, keyword only arguments. */
2865 "s" /* `name` */
2866 "s" /* `description` */
2867 "s" /* `translation_context` */
2868 "O&" /* `default` */
2869 "O&" /* `options` */
2870 "O&" /* `override` */
2871 "O&" /* `tags` */
2872 "O&" /* `subtype` */
2873 "O" /* `update` */
2874 "O" /* `get` */
2875 "O" /* `set` */
2876 ":BoolProperty",
2877 _keywords,
2878 nullptr,
2879 };
2880 if (!_PyArg_ParseTupleAndKeywordsFast(args,
2881 kw,
2882 &_parser,
2884 &id_data,
2885 &name,
2886 &description,
2887 &translation_context,
2889 &default_value,
2891 &options_enum,
2893 &override_enum,
2895 &tags_enum,
2897 &subtype_enum,
2898 &update_fn,
2899 &get_fn,
2900 &set_fn))
2901 {
2902 return nullptr;
2903 }
2904
2905 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
2906 return nullptr;
2907 }
2908 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
2909 return nullptr;
2910 }
2911 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
2912 return nullptr;
2913 }
2914
2915 if (id_data.prop_free_handle != nullptr) {
2916 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
2917 }
2918 prop = RNA_def_property(srna, id_data.value, PROP_BOOLEAN, subtype_enum.value);
2919
2920 RNA_def_property_boolean_default(prop, default_value);
2921 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
2922 if (translation_context) {
2923 RNA_def_property_translation_context(prop, translation_context);
2924 }
2925
2926 if (tags_enum.base.is_set) {
2927 RNA_def_property_tags(prop, tags_enum.base.value);
2928 }
2929 if (options_enum.is_set) {
2930 bpy_prop_assign_flag(prop, options_enum.value);
2931 }
2932 if (override_enum.is_set) {
2933 bpy_prop_assign_flag_override(prop, override_enum.value);
2934 }
2935 bpy_prop_callback_assign_update(prop, update_fn);
2936 bpy_prop_callback_assign_boolean(prop, get_fn, set_fn);
2938
2939 Py_RETURN_NONE;
2940}
2941
2943 /* Wrap. */
2944 BPy_BoolVectorProperty_doc,
2945 ".. function:: BoolVectorProperty("
2946 "*, "
2947 "name=\"\", "
2948 "description=\"\", "
2949 "translation_context=\"*\", "
2950 "default=(False, False, False), "
2951 "options={'ANIMATABLE'}, "
2952 "override=set(), "
2953 "tags=set(), "
2954 "subtype='NONE', "
2955 "size=3, "
2956 "update=None, "
2957 "get=None, "
2958 "set=None)\n"
2959 "\n"
2960 " Returns a new vector boolean property definition.\n"
2962 " :arg default: sequence of booleans the length of *size*.\n"
2963 " :type default: Sequence[bool]\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
2966 BPY_PROPDEF_SET_DOC("tuple[bool]"));
2967static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
2968{
2969 StructRNA *srna;
2970 { /* Keep this block first. */
2971 PyObject *deferred_result;
2973 self, args, kw, pymeth_BoolVectorProperty, &deferred_result);
2974 if (srna == nullptr) {
2975 return deferred_result;
2976 }
2977 }
2978
2979 BPy_PropIDParse id_data{};
2980 id_data.srna = srna;
2981
2982 const char *name = nullptr, *description = "";
2983 const char *translation_context = nullptr;
2984 Array<bool, RNA_STACK_ARRAY> default_value;
2985 BPyPropArrayLength array_len_info{};
2986 array_len_info.len_total = 3;
2987 PropertyRNA *prop;
2988 PyObject *default_py = nullptr;
2989
2990 BPy_EnumProperty_Parse options_enum{};
2991 options_enum.items = rna_enum_property_flag_items;
2992 options_enum.value = 0;
2993
2994 BPy_EnumProperty_Parse override_enum{};
2996 override_enum.value = 0;
2997
2999 tags_enum.srna = srna;
3000
3001 BPy_EnumProperty_Parse subtype_enum{};
3003 subtype_enum.value = PROP_NONE;
3004
3005 PyObject *update_fn = nullptr;
3006 PyObject *get_fn = nullptr;
3007 PyObject *set_fn = nullptr;
3008
3009 static const char *_keywords[] = {
3010 "attr",
3011 "name",
3012 "description",
3013 "translation_context",
3014 "default",
3015 "options",
3016 "override",
3017 "tags",
3018 "subtype",
3019 "size",
3020 "update",
3021 "get",
3022 "set",
3023 nullptr,
3024 };
3025 static _PyArg_Parser _parser = {
3027 "O&" /* `attr` */
3028 "|$" /* Optional, keyword only arguments. */
3029 "s" /* `name` */
3030 "s" /* `description` */
3031 "s" /* `translation_context` */
3032 "O" /* `default` */
3033 "O&" /* `options` */
3034 "O&" /* `override` */
3035 "O&" /* `tags` */
3036 "O&" /* `subtype` */
3037 "O&" /* `size` */
3038 "O" /* `update` */
3039 "O" /* `get` */
3040 "O" /* `set` */
3041 ":BoolVectorProperty",
3042 _keywords,
3043 nullptr,
3044 };
3045 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3046 kw,
3047 &_parser,
3049 &id_data,
3050 &name,
3051 &description,
3052 &translation_context,
3053 &default_py,
3055 &options_enum,
3057 &override_enum,
3059 &tags_enum,
3061 &subtype_enum,
3063 &array_len_info,
3064 &update_fn,
3065 &get_fn,
3066 &set_fn))
3067 {
3068 return nullptr;
3069 }
3070
3071 if (default_py != nullptr) {
3072 default_value.reinitialize(array_len_info.len_total);
3073 if (bpy_prop_array_from_py_with_dims(default_value.data(),
3074 sizeof(*default_value.data()),
3075 default_py,
3076 &array_len_info,
3077 &PyBool_Type,
3078 "BoolVectorProperty(default=sequence)") == -1)
3079 {
3080 return nullptr;
3081 }
3082 }
3083
3084 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3085 return nullptr;
3086 }
3087 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3088 return nullptr;
3089 }
3090 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3091 return nullptr;
3092 }
3093
3094 if (id_data.prop_free_handle != nullptr) {
3095 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
3096 }
3097 prop = RNA_def_property(srna, id_data.value, PROP_BOOLEAN, subtype_enum.value);
3098
3099 if (array_len_info.dims_len == 0) {
3100 RNA_def_property_array(prop, array_len_info.len_total);
3101 if (default_py != nullptr) {
3102 RNA_def_property_boolean_array_default(prop, default_value.data());
3103 }
3104 }
3105 else {
3106 RNA_def_property_multi_array(prop, array_len_info.dims_len, array_len_info.dims);
3107 if (default_py != nullptr) {
3108 RNA_def_property_boolean_array_default(prop, default_value.data());
3109 }
3110 }
3111
3112 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3113 if (translation_context) {
3114 RNA_def_property_translation_context(prop, translation_context);
3115 }
3116
3117 if (tags_enum.base.is_set) {
3118 RNA_def_property_tags(prop, tags_enum.base.value);
3119 }
3120 if (options_enum.is_set) {
3121 bpy_prop_assign_flag(prop, options_enum.value);
3122 }
3123 if (override_enum.is_set) {
3124 bpy_prop_assign_flag_override(prop, override_enum.value);
3125 }
3126 bpy_prop_callback_assign_update(prop, update_fn);
3127 bpy_prop_callback_assign_boolean_array(prop, get_fn, set_fn);
3129
3130 Py_RETURN_NONE;
3131}
3132
3134 /* Wrap. */
3135 BPy_IntProperty_doc,
3136 ".. function:: IntProperty("
3137 "*, "
3138 "name=\"\", "
3139 "description=\"\", "
3140 "translation_context=\"*\", "
3141 "default=0, "
3142 "min=-2**31, max=2**31-1, "
3143 "soft_min=-2**31, soft_max=2**31-1, "
3144 "step=1, "
3145 "options={'ANIMATABLE'}, "
3146 "override=set(), "
3147 "tags=set(), "
3148 "subtype='NONE', "
3149 "update=None, "
3150 "get=None, "
3151 "set=None)\n"
3152 "\n"
3153 " Returns a new int property definition.\n"
3159static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
3160{
3161 StructRNA *srna;
3162 { /* Keep this block first. */
3163 PyObject *deferred_result;
3164 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_IntProperty, &deferred_result);
3165 if (srna == nullptr) {
3166 return deferred_result;
3167 }
3168 }
3169
3170 BPy_PropIDParse id_data{};
3171 id_data.srna = srna;
3172
3173 const char *name = nullptr, *description = "";
3174 const char *translation_context = nullptr;
3175 int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX;
3176 int step = 1;
3177 int default_value = 0;
3178 PropertyRNA *prop;
3179
3180 BPy_EnumProperty_Parse options_enum{};
3181 options_enum.items = rna_enum_property_flag_items;
3182 options_enum.value = 0;
3183
3184 BPy_EnumProperty_Parse override_enum{};
3186 override_enum.value = 0;
3187
3189 tags_enum.srna = srna;
3190
3191 BPy_EnumProperty_Parse subtype_enum{};
3193 subtype_enum.value = PROP_NONE;
3194
3195 PyObject *update_fn = nullptr;
3196 PyObject *get_fn = nullptr;
3197 PyObject *set_fn = nullptr;
3198
3199 static const char *_keywords[] = {
3200 "attr",
3201 "name",
3202 "description",
3203 "translation_context",
3204 "default",
3205 "min",
3206 "max",
3207 "soft_min",
3208 "soft_max",
3209 "step",
3210 "options",
3211 "override",
3212 "tags",
3213 "subtype",
3214 "update",
3215 "get",
3216 "set",
3217 nullptr,
3218 };
3219 static _PyArg_Parser _parser = {
3221 "O&" /* `attr` */
3222 "|$" /* Optional, keyword only arguments. */
3223 "s" /* `name` */
3224 "s" /* `description` */
3225 "s" /* `translation_context` */
3226 "i" /* `default` */
3227 "i" /* `min` */
3228 "i" /* `max` */
3229 "i" /* `soft_min` */
3230 "i" /* `soft_max` */
3231 "i" /* `step` */
3232 "O&" /* `options` */
3233 "O&" /* `override` */
3234 "O&" /* `tags` */
3235 "O&" /* `subtype` */
3236 "O" /* `update` */
3237 "O" /* `get` */
3238 "O" /* `set` */
3239 ":IntProperty",
3240 _keywords,
3241 nullptr,
3242 };
3243 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3244 kw,
3245 &_parser,
3247 &id_data,
3248 &name,
3249 &description,
3250 &translation_context,
3251 &default_value,
3252 &min,
3253 &max,
3254 &soft_min,
3255 &soft_max,
3256 &step,
3258 &options_enum,
3260 &override_enum,
3262 &tags_enum,
3264 &subtype_enum,
3265 &update_fn,
3266 &get_fn,
3267 &set_fn))
3268 {
3269 return nullptr;
3270 }
3271
3272 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3273 return nullptr;
3274 }
3275 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3276 return nullptr;
3277 }
3278 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3279 return nullptr;
3280 }
3281
3282 if (id_data.prop_free_handle != nullptr) {
3283 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
3284 }
3285 prop = RNA_def_property(srna, id_data.value, PROP_INT, subtype_enum.value);
3286
3287 RNA_def_property_int_default(prop, default_value);
3288 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3289 if (translation_context) {
3290 RNA_def_property_translation_context(prop, translation_context);
3291 }
3292 RNA_def_property_range(prop, min, max);
3293 RNA_def_property_ui_range(prop, std::max(soft_min, min), std::min(soft_max, max), step, 3);
3294
3295 if (tags_enum.base.is_set) {
3296 RNA_def_property_tags(prop, tags_enum.base.value);
3297 }
3298 if (options_enum.is_set) {
3299 bpy_prop_assign_flag(prop, options_enum.value);
3300 }
3301 if (override_enum.is_set) {
3302 bpy_prop_assign_flag_override(prop, override_enum.value);
3303 }
3304 bpy_prop_callback_assign_update(prop, update_fn);
3305 bpy_prop_callback_assign_int(prop, get_fn, set_fn);
3307
3308 Py_RETURN_NONE;
3309}
3310
3312 /* Wrap. */
3313 BPy_IntVectorProperty_doc,
3314 ".. function:: IntVectorProperty("
3315 "*, "
3316 "name=\"\", "
3317 "description=\"\", "
3318 "translation_context=\"*\", "
3319 "default=(0, 0, 0), min=-2**31, max=2**31-1, "
3320 "soft_min=-2**31, "
3321 "soft_max=2**31-1, "
3322 "step=1, "
3323 "options={'ANIMATABLE'}, "
3324 "override=set(), "
3325 "tags=set(), "
3326 "subtype='NONE', "
3327 "size=3, "
3328 "update=None, "
3329 "get=None, "
3330 "set=None)\n"
3331 "\n"
3332 " Returns a new vector int property definition.\n"
3334 " :arg default: sequence of ints the length of *size*.\n"
3335 " :type default: Sequence[int]\n" BPY_PROPDEF_NUM_MINMAX_DOC("int")
3340 BPY_PROPDEF_SET_DOC("tuple[int]"));
3341static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
3342{
3343 StructRNA *srna;
3344 { /* Keep this block first. */
3345 PyObject *deferred_result;
3347 self, args, kw, pymeth_IntVectorProperty, &deferred_result);
3348 if (srna == nullptr) {
3349 return deferred_result;
3350 }
3351 }
3352
3353 BPy_PropIDParse id_data{};
3354 id_data.srna = srna;
3355
3356 const char *name = nullptr, *description = "";
3357 const char *translation_context = nullptr;
3358 int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX;
3359 int step = 1;
3360 Array<int, RNA_STACK_ARRAY> default_value;
3361 BPyPropArrayLength array_len_info{};
3362 array_len_info.len_total = 3;
3363 PropertyRNA *prop;
3364 PyObject *default_py = nullptr;
3365
3366 BPy_EnumProperty_Parse options_enum{};
3367 options_enum.items = rna_enum_property_flag_items;
3368 options_enum.value = 0;
3369
3370 BPy_EnumProperty_Parse override_enum{};
3372 override_enum.value = 0;
3373
3375 tags_enum.srna = srna;
3376
3377 BPy_EnumProperty_Parse subtype_enum{};
3379 subtype_enum.value = PROP_NONE;
3380
3381 PyObject *update_fn = nullptr;
3382 PyObject *get_fn = nullptr;
3383 PyObject *set_fn = nullptr;
3384
3385 static const char *_keywords[] = {
3386 "attr", "name", "description", "translation_context",
3387 "default", "min", "max", "soft_min",
3388 "soft_max", "step", "options", "override",
3389 "tags", "subtype", "size", "update",
3390 "get", "set", nullptr,
3391 };
3392 static _PyArg_Parser _parser = {
3394 "O&" /* `attr` */
3395 "|$" /* Optional, keyword only arguments. */
3396 "s" /* `name` */
3397 "s" /* `description` */
3398 "s" /* `translation_context` */
3399 "O" /* `default` */
3400 "i" /* `min` */
3401 "i" /* `max` */
3402 "i" /* `soft_min` */
3403 "i" /* `soft_max` */
3404 "i" /* `step` */
3405 "O&" /* `options` */
3406 "O&" /* `override` */
3407 "O&" /* `tags` */
3408 "O&" /* `subtype` */
3409 "O&" /* `size` */
3410 "O" /* `update` */
3411 "O" /* `get` */
3412 "O" /* `set` */
3413 ":IntVectorProperty",
3414 _keywords,
3415 nullptr,
3416 };
3417 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3418 kw,
3419 &_parser,
3421 &id_data,
3422 &name,
3423 &description,
3424 &translation_context,
3425 &default_py,
3426 &min,
3427 &max,
3428 &soft_min,
3429 &soft_max,
3430 &step,
3432 &options_enum,
3434 &override_enum,
3436 &tags_enum,
3438 &subtype_enum,
3440 &array_len_info,
3441 &update_fn,
3442 &get_fn,
3443 &set_fn))
3444 {
3445 return nullptr;
3446 }
3447
3448 if (default_py != nullptr) {
3449 default_value.reinitialize(array_len_info.len_total);
3450 if (bpy_prop_array_from_py_with_dims(default_value.data(),
3451 sizeof(*default_value.data()),
3452 default_py,
3453 &array_len_info,
3454 &PyLong_Type,
3455 "IntVectorProperty(default=sequence)") == -1)
3456 {
3457 return nullptr;
3458 }
3459 }
3460
3461 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3462 return nullptr;
3463 }
3464 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3465 return nullptr;
3466 }
3467 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3468 return nullptr;
3469 }
3470
3471 if (id_data.prop_free_handle != nullptr) {
3472 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
3473 }
3474 prop = RNA_def_property(srna, id_data.value, PROP_INT, subtype_enum.value);
3475
3476 if (array_len_info.dims_len == 0) {
3477 RNA_def_property_array(prop, array_len_info.len_total);
3478 if (default_py != nullptr) {
3479 RNA_def_property_int_array_default(prop, default_value.data());
3480 }
3481 }
3482 else {
3483 RNA_def_property_multi_array(prop, array_len_info.dims_len, array_len_info.dims);
3484 if (default_py != nullptr) {
3485 RNA_def_property_int_array_default(prop, default_value.data());
3486 }
3487 }
3488
3489 RNA_def_property_range(prop, min, max);
3490 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3491 if (translation_context) {
3492 RNA_def_property_translation_context(prop, translation_context);
3493 }
3494 RNA_def_property_ui_range(prop, std::max(soft_min, min), std::min(soft_max, max), step, 3);
3495
3496 if (tags_enum.base.is_set) {
3497 RNA_def_property_tags(prop, tags_enum.base.value);
3498 }
3499 if (options_enum.is_set) {
3500 bpy_prop_assign_flag(prop, options_enum.value);
3501 }
3502 if (override_enum.is_set) {
3503 bpy_prop_assign_flag_override(prop, override_enum.value);
3504 }
3505 bpy_prop_callback_assign_update(prop, update_fn);
3506 bpy_prop_callback_assign_int_array(prop, get_fn, set_fn);
3508
3509 Py_RETURN_NONE;
3510}
3511
3513 /* Wrap. */
3514 BPy_FloatProperty_doc,
3515 ".. function:: FloatProperty("
3516 "*, "
3517 "name=\"\", "
3518 "description=\"\", "
3519 "translation_context=\"*\", "
3520 "default=0.0, "
3521 "min=-3.402823e+38, max=3.402823e+38, "
3522 "soft_min=-3.402823e+38, soft_max=3.402823e+38, "
3523 "step=3, "
3524 "precision=2, "
3525 "options={'ANIMATABLE'}, "
3526 "override=set(), "
3527 "tags=set(), "
3528 "subtype='NONE', "
3529 "unit='NONE', "
3530 "update=None, "
3531 "get=None, "
3532 "set=None)\n"
3533 "\n"
3534 " Returns a new float (single precision) property definition.\n"
3536 "float") BPY_PROPDEF_NUM_SOFT_MINMAX_DOC("float")
3540 BPY_PROPDEF_SET_DOC("float"));
3541static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
3542{
3543 StructRNA *srna;
3544 { /* Keep this block first. */
3545 PyObject *deferred_result;
3546 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_FloatProperty, &deferred_result);
3547 if (srna == nullptr) {
3548 return deferred_result;
3549 }
3550 }
3551
3552 BPy_PropIDParse id_data{};
3553 id_data.srna = srna;
3554
3555 const char *name = nullptr, *description = "";
3556 const char *translation_context = nullptr;
3557 float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX;
3558 float step = 3;
3559 float default_value = 0.0f;
3560 int precision = 2;
3561 PropertyRNA *prop;
3562
3563 BPy_EnumProperty_Parse options_enum{};
3564 options_enum.items = rna_enum_property_flag_items;
3565 options_enum.value = 0;
3566
3567 BPy_EnumProperty_Parse override_enum{};
3569 override_enum.value = 0;
3570
3572 tags_enum.srna = srna;
3573
3574 BPy_EnumProperty_Parse subtype_enum{};
3576 subtype_enum.value = PROP_NONE;
3577
3578 BPy_EnumProperty_Parse unit_enum{};
3580 unit_enum.value = PROP_UNIT_NONE;
3581
3582 PyObject *update_fn = nullptr;
3583 PyObject *get_fn = nullptr;
3584 PyObject *set_fn = nullptr;
3585
3586 static const char *_keywords[] = {
3587 "attr", "name", "description", "translation_context",
3588 "default", "min", "max", "soft_min",
3589 "soft_max", "step", "precision", "options",
3590 "override", "tags", "subtype", "unit",
3591 "update", "get", "set", nullptr,
3592 };
3593 static _PyArg_Parser _parser = {
3595 "O&" /* `attr` */
3596 "|$" /* Optional, keyword only arguments. */
3597 "s" /* `name` */
3598 "s" /* `description` */
3599 "s" /* `translation_context` */
3600 "f" /* `default` */
3601 "f" /* `min` */
3602 "f" /* `max` */
3603 "f" /* `soft_min` */
3604 "f" /* `soft_max` */
3605 "f" /* `step` */
3606 "i" /* `precision` */
3607 "O&" /* `options` */
3608 "O&" /* `override` */
3609 "O&" /* `tags` */
3610 "O&" /* `subtype` */
3611 "O&" /* `unit` */
3612 "O" /* `update` */
3613 "O" /* `get` */
3614 "O" /* `set` */
3615 ":FloatProperty",
3616 _keywords,
3617 nullptr,
3618 };
3619 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3620 kw,
3621 &_parser,
3623 &id_data,
3624 &name,
3625 &description,
3626 &translation_context,
3627 &default_value,
3628 &min,
3629 &max,
3630 &soft_min,
3631 &soft_max,
3632 &step,
3633 &precision,
3635 &options_enum,
3637 &override_enum,
3639 &tags_enum,
3641 &subtype_enum,
3643 &unit_enum,
3644 &update_fn,
3645 &get_fn,
3646 &set_fn))
3647 {
3648 return nullptr;
3649 }
3650
3651 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3652 return nullptr;
3653 }
3654 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3655 return nullptr;
3656 }
3657 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3658 return nullptr;
3659 }
3660
3661 if (id_data.prop_free_handle != nullptr) {
3662 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
3663 }
3664 prop = RNA_def_property(srna, id_data.value, PROP_FLOAT, subtype_enum.value | unit_enum.value);
3665
3666 RNA_def_property_float_default(prop, default_value);
3667 RNA_def_property_range(prop, min, max);
3668 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3669 if (translation_context) {
3670 RNA_def_property_translation_context(prop, translation_context);
3671 }
3673 prop, std::max(soft_min, min), std::min(soft_max, max), step, precision);
3674
3675 if (tags_enum.base.is_set) {
3676 RNA_def_property_tags(prop, tags_enum.base.value);
3677 }
3678 if (options_enum.is_set) {
3679 bpy_prop_assign_flag(prop, options_enum.value);
3680 }
3681 if (override_enum.is_set) {
3682 bpy_prop_assign_flag_override(prop, override_enum.value);
3683 }
3684 bpy_prop_callback_assign_update(prop, update_fn);
3685 bpy_prop_callback_assign_float(prop, get_fn, set_fn);
3687
3688 Py_RETURN_NONE;
3689}
3690
3692 /* Wrap. */
3693 BPy_FloatVectorProperty_doc,
3694 ".. function:: FloatVectorProperty("
3695 "*, "
3696 "name=\"\", "
3697 "description=\"\", "
3698 "translation_context=\"*\", "
3699 "default=(0.0, 0.0, 0.0), "
3700 "min=sys.float_info.min, max=sys.float_info.max, "
3701 "soft_min=sys.float_info.min, soft_max=sys.float_info.max, "
3702 "step=3, "
3703 "precision=2, "
3704 "options={'ANIMATABLE'}, "
3705 "override=set(), "
3706 "tags=set(), "
3707 "subtype='NONE', "
3708 "unit='NONE', "
3709 "size=3, "
3710 "update=None, "
3711 "get=None, "
3712 "set=None)\n"
3713 "\n"
3714 " Returns a new vector float property definition.\n"
3716 " :arg default: Sequence of floats the length of *size*.\n"
3717 " :type default: Sequence[float]\n" BPY_PROPDEF_NUM_MINMAX_DOC(
3718 "float") BPY_PROPDEF_NUM_SOFT_MINMAX_DOC("float")
3723 BPY_PROPDEF_SET_DOC("tuple[float]"));
3724static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
3725{
3726 StructRNA *srna;
3727 { /* Keep this block first. */
3728 PyObject *deferred_result;
3730 self, args, kw, pymeth_FloatVectorProperty, &deferred_result);
3731 if (srna == nullptr) {
3732 return deferred_result;
3733 }
3734 }
3735
3736 BPy_PropIDParse id_data{};
3737 id_data.srna = srna;
3738
3739 const char *name = nullptr, *description = "";
3740 const char *translation_context = nullptr;
3741 float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX;
3742 float step = 3;
3743 Array<float, RNA_STACK_ARRAY> default_value;
3744 int precision = 2;
3745 BPyPropArrayLength array_len_info{};
3746 array_len_info.len_total = 3;
3747 PropertyRNA *prop;
3748 PyObject *default_py = nullptr;
3749
3750 BPy_EnumProperty_Parse options_enum{};
3751 options_enum.items = rna_enum_property_flag_items;
3752 options_enum.value = 0;
3753
3754 BPy_EnumProperty_Parse override_enum{};
3756 override_enum.value = 0;
3757
3759 tags_enum.srna = srna;
3760
3761 BPy_EnumProperty_Parse subtype_enum{};
3763 subtype_enum.value = PROP_NONE;
3764
3765 BPy_EnumProperty_Parse unit_enum{};
3767 unit_enum.value = PROP_UNIT_NONE;
3768
3769 PyObject *update_fn = nullptr;
3770 PyObject *get_fn = nullptr;
3771 PyObject *set_fn = nullptr;
3772
3773 static const char *_keywords[] = {
3774 "attr", "name", "description", "translation_context",
3775 "default", "min", "max", "soft_min",
3776 "soft_max", "step", "precision", "options",
3777 "override", "tags", "subtype", "unit",
3778 "size", "update", "get", "set",
3779 nullptr,
3780 };
3781 static _PyArg_Parser _parser = {
3783 "O&" /* `attr` */
3784 "|$" /* Optional, keyword only arguments. */
3785 "s" /* `name` */
3786 "s" /* `description` */
3787 "s" /* `translation_context` */
3788 "O" /* `default` */
3789 "f" /* `min` */
3790 "f" /* `max` */
3791 "f" /* `soft_min` */
3792 "f" /* `soft_max` */
3793 "f" /* `step` */
3794 "i" /* `precision` */
3795 "O&" /* `options` */
3796 "O&" /* `override` */
3797 "O&" /* `tags` */
3798 "O&" /* `subtype` */
3799 "O&" /* `unit` */
3800 "O&" /* `size` */
3801 "O" /* `update` */
3802 "O" /* `get` */
3803 "O" /* `set` */
3804 ":FloatVectorProperty",
3805 _keywords,
3806 nullptr,
3807 };
3808 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3809 kw,
3810 &_parser,
3812 &id_data,
3813 &name,
3814 &description,
3815 &translation_context,
3816 &default_py,
3817 &min,
3818 &max,
3819 &soft_min,
3820 &soft_max,
3821 &step,
3822 &precision,
3824 &options_enum,
3826 &override_enum,
3828 &tags_enum,
3830 &subtype_enum,
3832 &unit_enum,
3834 &array_len_info,
3835 &update_fn,
3836 &get_fn,
3837 &set_fn))
3838 {
3839 return nullptr;
3840 }
3841
3842 if (default_py != nullptr) {
3843 default_value.reinitialize(array_len_info.len_total);
3844 if (bpy_prop_array_from_py_with_dims(default_value.data(),
3845 sizeof(*default_value.data()),
3846 default_py,
3847 &array_len_info,
3848 &PyFloat_Type,
3849 "FloatVectorProperty(default=sequence)") == -1)
3850 {
3851 return nullptr;
3852 }
3853 if (bpy_prop_array_is_matrix_compatible_ex(subtype_enum.value, &array_len_info)) {
3854 bpy_prop_array_matrix_swap_row_column_vn(default_value.data(), &array_len_info);
3855 }
3856 }
3857
3858 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3859 return nullptr;
3860 }
3861 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3862 return nullptr;
3863 }
3864 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3865 return nullptr;
3866 }
3867
3868 if (id_data.prop_free_handle != nullptr) {
3869 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
3870 }
3871 prop = RNA_def_property(srna, id_data.value, PROP_FLOAT, subtype_enum.value | unit_enum.value);
3872
3873 if (array_len_info.dims_len == 0) {
3874 RNA_def_property_array(prop, array_len_info.len_total);
3875 if (default_py != nullptr) {
3876 RNA_def_property_float_array_default(prop, default_value.data());
3877 }
3878 }
3879 else {
3880 RNA_def_property_multi_array(prop, array_len_info.dims_len, array_len_info.dims);
3881 if (default_py != nullptr) {
3882 RNA_def_property_float_array_default(prop, default_value.data());
3883 }
3884 }
3885
3886 RNA_def_property_range(prop, min, max);
3887 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3888 if (translation_context) {
3889 RNA_def_property_translation_context(prop, translation_context);
3890 }
3892 prop, std::max(soft_min, min), std::min(soft_max, max), step, precision);
3893
3894 if (tags_enum.base.is_set) {
3895 RNA_def_property_tags(prop, tags_enum.base.value);
3896 }
3897 if (options_enum.is_set) {
3898 bpy_prop_assign_flag(prop, options_enum.value);
3899 }
3900 if (override_enum.is_set) {
3901 bpy_prop_assign_flag_override(prop, override_enum.value);
3902 }
3903 bpy_prop_callback_assign_update(prop, update_fn);
3904 bpy_prop_callback_assign_float_array(prop, get_fn, set_fn);
3906
3907 Py_RETURN_NONE;
3908}
3909
3911 /* Wrap. */
3912 BPy_StringProperty_doc,
3913 ".. function:: StringProperty("
3914 "*, "
3915 "name=\"\", "
3916 "description=\"\", "
3917 "translation_context=\"*\", "
3918 "default=\"\", "
3919 "maxlen=0, "
3920 "options={'ANIMATABLE'}, "
3921 "override=set(), "
3922 "tags=set(), "
3923 "subtype='NONE', "
3924 "update=None, "
3925 "get=None, "
3926 "set=None, "
3927 "search=None, "
3928 "search_options={'SUGGESTION'})\n"
3929 "\n"
3930 " Returns a new string property definition.\n"
3932 " :arg default: initializer string.\n"
3933 " :type default: str\n"
3934 " :arg maxlen: maximum length of the string.\n"
3938static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
3939{
3940 StructRNA *srna;
3941 { /* Keep this block first. */
3942 PyObject *deferred_result;
3943 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_StringProperty, &deferred_result);
3944 if (srna == nullptr) {
3945 return deferred_result;
3946 }
3947 }
3948
3949 BPy_PropIDParse id_data{};
3950 id_data.srna = srna;
3951
3952 const char *name = nullptr, *description = "";
3953 const char *translation_context = nullptr, *default_value = "";
3954 int maxlen = 0;
3955 PropertyRNA *prop;
3956
3957 BPy_EnumProperty_Parse options_enum{};
3958 options_enum.items = rna_enum_property_flag_items;
3959 options_enum.value = 0;
3960
3961 BPy_EnumProperty_Parse override_enum{};
3963 override_enum.value = 0;
3964
3966 tags_enum.srna = srna;
3967
3968 BPy_EnumProperty_Parse subtype_enum{};
3970 subtype_enum.value = PROP_NONE;
3971
3972 PyObject *update_fn = nullptr;
3973 PyObject *get_fn = nullptr;
3974 PyObject *set_fn = nullptr;
3975 PyObject *search_fn = nullptr;
3976 BPy_EnumProperty_Parse search_options_enum{};
3978 search_options_enum.value = PROP_STRING_SEARCH_SUGGESTION;
3979
3980 static const char *_keywords[] = {
3981 "attr",
3982 "name",
3983 "description",
3984 "translation_context",
3985 "default",
3986 "maxlen",
3987 "options",
3988 "override",
3989 "tags",
3990 "subtype",
3991 "update",
3992 "get",
3993 "set",
3994 "search",
3995 "search_options",
3996 nullptr,
3997 };
3998 static _PyArg_Parser _parser = {
4000 "O&" /* `attr` */
4001 "|$" /* Optional, keyword only arguments. */
4002 "s" /* `name` */
4003 "s" /* `description` */
4004 "s" /* `translation_context` */
4005 "s" /* `default` */
4006 "i" /* `maxlen` */
4007 "O&" /* `options` */
4008 "O&" /* `override` */
4009 "O&" /* `tags` */
4010 "O&" /* `subtype` */
4011 "O" /* `update` */
4012 "O" /* `get` */
4013 "O" /* `set` */
4014 "O" /* `search` */
4015 "O&" /* `search_options` */
4016 ":StringProperty",
4017 _keywords,
4018 nullptr,
4019 };
4020 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4021 kw,
4022 &_parser,
4024 &id_data,
4025 &name,
4026 &description,
4027 &translation_context,
4028 &default_value,
4029 &maxlen,
4031 &options_enum,
4033 &override_enum,
4035 &tags_enum,
4037 &subtype_enum,
4038 &update_fn,
4039 &get_fn,
4040 &set_fn,
4041 &search_fn,
4043 &search_options_enum))
4044 {
4045 return nullptr;
4046 }
4047
4048 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4049 return nullptr;
4050 }
4051 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4052 return nullptr;
4053 }
4054 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4055 return nullptr;
4056 }
4057 if (bpy_prop_callback_check(search_fn, "search", 3) == -1) {
4058 return nullptr;
4059 }
4060
4061 if (id_data.prop_free_handle != nullptr) {
4062 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
4063 }
4064 prop = RNA_def_property(srna, id_data.value, PROP_STRING, subtype_enum.value);
4065
4066 if (maxlen != 0) {
4067 /* +1 since it includes null terminator. */
4068 RNA_def_property_string_maxlength(prop, maxlen + 1);
4069 }
4070 if (default_value && default_value[0]) {
4071 RNA_def_property_string_default(prop, default_value);
4072 }
4073 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
4074 if (translation_context) {
4075 RNA_def_property_translation_context(prop, translation_context);
4076 }
4077
4078 if (tags_enum.base.is_set) {
4079 RNA_def_property_tags(prop, tags_enum.base.value);
4080 }
4081 if (options_enum.is_set) {
4082 bpy_prop_assign_flag(prop, options_enum.value);
4083 }
4084 if (override_enum.is_set) {
4085 bpy_prop_assign_flag_override(prop, override_enum.value);
4086 }
4087 bpy_prop_callback_assign_update(prop, update_fn);
4089 prop, get_fn, set_fn, search_fn, eStringPropertySearchFlag(search_options_enum.value));
4091
4092 Py_RETURN_NONE;
4093}
4094
4096 /* Wrap. */
4097 BPy_EnumProperty_doc,
4098 ".. function:: EnumProperty("
4099 "items, "
4100 "*, "
4101 "name=\"\", "
4102 "description=\"\", "
4103 "translation_context=\"*\", "
4104 "default=None, "
4105 "options={'ANIMATABLE'}, "
4106 "override=set(), "
4107 "tags=set(), "
4108 "update=None, "
4109 "get=None, "
4110 "set=None)\n"
4111 "\n"
4112 " Returns a new enumerator property definition.\n"
4113 "\n"
4114 " :arg items: sequence of enum items formatted:\n"
4115 " ``[(identifier, name, description, icon, number), ...]``.\n"
4116 "\n"
4117 " The first three elements of the tuples are mandatory.\n"
4118 "\n"
4119 " :identifier: The identifier is used for Python access.\n"
4120 " :name: Name for the interface.\n"
4121 " :description: Used for documentation and tooltips.\n"
4122 " :icon: An icon string identifier or integer icon value\n"
4123 " (e.g. returned by :class:`bpy.types.UILayout.icon`)\n"
4124 " :number: Unique value used as the identifier for this item (stored in file data).\n"
4125 " Use when the identifier may need to change. If the *ENUM_FLAG* option is used,\n"
4126 " the values are bit-masks and should be powers of two.\n"
4127 "\n"
4128 " When an item only contains 4 items they define ``(identifier, name, description, "
4129 "number)``.\n"
4130 "\n"
4131 " Separators may be added using None instead of a tuple."
4132 "\n"
4133 " For dynamic values a callback can be passed which returns a list in\n"
4134 " the same format as the static list.\n"
4135 " This function must take 2 arguments ``(self, context)``, **context may be None**.\n"
4136 "\n"
4137 " .. warning::\n"
4138 "\n"
4139 " There is a known bug with using a callback,\n"
4140 " Python must keep a reference to the strings returned by the callback or Blender\n"
4141 " will misbehave or even crash."
4142 "\n"
4143 " :type items: Sequence["
4144 "tuple[str, str, str] | "
4145 "tuple[str, str, str, int] | "
4146 "tuple[str, str, str, int, int] | "
4147 "None] | "
4148 "Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.Context` | None], "
4149 /* NOTE(@ideasman42): a type alias would be useful here (same as above). */
4150 "Sequence["
4151 "tuple[str, str, str] | "
4152 "tuple[str, str, str, int] | "
4153 "tuple[str, str, str, int, int] | "
4154 "None]"
4156 " :arg default: The default value for this enum, a string from the identifiers used in "
4157 "*items*, or integer matching an item number.\n"
4158 " If the *ENUM_FLAG* option is used this must be a set of such string identifiers "
4159 "instead.\n"
4160 " WARNING: Strings cannot be specified for dynamic enums\n"
4161 " (i.e. if a callback function is given as *items* parameter).\n"
4162 " :type default: str | int | set[str]\n" BPY_PROPDEF_OPTIONS_ENUM_DOC
4165static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
4166{
4167 StructRNA *srna;
4168 { /* Keep this block first. */
4169 PyObject *deferred_result;
4170 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_EnumProperty, &deferred_result);
4171 if (srna == nullptr) {
4172 return deferred_result;
4173 }
4174 }
4175
4176 BPy_PropIDParse id_data{};
4177 id_data.srna = srna;
4178
4179 const char *name = nullptr, *description = "";
4180 const char *translation_context = nullptr;
4181 PyObject *default_py = nullptr;
4182 int default_value = 0;
4183 PyObject *items, *items_fast;
4184 const EnumPropertyItem *eitems;
4185 PropertyRNA *prop;
4186
4187 BPy_EnumProperty_Parse options_enum{};
4189 options_enum.value = 0;
4190
4191 BPy_EnumProperty_Parse override_enum{};
4193 override_enum.value = 0;
4194
4196 tags_enum.srna = srna;
4197
4198 bool is_itemf = false;
4199 PyObject *update_fn = nullptr;
4200 PyObject *get_fn = nullptr;
4201 PyObject *set_fn = nullptr;
4202
4203 static const char *_keywords[] = {
4204 "attr",
4205 "items",
4206 "name",
4207 "description",
4208 "translation_context",
4209 "default",
4210 "options",
4211 "override",
4212 "tags",
4213 "update",
4214 "get",
4215 "set",
4216 nullptr,
4217 };
4218 static _PyArg_Parser _parser = {
4220 "O&" /* `attr` */
4221 "O" /* `items` */
4222 "|$" /* Optional, keyword only arguments. */
4223 "s" /* `name` */
4224 "s" /* `description` */
4225 "s" /* `translation_context` */
4226 "O" /* `default` */
4227 "O&" /* `options` */
4228 "O&" /* `override` */
4229 "O&" /* `tags` */
4230 "O" /* `update` */
4231 "O" /* `get` */
4232 "O" /* `set` */
4233 ":EnumProperty",
4234 _keywords,
4235 nullptr,
4236 };
4237 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4238 kw,
4239 &_parser,
4241 &id_data,
4242 &items,
4243 &name,
4244 &description,
4245 &translation_context,
4246 &default_py,
4248 &options_enum,
4250 &override_enum,
4252 &tags_enum,
4253 &update_fn,
4254 &get_fn,
4255 &set_fn))
4256 {
4257 return nullptr;
4258 }
4259
4260 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4261 return nullptr;
4262 }
4263 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4264 return nullptr;
4265 }
4266 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4267 return nullptr;
4268 }
4269
4270 if (default_py == Py_None) {
4271 /* This allows to get same behavior when explicitly passing None as default value,
4272 * and not defining a default value at all! */
4273 default_py = nullptr;
4274 }
4275
4276 /* Items can be a list or a callable.
4277 * NOTE: Don't use #PyCallable_Check because we need the function code for errors. */
4278 if (PyFunction_Check(items)) {
4279 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items);
4280 if (f_code->co_argcount != 2) {
4281 PyErr_Format(PyExc_ValueError,
4282 "EnumProperty(...): expected 'items' function to take 2 arguments, not %d",
4283 f_code->co_argcount);
4284 return nullptr;
4285 }
4286
4287 if (default_py) {
4288 /* Only support getting integer default values here. */
4289 if (!py_long_as_int(default_py, &default_value)) {
4290 /* NOTE: using type error here is odd but python does this for invalid arguments. */
4291 PyErr_SetString(
4292 PyExc_TypeError,
4293 "EnumProperty(...): 'default' can only be an integer when 'items' is a function");
4294 return nullptr;
4295 }
4296 }
4297
4298 is_itemf = true;
4300 }
4301 else {
4302 if (!(items_fast = PySequence_Fast(
4303 items,
4304 "EnumProperty(...): "
4305 "expected a sequence of tuples for the enum items or a function")))
4306 {
4307 return nullptr;
4308 }
4309
4310 eitems = enum_items_from_py(
4311 items_fast, (options_enum.value & PROP_ENUM_FLAG) != 0, default_py, &default_value);
4312
4313 if (!eitems) {
4314 Py_DECREF(items_fast);
4315 return nullptr;
4316 }
4317 }
4318
4319 if (id_data.prop_free_handle != nullptr) {
4320 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
4321 }
4322 if (options_enum.value & PROP_ENUM_FLAG) {
4323 prop = RNA_def_enum_flag(
4324 srna, id_data.value, eitems, default_value, name ? name : id_data.value, description);
4325 }
4326 else {
4327 prop = RNA_def_enum(
4328 srna, id_data.value, eitems, default_value, name ? name : id_data.value, description);
4329 }
4330 if (translation_context) {
4331 RNA_def_property_translation_context(prop, translation_context);
4332 }
4333
4334 if (tags_enum.base.is_set) {
4335 RNA_def_property_tags(prop, tags_enum.base.value);
4336 }
4337 if (options_enum.is_set) {
4338 bpy_prop_assign_flag(prop, options_enum.value);
4339 }
4340 if (override_enum.is_set) {
4341 bpy_prop_assign_flag_override(prop, override_enum.value);
4342 }
4343 bpy_prop_callback_assign_update(prop, update_fn);
4344 bpy_prop_callback_assign_enum(prop, get_fn, set_fn, (is_itemf ? items : nullptr));
4346
4347 if (is_itemf == false) {
4348 /* NOTE: this must be postponed until after #RNA_def_property_duplicate_pointers
4349 * otherwise if this is a generator it may free the strings before we copy them */
4350 Py_DECREF(items_fast);
4351
4352 MEM_freeN((void *)eitems);
4353 }
4354
4355 Py_RETURN_NONE;
4356}
4357
4358StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
4359{
4360 StructRNA *srna;
4361
4362 srna = srna_from_self(value, "");
4363 if (!srna) {
4364 if (PyErr_Occurred()) {
4365 PyObject *msg = PyC_ExceptionBuffer();
4366 const char *msg_char = PyUnicode_AsUTF8(msg);
4367 PyErr_Clear();
4368
4369 PyErr_Format(
4370 PyExc_TypeError, "%.200s expected an RNA type, failed with: %s", error_prefix, msg_char);
4371 Py_DECREF(msg);
4372 }
4373 else {
4374 PyErr_Format(PyExc_TypeError,
4375 "%.200s expected an RNA type, failed with type '%s'",
4376 error_prefix,
4377 Py_TYPE(value)->tp_name);
4378 }
4379 return nullptr;
4380 }
4381
4382 return srna;
4383}
4384
4386 /* Wrap. */
4387 BPy_PointerProperty_doc,
4388 ".. function:: PointerProperty("
4389 "type=None, "
4390 "*, "
4391 "name=\"\", "
4392 "description=\"\", "
4393 "translation_context=\"*\", "
4394 "options={'ANIMATABLE'}, "
4395 "override=set(), "
4396 "tags=set(), "
4397 "poll=None, "
4398 "update=None)\n"
4399 "\n"
4400 " Returns a new pointer property definition.\n"
4404PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
4405{
4406 StructRNA *srna;
4407 { /* Keep this block first. */
4408 PyObject *deferred_result;
4410 self, args, kw, pymeth_PointerProperty, &deferred_result);
4411 if (srna == nullptr) {
4412 return deferred_result;
4413 }
4414 }
4415
4416 BPy_PropIDParse id_data{};
4417 id_data.srna = srna;
4418
4419 const char *name = nullptr, *description = "";
4420 const char *translation_context = nullptr;
4421 PropertyRNA *prop;
4422 StructRNA *ptype;
4423 PyObject *type = Py_None;
4424
4425 BPy_EnumProperty_Parse options_enum{};
4426 options_enum.items = rna_enum_property_flag_items;
4427 options_enum.value = 0;
4428
4429 BPy_EnumProperty_Parse override_enum{};
4431 override_enum.value = 0;
4432
4434 tags_enum.srna = srna;
4435
4436 PyObject *update_fn = nullptr, *poll_fn = nullptr;
4437
4438 static const char *_keywords[] = {
4439 "attr",
4440 "type",
4441 "name",
4442 "description",
4443 "translation_context",
4444 "options",
4445 "override",
4446 "tags",
4447 "poll",
4448 "update",
4449 nullptr,
4450 };
4451 static _PyArg_Parser _parser = {
4453 "O&" /* `attr` */
4454 "O" /* `type` */
4455 "|$" /* Optional, keyword only arguments. */
4456 "s" /* `name` */
4457 "s" /* `description` */
4458 "s" /* `translation_context` */
4459 "O&" /* `options` */
4460 "O&" /* `override` */
4461 "O&" /* `tags` */
4462 "O" /* `poll` */
4463 "O" /* `update` */
4464 ":PointerProperty",
4465 _keywords,
4466 nullptr,
4467 };
4468 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4469 kw,
4470 &_parser,
4472 &id_data,
4473 &type,
4474 &name,
4475 &description,
4476 &translation_context,
4478 &options_enum,
4480 &override_enum,
4482 &tags_enum,
4483 &poll_fn,
4484 &update_fn))
4485 {
4486 return nullptr;
4487 }
4488
4489 ptype = pointer_type_from_py(type, "PointerProperty(...)");
4490 if (!ptype) {
4491 return nullptr;
4492 }
4493 if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup) && !RNA_struct_is_ID(ptype)) {
4494 PyErr_Format(PyExc_TypeError,
4495 "PointerProperty(...) expected an RNA type derived from %.200s or %.200s",
4496 RNA_struct_ui_name(&RNA_ID),
4498 return nullptr;
4499 }
4500 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4501 return nullptr;
4502 }
4503 if (bpy_prop_callback_check(poll_fn, "poll", 2) == -1) {
4504 return nullptr;
4505 }
4506
4507 if (id_data.prop_free_handle != nullptr) {
4508 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
4509 }
4511 srna, id_data.value, ptype, name ? name : id_data.value, description);
4512 if (translation_context) {
4513 RNA_def_property_translation_context(prop, translation_context);
4514 }
4515
4516 if (tags_enum.base.is_set) {
4517 RNA_def_property_tags(prop, tags_enum.base.value);
4518 }
4519 if (options_enum.is_set) {
4520 bpy_prop_assign_flag(prop, options_enum.value);
4521 }
4522 if (override_enum.is_set) {
4523 bpy_prop_assign_flag_override(prop, override_enum.value);
4524 }
4525
4527 if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
4529 }
4530 }
4531 bpy_prop_callback_assign_update(prop, update_fn);
4532 bpy_prop_callback_assign_pointer(prop, poll_fn);
4534
4535 Py_RETURN_NONE;
4536}
4537
4539 /* Wrap. */
4540 BPy_CollectionProperty_doc,
4541 ".. function:: CollectionProperty("
4542 "type=None, "
4543 "*, "
4544 "name=\"\", "
4545 "description=\"\", "
4546 "translation_context=\"*\", "
4547 "options={'ANIMATABLE'}, "
4548 "override=set(), "
4549 "tags=set())\n"
4550 "\n"
4551 " Returns a new collection property definition.\n"
4555PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
4556{
4557 StructRNA *srna;
4558 { /* Keep this block first. */
4559 PyObject *deferred_result;
4561 self, args, kw, pymeth_CollectionProperty, &deferred_result);
4562 if (srna == nullptr) {
4563 return deferred_result;
4564 }
4565 }
4566
4567 BPy_PropIDParse id_data{};
4568 id_data.srna = srna;
4569
4570 const char *name = nullptr, *description = "";
4571 const char *translation_context = nullptr;
4572 PropertyRNA *prop;
4573 StructRNA *ptype;
4574 PyObject *type = Py_None;
4575
4576 BPy_EnumProperty_Parse options_enum{};
4577 options_enum.items = rna_enum_property_flag_items;
4578 options_enum.value = 0;
4579
4580 BPy_EnumProperty_Parse override_enum{};
4582 override_enum.value = 0;
4583
4585 tags_enum.srna = srna;
4586
4587 static const char *_keywords[] = {
4588 "attr",
4589 "type",
4590 "name",
4591 "description",
4592 "translation_context",
4593 "options",
4594 "override",
4595 "tags",
4596 nullptr,
4597 };
4598 static _PyArg_Parser _parser = {
4600 "O&" /* `attr` */
4601 "O" /* `type` */
4602 "|$" /* Optional, keyword only arguments. */
4603 "s" /* `name` */
4604 "s" /* `description` */
4605 "s" /* `translation_context` */
4606 "O&" /* `options` */
4607 "O&" /* `override` */
4608 "O&" /* `tags` */
4609 ":CollectionProperty",
4610 _keywords,
4611 nullptr,
4612 };
4613 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4614 kw,
4615 &_parser,
4617 &id_data,
4618 &type,
4619 &name,
4620 &description,
4621 &translation_context,
4623 &options_enum,
4625 &override_enum,
4627 &tags_enum))
4628 {
4629 return nullptr;
4630 }
4631
4632 ptype = pointer_type_from_py(type, "CollectionProperty(...):");
4633 if (!ptype) {
4634 return nullptr;
4635 }
4636
4637 if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup)) {
4638 PyErr_Format(PyExc_TypeError,
4639 "CollectionProperty(...) expected an RNA type derived from %.200s",
4641 return nullptr;
4642 }
4643
4644 if (id_data.prop_free_handle != nullptr) {
4645 RNA_def_property_free_identifier_deferred_finish(srna, id_data.prop_free_handle);
4646 }
4648 srna, id_data.value, ptype, name ? name : id_data.value, description);
4649 if (translation_context) {
4650 RNA_def_property_translation_context(prop, translation_context);
4651 }
4652
4653 if (tags_enum.base.is_set) {
4654 RNA_def_property_tags(prop, tags_enum.base.value);
4655 }
4656 if (options_enum.is_set) {
4657 bpy_prop_assign_flag(prop, options_enum.value);
4658 }
4659 if (override_enum.is_set) {
4660 bpy_prop_assign_flag_override(prop, override_enum.value);
4661 }
4662
4664 if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
4666 }
4667 }
4669
4670 Py_RETURN_NONE;
4671}
4672
4674 /* Wrap. */
4675 BPy_RemoveProperty_doc,
4676 ".. function:: RemoveProperty(cls, attr)\n"
4677 "\n"
4678 " Removes a dynamically defined property.\n"
4679 "\n"
4680 " :arg cls: The class containing the property (must be a positional argument).\n"
4681 " :type cls: type\n"
4682 " :arg attr: Property name (must be passed as a keyword).\n"
4683 " :type attr: str\n"
4684 "\n"
4685 ".. note:: Typically this function doesn't need to be accessed directly.\n"
4686 " Instead use ``del cls.attr``\n");
4687static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
4688{
4689 StructRNA *srna;
4690
4691 if (PyTuple_GET_SIZE(args) == 1) {
4692 PyObject *ret;
4693 self = PyTuple_GET_ITEM(args, 0);
4694 args = PyTuple_New(0);
4695 ret = BPy_RemoveProperty(self, args, kw);
4696 Py_DECREF(args);
4697 return ret;
4698 }
4699 if (PyTuple_GET_SIZE(args) > 1) {
4700 PyErr_SetString(PyExc_ValueError, "expected one positional arg, one keyword arg");
4701 return nullptr;
4702 }
4703
4704 srna = srna_from_self(self, "RemoveProperty(...):");
4705 if (srna == nullptr && PyErr_Occurred()) {
4706 return nullptr; /* self's type was compatible but error getting the srna */
4707 }
4708 if (srna == nullptr) {
4709 PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type");
4710 return nullptr;
4711 }
4712
4713 const char *id = nullptr;
4714
4715 static const char *_keywords[] = {
4716 "attr",
4717 nullptr,
4718 };
4719 static _PyArg_Parser _parser = {
4721 "s" /* `attr` */
4722 ":RemoveProperty",
4723 _keywords,
4724 nullptr,
4725 };
4726 if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &id)) {
4727 return nullptr;
4728 }
4729
4730 if (RNA_def_property_free_identifier(srna, id) != 1) {
4731 PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id);
4732 return nullptr;
4733 }
4734
4735 Py_RETURN_NONE;
4736}
4737
4740/* -------------------------------------------------------------------- */
4744#if (defined(__GNUC__) && !defined(__clang__))
4745# pragma GCC diagnostic push
4746# pragma GCC diagnostic ignored "-Wcast-function-type"
4747#endif
4748
4749static PyMethodDef props_methods[] = {
4750 {"BoolProperty",
4751 (PyCFunction)BPy_BoolProperty,
4752 METH_VARARGS | METH_KEYWORDS,
4753 BPy_BoolProperty_doc},
4754 {"BoolVectorProperty",
4755 (PyCFunction)BPy_BoolVectorProperty,
4756 METH_VARARGS | METH_KEYWORDS,
4757 BPy_BoolVectorProperty_doc},
4758 {"IntProperty",
4759 (PyCFunction)BPy_IntProperty,
4760 METH_VARARGS | METH_KEYWORDS,
4761 BPy_IntProperty_doc},
4762 {"IntVectorProperty",
4763 (PyCFunction)BPy_IntVectorProperty,
4764 METH_VARARGS | METH_KEYWORDS,
4765 BPy_IntVectorProperty_doc},
4766 {"FloatProperty",
4767 (PyCFunction)BPy_FloatProperty,
4768 METH_VARARGS | METH_KEYWORDS,
4769 BPy_FloatProperty_doc},
4770 {"FloatVectorProperty",
4771 (PyCFunction)BPy_FloatVectorProperty,
4772 METH_VARARGS | METH_KEYWORDS,
4773 BPy_FloatVectorProperty_doc},
4774 {"StringProperty",
4775 (PyCFunction)BPy_StringProperty,
4776 METH_VARARGS | METH_KEYWORDS,
4777 BPy_StringProperty_doc},
4778 {"EnumProperty",
4779 (PyCFunction)BPy_EnumProperty,
4780 METH_VARARGS | METH_KEYWORDS,
4781 BPy_EnumProperty_doc},
4782 {"PointerProperty",
4783 (PyCFunction)BPy_PointerProperty,
4784 METH_VARARGS | METH_KEYWORDS,
4785 BPy_PointerProperty_doc},
4786 {"CollectionProperty",
4787 (PyCFunction)BPy_CollectionProperty,
4788 METH_VARARGS | METH_KEYWORDS,
4789 BPy_CollectionProperty_doc},
4790
4791 {"RemoveProperty",
4792 (PyCFunction)BPy_RemoveProperty,
4793 METH_VARARGS | METH_KEYWORDS,
4794 BPy_RemoveProperty_doc},
4795 {nullptr, nullptr, 0, nullptr},
4796};
4797
4798#if (defined(__GNUC__) && !defined(__clang__))
4799# pragma GCC diagnostic pop
4800#endif
4801
4802static int props_visit(PyObject * /*self*/, visitproc visit, void *arg)
4803{
4805 PyObject **py_data = (PyObject **)&prop_store->py_data;
4806 for (int i = 0; i < BPY_PROP_STORE_PY_DATA_SIZE; i++) {
4807 Py_VISIT(py_data[i]);
4808 }
4809 }
4810 return 0;
4811}
4812
4813static int props_clear(PyObject * /*self*/)
4814{
4816 PyObject **py_data = (PyObject **)&prop_store->py_data;
4817 for (int i = 0; i < BPY_PROP_STORE_PY_DATA_SIZE; i++) {
4818 Py_CLEAR(py_data[i]);
4819 }
4820 }
4821 return 0;
4822}
4823
4825 /* Wrap. */
4826 props_module_doc,
4827 "This module defines properties to extend Blender's internal data. The result of these "
4828 "functions"
4829 " is used to assign properties to classes registered with Blender and can't be used "
4830 "directly.\n"
4831 "\n"
4832 ".. note:: All parameters to these functions must be passed as keywords.\n");
4833
4834static PyModuleDef props_module = {
4835 /*m_base*/ PyModuleDef_HEAD_INIT,
4836 /*m_name*/ "bpy.props",
4837 /*m_doc*/ props_module_doc,
4838 /*m_size*/ -1, /* multiple "initialization" just copies the module dict. */
4839 /*m_methods*/ props_methods,
4840 /*m_slots*/ nullptr,
4841 /*m_traverse*/ props_visit,
4842 /*m_clear*/ props_clear,
4843 /*m_free*/ nullptr,
4844};
4845
4846PyObject *BPY_rna_props()
4847{
4848 PyObject *submodule;
4849 PyObject *submodule_dict;
4850
4851 submodule = PyModule_Create(&props_module);
4852 PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
4853
4854 /* api needs the PyObjects internally */
4855 submodule_dict = PyModule_GetDict(submodule);
4856
4857#define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name)
4858
4859 ASSIGN_STATIC(BoolProperty);
4860 ASSIGN_STATIC(BoolVectorProperty);
4861 ASSIGN_STATIC(IntProperty);
4862 ASSIGN_STATIC(IntVectorProperty);
4863 ASSIGN_STATIC(FloatProperty);
4864 ASSIGN_STATIC(FloatVectorProperty);
4865 ASSIGN_STATIC(StringProperty);
4866 ASSIGN_STATIC(EnumProperty);
4867 ASSIGN_STATIC(PointerProperty);
4868 ASSIGN_STATIC(CollectionProperty);
4869 ASSIGN_STATIC(RemoveProperty);
4870
4871 if (PyType_Ready(&bpy_prop_deferred_Type) < 0) {
4872 return nullptr;
4873 }
4874 PyModule_AddType(submodule, &bpy_prop_deferred_Type);
4875
4876 /* Run this when properties are freed. */
4878
4879 return submodule;
4880}
4881
4883{
4884 /* Remove all user counts, so this isn't considered a leak from Python's perspective. */
4885 props_clear(nullptr);
4886
4887 /* Running is harmless, but redundant. */
4889
4890 /* Include as it's correct, in practice this should never be used again. */
4892}
4893
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
#define STRINGIFY(x)
#define UNLIKELY(x)
#define STREQ(a, b)
ID and Library types, which are fundamental for SDNA.
#define MAX_IDPROP_NAME
Definition DNA_ID.h:185
Read Guarded memory(de)allocation.
int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier)
void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA *prop)
void RNA_def_property_free_pointers_set_py_data_callback(void(*py_data_clear_fn)(PropertyRNA *prop))
void RNA_def_property_free_identifier_deferred_finish(StructOrFunctionRNA *cont_, void *handle)
int RNA_def_property_free_identifier_deferred_prepare(StructOrFunctionRNA *cont_, const char *identifier, void **handle)
#define RNA_MAX_ARRAY_DIMENSION
Definition RNA_define.hh:26
int(*)(PointerRNA *ptr, PropertyRNA *prop) EnumPropertyGetFunc
Definition RNA_types.hh:605
void(*)(PointerRNA *ptr, PropertyRNA *prop, char *value) StringPropertyGetFunc
Definition RNA_types.hh:557
void(*)(PointerRNA *ptr, PropertyRNA *prop, bool *values) BooleanArrayPropertyGetFunc
Definition RNA_types.hh:539
void(*)(PointerRNA *ptr, PropertyRNA *prop, const bool *values) BooleanArrayPropertySetFunc
Definition RNA_types.hh:540
int(*)(PointerRNA *ptr, PropertyRNA *prop) StringPropertyLengthFunc
Definition RNA_types.hh:558
@ STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES
Definition RNA_types.hh:733
void(*)(PointerRNA *ptr, PropertyRNA *prop, float *values) FloatArrayPropertyGetFunc
Definition RNA_types.hh:551
#define RNA_ENUM_BITFLAG_SIZE
Definition RNA_types.hh:125
void(*)(PointerRNA *ptr, PropertyRNA *prop, const char *value) StringPropertySetFunc
Definition RNA_types.hh:559
eStringPropertySearchFlag
Definition RNA_types.hh:570
@ PROP_STRING_SEARCH_SUGGESTION
Definition RNA_types.hh:584
void(*)(PointerRNA *ptr, PropertyRNA *prop, int *values) IntArrayPropertyGetFunc
Definition RNA_types.hh:545
void(*)(PointerRNA *ptr, PropertyRNA *prop, int value) EnumPropertySetFunc
Definition RNA_types.hh:606
void(*)(PointerRNA *ptr, PropertyRNA *prop, const int *values) IntArrayPropertySetFunc
Definition RNA_types.hh:546
@ PROP_FLOAT
Definition RNA_types.hh:67
@ PROP_BOOLEAN
Definition RNA_types.hh:65
@ PROP_INT
Definition RNA_types.hh:66
@ PROP_STRING
Definition RNA_types.hh:68
void(*)(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *edit_text, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn) StringPropertySearchFunc
Definition RNA_types.hh:598
bool(*)(PointerRNA *ptr, PropertyRNA *prop) BooleanPropertyGetFunc
Definition RNA_types.hh:537
@ PROP_UNIT_NONE
Definition RNA_types.hh:76
float(*)(PointerRNA *ptr, PropertyRNA *prop) FloatPropertyGetFunc
Definition RNA_types.hh:549
int(*)(PointerRNA *ptr, PropertyRNA *prop) IntPropertyGetFunc
Definition RNA_types.hh:543
void(*)(PointerRNA *ptr, PropertyRNA *prop, float value) FloatPropertySetFunc
Definition RNA_types.hh:550
PropertyOverrideFlag
Definition RNA_types.hh:353
void(*)(PointerRNA *ptr, PropertyRNA *prop, int value) IntPropertySetFunc
Definition RNA_types.hh:544
PropertyFlag
Definition RNA_types.hh:201
@ PROP_ANIMATABLE
Definition RNA_types.hh:220
@ PROP_ENUM_FLAG
Definition RNA_types.hh:293
const EnumPropertyItem *(*)(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free) EnumPropertyItemFunc
Definition RNA_types.hh:608
void(*)(PointerRNA *ptr, PropertyRNA *prop, bool value) BooleanPropertySetFunc
Definition RNA_types.hh:538
void(*)(PointerRNA *ptr, PropertyRNA *prop, const float *values) FloatArrayPropertySetFunc
Definition RNA_types.hh:552
@ PROP_MATRIX
Definition RNA_types.hh:168
@ PROP_NONE
Definition RNA_types.hh:136
void bpy_context_clear(struct bContext *C, const PyGILState_STATE *gilstate)
void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate)
PyObject * self
#define BPY_PROPDEF_SUBTYPE_STRING_DOC
Definition bpy_props.cc:70
static void bpy_prop_string_visit_for_search_fn(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *edit_text, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static PyObject * pymeth_FloatProperty
Definition bpy_props.cc:367
static void bpy_prop_callback_assign_float_array(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
static bool bpy_prop_string_visit_fn_call(PyObject *py_func, PyObject *item, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static void bpy_prop_callback_assign_boolean_array(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
Definition bpy_props.cc:813
static PyObject * BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
#define ASSIGN_PYOBJECT_INCREF(a, b)
Definition bpy_props.cc:159
static void bpy_prop_array_matrix_swap_row_column_vn_vn(float *values_dst, const float *values_src, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:535
static PyObject * BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
static void bpy_prop_callback_assign_string(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *search_fn, const eStringPropertySearchFlag search_flag)
static PyModuleDef props_module
static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, PropertyRNA *prop)
#define BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC
Definition bpy_props.cc:66
static bool py_long_as_int(PyObject *py_long, int *r_int)
PyObject * BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
static bool bpy_prop_array_is_matrix_compatible_ex(int subtype, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:517
static float bpy_prop_float_get_fn(PointerRNA *ptr, PropertyRNA *prop)
#define BPY_PROPDEF_NAME_DOC
static int bpy_prop_int_get_fn(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_props.cc:887
static PyGetSetDef bpy_prop_deferred_getset[]
Definition bpy_props.cc:273
static void bpy_prop_callback_assign_int_array(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
#define BPY_PROPDEF_FLOAT_STEP_DOC
static PyObject * pymeth_IntVectorProperty
Definition bpy_props.cc:366
PyDoc_STRVAR(bpy_prop_deferred_doc, "Intermediate storage for properties before registration.\n" "\n" ".. note::\n" "\n" " This is not part of the stable API and may change between releases.")
#define BPY_PROPDEF_UPDATE_DOC
static bool bpy_prop_array_is_matrix_compatible(PropertyRNA *prop, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:525
static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bool *values)
Definition bpy_props.cc:743
static int bpy_prop_string_length_fn(PointerRNA *ptr, PropertyRNA *prop)
static PyObject * pymeth_EnumProperty
Definition bpy_props.cc:370
#define BPY_PROPDEF_NUM_SOFT_MINMAX_DOC(ty)
static PyObject * bpy_prop_deferred_keywords_get(BPy_PropDeferred *self, void *)
Definition bpy_props.cc:266
static int bpy_prop_deferred_clear(BPy_PropDeferred *self)
Definition bpy_props.cc:224
static void bpy_prop_py_data_remove(PropertyRNA *prop)
Definition bpy_props.cc:187
static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *values)
#define BPY_PROPDEF_FLOAT_PREC_DOC
static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const float *values)
#define BPY_PROPDEF_POLL_DOC
#define BPY_PROPDEF_NUM_MINMAX_DOC(ty)
static PyObject * BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
static PyObject * pymeth_FloatVectorProperty
Definition bpy_props.cc:368
static PyObject * BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject * BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
static void bpy_prop_int_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition bpy_props.cc:947
static PyObject * pymeth_IntProperty
Definition bpy_props.cc:365
#define BPY_PROPDEF_SET_DOC(ty)
static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const int *values)
#define BPY_PROPDEF_POINTER_TYPE_DOC
PyObject * BPY_rna_props()
static PyMethodDef props_methods[]
static void bpy_prop_callback_assign_pointer(PropertyRNA *prop, PyObject *poll_fn)
static PyObject * pyrna_struct_as_instance(PointerRNA *ptr)
Definition bpy_props.cc:375
static PyObject * BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
static PyObject * bpy_prop_deferred_function_get(BPy_PropDeferred *self, void *)
Definition bpy_props.cc:255
static void bpy_prop_deferred_dealloc(BPy_PropDeferred *self)
Definition bpy_props.cc:211
static int props_clear(PyObject *)
static void bpy_prop_boolean_set_fn(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition bpy_props.cc:687
void BPY_rna_props_clear_all()
static PyObject * pymeth_RemoveProperty
Definition bpy_props.cc:373
static void bpy_prop_callback_assign_int(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
static void bpy_prop_enum_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
static int icon_id_from_name(const char *name)
static PyObject * pymeth_CollectionProperty
Definition bpy_props.cc:372
static void bpy_prop_assign_flag(PropertyRNA *prop, const int flag)
Definition bpy_props.cc:399
static const EnumPropertyItem * enum_items_from_py(PyObject *seq_fast, const bool is_enum_flag, PyObject *default_py, int *r_default_value)
static PyObject * BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
static void bpy_prop_callback_assign_float(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
static PyObject * BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
#define BPY_PROPDEF_CTXT_DOC
#define BPY_PROPDEF_COLLECTION_TYPE_DOC
#define BPY_PROPDEF_TAGS_DOC
static int bpy_prop_deferred_traverse(BPy_PropDeferred *self, visitproc visit, void *arg)
Definition bpy_props.cc:218
#define BPY_PROP_STORE_PY_DATA_SIZE
Definition bpy_props.cc:157
static int bpy_prop_array_length_parse(PyObject *o, void *p)
Definition bpy_props.cc:433
static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, float *values)
static PyObject * pymeth_PointerProperty
Definition bpy_props.cc:371
#define BPY_PROPDEF_OPTIONS_DOC
Definition bpy_props.cc:54
static int bpy_prop_arg_parse_id(PyObject *o, void *p)
static int bpy_prop_array_from_py_with_dims(void *values, size_t values_elem_size, PyObject *py_values, const BPyPropArrayLength *array_len_info, const PyTypeObject *type, const char *error_str)
Definition bpy_props.cc:501
static bool bpy_prop_boolean_get_fn(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_props.cc:624
#define BPY_PROPDEF_GET_DOC(ty)
static void bpy_prop_float_set_fn(PointerRNA *ptr, PropertyRNA *prop, float value)
static void bpy_prop_callback_assign_boolean(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn)
static BPyPropStore * bpy_prop_py_data_ensure(PropertyRNA *prop)
Definition bpy_props.cc:173
static StructRNA * bpy_prop_deferred_data_or_srna(PyObject *self, PyObject *args, PyObject *kw, PyObject *method_object, PyObject **r_deferred_result)
#define BPY_PROPDEF_SEARCH_DOC
static void bpy_prop_string_get_fn(PointerRNA *ptr, PropertyRNA *prop, char *value)
StructRNA * pointer_type_from_py(PyObject *value, const char *error_prefix)
static PyObject * bpy_prop_deferred_data_CreatePyObject(PyObject *fn, PyObject *kw)
Definition bpy_props.cc:340
static int bpy_prop_enum_get_fn(PointerRNA *ptr, PropertyRNA *prop)
static const EnumPropertyItem * bpy_prop_enum_itemf_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
static PyObject * pymeth_BoolProperty
Definition bpy_props.cc:363
static void bpy_prop_array_matrix_swap_row_column_vn(float *values, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:549
#define BPY_PROPDEF_OPTIONS_ENUM_DOC
Definition bpy_props.cc:58
static int bpy_prop_arg_parse_tag_defines(PyObject *o, void *p)
static void bpy_prop_update_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_props.cc:568
static void bpy_prop_callback_assign_update(PropertyRNA *prop, PyObject *update_fn)
#define BPY_PROPDEF_UNIT_DOC
static void bpy_prop_callback_assign_enum(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *itemf_fn)
#define BPY_PROPDEF_SUBTYPE_NUMBER_DOC
Definition bpy_props.cc:74
static PyObject * bpy_prop_deferred_call(BPy_PropDeferred *, PyObject *, PyObject *)
Definition bpy_props.cc:241
static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
static PyObject * BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
#define ASSIGN_STATIC(_name)
#define BPY_PROPDEF_SUBTYPE_NUMBER_ARRAY_DOC
Definition bpy_props.cc:78
#define BPY_PROPDEF_VECSIZE_DOC
#define BPY_PROPDEF_INT_STEP_DOC
#define BPY_PROPDEF_DESC_DOC
PyTypeObject bpy_prop_deferred_Type
Definition bpy_props.cc:288
static PyObject * pymeth_BoolVectorProperty
Definition bpy_props.cc:364
static PyObject * BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
static void bpy_prop_string_set_fn(PointerRNA *ptr, PropertyRNA *prop, const char *value)
static ListBase g_bpy_prop_store_list
Definition bpy_props.cc:171
static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_override)
Definition bpy_props.cc:412
#define BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
Definition bpy_props.cc:62
static int props_visit(PyObject *, visitproc visit, void *arg)
static PyObject * bpy_prop_deferred_repr(BPy_PropDeferred *self)
Definition bpy_props.cc:230
static PyObject * pymeth_StringProperty
Definition bpy_props.cc:369
#define PYRNA_STACK_ARRAY
Definition bpy_props.hh:35
bool pyrna_write_check()
Definition bpy_rna.cc:369
StructRNA * srna_from_self(PyObject *self, const char *error_prefix)
Definition bpy_rna.cc:8223
void pyrna_write_set(bool val)
Definition bpy_rna.cc:374
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:7694
BPy_StructRNA * bpy_context_module
Definition bpy_rna.cc:91
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
const T * data() const
Definition BLI_array.hh:301
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:388
int len
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
int pyrna_enum_bitfield_parse_set(PyObject *o, void *p)
int pyrna_enum_value_parse_string(PyObject *o, void *p)
PyObject * PyC_Tuple_PackArray_Bool(const bool *array, uint len)
PyObject * PyC_Tuple_PackArray_Multi_Bool(const bool *array, const int dims[], const int dims_len)
PyObject * PyC_Tuple_PackArray_I32(const int *array, uint len)
PyObject * PyC_ExceptionBuffer()
int PyC_Long_AsBool(PyObject *value)
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
PyObject * PyC_Tuple_PackArray_Multi_F32(const float *array, const int dims[], const int dims_len)
int PyC_AsArray_Multi(void *array, const size_t array_item_size, PyObject *value, const int *dims, const int dims_len, const PyTypeObject *type, const char *error_prefix)
void PyC_Err_PrintWithFunc(PyObject *py_func)
PyObject * PyC_Tuple_PackArray_F32(const float *array, uint len)
PyObject * PyC_Tuple_PackArray_Multi_I32(const int *array, const int dims[], const int dims_len)
int PyC_ParseBool(PyObject *o, void *p)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
return ret
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
bool RNA_struct_is_ID(const StructRNA *type)
int RNA_property_enum_get_default(PointerRNA *, PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
const EnumPropertyItem * RNA_struct_property_tag_defines(const StructRNA *type)
PropertyType RNA_property_type(PropertyRNA *prop)
void ** RNA_struct_instance(PointerRNA *ptr)
const char * RNA_struct_identifier(const StructRNA *type)
bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
int RNA_property_array_dimension(const PointerRNA *ptr, PropertyRNA *prop, int length[])
void * RNA_property_py_data_get(PropertyRNA *prop)
int RNA_property_flag(PropertyRNA *prop)
const char * RNA_struct_ui_name(const StructRNA *type)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
void RNA_def_property_string_search_func_runtime(PropertyRNA *prop, StringPropertySearchFunc search_fn, const eStringPropertySearchFlag search_flag)
void RNA_def_struct_flag(StructRNA *srna, int flag)
PropertyRNA * RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
void RNA_def_property_boolean_default(PropertyRNA *prop, bool value)
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc)
void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_int_default(PropertyRNA *prop, int value)
void RNA_def_py_data(PropertyRNA *prop, void *py_data)
void RNA_def_property_array(PropertyRNA *prop, int length)
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func)
void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
void RNA_def_property_update_runtime_with_context_and_property(PropertyRNA *prop, RNAPropertyUpdateFuncWithContextAndProperty func)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_boolean_array_default(PropertyRNA *prop, const bool *array)
void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
void RNA_def_property_tags(PropertyRNA *prop, int tags)
void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc)
void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
StructRNA RNA_PropertyGroup
const EnumPropertyItem rna_enum_property_override_flag_collection_items[]
Definition rna_rna.cc:224
const EnumPropertyItem rna_enum_dummy_NULL_items[]
Definition rna_rna.cc:29
const EnumPropertyItem rna_enum_property_subtype_number_array_items[]
Definition rna_rna.cc:120
const EnumPropertyItem rna_enum_property_unit_items[]
Definition rna_rna.cc:142
const EnumPropertyItem rna_enum_property_subtype_number_items[]
Definition rna_rna.cc:113
const EnumPropertyItem rna_enum_property_string_search_flag_items[]
Definition rna_rna.cc:239
const EnumPropertyItem rna_enum_property_override_flag_items[]
Definition rna_rna.cc:219
const EnumPropertyItem rna_enum_property_subtype_string_items[]
Definition rna_rna.cc:106
const EnumPropertyItem rna_enum_property_flag_items[]
Definition rna_rna.cc:180
const EnumPropertyItem rna_enum_property_flag_enum_items[]
Definition rna_rna.cc:201
const EnumPropertyItem rna_enum_icon_items[]
Definition rna_ui_api.cc:31
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
_W64 int intptr_t
Definition stdint.h:118
int dims[RNA_MAX_ARRAY_DIMENSION]
Definition bpy_props.cc:426
PyObject * get_fn
Definition bpy_props.cc:131
struct BPyPropStore::@1345::@1346::@1349 pointer_data
PyObject * update_fn
Definition bpy_props.cc:134
struct BPyPropStore::@1345::@1346::@1348 enum_data
BPyPropStore * next
Definition bpy_props.cc:123
BPyPropStore * prev
Definition bpy_props.cc:123
PyObject * itemf_fn
Definition bpy_props.cc:141
PyObject * poll_fn
Definition bpy_props.cc:146
struct BPyPropStore::@1345 py_data
struct BPyPropStore::@1345::@1346::@1350 string_data
PyObject * set_fn
Definition bpy_props.cc:132
PyObject * search_fn
Definition bpy_props.cc:151
BPy_EnumProperty_Parse base
const EnumPropertyItem * items
void * prop_free_handle
const char * value
StructRNA * srna
const char * identifier
Definition RNA_types.hh:506
const char * name
Definition RNA_types.hh:510
const char * description
Definition RNA_types.hh:512
void * data
Definition RNA_types.hh:42
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138