diff --git a/rigify/legacy/generate.py b/rigify/legacy/generate.py
index 476cdbe80e0fcd5e1ac44a09be0c8600f574546d..33696cf0f3edfc672941887b596126900daa7ebf 100644
--- a/rigify/legacy/generate.py
+++ b/rigify/legacy/generate.py
@@ -99,6 +99,7 @@ def generate_rig(context, metarig):
     # Get rid of anim data in case the rig already existed
     print("Clear rig animation data.")
     obj.animation_data_clear()
+    obj.data.animation_data_clear()
 
     # Select generated rig object
     metarig.select_set(False)
diff --git a/rigify/legacy/rig_ui_pitchipoy_template.py b/rigify/legacy/rig_ui_pitchipoy_template.py
index 2b4ef36c943d08945675fd564cc2c6787b54cb07..3fc50767c1082c8631fc1cce4c9c2ae5a3285336 100644
--- a/rigify/legacy/rig_ui_pitchipoy_template.py
+++ b/rigify/legacy/rig_ui_pitchipoy_template.py
@@ -632,8 +632,8 @@ class RigUI(bpy.types.Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Rig Main Properties"
-    bl_idname = rig_id + "_PT_rig_ui"
-    bl_category = 'View'
+    bl_idname = "VIEW3D_PT_rig_ui_" + rig_id
+    bl_category = 'Item'
 
     @classmethod
     def poll(self, context):
@@ -676,8 +676,8 @@ class RigLayers(bpy.types.Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Rig Layers"
-    bl_idname = rig_id + "_PT_rig_layers"
-    bl_category = 'View'
+    bl_idname = "VIEW3D_PT_rig_layers_" + rig_id
+    bl_category = 'Item'
 
     @classmethod
     def poll(self, context):
diff --git a/rigify/legacy/rig_ui_template.py b/rigify/legacy/rig_ui_template.py
index 6cdd1c635524f35366bdb981028e3cfede308df0..db6ab4a145d9246467205d604d3a38da35ee6e63 100644
--- a/rigify/legacy/rig_ui_template.py
+++ b/rigify/legacy/rig_ui_template.py
@@ -479,8 +479,8 @@ class RigUI(bpy.types.Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Rig Main Properties"
-    bl_idname = rig_id + "_PT_rig_ui"
-    bl_category = 'View'
+    bl_idname = "VIEW3D_PT_rig_ui_" + rig_id
+    bl_category = 'Item'
 
     @classmethod
     def poll(self, context):
@@ -523,8 +523,8 @@ class RigLayers(bpy.types.Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Rig Layers"
-    bl_idname = rig_id + "_PT_rig_layers"
-    bl_category = 'View'
+    bl_idname = "VIEW3D_PT_rig_layers_" + rig_id
+    bl_category = 'Item'
 
     @classmethod
     def poll(self, context):
diff --git a/rigify/legacy/rigs/pitchipoy/limbs/arm.py b/rigify/legacy/rigs/pitchipoy/limbs/arm.py
index 9de1657a51b9ce5a9f226e6d0598a2cd7aa0c445..2bf0fe6f75c25f66ce9f36839242a0fb313d74ef 100644
--- a/rigify/legacy/rigs/pitchipoy/limbs/arm.py
+++ b/rigify/legacy/rigs/pitchipoy/limbs/arm.py
@@ -86,7 +86,8 @@ def create_arm( cls, bones ):
 
     # Add driver to limit scale constraint influence
     b        = bones['ik']['mch_str']
-    drv      = pb[b].constraints[-1].driver_add("influence").driver
+    drv_fcu  = pb[b].constraints[-1].driver_add("influence")
+    drv      = drv_fcu.driver
     drv.type = 'SUM'
 
     var = drv.variables.new()
@@ -96,7 +97,7 @@ def create_arm( cls, bones ):
     var.targets[0].data_path = \
         pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
 
-    drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
+    drv_modifier = drv_fcu.modifiers[0]
 
     drv_modifier.mode            = 'POLYNOMIAL'
     drv_modifier.poly_order      = 1
diff --git a/rigify/legacy/rigs/pitchipoy/limbs/leg.py b/rigify/legacy/rigs/pitchipoy/limbs/leg.py
index 96aa1c02c42ba41e181fb880108b864fe3c76dde..360a2a491832a0947efe95104a375546ae512574 100644
--- a/rigify/legacy/rigs/pitchipoy/limbs/leg.py
+++ b/rigify/legacy/rigs/pitchipoy/limbs/leg.py
@@ -242,7 +242,8 @@ def create_leg( cls, bones ):
 
     # Add driver to limit scale constraint influence
     b        = bones['ik']['mch_str']
-    drv      = pb[b].constraints[-1].driver_add("influence").driver
+    drv_fcu  = pb[b].constraints[-1].driver_add("influence")
+    drv      = drv_fcu.driver
     drv.type = 'AVERAGE'
 
     var = drv.variables.new()
@@ -252,7 +253,7 @@ def create_leg( cls, bones ):
     var.targets[0].data_path = \
         pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
 
-    drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
+    drv_modifier = drv_fcu.modifiers[0]
 
     drv_modifier.mode            = 'POLYNOMIAL'
     drv_modifier.poly_order      = 1
@@ -302,7 +303,8 @@ def create_leg( cls, bones ):
 
         # Add driver to limit scale constraint influence
         b        = org_bones[3]
-        drv      = pb[b].constraints[-1].driver_add("influence").driver
+        drv_fcu  = pb[b].constraints[-1].driver_add("influence")
+        drv      = drv_fcu.driver
         drv.type = 'AVERAGE'
 
         var = drv.variables.new()
@@ -312,7 +314,7 @@ def create_leg( cls, bones ):
         var.targets[0].data_path = \
             pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
 
-        drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
+        drv_modifier = drv_fcu.modifiers[0]
 
         drv_modifier.mode            = 'POLYNOMIAL'
         drv_modifier.poly_order      = 1
diff --git a/rigify/legacy/rigs/pitchipoy/limbs/paw.py b/rigify/legacy/rigs/pitchipoy/limbs/paw.py
index 7691007a83a600fb878999ec022b01d07c6cb3d7..dd9fa1e78ba9e270e1ada1e9e9ab3237f9db63f8 100644
--- a/rigify/legacy/rigs/pitchipoy/limbs/paw.py
+++ b/rigify/legacy/rigs/pitchipoy/limbs/paw.py
@@ -111,7 +111,8 @@ def create_paw( cls, bones ):
 
     # Add driver to limit scale constraint influence
     b        = bones['ik']['mch_str']
-    drv      = pb[b].constraints[-1].driver_add("influence").driver
+    drv_fcu  = pb[b].constraints[-1].driver_add("influence")
+    drv      = drv_fcu.driver
     drv.type = 'AVERAGE'
 
     var = drv.variables.new()
@@ -121,7 +122,7 @@ def create_paw( cls, bones ):
     var.targets[0].data_path = \
         pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
 
-    drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
+    drv_modifier = drv_fcu.modifiers[0]
 
     drv_modifier.mode            = 'POLYNOMIAL'
     drv_modifier.poly_order      = 1
@@ -183,7 +184,8 @@ def create_paw( cls, bones ):
 
         # Add driver to limit scale constraint influence
         b        = org_bones[3]
-        drv      = pb[b].constraints[-1].driver_add("influence").driver
+        drv_fcu  = pb[b].constraints[-1].driver_add("influence")
+        drv      = drv_fcu.driver
         drv.type = 'AVERAGE'
 
         var = drv.variables.new()
@@ -193,7 +195,7 @@ def create_paw( cls, bones ):
         var.targets[0].data_path = \
             pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
 
-        drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
+        drv_modifier = drv_fcu.modifiers[0]
 
         drv_modifier.mode            = 'POLYNOMIAL'
         drv_modifier.poly_order      = 1
diff --git a/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py
index 706b82cfbb40bc5d7a386fdfb012eb22fbcaf646..05c2b4c62194c3632719494ebc9bb709f51c31d9 100644
--- a/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py
+++ b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py
@@ -528,7 +528,8 @@ class Rig:
         # driving the follow rotation switches for neck and head
         for bone, prop, in zip( owners, props ):
             # Add driver to copy rotation constraint
-            drv = pb[ bone ].constraints[ 0 ].driver_add("influence").driver
+            drv_fcu = pb[ bone ].constraints[ 0 ].driver_add("influence")
+            drv = drv_fcu.driver
             drv.type = 'AVERAGE'
 
             var = drv.variables.new()
@@ -538,7 +539,7 @@ class Rig:
             var.targets[0].data_path = \
                 torso.path_from_id() + '['+ '"' + prop + '"' + ']'
 
-            drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
+            drv_modifier = drv_fcu.modifiers[0]
 
             drv_modifier.mode            = 'POLYNOMIAL'
             drv_modifier.poly_order      = 1
diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py
index 2a3a85f690c0eb1838753d555c92a688cf78f413..f3d0e1824e09656b7d1b627943ad7901b14b6db6 100644
--- a/rigify/rigs/experimental/super_chain.py
+++ b/rigify/rigs/experimental/super_chain.py
@@ -5,7 +5,7 @@ from ...utils import strip_org, make_deformer_name, connected_children_names
 from ...utils import create_chain_widget
 from ...utils import make_mechanism_name, create_cube_widget
 from ...utils import ControlLayersOption
-from ...utils.mechanism import make_property
+from ...utils.mechanism import make_property, make_driver
 from ..limbs.limb_utils import get_bone_name
 
 
@@ -473,22 +473,7 @@ class Rig:
         # driving the follow rotation switches for neck and head
         for bone, prop, in zip(owners, props):
             # Add driver to copy rotation constraint
-            drv = pb[bone].constraints[0].driver_add("influence").driver
-            drv.type = 'AVERAGE'
-
-            var = drv.variables.new()
-            var.name = prop
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                torso.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-            drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-            drv_modifier.mode = 'POLYNOMIAL'
-            drv_modifier.poly_order = 1
-            drv_modifier.coefficients[0] = 1.0
-            drv_modifier.coefficients[1] = -1.0
+            make_driver(pb[bone].constraints[0], "influence", variables=[(self.obj, torso, prop)], polynomial=[1.0, -1.0])
 
     def locks_and_widgets(self, bones):
         bpy.ops.object.mode_set(mode='OBJECT')
diff --git a/rigify/rigs/limbs/arm.py b/rigify/rigs/limbs/arm.py
index 1fe9763897ed4251cdfe74076bb0e5fd5708e5c6..3b2f3658ebdcc575e17e18d9881c3e210a9948fd 100644
--- a/rigify/rigs/limbs/arm.py
+++ b/rigify/rigs/limbs/arm.py
@@ -11,7 +11,7 @@ from ...utils       import create_limb_widget, connected_children_names
 from ...utils       import align_bone_x_axis, align_bone_z_axis
 from ...rig_ui_template import UTILITIES_RIG_ARM, REGISTER_RIG_ARM
 from ...utils       import ControlLayersOption
-from ...utils.mechanism import make_property
+from ...utils.mechanism import make_property, make_driver
 from ..widgets import create_ikarrow_widget
 from math import trunc, pi
 
@@ -123,15 +123,7 @@ class Rig:
         # prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True )
         make_property(pb[main_parent], name, 0.0)
 
-        drv = pb[mch].constraints[0].driver_add("influence").driver
-
-        drv.type = 'AVERAGE'
-        var = drv.variables.new()
-        var.name = name
-        var.type = "SINGLE_PROP"
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = pb[main_parent].path_from_id() + \
-                                   '[' + '"' + name + '"' + ']'
+        make_driver(pb[mch].constraints[0], "influence", variables=[(self.obj, main_parent, name)])
 
         size = pb[main_parent].bone.y_axis.length * 10
         create_gear_widget(self.obj, main_parent, size=size, bone_transform_name=None)
@@ -332,25 +324,11 @@ class Rig:
             make_property(pb[t], name, defval, max=2.0, soft_max=1.0)
 
         for j,d in enumerate(def_bones[:-1]):
-            drvs = {}
             if j != 0:
-                tidx = j
-                drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_easein").driver
+                make_driver(self.obj.data.bones[d], "bbone_easein", variables=[(self.obj, tweaks[j], 'rubber_tweak')])
 
             if j != len( def_bones[:-1] ) - 1:
-                tidx = j + 1
-                drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_easeout").driver
-
-            for d in drvs:
-                drv = drvs[d]
-                name = 'rubber_tweak'
-                drv.type = 'AVERAGE'
-                var = drv.variables.new()
-                var.name = name
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = pb[tweaks[d]].path_from_id() + \
-                                           '[' + '"' + name + '"' + ']'
+                make_driver(self.obj.data.bones[d], "bbone_easeout", variables=[(self.obj, tweaks[j+1], 'rubber_tweak')])
 
         return def_bones
 
@@ -561,15 +539,7 @@ class Rig:
             })
 
             # Add driver to relevant constraint
-            drv = pb[o].constraints[-1].driver_add("influence").driver
-            drv.type = 'AVERAGE'
-
-            var = drv.variables.new()
-            var.name = prop.name
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']'
+            make_driver(pb[o].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)])
 
     def create_arm(self, bones):
         org_bones = self.org_bones
@@ -698,22 +668,8 @@ class Rig:
 
         # Add driver to limit scale constraint influence
         b = bones['ik']['mch_str']
-        drv = pb[b].constraints[-1].driver_add("influence").driver
-        drv.type = 'SUM'
-
-        var = drv.variables.new()
-        var.name = prop.name
-        var.type = "SINGLE_PROP"
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = \
-            pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']'
-
-        drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
 
-        drv_modifier.mode = 'POLYNOMIAL'
-        drv_modifier.poly_order = 1
-        drv_modifier.coefficients[0] = 1.0
-        drv_modifier.coefficients[1] = -1.0
+        make_driver(pb[b].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)], polynomial=[1.0, -1.0])
 
         # Create hand widget
         create_hand_widget(self.obj, ctrl, bone_transform_name=None)
@@ -747,184 +703,50 @@ class Rig:
 
                 # ik target hide driver
                 pole_target = pb[bones['ik']['ctrl']['ik_target']]
-                drv = pole_target.bone.driver_add("hide").driver
-                drv.type = 'AVERAGE'
 
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(pole_target.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 # vis-pole hide driver
                 vispole = pb[bones['ik']['visuals']['vispole']]
-                drv = vispole.bone.driver_add("hide").driver
-                drv.type = 'AVERAGE'
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+
+                make_driver(vispole.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 # arrow hide driver
-                # pole_target = pb[bones['ik']['ctrl']['limb']]
-                # drv = pole_target.bone.driver_add("hide").driver
-                # drv.type = 'AVERAGE'
+                # limb = pb[bones['ik']['ctrl']['limb']]
                 #
-                # var = drv.variables.new()
-                # var.name = prop
-                # var.type = "SINGLE_PROP"
-                # var.targets[0].id = self.obj
-                # var.targets[0].data_path = \
-                #     owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-                #
-                # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-                #
-                # drv_modifier.mode = 'POLYNOMIAL'
-                # drv_modifier.poly_order = 1
-                # drv_modifier.coefficients[0] = 0.0
-                # drv_modifier.coefficients[1] = 1.0
+                # make_driver(limb.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[0.0, 1.0])
 
                 for cns in mch_ik.constraints:
                     if 'IK' in cns.type:
-                        drv = cns.driver_add("mute").driver
-                        drv.type = 'AVERAGE'
-
-                        var = drv.variables.new()
-                        var.name = prop
-                        var.type = "SINGLE_PROP"
-                        var.targets[0].id = self.obj
-                        var.targets[0].data_path = \
-                            owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                        drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                        drv_modifier.mode = 'POLYNOMIAL'
-                        drv_modifier.poly_order = 1
                         if not cns.pole_subtarget:
-                            drv_modifier.coefficients[0] = 0.0
-                            drv_modifier.coefficients[1] = 1
+                            make_driver(cns, "mute", variables=[(self.obj, owner, prop)], polynomial=[0.0, 1.0])
                         else:
-                            drv_modifier.coefficients[0] = 1.0
-                            drv_modifier.coefficients[1] = -1.0
+                            make_driver(cns, "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
             elif prop == 'IK_follow':
-
                 make_property(owner, prop, True)
 
-                drv = ctrl.constraints[0].driver_add("mute").driver
-                drv.type = 'AVERAGE'
-
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(ctrl.constraints[0], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 if len(ctrl.constraints) > 1:
-                    drv = ctrl.constraints[1].driver_add("mute").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                    drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                    drv_modifier.mode = 'POLYNOMIAL'
-                    drv_modifier.poly_order = 1
-                    drv_modifier.coefficients[0] = 1.0
-                    drv_modifier.coefficients[1] = -1.0
-
-                drv = ctrl_pole.constraints[0].driver_add("mute").driver
-                drv.type = 'AVERAGE'
-
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl.constraints[1], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(ctrl_pole.constraints[0], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 if len(ctrl_pole.constraints) > 1:
-                    drv = ctrl_pole.constraints[1].driver_add("mute").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                    drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                    drv_modifier.mode = 'POLYNOMIAL'
-                    drv_modifier.poly_order = 1
-                    drv_modifier.coefficients[0] = 1.0
-                    drv_modifier.coefficients[1] = -1.0
+                    make_driver(ctrl_pole.constraints[1], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
             elif prop == 'root/parent':
                 if len(ctrl.constraints) > 1:
                     make_property(owner, prop, 0.0)
 
-                    drv = ctrl.constraints[1].driver_add("influence").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl.constraints[1], "influence", variables=[(self.obj, owner, prop)])
 
             elif prop == 'pole_follow':
                 if len(ctrl_pole.constraints) > 1:
                     make_property(owner, prop, 0.0)
 
-                    drv = ctrl_pole.constraints[1].driver_add("influence").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl_pole.constraints[1], "influence", variables=[(self.obj, owner, prop)])
 
     @staticmethod
     def get_future_names(bones):
diff --git a/rigify/rigs/limbs/leg.py b/rigify/rigs/limbs/leg.py
index 78974be2b38351d088c94c1afc89714ca615e829..2b846eca856d51094668d6dd8194643595128280 100644
--- a/rigify/rigs/limbs/leg.py
+++ b/rigify/rigs/limbs/leg.py
@@ -13,7 +13,7 @@ from ...utils import align_bone_y_axis, align_bone_x_axis, align_bone_z_axis
 from ...rig_ui_template import UTILITIES_RIG_LEG, REGISTER_RIG_LEG
 from ...utils import ControlLayersOption
 from rna_prop_ui import rna_idprop_ui_prop_get
-from ...utils.mechanism import make_property
+from ...utils.mechanism import make_property, make_driver
 from ..widgets import create_ikarrow_widget
 from math import trunc, pi
 
@@ -151,15 +151,7 @@ class Rig:
         # prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True )
         make_property(pb[main_parent], name, 0.0)
 
-        drv = pb[mch].constraints[0].driver_add("influence").driver
-
-        drv.type = 'AVERAGE'
-        var = drv.variables.new()
-        var.name = name
-        var.type = "SINGLE_PROP"
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = pb[main_parent].path_from_id() + \
-                                   '[' + '"' + name + '"' + ']'
+        make_driver(pb[mch].constraints[0], "influence", variables=[(self.obj, main_parent, name)])
 
         size = pb[main_parent].bone.y_axis.length * 10
         create_gear_widget(self.obj, main_parent, size=size, bone_transform_name=None)
@@ -360,25 +352,11 @@ class Rig:
             make_property(pb[t], name, defval, max=2.0, soft_max=1.0)
 
         for j,d in enumerate(def_bones[:-1]):
-            drvs = {}
             if j != 0:
-                tidx = j
-                drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_easein").driver
+                make_driver(self.obj.data.bones[d], "bbone_easein", variables=[(self.obj, tweaks[j], 'rubber_tweak')])
 
             if j != len( def_bones[:-1] ) - 1:
-                tidx = j + 1
-                drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_easeout").driver
-
-            for d in drvs:
-                drv = drvs[d]
-                name = 'rubber_tweak'
-                drv.type = 'AVERAGE'
-                var = drv.variables.new()
-                var.name = name
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = pb[tweaks[d]].path_from_id() + \
-                                           '[' + '"' + name + '"' + ']'
+                make_driver(self.obj.data.bones[d], "bbone_easeout", variables=[(self.obj, tweaks[j+1], 'rubber_tweak')])
 
         return def_bones
 
@@ -589,15 +567,7 @@ class Rig:
             })
 
             # Add driver to relevant constraint
-            drv = pb[o].constraints[-1].driver_add("influence").driver
-            drv.type = 'AVERAGE'
-
-            var = drv.variables.new()
-            var.name = prop.name
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']'
+            make_driver(pb[o].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)])
 
     def create_leg(self, bones):
         org_bones = list(
@@ -941,22 +911,8 @@ class Rig:
 
         # Add driver to limit scale constraint influence
         b = bones['ik']['mch_str']
-        drv = pb[b].constraints[-1].driver_add("influence").driver
-        drv.type = 'AVERAGE'
-
-        var = drv.variables.new()
-        var.name = prop.name
-        var.type = "SINGLE_PROP"
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = \
-            pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']'
-
-        drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
 
-        drv_modifier.mode = 'POLYNOMIAL'
-        drv_modifier.poly_order = 1
-        drv_modifier.coefficients[0] = 1.0
-        drv_modifier.coefficients[1] = -1.0
+        make_driver(pb[b].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)], polynomial=[1.0, -1.0])
 
         # Create leg widget
         create_foot_widget(self.obj, ctrl, bone_transform_name=None)
@@ -1016,22 +972,8 @@ class Rig:
 
             # Add driver to limit scale constraint influence
             b = toe_mch
-            drv = pb[b].constraints[-1].driver_add("influence").driver
-            drv.type = 'AVERAGE'
 
-            var = drv.variables.new()
-            var.name = prop.name
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
-            drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-            drv_modifier.mode = 'POLYNOMIAL'
-            drv_modifier.poly_order = 1
-            drv_modifier.coefficients[0] = 1.0
-            drv_modifier.coefficients[1] = -1.0
+            make_driver(pb[b].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)], polynomial=[1.0, -1.0])
 
             # Create toe circle widget
             create_circle_widget(self.obj, toes, radius=0.4, head_tail=0.5)
@@ -1068,184 +1010,51 @@ class Rig:
 
                 # ik target hide driver
                 pole_target = pb[bones['ik']['ctrl']['ik_target']]
-                drv = pole_target.bone.driver_add("hide").driver
-                drv.type = 'AVERAGE'
-
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
 
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(pole_target.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 # vis-pole hide driver
                 vispole = pb[bones['ik']['visuals']['vispole']]
-                drv = vispole.bone.driver_add("hide").driver
-                drv.type = 'AVERAGE'
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+
+                make_driver(vispole.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 # arrow hide driver
-                # pole_target = pb[bones['ik']['ctrl']['limb']]
-                # drv = pole_target.bone.driver_add("hide").driver
-                # drv.type = 'AVERAGE'
-                #
-                # var = drv.variables.new()
-                # var.name = prop
-                # var.type = "SINGLE_PROP"
-                # var.targets[0].id = self.obj
-                # var.targets[0].data_path = \
-                #     owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                # limb = pb[bones['ik']['ctrl']['limb']]
                 #
-                # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-                #
-                # drv_modifier.mode = 'POLYNOMIAL'
-                # drv_modifier.poly_order = 1
-                # drv_modifier.coefficients[0] = 0.0
-                # drv_modifier.coefficients[1] = 1.0
+                # make_driver(limb.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[0.0, 1.0])
 
                 for cns in mch_ik.constraints:
                     if 'IK' in cns.type:
-                        drv = cns.driver_add("mute").driver
-                        drv.type = 'AVERAGE'
-
-                        var = drv.variables.new()
-                        var.name = prop
-                        var.type = "SINGLE_PROP"
-                        var.targets[0].id = self.obj
-                        var.targets[0].data_path = \
-                            owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                        drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                        drv_modifier.mode = 'POLYNOMIAL'
-                        drv_modifier.poly_order = 1
                         if not cns.pole_subtarget:
-                            drv_modifier.coefficients[0] = 0.0
-                            drv_modifier.coefficients[1] = 1
+                            make_driver(cns, "mute", variables=[(self.obj, owner, prop)], polynomial=[0.0, 1.0])
                         else:
-                            drv_modifier.coefficients[0] = 1.0
-                            drv_modifier.coefficients[1] = -1.0
+                            make_driver(cns, "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
-            elif prop == 'IK_follow':
 
+            elif prop == 'IK_follow':
                 make_property(owner, prop, True)
 
-                drv = ctrl.constraints[0].driver_add("mute").driver
-                drv.type = 'AVERAGE'
-
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(ctrl.constraints[0], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 if len(ctrl.constraints) > 1:
-                    drv = ctrl.constraints[1].driver_add("mute").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                    drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                    drv_modifier.mode = 'POLYNOMIAL'
-                    drv_modifier.poly_order = 1
-                    drv_modifier.coefficients[0] = 1.0
-                    drv_modifier.coefficients[1] = -1.0
-
-                drv = ctrl_pole.constraints[0].driver_add("mute").driver
-                drv.type = 'AVERAGE'
+                    make_driver(ctrl.constraints[1], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(ctrl_pole.constraints[0], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 if len(ctrl_pole.constraints) > 1:
-                    drv = ctrl_pole.constraints[1].driver_add("mute").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                    drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                    drv_modifier.mode = 'POLYNOMIAL'
-                    drv_modifier.poly_order = 1
-                    drv_modifier.coefficients[0] = 1.0
-                    drv_modifier.coefficients[1] = -1.0
+                    make_driver(ctrl_pole.constraints[1], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
             elif prop == 'root/parent':
                 if len(ctrl.constraints) > 1:
                     make_property(owner, prop, 0.0)
 
-                    drv = ctrl.constraints[1].driver_add("influence").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl.constraints[1], "influence", variables=[(self.obj, owner, prop)])
 
             elif prop == 'pole_follow':
                 if len(ctrl_pole.constraints) > 1:
                     make_property(owner, prop, 0.0)
 
-                    drv = ctrl_pole.constraints[1].driver_add("influence").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl_pole.constraints[1], "influence", variables=[(self.obj, owner, prop)])
 
     @staticmethod
     def get_future_names(bones):
diff --git a/rigify/rigs/limbs/paw.py b/rigify/rigs/limbs/paw.py
index 0350d36abc6098f75fa97bbb7d42244c5b5cd20a..b57f07ddd5bd13a24992556d8da0356d4f23afa6 100644
--- a/rigify/rigs/limbs/paw.py
+++ b/rigify/rigs/limbs/paw.py
@@ -11,7 +11,7 @@ from ...utils import align_bone_x_axis, align_bone_z_axis
 from ...rig_ui_template import UTILITIES_RIG_LEG, REGISTER_RIG_LEG
 from ...utils import ControlLayersOption
 from rna_prop_ui import rna_idprop_ui_prop_get
-from ...utils.mechanism import make_property
+from ...utils.mechanism import make_property, make_driver
 from ..widgets import create_ikarrow_widget, create_gear_widget
 from ..widgets import create_foot_widget, create_ballsocket_widget
 from math import trunc, pi
@@ -137,15 +137,7 @@ class Rig:
         # prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True )
         make_property(pb[main_parent], name, 0.0)
 
-        drv = pb[mch].constraints[0].driver_add("influence").driver
-
-        drv.type = 'AVERAGE'
-        var = drv.variables.new()
-        var.name = name
-        var.type = "SINGLE_PROP"
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = pb[main_parent].path_from_id() + \
-                                   '[' + '"' + name + '"' + ']'
+        make_driver(pb[mch].constraints[0], "influence", variables=[(self.obj, main_parent, name)])
 
         size = pb[main_parent].bone.y_axis.length * 10
         create_gear_widget(self.obj, main_parent, size=size, bone_transform_name=None)
@@ -351,25 +343,11 @@ class Rig:
             make_property(pb[t], name, defvalue, max=2.0, soft_max=1.0)
 
         for j,d in enumerate(def_bones[:-1]):
-            drvs = {}
             if j != 0:
-                tidx = j
-                drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_easein").driver
+                make_driver(self.obj.data.bones[d], "bbone_easein", variables=[(self.obj, tweaks[j], 'rubber_tweak')])
 
             if j != len( def_bones[:-1] ) - 1:
-                tidx = j + 1
-                drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_easeout").driver
-
-            for d in drvs:
-                drv = drvs[d]
-                name = 'rubber_tweak'
-                drv.type = 'AVERAGE'
-                var = drv.variables.new()
-                var.name = name
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = pb[tweaks[d]].path_from_id() + \
-                                           '[' + '"' + name + '"' + ']'
+                make_driver(self.obj.data.bones[d], "bbone_easeout", variables=[(self.obj, tweaks[j+1], 'rubber_tweak')])
 
         return def_bones
 
@@ -583,15 +561,7 @@ class Rig:
             })
 
             # Add driver to relevant constraint
-            drv = pb[o].constraints[-1].driver_add("influence").driver
-            drv.type = 'AVERAGE'
-
-            var = drv.variables.new()
-            var.name = prop.name
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']'
+            make_driver(pb[o].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)])
 
     def create_paw(self, bones):
         org_bones = list(
@@ -770,22 +740,8 @@ class Rig:
 
         # Add driver to limit scale constraint influence
         b = bones['ik']['mch_str']
-        drv = pb[b].constraints[-1].driver_add("influence").driver
-        drv.type = 'AVERAGE'
-
-        var = drv.variables.new()
-        var.name = prop.name
-        var.type = "SINGLE_PROP"
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = \
-            pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']'
-
-        drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
 
-        drv_modifier.mode = 'POLYNOMIAL'
-        drv_modifier.poly_order = 1
-        drv_modifier.coefficients[0] = 1.0
-        drv_modifier.coefficients[1] = -1.0
+        make_driver(pb[b].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)], polynomial=[1.0, -1.0])
 
         # Create paw widget
         create_foot_widget(self.obj, ctrl, bone_transform_name=None)
@@ -843,22 +799,8 @@ class Rig:
 
             # Add driver to limit scale constraint influence
             b = toes_mch_parent
-            drv = pb[b].constraints[-1].driver_add("influence").driver
-            drv.type = 'AVERAGE'
 
-            var = drv.variables.new()
-            var.name = prop.name
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
-            drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-            drv_modifier.mode = 'POLYNOMIAL'
-            drv_modifier.poly_order = 1
-            drv_modifier.coefficients[0] = 1.0
-            drv_modifier.coefficients[1] = -1.0
+            make_driver(pb[b].constraints[-1], "influence", variables=[(self.obj, pb_parent, prop.name)], polynomial=[1.0, -1.0])
 
             # Create toe circle widget
             create_circle_widget(self.obj, toes, radius=0.4, head_tail=0.5)
@@ -895,184 +837,50 @@ class Rig:
 
                 # ik target hide driver
                 pole_target = pb[bones['ik']['ctrl']['ik_target']]
-                drv = pole_target.bone.driver_add("hide").driver
-                drv.type = 'AVERAGE'
-
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
 
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(pole_target.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 # vis-pole hide driver
                 vispole = pb[bones['ik']['visuals']['vispole']]
-                drv = vispole.bone.driver_add("hide").driver
-                drv.type = 'AVERAGE'
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+
+                make_driver(vispole.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 # arrow hide driver
-                # pole_target = pb[bones['ik']['ctrl']['limb']]
-                # drv = pole_target.bone.driver_add("hide").driver
-                # drv.type = 'AVERAGE'
-                #
-                # var = drv.variables.new()
-                # var.name = prop
-                # var.type = "SINGLE_PROP"
-                # var.targets[0].id = self.obj
-                # var.targets[0].data_path = \
-                #     owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                # limb = pb[bones['ik']['ctrl']['limb']]
                 #
-                # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-                #
-                # drv_modifier.mode = 'POLYNOMIAL'
-                # drv_modifier.poly_order = 1
-                # drv_modifier.coefficients[0] = 0.0
-                # drv_modifier.coefficients[1] = 1.0
+                # make_driver(limb.bone, "hide", variables=[(self.obj, owner, prop)], polynomial=[0.0, 1.0])
 
                 for cns in mch_ik.constraints:
                     if 'IK' in cns.type:
-                        drv = cns.driver_add("mute").driver
-                        drv.type = 'AVERAGE'
-
-                        var = drv.variables.new()
-                        var.name = prop
-                        var.type = "SINGLE_PROP"
-                        var.targets[0].id = self.obj
-                        var.targets[0].data_path = \
-                            owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                        drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                        drv_modifier.mode = 'POLYNOMIAL'
-                        drv_modifier.poly_order = 1
                         if not cns.pole_subtarget:
-                            drv_modifier.coefficients[0] = 0.0
-                            drv_modifier.coefficients[1] = 1
+                            make_driver(cns, "mute", variables=[(self.obj, owner, prop)], polynomial=[0.0, 1.0])
                         else:
-                            drv_modifier.coefficients[0] = 1.0
-                            drv_modifier.coefficients[1] = -1.0
+                            make_driver(cns, "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
             elif prop == 'IK_follow':
-
                 make_property(owner, prop, True)
 
-                drv = ctrl.constraints[0].driver_add("mute").driver
-                drv.type = 'AVERAGE'
-
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(ctrl.constraints[0], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 if len(ctrl.constraints) > 1:
-                    drv = ctrl.constraints[1].driver_add("mute").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                    drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                    drv_modifier.mode = 'POLYNOMIAL'
-                    drv_modifier.poly_order = 1
-                    drv_modifier.coefficients[0] = 1.0
-                    drv_modifier.coefficients[1] = -1.0
-
-                drv = ctrl_pole.constraints[0].driver_add("mute").driver
-                drv.type = 'AVERAGE'
+                    make_driver(ctrl.constraints[1], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
-                var = drv.variables.new()
-                var.name = prop
-                var.type = "SINGLE_PROP"
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = \
-                    owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                drv_modifier.mode = 'POLYNOMIAL'
-                drv_modifier.poly_order = 1
-                drv_modifier.coefficients[0] = 1.0
-                drv_modifier.coefficients[1] = -1.0
+                make_driver(ctrl_pole.constraints[0], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
                 if len(ctrl_pole.constraints) > 1:
-                    drv = ctrl_pole.constraints[1].driver_add("mute").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-                    drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-                    drv_modifier.mode = 'POLYNOMIAL'
-                    drv_modifier.poly_order = 1
-                    drv_modifier.coefficients[0] = 1.0
-                    drv_modifier.coefficients[1] = -1.0
+                    make_driver(ctrl_pole.constraints[1], "mute", variables=[(self.obj, owner, prop)], polynomial=[1.0, -1.0])
 
             elif prop == 'root/parent':
                 if len(ctrl.constraints) > 1:
                     make_property(owner, prop, 0.0)
 
-                    drv = ctrl.constraints[1].driver_add("influence").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl.constraints[1], "influence", variables=[(self.obj, owner, prop)])
 
             elif prop == 'pole_follow':
                 if len(ctrl_pole.constraints) > 1:
                     make_property(owner, prop, 0.0)
 
-                    drv = ctrl_pole.constraints[1].driver_add("influence").driver
-                    drv.type = 'AVERAGE'
-
-                    var = drv.variables.new()
-                    var.name = prop
-                    var.type = "SINGLE_PROP"
-                    var.targets[0].id = self.obj
-                    var.targets[0].data_path = \
-                        owner.path_from_id() + '[' + '"' + prop + '"' + ']'
+                    make_driver(ctrl_pole.constraints[1], "influence", variables=[(self.obj, owner, prop)])
 
     @staticmethod
     def get_future_names(bones):
diff --git a/rigify/rigs/spines/super_spine.py b/rigify/rigs/spines/super_spine.py
index 85169ca61c84f551193d401f91940e4f25624da0..5afe15b0fc5a620e72b8a4853eefd52db8e84dc8 100644
--- a/rigify/rigs/spines/super_spine.py
+++ b/rigify/rigs/spines/super_spine.py
@@ -6,7 +6,7 @@ from ...utils import create_circle_widget, create_sphere_widget, create_neck_ben
 from ..widgets import create_ballsocket_widget
 from ...utils import MetarigError, make_mechanism_name, create_cube_widget
 from ...utils import ControlLayersOption
-from ...utils.mechanism import make_property
+from ...utils.mechanism import make_property, make_driver
 
 script = """
 controls = [%s]
@@ -775,22 +775,7 @@ class Rig:
         # driving the follow rotation switches for neck and head
         for bone, prop, in zip(owners, props):
             # Add driver to copy rotation constraint
-            drv = pb[bone].constraints[0].driver_add("influence").driver
-            drv.type = 'AVERAGE'
-
-            var = drv.variables.new()
-            var.name = prop
-            var.type = "SINGLE_PROP"
-            var.targets[0].id = self.obj
-            var.targets[0].data_path = \
-                torso.path_from_id() + '[' + '"' + prop + '"' + ']'
-
-            drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
-            drv_modifier.mode = 'POLYNOMIAL'
-            drv_modifier.poly_order = 1
-            drv_modifier.coefficients[0] = 1.0
-            drv_modifier.coefficients[1] = -1.0
+            make_driver(pb[bone].constraints[0], "influence", variables=[(self.obj, torso, prop)], polynomial=[1.0, -1.0])
 
     def locks_and_widgets(self, bones):
         bpy.ops.object.mode_set(mode='OBJECT')
diff --git a/rigify/ui.py b/rigify/ui.py
index 0091f7b91350d3fefbc2329c81914483ed753ad4..48f34e0efc3e6368113c0084138e5b84c17ec5ac 100644
--- a/rigify/ui.py
+++ b/rigify/ui.py
@@ -1277,17 +1277,15 @@ class OBJECT_OT_ClearAnimation(bpy.types.Operator):
     anim_type: StringProperty()
 
     def execute(self, context):
+        rig = context.object
+        scn = context.scene
+        if not rig.animation_data:
+            return {'FINISHED'}
+        act = rig.animation_data.action
+        if not act:
+            return {'FINISHED'}
 
-        try:
-            rig = context.object
-            scn = context.scene
-            if not rig.animation_data:
-                return {'FINISHED'}
-            act = rig.animation_data.action
-            if not act:
-                return {'FINISHED'}
-
-            clearAnimation(act, self.anim_type, names=get_limb_generated_names(rig))
+        clearAnimation(act, self.anim_type, names=get_limb_generated_names(rig))
         return {'FINISHED'}