Page MenuHome

Python: "drivers_remove" not working and crashing with invalid drivers
Closed, ResolvedPublic

Description

Win 10
Gtx 980

The drivers_remove function is broken when removing invalid drivers.

  • Open the attached blend:

  • Click Run Script to execute the function (text data block "remove1")
  • Error: bpy_struct.driver_remove(): property "pose.bones["thigh.l"].constraints["rotIK"].influence" not found

A workaround I did in Blender 2.79 was changing the driver data_path to a valid one before deleting. It now crashes in 2.8:

  • Open the text data block "remove2"
  • Run Script
  • Should crash

Event Timeline

lucas veber (lucky3) updated the task description. (Show Details)
lucas veber (lucky3) updated the task description. (Show Details)
lucas veber (lucky3) updated the task description. (Show Details)
Sebastian Parborg (zeddb) triaged this task as Confirmed, Medium priority.

I can reproduce this issue, this is the backtrace I get:
(I'm guessing this is depsgraph related)

Thread 1 "blender" received signal SIGSEGV, Segmentation fault.
0x0000555557e2b9a1 in BKE_animsys_eval_driver (depsgraph=0x7fffeaeecf08, id=0x7fffdcc0b008, driver_index=37, driver_orig=0x7fffd27ce948)
    at /home/zed/programmering/blender_master/blender/source/blender/blenkernel/intern/anim_sys.c:2922
2922		DEG_debug_print_eval_subdata_index(
(gdb) bt
#0  0x0000555557e2b9a1 in BKE_animsys_eval_driver (depsgraph=0x7fffeaeecf08, id=0x7fffdcc0b008, driver_index=37, driver_orig=0x7fffd27ce948)
    at /home/zed/programmering/blender_master/blender/source/blender/blenkernel/intern/anim_sys.c:2922
#1  0x000055555840194d in std::__invoke_impl<void, void (*&)(Depsgraph*, ID*, int, ChannelDriver*), Depsgraph*, ID*&, int&, ChannelDriver*&> (__f=
    @0x7fffd2b4b8e0: 0x555557e2b910 <BKE_animsys_eval_driver>, __args#0=@0x7fffffffd7d0: 0x7fffeaeecf08, __args#1=@0x7fffd2b4b8f8: 0x7fffdcc0b008, 
    __args#2=@0x7fffd2b4b8f0: 37, __args#3=@0x7fffd2b4b8e8: 0x7fffd27ce948) at /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/bits/invoke.h:60
#2  0x0000555558400650 in std::__invoke<void (*&)(Depsgraph*, ID*, int, ChannelDriver*), Depsgraph*, ID*&, int&, ChannelDriver*&> (__fn=
    @0x7fffd2b4b8e0: 0x555557e2b910 <BKE_animsys_eval_driver>, __args#0=@0x7fffffffd7d0: 0x7fffeaeecf08, __args#1=@0x7fffd2b4b8f8: 0x7fffdcc0b008, 
    __args#2=@0x7fffd2b4b8f0: 37, __args#3=@0x7fffd2b4b8e8: 0x7fffd27ce948) at /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/bits/invoke.h:95
#3  0x00005555583ff01d in std::_Bind<void (*(std::_Placeholder<1>, ID*, int, ChannelDriver*))(Depsgraph*, ID*, int, ChannelDriver*)>::__call<void, Depsgraph*&&, 0ul, 1ul, 2ul, 3ul>(std::tuple<Depsgraph*&&>&&, std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) (this=0x7fffd2b4b8e0, __args=...)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/functional:400
#4  0x00005555583fd248 in std::_Bind<void (*(std::_Placeholder<1>, ID*, int, ChannelDriver*))(Depsgraph*, ID*, int, ChannelDriver*)>::operator()<Depsgraph*, void>(Depsgraph*&&) (this=0x7fffd2b4b8e0, __args#0=@0x7fffffffd7d0: 0x7fffeaeecf08) at /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/functional:484
#5  0x00005555583fa600 in std::_Function_handler<void (Depsgraph*), std::_Bind<void (*(std::_Placeholder<1>, ID*, int, ChannelDriver*))(Depsgraph*, ID*, int, ChannelDriver*)> >::_M_invoke(std::_Any_data const&, Depsgraph*&&) (__functor=..., __args#0=@0x7fffffffd7d0: 0x7fffeaeecf08)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/bits/std_function.h:297
#6  0x00005555584132c9 in std::function<void (Depsgraph*)>::operator()(Depsgraph*) const (this=0x7fffd5c51268, __args#0=0x7fffeaeecf08)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/bits/std_function.h:687
#7  0x00005555584128aa in DEG::deg_task_run_func (pool=0x7fffd2fb9008, taskdata=0x7fffd5c51208, thread_id=0)
    at /home/zed/programmering/blender_master/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:95
#8  0x00005555583d3025 in BLI_task_pool_work_and_wait (pool=0x7fffd2fb9008)
    at /home/zed/programmering/blender_master/blender/source/blender/blenlib/intern/task.c:899
#9  0x00005555584131fd in DEG::deg_evaluate_on_refresh (graph=0x7fffeaeecf08)
    at /home/zed/programmering/blender_master/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:334
#10 0x00005555583e93ff in DEG_evaluate_on_refresh (graph=0x7fffeaeecf08)
    at /home/zed/programmering/blender_master/blender/source/blender/depsgraph/intern/depsgraph_eval.cc:70
#11 0x000055555801b51c in BKE_scene_graph_update_tagged (depsgraph=0x7fffeaeecf08, bmain=0x7fffd5058e08)
    at /home/zed/programmering/blender_master/blender/source/blender/blenkernel/intern/scene.c:1438
#12 0x0000555557044705 in wm_event_do_depsgraph (C=0x7ffff0030288)
    at /home/zed/programmering/blender_master/blender/source/blender/windowmanager/intern/wm_event_system.c:336
#13 0x00005555570447ea in wm_event_do_refresh_wm_and_depsgraph (C=0x7ffff0030288)
    at /home/zed/programmering/blender_master/blender/source/blender/windowmanager/intern/wm_event_system.c:361
#14 0x000055555704502a in wm_event_do_notifiers (C=0x7ffff0030288)
    at /home/zed/programmering/blender_master/blender/source/blender/windowmanager/intern/wm_event_system.c:519
#15 0x0000555557040995 in WM_main (C=0x7ffff0030288) at /home/zed/programmering/blender_master/blender/source/blender/windowmanager/intern/wm.c:430
#16 0x000055555703b2ee in main (argc=1, argv=0x7fffffffdc98) at /home/zed/programmering/blender_master/blender/source/creator/creator.c:521

@Campbell Barton (campbellbarton) , i've fixed the crash issue, but is still annoying that driver_remove can't be used for an invalid driver. This is caused by some validation happening in pyrna_struct_anim_args_parse() which i am not sure why we need that at all. I think is reasonable to use path and index passed to the function?

P.S. Even if the driver_remove() is solved for the invalid drivers, the original script will still crash because it removes drivers from a list during traversal of that list.

Well, pyrna_struct_anim_args_parse() is also used to build a valid, normalized RNA path from given path & index, so think using it here first is OK. Though we should probably not error if it fails, but instead just build a dummy unchecked path out of path/index pair, and try to remove that one?

@Bastien Montagne (mont29), but this is like saying that rm utility will first normalize and such path you give to it before attempting to remove it. Not sure i'd trust such a removal utility =/

In this case it's best to directly remove the drivers, committed API calls to create/remove drivers directly. rBabe32d2a35e4d3ca86caca7e5f7d212d8802107f

Now you can call obj.animation_data.drivers.remove(some_driver).

Even so, driver_remove() should be able to support drivers which have data-paths that no-longer resolve.

There is a chance that this will fail (if the string isn't an exact match for eg), a collection could be referenced by string or by index, but think this isn't all that likely.

So we could make keyframe & driver removal fall-back to doing a string match.