Skip to content

Commit ce3998f

Browse files
committed
Refactor: simplify "_bpy_types" initialization internals
- Store the `_bpy_types` dictionary on startup instead of importing and setting on demand. - Remove duplicate `_bpy_types` import.
1 parent eb2cc80 commit ce3998f

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

source/blender/python/intern/bpy.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -757,9 +757,21 @@ void BPy_init_modules(bContext *C)
757757

758758
BPY_rna_gizmo_module(mod);
759759

760-
bpy_import_test("_bpy_types");
761-
PyModule_AddObject(mod, "data", BPY_rna_module()); /* Imports `_bpy_types` by running this. */
762-
bpy_import_test("_bpy_types");
760+
/* Important to internalizes `_bpy_types` before creating RNA instances. */
761+
{
762+
/* Set a dummy module so the `_bpy_types.py` can access `bpy.types.ID`
763+
* without a null pointer dereference when instancing types. */
764+
PyObject *bpy_types_dict_dummy = PyDict_New();
765+
BPY_rna_types_dict_set(bpy_types_dict_dummy);
766+
PyObject *bpy_types_module_py = bpy_import_test("_bpy_types");
767+
/* Something has gone wrong if this is ever populated. */
768+
BLI_assert(PyDict_GET_SIZE(bpy_types_dict_dummy) == 0);
769+
Py_DECREF(bpy_types_dict_dummy);
770+
771+
PyObject *bpy_types_module_py_dict = PyModule_GetDict(bpy_types_module_py);
772+
BPY_rna_types_dict_set(bpy_types_module_py_dict);
773+
}
774+
PyModule_AddObject(mod, "data", BPY_rna_module());
763775
BPY_rna_types_finalize_external_types(bpy_types);
764776

765777
PyModule_AddObject(mod, "props", BPY_rna_props());

source/blender/python/intern/bpy_rna.cc

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8130,7 +8130,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
81308130
/**
81318131
* \return borrowed reference.
81328132
*/
8133-
static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict)
8133+
static PyObject *pyrna_srna_PyBase(StructRNA *srna)
81348134
{
81358135
/* Assume RNA_struct_py_type_get(srna) was already checked. */
81368136
StructRNA *base;
@@ -8153,9 +8153,15 @@ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dic
81538153
return py_base;
81548154
}
81558155

8156-
/* Check if we have a native Python subclass, use it when it exists
8157-
* return a borrowed reference. */
8156+
/**
8157+
* Check if we have a native Python subclass, use it when it exists
8158+
* return a borrowed reference.
8159+
*/
81588160
static PyObject *bpy_types_dict = nullptr;
8161+
void BPY_rna_types_dict_set(PyObject *dict)
8162+
{
8163+
bpy_types_dict = dict; /* Borrow. */
8164+
}
81598165

81608166
/**
81618167
* Return the #PyTypeObject or null,
@@ -8164,22 +8170,10 @@ static PyObject *bpy_types_dict = nullptr;
81648170
*/
81658171
static PyObject *pyrna_srna_ExternalType(StructRNA *srna)
81668172
{
8167-
const char *idname = RNA_struct_identifier(srna);
8168-
PyObject *newclass;
8169-
8170-
if (bpy_types_dict == nullptr) {
8171-
PyObject *bpy_types = PyImport_ImportModuleLevel("_bpy_types", nullptr, nullptr, nullptr, 0);
8173+
BLI_assert(bpy_types_dict);
81728174

8173-
if (bpy_types == nullptr) {
8174-
PyErr_Print();
8175-
CLOG_ERROR(BPY_LOG_RNA, "failed to find '_bpy_types' module");
8176-
return nullptr;
8177-
}
8178-
bpy_types_dict = PyModule_GetDict(bpy_types); /* Borrow. */
8179-
Py_DECREF(bpy_types); /* Fairly safe to assume the dict is kept. */
8180-
}
8181-
8182-
newclass = PyDict_GetItemString(bpy_types_dict, idname);
8175+
const char *idname = RNA_struct_identifier(srna);
8176+
PyObject *newclass = PyDict_GetItemString(bpy_types_dict, idname);
81838177

81848178
/* Sanity check, could skip this unless in debug mode. */
81858179
if (newclass) {

source/blender/python/intern/bpy_rna.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ void BPY_rna_exit();
203203
void BPY_update_rna_module();
204204
// PyObject *BPY_rna_doc();
205205
[[nodiscard]] PyObject *BPY_rna_types();
206+
/**
207+
* Set the `_bpy_types.py` modules `__dict__`, needed for instancing RNA types.
208+
*/
209+
void BPY_rna_types_dict_set(PyObject *dict);
206210
void BPY_rna_types_finalize_external_types(PyObject *submodule);
207211

208212
[[nodiscard]] PyObject *pyrna_struct_CreatePyObject_with_primitive_support(PointerRNA *ptr);

0 commit comments

Comments
 (0)