Set active bone in pose mode from Python script

I'm trying to use the function bpy.ops.pose.constraint_add() on bones through a script, but stupid thing is that I can't find how to set the bones as active ones which is needed to call this function.

• My bad, I forgot to mention that this is under Blender 2.8 – Branck Mar 13 '19 at 23:32

Set bpy.types.ArmatureBones.active

It's a matter of setting the active bone of the armature (the data part), and hence the active pose bone.

Python console code. An armature object is active and in pose mode. Long windedly sets the active bone.

>>> C.object
bpy.data.objects['Armature']

>>> C.object.data
bpy.data.armatures['Armature']

>>> C.object.data.bones["Bone"]
bpy.data.armatures['Armature'].bones["Bone"]

>>> C.object.pose.bones["Bone"]
bpy.data.objects['Armature'].pose.bones["Bone"]

>>> C.object.pose.bones["Bone"].bone
bpy.data.objects['Armature'].pose.bones["Bone"].bone

>>> C.object.data.bones["Bone"] == C.object.pose.bones['Bone'].bone
True

>>> bone = C.object.pose.bones["Bone"].bone
>>> C.active_pose_bone
bpy.data.objects['Armature'].pose.bones["Bone.001"]

>>> C.object.data.bones.active
bpy.data.armatures['Armature'].bones["Bone.001"]

>>> C.object.data.bones.active = bone
>>> C.object.data.bones.active
bpy.data.armatures['Armature'].bones["Bone"]

>>> C.active_pose_bone
bpy.data.objects['Armature'].pose.bones["Bone"]


Use bone.select = True to have bone both active and selected.

Note There is no need for the operator.

Example adds a copy rotation constraint to each selected pose bone. The cube is used as the constraint target. Run script in pose mode, else context.selected_pose_bones will be None

import bpy

context = bpy.context
scene = context.scene
cube = context.scene.objects.get("Cube")

if cube and context.object.mode == 'POSE':
for pb in context.selected_pose_bones_from_active_object:
# use if already existes, else create
cr = (pb.constraints.get("CubeRot")
or pb.constraints.new(type='COPY_ROTATION'))
# set some properties
cr.name = "CubeRot"
cr.target_space = 'LOCAL'
cr.target = cube

• Thanks, that was quite simple after all. The API seems so different in 2.8 that i'm quite lost with it. Thanks again – Branck Mar 16 '19 at 23:02