mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 00:03:17 +00:00
Fix get_property_unit() crash on IfcPropertySingleValue.NominalValue = None
NominalValue is optional -- IfcPropertySingleValue permits a null value --
but get_property_unit() unconditionally accessed prop.NominalValue.is_a(),
crashing on any single-value property that's legitimately blank.
Also adds a regression test confirming IfcContextDependentUnit symbols
("each", "boxes", etc.) aren't shadowed by the IfcDerivedUnit branch added
in the previous commit.
This commit is contained in:
@@ -525,7 +525,8 @@ def get_property_unit(
|
||||
entity = prop.wrapped_data.declaration().as_entity()
|
||||
measure_class = entity.attribute_by_index(3).type_of_attribute().declared_type().name()
|
||||
elif prop.is_a("IfcPropertySingleValue"):
|
||||
measure_class = prop.NominalValue.is_a()
|
||||
if value := prop.NominalValue:
|
||||
measure_class = value.is_a()
|
||||
elif prop.is_a("IfcPropertyEnumeratedValue"):
|
||||
if prop.EnumerationReference:
|
||||
if unit := prop.EnumerationReference.Unit:
|
||||
|
||||
@@ -123,6 +123,12 @@ class TestGetPropertyUnit(test.bootstrap.IFC4):
|
||||
prop.Unit = length2
|
||||
assert subject.get_property_unit(prop, self.file) == length2
|
||||
|
||||
def test_single_value_with_no_nominal_value(self):
|
||||
# NominalValue is optional -- a property may be null. Must not crash.
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
prop = self.file.createIfcPropertySingleValue(Name="Foo", NominalValue=None)
|
||||
assert subject.get_property_unit(prop, self.file) is None
|
||||
|
||||
def test_enumerated_value(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
length = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
@@ -311,6 +317,13 @@ class TestGetUnitSymbol(test.bootstrap.IFC4):
|
||||
weird = ifcopenshell.api.unit.add_derived_unit(self.file, "USERDEFINED", "force per time", {force: 1, time: -1})
|
||||
assert subject.get_unit_symbol(weird) == "N/s"
|
||||
|
||||
def test_context_dependent_userdefined_unit_is_not_shadowed_by_the_derived_unit_check(self):
|
||||
# IfcContextDependentUnit (e.g. "each", "boxes") is a distinct entity
|
||||
# from IfcDerivedUnit, so the is_a("IfcDerivedUnit") check added for
|
||||
# derived-unit symbol composition must not shadow this fallback.
|
||||
each = ifcopenshell.api.unit.add_context_dependent_unit(self.file, name="EACH")
|
||||
assert subject.get_unit_symbol(each) == "EACH"
|
||||
|
||||
|
||||
class TestIdentifyUnitDimensions(test.bootstrap.IFC4):
|
||||
def test_matches_a_named_unit_type_by_dimension(self):
|
||||
|
||||
Reference in New Issue
Block a user