I tried to extract all attributes from the example, and it works for “SantaSleigh”, when I call find_element_by_name, it then prints (see code snippet below)
rudolph.energyLevel = 200.0
But when I try to do the same for “Reindeer” then it fails, because the noseColor attribute is referencing an enumeration, which does not seem to be handled as a part.feature_value_expression, so in the following code, the assert is triggered….
# print if it is an attribute
if type(part) == syside.AttributeUsage:
print ("-- at ", part.name)
expression = part.feature_value_expression
assert expression is not None
evaluation = syside.Compiler().evaluate(expression)
if evaluation[1].fatal:
print(f"Error evaluating {part.name}")
else:
value = evaluation[0]
print(" " * part_level, f"{part.owner.name}.{part.name} = {value}")
So, can you show me how to handle the case of the enumeration?
From this code snippet I think that you simply encounter the attribute noseColor : Color; that belongs to the part def Reindeer - and it does not have a feature value expression. In the case of noseColor = Color::red; the feature noseColor is Color::red, but in the case of noseColor : Color the feature is typed by the enumeration, but is not equal to a specific color.
As for why the code is failing - you are asserting that part.feature_value_expression is not None.
Assuming that you are looping through different values of part, you could do
for part in some_list:
if type(part) == syside.AttributeUsage:
print ("-- at ", part.name)
expression = part.feature_value_expression
if expression is None:
print(f"Encountered an attribute {part.name} without a feature value expression")
continue
assert expression is not None
evaluation = syside.Compiler().evaluate(expression)
if evaluation[1].fatal:
print(f"Error evaluating {part.name}")
# If the feature value expression evaluates to
# an enumeration - we want to print its name
elif isinstance(evaluation[0], syside.EnumerationUsage):
value = evaluation[0].name
else:
value = evaluation[0]
print(" " * part_level, f"{part.owner.name}.{part.name} = {value}")
This way you can verify that the issue is what I think it is, and you jump over the attribute without a value expression without breaking the rest of the code. Hope that helps.
On a somewhat related note, we have realized that the example model is a bit confusing - the noseColors are references rather than attributes in the “SantaSleigh”, which is why your code only outputs
rudolph.energyLevel = 200.0
and skips over the different colors assigned to noseColor, but breaks in the Reindeer.