Fix #4696. Null properties are now purged by default to prevent cruft build up. Add support for purging empty enum props.

This commit is contained in:
Dion Moult
2024-05-20 16:04:18 +10:00
parent 16285e0625
commit c4157673f5
2 changed files with 21 additions and 6 deletions
@@ -27,7 +27,7 @@ def edit_pset(
name: Optional[str] = None, name: Optional[str] = None,
properties: Optional[dict[str, Any]] = None, properties: Optional[dict[str, Any]] = None,
pset_template: Optional[ifcopenshell.entity_instance] = None, pset_template: Optional[ifcopenshell.entity_instance] = None,
should_purge: bool = False, should_purge: bool = True,
) -> None: ) -> None:
"""Edits a property set and its properties """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 be used to determine data types. If no user-defined template is
provided, the built-in buildingSMART templates will be loaded. provided, the built-in buildingSMART templates will be loaded.
:type pset_template: ifcopenshell.entity_instance, optional :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 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 :type should_purge: bool, optional
:return: None :return: None
:rtype: None :rtype: None
@@ -241,6 +242,9 @@ class Usecase:
if isinstance(value, (tuple, list)): if isinstance(value, (tuple, list)):
sel_vals = [] sel_vals = []
if not value:
if self._try_purge(prop):
return
for val in value: for val in value:
primary_measure_type = prop.EnumerationReference.EnumerationValues[ primary_measure_type = prop.EnumerationReference.EnumerationValues[
0 0
@@ -59,7 +59,9 @@ class TestEditPset(test.bootstrap.IFC4):
pset=pset, pset=pset,
properties={"Reference": "foo", "Status": ["NEW"], "Combustible": True, "ThermalTransmittance": 42}, 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 pset = element.IsDefinedBy[0].RelatingPropertyDefinition
assert pset.HasProperties[0].Name == "Reference" 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): def test_adding_a_property_if_it_is_none(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") 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") 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}, should_purge=False)
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Reference": None})
pset = element.IsDefinedBy[0].RelatingPropertyDefinition pset = element.IsDefinedBy[0].RelatingPropertyDefinition
assert len(pset.HasProperties) == 1 assert len(pset.HasProperties) == 1
@@ -108,6 +109,16 @@ class TestEditPset(test.bootstrap.IFC4):
pset = element.IsDefinedBy[0].RelatingPropertyDefinition pset = element.IsDefinedBy[0].RelatingPropertyDefinition
assert len(pset.HasProperties) == 0 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): def test_editing_a_pset_name(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") 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") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="foo")