From e125305af41a7360c52b9a38024b7e24fde06d70 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Mar 2021 12:18:56 +1100 Subject: Fix T86332: Error using lambda in annotations in Python 3.10 Callbacks used in `bpy.props` didn't hold a references to the functions they used. While this has been the case since early 2.5x it didn't cause any problems as long as the class held a reference. With Python 3.10 or when using `from __future__ import annotations`, the annotations are no longer owned by the class once evaluated. Resolve this by holding a reference in the module, which now supports traverse & clear callbacks so the objects are visible to Python's garbage collector. Also refactor storage of Python data, moving from an array into a struct. --- source/blender/makesrna/intern/rna_define.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'source/blender/makesrna/intern/rna_define.c') diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 5e188285e39..019823a7de3 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -3305,12 +3305,6 @@ void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, } } -void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data) -{ - EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; - eprop->py_data = py_data; -} - void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, @@ -4632,11 +4626,28 @@ void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA prop->flag_internal |= PROP_INTERN_FREE_POINTERS; } +static void (*g_py_data_clear_fn)(PropertyRNA *prop) = NULL; + +/** + * Set the callback used to decrement the user count of a property. + * + * This function is called when freeing each dynamically defined property. + */ +void RNA_def_property_free_pointers_set_py_data_callback( + void (*py_data_clear_fn)(PropertyRNA *prop)) +{ + g_py_data_clear_fn = py_data_clear_fn; +} + void RNA_def_property_free_pointers(PropertyRNA *prop) { if (prop->flag_internal & PROP_INTERN_FREE_POINTERS) { int a; + if (g_py_data_clear_fn) { + g_py_data_clear_fn(prop); + } + if (prop->identifier) { MEM_freeN((void *)prop->identifier); } -- cgit v1.2.3