Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-02-20 08:16:43 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-02-20 08:19:33 +0300
commit37e6a1995ac7eeabd5b6a56621ad5a850dae4149 (patch)
tree5a3531d6e7a033c7afe81f97ac3dc157c79cb00a /source/blender/python/intern/bpy_props.c
parent4cd808f912173b8c59c217860313e178102e893e (diff)
PyAPI: use a new type for storing the deferred result of bpy.props
This is needed to support Python 3.10's Postponed annotation evaluation. It also simplifies type checking.
Diffstat (limited to 'source/blender/python/intern/bpy_props.c')
-rw-r--r--source/blender/python/intern/bpy_props.c92
1 files changed, 70 insertions, 22 deletions
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 878bf4aec5d..c596f81a91c 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -193,6 +193,71 @@ static const EnumPropertyItem property_subtype_array_items[] = {
"'XYZ', 'XYZ_LENGTH', 'COLOR_GAMMA', 'COORDINATES', 'LAYER', 'LAYER_MEMBER', 'NONE'].\n" \
" :type subtype: string\n"
+/* -------------------------------------------------------------------- */
+/** \name Deferred Property Type
+ *
+ * Operators and classes use this so it can store the arguments given but defer
+ * running it until the operator runs where these values are used to setup
+ * the default arguments for that operator instance.
+ * \{ */
+
+static void bpy_prop_deferred_dealloc(BPy_PropDeferred *self)
+{
+ if (self->kw) {
+ PyObject_GC_UnTrack(self);
+ Py_CLEAR(self->kw);
+ }
+ PyObject_GC_Del(self);
+}
+
+static int bpy_prop_deferred_traverse(BPy_PropDeferred *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->kw);
+ return 0;
+}
+
+static int bpy_prop_deferred_clear(BPy_PropDeferred *self)
+{
+ Py_CLEAR(self->kw);
+ return 0;
+}
+
+static PyObject *bpy_prop_deferred_repr(BPy_PropDeferred *self)
+{
+ return PyUnicode_FromFormat("<%.200s, %R, %R>", Py_TYPE(self)->tp_name, self->fn, self->kw);
+}
+
+PyTypeObject bpy_prop_deferred_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "bpy_prop_deferred",
+ .tp_basicsize = sizeof(BPy_PropDeferred),
+ .tp_dealloc = (destructor)bpy_prop_deferred_dealloc,
+ .tp_repr = (reprfunc)bpy_prop_deferred_repr,
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+
+ .tp_traverse = (traverseproc)bpy_prop_deferred_traverse,
+ .tp_clear = (inquiry)bpy_prop_deferred_clear,
+};
+
+static PyObject *bpy_prop_deferred_data_CreatePyObject(PyObject *fn, PyObject *kw)
+{
+ BPy_PropDeferred *self = PyObject_GC_New(BPy_PropDeferred, &bpy_prop_deferred_Type);
+ self->fn = fn;
+ if (kw == NULL) {
+ kw = PyDict_New();
+ }
+ else {
+ Py_INCREF(kw);
+ }
+ self->kw = kw;
+ PyObject_GC_Track(self);
+ return (PyObject *)self;
+}
+
+/** \} */
+
/* PyObject's */
static PyObject *pymeth_BoolProperty = NULL;
static PyObject *pymeth_BoolVectorProperty = NULL;
@@ -248,27 +313,6 @@ static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_over
RNA_def_property_override_flag(prop, flag_override);
}
-/* operators and classes use this so it can store the args given but defer
- * running it until the operator runs where these values are used to setup
- * the default args for that operator instance */
-static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
-{
- PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, func);
- Py_INCREF(func);
-
- if (kw == NULL) {
- kw = PyDict_New();
- }
- else {
- Py_INCREF(kw);
- }
-
- PyTuple_SET_ITEM(ret, 1, kw);
-
- return ret;
-}
-
/* callbacks */
static void bpy_prop_update_cb(struct bContext *C,
struct PointerRNA *ptr,
@@ -1997,7 +2041,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop,
if (PyErr_Occurred()) { \
return NULL; \
} \
- return bpy_prop_deferred_return(pymeth_##_func, kw); \
+ return bpy_prop_deferred_data_CreatePyObject(pymeth_##_func, kw); \
} \
(void)0
@@ -3668,5 +3712,9 @@ PyObject *BPY_rna_props(void)
ASSIGN_STATIC(CollectionProperty);
ASSIGN_STATIC(RemoveProperty);
+ if (PyType_Ready(&bpy_prop_deferred_Type) < 0) {
+ return NULL;
+ }
+
return submodule;
}