Best way to let users target a specific property

so i’m polishing off an update to my vr add-on that lets users bind vr controller inputs to any property in blender: OpenVR Tracker Streaming

i’m using getattr() and setattr() to accomplish this.

i’m using a prop_search of scene objects in the ui to let the user select an object, and i give a text field so the user needs to enter the specific property path and then i parse it with sequential getattr() calls.

so for a simple example like a light’s energy value, the property would be:
‘data.energy’

but when i start getting into more complex situations, like the x location of a given bone in an armature, the property path starts getting much more complex:
‘pose.bones[Bone.001].location.x’

so now i’m getting into regular expressions and more complicated logic to figure out when i’m dealing with lists and whether the lists are indexed by strings or ints, etc.

i’ve more or less figured it out, but i wanted to gut check if theres some easier way that i’m just overlooking.

I get three ideas about it

[1]
To use general purpose functions with lots of conditional checks and meta-programming.
A.
set_special_value("Armature.001", "location", "x", 10)
That way you simplify your API calls and make high-level. The implementation of the function has lots of modular and complex logic inside it but at least is implemented only once and is testable.
B.
if object type is armature and it has this attribute and is not zero then set this value to it.
You have lots of low-level conditional code just to set one property, now imagine about scaling it with many properties per object and and many object types per scene.

[2]
To use your own type system that wraps around the Blender system using strong typing (see Python strong typing). That way you can create a much higher-level layer, and hopefully with some inheritance and method overriding you will end up with a much more simplified and well defined structure of the code.

import bpy


class SuperObject:
    def __init__(self):
        self.blenderobject = None
        
    @staticmethod
    def new(name):
        o = SuperObject()
        o.blenderobject = bpy.context.scene.objects[name]
        return o
        
    @property
    def name(self):
        return self.blenderobject.name
    
    @property
    def type(self):
        return self.blenderobject.type
    
o1 = SuperObject.new('Cube')
print(o1.name, o1.type) 

[3]
Something else…

I have not examined these ideas in detail so I might miss the big picture, but it looks very interesting, it might lead to new ways of writing addons. If you have any further test cases post them here.