Some properties are converted to Python objects when you retrieve them. This needs to be avoided in order to create the subscription, by using datablock.path_resolve("property_name", False)
technically I think you want something closer to this:
import bpy
owner = None
subscribe_to = (bpy.types.Object, "active_shape_key_index")
#subscribe_to = bpy.context.object.path_resolve("active_shape_key_index", False)
def set_active_shape_key(*args):
obj = bpy.context.object
active_shape_key_index = obj.active_shape_key_index
print(f'{obj.name} shape key index change {active_shape_key_index}')
for shape_key in obj.data.shape_keys.key_blocks:
if shape_key.name != 'Basis':
shape_key.value = int(shape_key.name == obj.active_shape_key.name)
print(f'{shape_key.name} set to {shape_key.value}')
bpy.msgbus.subscribe_rna(
key=subscribe_to,
owner=owner,
args=(1, 2, 3),
notify=set_active_shape_key
)
by using subscribe_to = (bpy.types.Object, "active_shape_key_index") it will work for all objects in a scene if you only use subscribe_to = bpy.context.object.path_resolve("active_shape_key_index", False) you’re only catching messages for the object that was active when you ran the script.
also keep in mind you don’t have a clear in this so you don’t want to run it multiple times.