From a80c1e50bc7f57bc4d4c41bc51ac92d1d4c39030 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 25 May 2015 14:19:51 +0200 Subject: Fix T44822: python enums' itemf callback did not handle 'NULL' context case. Enum's itemf callback can be called without context in some cases (UI, doc generation...). Python's enum properties did not handle this at all - it's kind of odd this did not cause more trouble and wasn't notice earlier... Probably dynamic enums using context are not much used in py code. Note about nodes: those are heavy users of dynamic enum with context. Now, we expect `NodeCategory.poll()` and `NodeItem.poll()` to always be called with a valid context (since when there is no context available, we can assume `poll()` is always True). `NodeCategory.items()`, however, must accept NULL context, so if you use custom `items` callable for your custom node categories, you may need to update it (as was done here for builtin `node_group_items()`). --- source/blender/python/intern/bpy_props.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'source/blender/python/intern/bpy_props.c') diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 779c738b19f..b0fae243182 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -1481,15 +1481,26 @@ static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA * EnumPropertyItem *eitems = NULL; int err = 0; - bpy_context_set(C, &gilstate); + if (C) { + bpy_context_set(C, &gilstate); + } + else { + gilstate = PyGILState_Ensure(); + } args = PyTuple_New(2); self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); /* now get the context */ - PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); - Py_INCREF(bpy_context_module); + if (C) { + PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); + Py_INCREF(bpy_context_module); + } + else { + PyTuple_SET_ITEM(args, 1, Py_None); + Py_INCREF(Py_None); + } items = PyObject_CallObject(py_func, args); @@ -1530,8 +1541,13 @@ static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA * eitems = DummyRNA_NULL_items; } + if (C) { + bpy_context_clear(C, &gilstate); + } + else { + PyGILState_Release(gilstate); + } - bpy_context_clear(C, &gilstate); return eitems; } @@ -2618,7 +2634,7 @@ PyDoc_STRVAR(BPy_EnumProperty_doc, " Note the item is optional.\n" " For dynamic values a callback can be passed which returns a list in\n" " the same format as the static list.\n" -" This function must take 2 arguments (self, context)\n" +" This function must take 2 arguments (self, context), **context may be None**.\n" " WARNING: There is a known bug with using a callback,\n" " Python must keep a reference to the strings returned or Blender will crash.\n" " :type items: sequence of string tuples or a function\n" -- cgit v1.2.3