From 25c1a14e648dc354361160d5931f05ccbce45fcb Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 17 May 2024 15:25:39 +0500 Subject: [PATCH] set_element_value - pass attr value to the next part of the query #4495 E.g. previously set_element_value with query "material.item.Material.Name" would fail with error "Material property is expecting an IFC entity and not a string". But now it will detect that "Material" property is not a last key in the query and will pass `.Material` value forward and try to set it's `.Name` attribute with value. The main goal is to make sure get_element_value and set_element_value would have a same result for same queries. --- .../ifcopenshell/util/selector.py | 14 ++++++++++++-- src/ifcopenshell-python/test/util/test_selector.py | 7 +++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py index 04b8e4a5f3..2983f9239d 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/selector.py +++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py @@ -397,8 +397,14 @@ def set_element_value( if key == "Name" and element.is_a("IfcMaterialLayerSet"): key = "LayerSetName" # This oddity in the IFC spec is annoying so we account for it. - if isinstance(key, str) and hasattr(element, key): - if getattr(element, key) != value: + if isinstance(key, str) and ((current_value := getattr(element, key, ...)) is not ...): + # check if key is not last + if len(keys) != i + 1: + element = current_value + continue + + if current_value != value: + # check if key is not last try: # Try our luck return setattr(element, key, value) @@ -422,6 +428,10 @@ def set_element_value( value = False else: value = bool(value) + elif data_type == "entity": + value = ifc_file.by_guid(value) + if current_value == value: + return return setattr(element, key, value) else: # Try to extract pset diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py index 78dbc7e946..37a103d313 100644 --- a/src/ifcopenshell-python/test/util/test_selector.py +++ b/src/ifcopenshell-python/test/util/test_selector.py @@ -311,6 +311,13 @@ class TestSetElementValue(test.bootstrap.IFC4): subject.set_element_value(self.file, element, "Name", 123) assert element.Name == "123" + def test_set_attributes_attribute(self): + material = self.file.create_entity("IfcMaterial") + layer = self.file.create_entity("IfcMaterialLayer") + layer.Material = material + subject.set_element_value(self.file, layer, "Material.Name", "Foo") + assert material.Name == "Foo" + class TestSelector(test.bootstrap.IFC4): def test_selecting_from_specified_elements(self):