From c4157673f5c3dd812a985859c0ec2ba085a32b15 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 20 May 2024 16:04:18 +1000 Subject: [PATCH] Fix #4696. Null properties are now purged by default to prevent cruft build up. Add support for purging empty enum props. --- .../ifcopenshell/api/pset/edit_pset.py | 10 +++++++--- .../test/api/pset/test_edit_pset.py | 17 ++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py index f8c0974b0d..2fe9c22c0e 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py +++ b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py @@ -27,7 +27,7 @@ def edit_pset( name: Optional[str] = None, properties: Optional[dict[str, Any]] = None, pset_template: Optional[ifcopenshell.entity_instance] = None, - should_purge: bool = False, + should_purge: bool = True, ) -> None: """Edits a property set and its properties @@ -77,9 +77,10 @@ def edit_pset( be used to determine data types. If no user-defined template is provided, the built-in buildingSMART templates will be loaded. :type pset_template: ifcopenshell.entity_instance, optional - :param should_purge: If left as False, properties set to None will be + :param should_purge: If set as False, properties set to None will be left as None but not removed. If set to true, properties set to None - will actually be removed. + will actually be removed. The default of true is the same behaviour as + :func:`ifcopenshell.api.pset.edit_qto`. :type should_purge: bool, optional :return: None :rtype: None @@ -241,6 +242,9 @@ class Usecase: if isinstance(value, (tuple, list)): sel_vals = [] + if not value: + if self._try_purge(prop): + return for val in value: primary_measure_type = prop.EnumerationReference.EnumerationValues[ 0 diff --git a/src/ifcopenshell-python/test/api/pset/test_edit_pset.py b/src/ifcopenshell-python/test/api/pset/test_edit_pset.py index 7912771759..5c065495ab 100644 --- a/src/ifcopenshell-python/test/api/pset/test_edit_pset.py +++ b/src/ifcopenshell-python/test/api/pset/test_edit_pset.py @@ -59,7 +59,9 @@ class TestEditPset(test.bootstrap.IFC4): pset=pset, properties={"Reference": "foo", "Status": ["NEW"], "Combustible": True, "ThermalTransmittance": 42}, ) - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Reference": "bar", "Status": []}) + ifcopenshell.api.run( + "pset.edit_pset", self.file, pset=pset, properties={"Reference": "bar", "Status": []}, should_purge=False + ) pset = element.IsDefinedBy[0].RelatingPropertyDefinition assert pset.HasProperties[0].Name == "Reference" @@ -88,8 +90,7 @@ class TestEditPset(test.bootstrap.IFC4): def test_adding_a_property_if_it_is_none(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Pset_WallCommon") - # should_purge is false by default - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Reference": None}) + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Reference": None}, should_purge=False) pset = element.IsDefinedBy[0].RelatingPropertyDefinition assert len(pset.HasProperties) == 1 @@ -108,6 +109,16 @@ class TestEditPset(test.bootstrap.IFC4): pset = element.IsDefinedBy[0].RelatingPropertyDefinition assert len(pset.HasProperties) == 0 + def test_removing_a_none_enumeration_property_if_specified(self): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Pset_WallCommon") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Status": ["NEW"]}) + assert pset.HasProperties[0].Name == "Status" + assert pset.HasProperties[0].EnumerationValues[0].wrappedValue == "NEW" + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Status": []}, should_purge=True) + pset = element.IsDefinedBy[0].RelatingPropertyDefinition + assert len(pset.HasProperties) == 0 + def test_editing_a_pset_name(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="foo")