PyAPI: Add "path_from_module" function to get full bpy path to structs and props
This is to make it easy to get the bpy paths to bpy.context.property for example. Before this change, the easiest way was to use the clipboard bpy.ops function. However this would make the python scripts using this fragile as it we do not have full control of what is stored in the system clipboard. Pull Request: https://projects.blender.org/blender/blender/pulls/147116
This commit is contained in:
committed by
Sebastian Parborg
parent
8d417cb280
commit
df7273930f
@@ -3993,6 +3993,133 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
pyrna_struct_path_from_module_doc,
|
||||
".. method:: path_from_module(property=\"\", index=-1, /)\n"
|
||||
"\n"
|
||||
" Returns the full data path to this struct (as a string) from the bpy module.\n"
|
||||
"\n"
|
||||
" :arg property: Optional property name to get the full path from\n"
|
||||
" :type property: str\n"
|
||||
" :arg index: Optional index of the property.\n"
|
||||
" \"-1\" means that the property has no indices.\n"
|
||||
" :type index: int\n"
|
||||
" :return: The full path to the data.\n"
|
||||
" :rtype: str\n"
|
||||
"\n"
|
||||
" :raises ValueError:\n"
|
||||
" if the input data cannot be converted into a full data path.\n"
|
||||
"\n"
|
||||
" .. note:: Even if all input data is correct, this function might\n"
|
||||
" error out because Blender cannot derive a valid path.\n"
|
||||
" The incomplete path will be printed in the error message.\n");
|
||||
static PyObject *pyrna_struct_path_from_module(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
const char *name = nullptr;
|
||||
PropertyRNA *prop;
|
||||
int index = -1;
|
||||
|
||||
PYRNA_STRUCT_CHECK_OBJ(self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|si:path_from_module", &name, &index)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<std::string> path;
|
||||
if (name) {
|
||||
prop = RNA_struct_find_property(&self->ptr.value(), name);
|
||||
if (prop == nullptr) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"%.200s.path_from_module(\"%.200s\") not found",
|
||||
RNA_struct_identifier(self->ptr->type),
|
||||
name);
|
||||
return nullptr;
|
||||
}
|
||||
path = RNA_path_full_property_py_ex(&self->ptr.value(), prop, index, true);
|
||||
}
|
||||
else {
|
||||
if (RNA_struct_is_ID(self->ptr->type)) {
|
||||
path = RNA_path_full_ID_py(self->ptr->owner_id);
|
||||
}
|
||||
else {
|
||||
path = RNA_path_full_struct_py(&self->ptr.value());
|
||||
}
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
if (name) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.path_from_module(\"%s\", %d) found, but does not support path creation",
|
||||
RNA_struct_identifier(self->ptr->type),
|
||||
name,
|
||||
index);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.path_from_module() does not support path creation for this type",
|
||||
RNA_struct_identifier(self->ptr->type));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (path.value().back() == '.') {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.path_from_module() could not derive a complete path for this type.\n"
|
||||
"Only got \"%.200s\" as an incomplete path",
|
||||
RNA_struct_identifier(self->ptr->type),
|
||||
path.value().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return PyC_UnicodeFromStdStr(path.value());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
pyrna_prop_path_from_module_doc,
|
||||
".. method:: path_from_module()\n"
|
||||
"\n"
|
||||
" Returns the full data path to this struct (as a string) from the bpy module.\n"
|
||||
"\n"
|
||||
" :return: The full path to the data.\n"
|
||||
" :rtype: str\n"
|
||||
"\n"
|
||||
" :raises ValueError:\n"
|
||||
" if the input data cannot be converted into a full data path.\n"
|
||||
"\n"
|
||||
" .. note:: Even if all input data is correct, this function might\n"
|
||||
" error out because Blender cannot derive a valid path.\n"
|
||||
" The incomplete path will be printed in the error message.\n");
|
||||
static PyObject *pyrna_prop_path_from_module(BPy_PropertyRNA *self)
|
||||
{
|
||||
PropertyRNA *prop = self->prop;
|
||||
|
||||
const std::optional<std::string> path = RNA_path_full_property_py_ex(
|
||||
&self->ptr.value(), prop, -1, true);
|
||||
|
||||
if (!path) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.%.200s.path_from_module() does not support path creation for this type",
|
||||
RNA_struct_identifier(self->ptr->type),
|
||||
RNA_property_identifier(prop));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (path.value().back() == '.') {
|
||||
PyErr_Format(
|
||||
PyExc_ValueError,
|
||||
"%.200s.%.200s.path_from_module() could not derive a complete path for this type.\n"
|
||||
"Only got \"%.200s\" as an incomplete path",
|
||||
RNA_struct_identifier(self->ptr->type),
|
||||
RNA_property_identifier(prop),
|
||||
path.value().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return PyC_UnicodeFromStdStr(path.value());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
pyrna_struct_path_from_id_doc,
|
||||
@@ -6238,6 +6365,10 @@ static PyMethodDef pyrna_struct_methods[] = {
|
||||
(PyCFunction)pyrna_struct_path_from_id,
|
||||
METH_VARARGS,
|
||||
pyrna_struct_path_from_id_doc},
|
||||
{"path_from_module",
|
||||
(PyCFunction)pyrna_struct_path_from_module,
|
||||
METH_VARARGS,
|
||||
pyrna_struct_path_from_module_doc},
|
||||
{"type_recast",
|
||||
(PyCFunction)pyrna_struct_type_recast,
|
||||
METH_NOARGS,
|
||||
@@ -6291,6 +6422,10 @@ static PyMethodDef pyrna_prop_methods[] = {
|
||||
(PyCFunction)pyrna_prop_path_from_id,
|
||||
METH_NOARGS,
|
||||
pyrna_prop_path_from_id_doc},
|
||||
{"path_from_module",
|
||||
(PyCFunction)pyrna_prop_path_from_module,
|
||||
METH_NOARGS,
|
||||
pyrna_prop_path_from_module_doc},
|
||||
{"as_bytes", (PyCFunction)pyrna_prop_as_bytes, METH_NOARGS, pyrna_prop_as_bytes_doc},
|
||||
{"update", (PyCFunction)pyrna_prop_update, METH_NOARGS, pyrna_prop_update_doc},
|
||||
{"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, nullptr},
|
||||
|
||||
Reference in New Issue
Block a user