Fix #112788: python modules should have ModuleType attributes #112813

Open
Leonardo Covarrubias wants to merge 1 commits from leocov/blender:112788-add-bpy-module-attrs into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 53 additions and 2 deletions

View File

@ -78,6 +78,10 @@ extern "C" char build_system[];
static PyTypeObject BlenderAppType;
static PyStructSequence_Field app_info_fields[] = {
{"__name__", nullptr},
{"__spec__", nullptr},
{"__package__", nullptr},
{"__loader__", nullptr},
{"version", "The Blender version as a tuple of 3 numbers. eg. (2, 83, 1)"},
{"version_file",
"The Blender version, as a tuple, last used to save a .blend file, compatible with "
@ -147,6 +151,10 @@ static PyObject *make_app_info()
#define SetBytesItem(str) PyStructSequence_SET_ITEM(app_info, pos++, PyBytes_FromString(str))
#define SetObjItem(obj) PyStructSequence_SET_ITEM(app_info, pos++, obj)
SetStrItem("bpy.app");
SetObjItem(Py_INCREF_RET(Py_None));
SetObjItem(Py_INCREF_RET(Py_None));
SetObjItem(Py_INCREF_RET(Py_None));
SetObjItem(
PyC_Tuple_Pack_I32({BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_VERSION_PATCH}));
SetObjItem(PyC_Tuple_Pack_I32(
@ -198,6 +206,8 @@ static PyObject *make_app_info()
SetObjItem(BPY_app_openvdb_struct());
SetObjItem(BPY_app_sdl_struct());
SetObjItem(BPY_app_build_options_struct());
/* pretend modules */
SetObjItem(BPY_app_handlers_struct());
SetObjItem(BPY_app_translations_struct());

View File

@ -97,9 +97,14 @@ static PyStructSequence_Field app_cb_info_fields[] = {
{"_extension_repos_update_post", "on changes to extension repos (after)"},
/* sets the permanent tag */
#define APP_CB_OTHER_FIELDS 1
#define APP_CB_OTHER_FIELDS 5
{"persistent",
"Function decorator for callback functions not to be removed when loading new files"},
/* module attributes */
{"__name__", nullptr},
{"__spec__", nullptr},
{"__package__", nullptr},
{"__loader__", nullptr},
{nullptr},
};
@ -228,18 +233,29 @@ static PyObject *make_app_cb_info()
return nullptr;
}
/* for BKE_callbacks.h, validate fields and prepare sequence */
for (pos = 0; pos < BKE_CB_EVT_TOT; pos++) {
if (app_cb_info_fields[pos].name == nullptr) {
Py_FatalError("invalid callback slots 1");
}
PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos] = PyList_New(0)));
}
/* custom sequence items */
if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != nullptr) {
Py_FatalError("invalid callback slots 2");
}
/* custom function */
/* persistent decorator func */
PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
/* __name__ */
PyStructSequence_SET_ITEM(app_cb_info, pos++, PyUnicode_FromString("bpy.app.handlers"));
/* __spec__ */
PyStructSequence_SET_ITEM(app_cb_info, pos++, Py_INCREF_RET(Py_None));
/* __package__ */
PyStructSequence_SET_ITEM(app_cb_info, pos++, Py_INCREF_RET(Py_None));
/* __loader__ */
PyStructSequence_SET_ITEM(app_cb_info, pos++, Py_INCREF_RET(Py_None));
return app_cb_info;
}

View File

@ -45,6 +45,9 @@ struct BlenderAppTranslations {
PyObject *contexts;
/** A readonly mapping {C context id: python id} (actually, a MappingProxy). */
PyObject *contexts_C_to_py;
PyObject *module_name_attr;
/**
* A Python dictionary containing all registered Python dictionaries
* (order is more or less random, first match wins!).
@ -482,6 +485,26 @@ static PyMemberDef app_translations_members[] = {
offsetof(BlenderAppTranslations, contexts_C_to_py),
READONLY,
app_translations_contexts_C_to_py_doc},
{"__name__",
T_OBJECT,
offsetof(BlenderAppTranslations, module_name_attr),
READONLY,
nullptr},
{"__spec__",
T_NONE,
0,
READONLY,
nullptr},
{"__package__",
T_NONE,
0,
READONLY,
nullptr},
{"__loader__",
T_NONE,
0,
READONLY,
nullptr},
{nullptr},
};
@ -765,6 +788,8 @@ static PyObject *app_translations_new(PyTypeObject *type, PyObject * /*args*/, P
PyObject *py_ctxts;
BLT_i18n_contexts_descriptor *ctxt;
_translations->module_name_attr = PyUnicode_FromString("bpy.app.translations");
_translations->contexts = app_translations_contexts_make();
py_ctxts = _PyDict_NewPresized(ARRAY_SIZE(_contexts));