From 4326a74c64ec1d7be63525bba46357c2f43c442f Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 10 May 2022 21:40:35 +1000 Subject: [PATCH] Fix IDS to not allow subclasses and allow restrictions in the class name --- src/ifcopenshell-python/ifcopenshell/ids.py | 13 ++++++++----- src/ifcopenshell-python/test/test_ids.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/ids.py b/src/ifcopenshell-python/ifcopenshell/ids.py index 2f4174c09a..6ff2edf8b5 100644 --- a/src/ifcopenshell-python/ifcopenshell/ids.py +++ b/src/ifcopenshell-python/ifcopenshell/ids.py @@ -498,9 +498,8 @@ class entity(facet): def __call__(self, inst, logger=None): """Validate an entity. - When a simple value is provided for the name, subclasses are also - treated as valid. PredefinedType checks support userdefined types for - both element and type elements. + Subclasses are not considered to pass the requirements. PredefinedType + checks support userdefined types for both element and type elements. :param inst: IFC entity element :type inst: IFC entity @@ -509,16 +508,20 @@ class entity(facet): :return: result of the validation as bool and message :rtype: facet_evaluation(bool, str) """ + if isinstance(self.name, str): + is_class = inst.is_a().lower() == self.name.lower() + else: + is_class = inst.is_a() == self.name if self.predefinedType: predefined_type = ifcopenshell.util.element.get_predefined_type(inst) self.message = "an entity name '%(name)s' of predefined type '%(predefinedType)s'" return facet_evaluation( - inst.is_a(self.name) and predefined_type == self.predefinedType, + is_class and predefined_type == self.predefinedType, self.message % {"name": inst.is_a(), "predefinedType": predefined_type}, ) else: self.message = "an entity name '%(name)s'" - return facet_evaluation(inst.is_a(self.name), self.message % {"name": inst.is_a()}) + return facet_evaluation(is_class, self.message % {"name": inst.is_a()}) class attribute(facet): diff --git a/src/ifcopenshell-python/test/test_ids.py b/src/ifcopenshell-python/test/test_ids.py index 3605e18e1f..92434bd0fd 100644 --- a/src/ifcopenshell-python/test/test_ids.py +++ b/src/ifcopenshell-python/test/test_ids.py @@ -280,6 +280,11 @@ class TestIdsAuthoring(unittest.TestCase): assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is True assert bool(facet(ifc.createIfcSlab())) is False + facet = ids.entity.create(name="IFCWALL") + assert bool(facet(ifc.createIfcWall())) is True + assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is True + assert bool(facet(ifc.createIfcSlab())) is False + facet = ids.entity.create(name="IfcWall", predefinedType="SOLIDWALL") assert bool(facet(ifc.createIfcWall())) is False assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is True @@ -291,6 +296,17 @@ class TestIdsAuthoring(unittest.TestCase): facet = ids.entity.create(name="IfcWallType", predefinedType="WALDO") assert bool(facet(ifc.createIfcWallType(PredefinedType="USERDEFINED", ElementType="WALDO"))) is True + restriction = ids.restriction.create(options=["IfcWall", "IfcSlab"], type="enumeration", base="string") + facet = ids.entity.create(name=restriction) + assert bool(facet(ifc.createIfcWall())) is True + assert bool(facet(ifc.createIfcSlab())) is True + assert bool(facet(ifc.createIfcBeam())) is False + + restriction = ids.restriction.create(options="Ifc.*Type", type="pattern", base="string") + facet = ids.entity.create(name=restriction) + assert bool(facet(ifc.createIfcWall())) is False + assert bool(facet(ifc.createIfcWallType())) is True + def test_attribute_create(self): attribute = ids.attribute.create(name="Name", value="Value") assert attribute.name == "Name"