Created
November 21, 2023 07:49
-
-
Save hesido/eef189fe1f6e111c704ac5f927f985f8 to your computer and use it in GitHub Desktop.
Blender Python Function To Evaluate User Input Property Paths without Eval
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def evaluate_path(path, alternative_root = None): | |
#alternative_root can be used to define a default parent root object if user is not expected to enter full path | |
#Note: full paths start with "bpy." | |
if(path is None or path == ""): | |
return (None, None, None) | |
#Regular expression pattern to match segments of the path | |
pattern = r'(.+?)\.|(?:\["(.+?)"\])|([^"\[\]]+)' | |
segments = re.findall(pattern, path) | |
parent_obj = None | |
enumerate_from = 0 | |
# If full path, start with bpy | |
if segments[0][0] == "bpy": | |
current_obj = bpy | |
enumerate_from = 1 | |
else: | |
current_obj = alternative_root | |
if(current_obj is None): | |
return (None, None, None) | |
for segment in segments[enumerate_from:]: | |
prop_name = segment[0] or segment[1] or segment[2] | |
# Check if the property exists | |
if hasattr(current_obj, prop_name): | |
parent_obj = current_obj | |
current_obj = getattr(current_obj, prop_name) | |
else: | |
if isinstance(current_obj, list): | |
# Check if the property is an indexed attribute in a list | |
index = int(prop_name) # Extract the index | |
if 0 <= index < len(current_obj): | |
parent_obj = current_obj | |
current_obj = current_obj[index] | |
else: | |
return (None, None, None) # Index out of range | |
elif prop_name in current_obj: | |
parent_obj = current_obj | |
current_obj = current_obj[prop_name] | |
else: | |
return (None, None, None) # Key not found | |
#return (target object of path, parent of target object, property name string of the target object) | |
return (current_obj, parent_obj, prop_name) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment