Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-01-07 07:27:59 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-01-07 07:27:59 +0300
commit07287ceda1bb8e14d29566c92eca23bb147f2dd1 (patch)
tree0bc55f2204e39abe76e765c6da32f18411e9b81e /source/blender/python/intern/bpy_rna_anim.c
parentabe32d2a35e4d3ca86caca7e5f7d212d8802107f (diff)
Fix T58964: drivers_remove fails w/ missing paths
Diffstat (limited to 'source/blender/python/intern/bpy_rna_anim.c')
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c146
1 files changed, 116 insertions, 30 deletions
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 5a18fd8b177..16fe6c50baa 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -33,6 +33,7 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
+#include "BLI_string_utils.h"
#include "DNA_scene_types.h"
#include "DNA_anim_types.h"
@@ -61,9 +62,9 @@
#include "../generic/python_utildefines.h"
/* for keyframes and drivers */
-static int pyrna_struct_anim_args_parse(
+static int pyrna_struct_anim_args_parse_ex(
PointerRNA *ptr, const char *error_prefix, const char *path,
- const char **path_full, int *index)
+ const char **path_full, int *index, bool *r_path_no_validate)
{
const bool is_idbase = RNA_struct_is_ID(ptr->type);
PropertyRNA *prop;
@@ -101,38 +102,47 @@ static int pyrna_struct_anim_args_parse(
}
if (prop == NULL) {
+ if (r_path_no_validate) {
+ *r_path_no_validate = true;
+ return -1;
+ }
PyErr_Format(PyExc_TypeError,
"%.200s property \"%s\" not found",
error_prefix, path);
return -1;
}
- if (!RNA_property_animateable(&r_ptr, prop)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s property \"%s\" not animatable",
- error_prefix, path);
- return -1;
- }
-
- if (RNA_property_array_check(prop) == 0) {
- if ((*index) == -1) {
- *index = 0;
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "%.200s index %d was given while property \"%s\" is not an array",
- error_prefix, *index, path);
- return -1;
- }
+ if (r_path_no_validate) {
+ /* Don't touch the index. */
}
else {
- int array_len = RNA_property_array_length(&r_ptr, prop);
- if ((*index) < -1 || (*index) >= array_len) {
+ if (!RNA_property_animateable(&r_ptr, prop)) {
PyErr_Format(PyExc_TypeError,
- "%.200s index out of range \"%s\", given %d, array length is %d",
- error_prefix, path, *index, array_len);
+ "%.200s property \"%s\" not animatable",
+ error_prefix, path);
return -1;
}
+
+ if (RNA_property_array_check(prop) == 0) {
+ if ((*index) == -1) {
+ *index = 0;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s index %d was given while property \"%s\" is not an array",
+ error_prefix, *index, path);
+ return -1;
+ }
+ }
+ else {
+ int array_len = RNA_property_array_length(&r_ptr, prop);
+ if ((*index) < -1 || (*index) >= array_len) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s index out of range \"%s\", given %d, array length is %d",
+ error_prefix, path, *index, array_len);
+ return -1;
+ }
+ }
}
if (is_idbase) {
@@ -152,6 +162,68 @@ static int pyrna_struct_anim_args_parse(
return 0;
}
+static int pyrna_struct_anim_args_parse(
+ PointerRNA *ptr, const char *error_prefix, const char *path,
+ const char **path_full, int *index)
+{
+ return pyrna_struct_anim_args_parse_ex(ptr, error_prefix, path, path_full, index, NULL);
+}
+
+/**
+ * Unlike #pyrna_struct_anim_args_parse \a path_full may be copied from \a path.
+ */
+static int pyrna_struct_anim_args_parse_no_resolve(
+ PointerRNA *ptr, const char *error_prefix, const char *path,
+ const char **path_full)
+{
+ const bool is_idbase = RNA_struct_is_ID(ptr->type);
+ if (is_idbase) {
+ *path_full = path;
+ return 0;
+ }
+ else {
+ char *path_prefix = RNA_path_from_ID_to_struct(ptr);
+ if (path_prefix == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s could not make path for type %s",
+ error_prefix, RNA_struct_identifier(ptr->type));
+ return -1;
+ }
+
+ if (*path == '[') {
+ *path_full = BLI_string_joinN(path_prefix, path);
+ }
+ else {
+ *path_full = BLI_string_join_by_sep_charN('.', path_prefix, path);
+ }
+ MEM_freeN(path_prefix);
+ }
+ return 0;
+}
+
+static int pyrna_struct_anim_args_parse_no_resolve_fallback(
+ PointerRNA *ptr, const char *error_prefix, const char *path,
+ const char **path_full, int *index)
+{
+ bool path_unresolved = false;
+ if (pyrna_struct_anim_args_parse_ex(
+ ptr, error_prefix, path,
+ path_full, index, &path_unresolved) == -1)
+ {
+ if (path_unresolved == true) {
+ if (pyrna_struct_anim_args_parse_no_resolve(
+ ptr, error_prefix, path, path_full) == -1)
+ {
+ return -1;
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ return 0;
+}
+
/* internal use for insert and delete */
static int pyrna_struct_keyframe_parse(
PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
@@ -162,14 +234,19 @@ static int pyrna_struct_keyframe_parse(
const char *path;
/* note, parse_str MUST start with 's|ifsO!' */
- if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name,
- &PySet_Type, &pyoptions))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name,
+ &PySet_Type, &pyoptions))
{
return -1;
}
- if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1)
+ if (pyrna_struct_anim_args_parse(
+ ptr, error_prefix, path,
+ path_full, index) == -1)
+ {
return -1;
+ }
if (*cfra == FLT_MAX)
*cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
@@ -419,7 +496,10 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
+ if (pyrna_struct_anim_args_parse(
+ &self->ptr, "bpy_struct.driver_add():", path,
+ &path_full, &index) == -1)
+ {
return NULL;
}
else {
@@ -490,10 +570,14 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
PYRNA_STRUCT_CHECK_OBJ(self);
- if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
+ if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index)) {
return NULL;
+ }
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
+ if (pyrna_struct_anim_args_parse_no_resolve_fallback(
+ &self->ptr, "bpy_struct.driver_remove():", path,
+ &path_full, &index) == -1)
+ {
return NULL;
}
else {
@@ -504,7 +588,9 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
result = ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
- MEM_freeN((void *)path_full);
+ if (path != path_full) {
+ MEM_freeN((void *)path_full);
+ }
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;