From 3d441b4ad3dd43683468a65cb83d617231bb13ee Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 20 Apr 2023 17:41:52 +1000 Subject: [PATCH] Fix #3038. Fix #3039. Selector should default to none instead for throwing errors if the query doesn't have a result. --- .../ifcopenshell/util/selector.py | 7 ++++++- .../test/util/test_selector.py | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py index ddd7220f17..216b807799 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/selector.py +++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py @@ -255,6 +255,8 @@ class Selector: value = element for key in keys: key = key.strip() + if value is None: + return if key == "type": value = ifcopenshell.util.element.get_type(value) elif key in ("material", "mat"): @@ -302,7 +304,10 @@ class Selector: value = value.get(key, None) elif isinstance(value, (list, tuple)): # If we use regex if key.isnumeric(): - value = value[int(key)] + try: + value = value[int(key)] + except IndexError: + return else: results = [] for v in value: diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py index 180a168815..54780279e0 100644 --- a/src/ifcopenshell-python/test/util/test_selector.py +++ b/src/ifcopenshell-python/test/util/test_selector.py @@ -56,6 +56,23 @@ class TestGetElementValue(test.bootstrap.IFC4): # Provide shortform for convenience assert subject.get_element_value(element, "mat.i.Name") == ["L1", "L2"] + def test_selecting_a_query_that_fails_silently(self): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + assert subject.get_element_value(element, "material.item.Name.0") is None + + def test_selceting_a_list_item_that_fails_silently(self): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + material = ifcopenshell.api.run("material.add_material", self.file, name="CON01") + material2 = ifcopenshell.api.run("material.add_material", self.file, name="CON02") + material_set = ifcopenshell.api.run( + "material.add_material_set", self.file, name="FOO", set_type="IfcMaterialLayerSet" + ) + layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=material_set, material=material) + layer.Name = "L1" + ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material_set) + assert subject.get_element_value(element, "material.item.Name.0") == "L1" + assert subject.get_element_value(element, "material.item.Name.1") is None + class TestSelector(test.bootstrap.IFC4): def test_selecting_by_class(self):