diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-02-19 11:08:28 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-02-19 14:12:41 +0300 |
commit | eafcbbb4f741cab7990f17eb07aab0843b242ebd (patch) | |
tree | 8fd4fd85bff95cea80b8862b52520a42a9d39cc3 /source/blender/python | |
parent | 80e5697b0ba8e5ce2a918980bc8d63668656afba (diff) |
PyAPI: use real module for bpy.types
This is needed to support `typing.get_type_hints`,
which expects each classes module to have a module '__dict__'.
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 121 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 3 |
2 files changed, 53 insertions, 71 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 4dfdba7758c..c48a50c5ec6 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -90,6 +90,9 @@ BPy_StructRNA *bpy_context_module = NULL; /* for fast access */ static PyObject *pyrna_struct_Subtype(PointerRNA *ptr); static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self); +static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class); +static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class); + #define BPY_DOC_ID_PROP_TYPE_NOTE \ " .. note::\n" \ "\n" \ @@ -7657,11 +7660,26 @@ PyObject *BPY_rna_doc(void) } #endif -/* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a different type - * the self->ptr and self->prop are always set to the "structs" collection */ -/* ---------------getattr-------------------------------------------- */ -static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname) +/* -------------------------------------------------------------------- */ +/** \name RNA Types Module `bpy.types` + * \{ */ + +/** + * This could be a static variable as we only have one `bpy.types` module, + * it just keeps the data isolated to store in the module it's self. + * + * This data doesn't chance one initialized. + */ +struct BPy_TypesModule_State { + /** `RNA_BlenderRNA`. */ + PointerRNA ptr; + /** `RNA_BlenderRNA.structs`, exposed as `bpy.types` */ + PropertyRNA *prop; +}; + +static PyObject *bpy_types_module_getattro(PyObject *self, PyObject *pyname) { + struct BPy_TypesModule_State *state = PyModule_GetState(self); PointerRNA newptr; PyObject *ret; const char *name = PyUnicode_AsUTF8(pyname); @@ -7670,7 +7688,7 @@ static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string"); ret = NULL; } - else if (RNA_property_collection_lookup_string(&self->ptr, self->prop, name, &newptr)) { + else if (RNA_property_collection_lookup_string(&state->ptr, state->prop, name, &newptr)) { ret = pyrna_struct_Subtype(&newptr); if (ret == NULL) { PyErr_Format(PyExc_RuntimeError, @@ -7692,79 +7710,52 @@ static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname return ret; } -static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self); -static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class); -static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class); - -static struct PyMethodDef pyrna_basetype_methods[] = { - {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""}, - {NULL, NULL, 0, NULL}, -}; - -/* Used to call ..._keys() direct, but we need to filter out operator subclasses. */ -#if 0 -static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) -{ - PyObject *list; -# if 0 - PyMethodDef *meth; -# endif - - list = pyrna_prop_collection_keys(self); /* Like calling structs.keys(), avoids looping here. */ - -# if 0 /* For now only contains __dir__. */ - for (meth = pyrna_basetype_methods; meth->ml_name; meth++) { - PyList_APPEND(list, PyUnicode_FromString(meth->ml_name)); - } -# endif - return list; -} - -#else - -static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) +static PyObject *bpy_types_module_dir(PyObject *self) { + struct BPy_TypesModule_State *state = PyModule_GetState(self); PyObject *ret = PyList_New(0); - RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { + RNA_PROP_BEGIN (&state->ptr, itemptr, state->prop) { StructRNA *srna = itemptr.data; PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna))); } RNA_PROP_END; - return ret; } -#endif +static struct PyMethodDef bpy_types_module_methods[] = { + {"__getattr__", (PyCFunction)bpy_types_module_getattro, METH_O, NULL}, + {"__dir__", (PyCFunction)bpy_types_module_dir, METH_NOARGS, NULL}, + {NULL, NULL, 0, NULL}, +}; -static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE; +PyDoc_STRVAR(bpy_types_module_doc, "Access to internal Blender types"); +static struct PyModuleDef bpy_types_module_def = { + PyModuleDef_HEAD_INIT, + "bpy.types", /* m_name */ + bpy_types_module_doc, /* m_doc */ + sizeof(struct BPy_TypesModule_State), /* m_size */ + bpy_types_module_methods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; /** * Accessed from Python as 'bpy.types' */ PyObject *BPY_rna_types(void) { - BPy_BaseTypeRNA *self; + PyObject *submodule = PyModule_Create(&bpy_types_module_def); + struct BPy_TypesModule_State *state = PyModule_GetState(submodule); - if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY) == 0) { - pyrna_basetype_Type.tp_name = "RNA_Types"; - pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA); - pyrna_basetype_Type.tp_getattro = (getattrofunc)pyrna_basetype_getattro; - pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT; - pyrna_basetype_Type.tp_methods = pyrna_basetype_methods; - - if (PyType_Ready(&pyrna_basetype_Type) < 0) { - return NULL; - } - } - - /* Static members for the base class. */ - /* Add __name__ since help() expects it. */ - PyDict_SetItem(pyrna_basetype_Type.tp_dict, bpy_intern_str___name__, bpy_intern_str_bpy_types); + RNA_blender_rna_pointer_create(&state->ptr); + state->prop = RNA_struct_find_property(&state->ptr, "structs"); /* Internal base types we have no other accessors for. */ { - PyTypeObject *pyrna_types[] = { + static PyTypeObject *pyrna_types[] = { &pyrna_struct_meta_idprop_Type, &pyrna_struct_Type, &pyrna_prop_Type, @@ -7773,23 +7764,17 @@ PyObject *BPY_rna_types(void) &pyrna_func_Type, }; + PyObject *submodule_dict = PyModule_GetDict(submodule); for (int i = 0; i < ARRAY_SIZE(pyrna_types); i += 1) { - PyDict_SetItemString( - pyrna_basetype_Type.tp_dict, pyrna_types[i]->tp_name, (PyObject *)pyrna_types[i]); + PyDict_SetItemString(submodule_dict, pyrna_types[i]->tp_name, (PyObject *)pyrna_types[i]); } } - self = (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type); - - /* Avoid doing this lookup for every getattr. */ - RNA_blender_rna_pointer_create(&self->ptr); - self->prop = RNA_struct_find_property(&self->ptr, "structs"); -#ifdef USE_WEAKREFS - self->in_weakreflist = NULL; -#endif - return (PyObject *)self; + return submodule; } +/** \} */ + StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix) { BPy_StructRNA *py_srna = NULL; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index a2c2171d151..e891f5c1fc1 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -177,9 +177,6 @@ typedef struct { FunctionRNA *func; } BPy_FunctionRNA; -/* cheap trick */ -#define BPy_BaseTypeRNA BPy_PropertyRNA - StructRNA *srna_from_self(PyObject *self, const char *error_prefix); StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix); |