From 4670715ef33c24740c72894747598cb09441a2db Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 6 May 2026 11:41:43 +0200 Subject: [PATCH] Work a bit on failing tests --- .../ifcopenshell/entity_instance.py | 2 +- .../api/alignment/test_add_segment_to_layout.py | 13 ++++++++++--- .../alignment/test_add_stationing_to_alignment.py | 13 ++++++++++--- .../api/alignment/test_add_vertical_alignment.py | 13 ++++++++++--- .../test/api/alignment/test_create.py | 13 ++++++++++--- .../api/alignment/test_create_as_offset_curve.py | 13 ++++++++++--- .../test/api/alignment/test_create_as_polyline.py | 13 ++++++++++--- .../test/api/alignment/test_create_by_pi_method.py | 13 ++++++++++--- .../api/alignment/test_create_layout_segment.py | 13 ++++++++++--- .../test/api/alignment/test_create_no_geometry.py | 13 ++++++++++--- .../alignment/test_distance_along_from_station.py | 11 ++++++++--- .../test/api/alignment/test_get_alignment.py | 10 ++++++++++ .../test/api/alignment/test_get_basis_curve.py | 10 ++++++++++ .../test/api/alignment/test_get_curve.py | 10 ++++++++++ .../test/api/alignment/test_get_layout_curve.py | 10 ++++++++++ .../api/alignment/test_has_zero_length_segment.py | 13 ++++++++++--- .../test_horizontal_layout_by_pi_method.py | 13 ++++++++++--- .../alignment/test_map_alignment_cant_segment.py | 9 ++++++--- .../test_map_alignment_horizontal_segment.py | 9 ++++++--- .../test_map_alignment_vertical_segment.py | 9 ++++++--- .../test/api/alignment/test_name_segments.py | 13 ++++++++++--- .../test/api/alignment/test_referent_names.py | 9 +++++++++ .../test_update_curve_segment_transition_code.py | 11 ++++++++--- .../api/alignment/test_update_fallback_position.py | 11 ++++++++--- .../alignment/test_vertical_layout_by_pi_method.py | 13 ++++++++++--- .../test/api/cogo/test_add_survey_point.py | 8 ++++++++ .../test/api/cogo/test_assign_survey_point.py | 8 ++++++++ .../test/api/cogo/test_bearing2dd.py | 3 --- .../test/api/cogo/test_edit_survey_point.py | 8 ++++++++ src/ifcopenshell-python/test/test_file.py | 9 +++++++++ src/ifcopenshell-python/test/util/test_alignment.py | 13 ++++++++++--- src/ifcparse/file.h | 2 +- src/ifcparse/parse.cpp | 2 +- src/ifcwrap/IfcParseWrapper.i | 5 ++--- src/pyodide/demo-app/index.html | 2 +- 35 files changed, 270 insertions(+), 70 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/entity_instance.py b/src/ifcopenshell-python/ifcopenshell/entity_instance.py index b98529e270..026352dd03 100644 --- a/src/ifcopenshell-python/ifcopenshell/entity_instance.py +++ b/src/ifcopenshell-python/ifcopenshell/entity_instance.py @@ -103,7 +103,7 @@ class entity_instance_mixin: idx = self.get_argument_index(name) return self.get_argument(idx) elif attr_cat == INVERSE: - vs = self.get_inverse(name) + vs = self._get_inverse(name) if settings.unpack_non_aggregate_inverses: schema_name = self.is_a(True).split(".")[0] ent: ifcopenshell_wrapper.entity diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py b/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py index 90a4d97d11..51350b1ac2 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py +++ b/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py @@ -17,12 +17,22 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit from ifcopenshell.api.alignment._add_segment_to_layout import _add_segment_to_layout +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_add_segment_to_layout(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -71,6 +81,3 @@ def test_add_segment_to_layout(): assert len(segment_nest.RelatedObjects) == 2 referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, alignment) assert len(referent_nest.RelatedObjects) == 3 - - -test_add_segment_to_layout() diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py index 4dd113ebbc..87c056c4c4 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py @@ -17,12 +17,22 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit import ifcopenshell.util.element +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_add_stationing_to_alignment(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -47,6 +57,3 @@ def test_add_stationing_to_alignment(): assert ifcopenshell.util.element.get_pset(element=referent, name="Pset_Stationing") assert ifcopenshell.util.element.get_pset(element=referent, name="Pset_Stationing", prop="Station") == 2000.0 assert referent.ObjectPlacement != None - - -test_add_stationing_to_alignment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py index 5a09cd1890..74926b885a 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py @@ -17,11 +17,21 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_add_vertical_alignment(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -70,6 +80,3 @@ def test_add_vertical_alignment(): assert len(alignment.IsNestedBy) == 2 assert len(layout_nest.RelatedObjects) == 1 assert layout_nest.RelatedObjects[0].is_a("IfcAlignmentHorizontal") - - -test_add_vertical_alignment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_create.py b/src/ifcopenshell-python/test/api/alignment/test_create.py index f227bfd758..569daa4474 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create.py @@ -17,11 +17,21 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_create(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -81,6 +91,3 @@ def test_create(): curves = file.by_type("IfcSegmentedReferenceCurve") for curve in curves: assert ifcopenshell.api.alignment.has_zero_length_segment(curve) - - -test_create() diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py b/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py index ac763e6af1..925061ae75 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py @@ -18,12 +18,22 @@ import math +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.unit import ifcopenshell.util import ifcopenshell.util.unit +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_create_as_offset_curve(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="OCBD Test Alignment") @@ -135,6 +145,3 @@ def test_create_as_offset_curve(): curve = ifcopenshell.api.alignment.get_curve(offset_alignment) assert curve.is_a("IfcOffsetCurveByDistances") assert curve.BasisCurve == basis_curve - - -test_create_as_offset_curve() diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py b/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py index 6e4eee9527..24bfaf2a0f 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py @@ -17,10 +17,20 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_create_as_polyline(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -44,6 +54,3 @@ def test_create_as_polyline(): curve = ifcopenshell.api.alignment.get_curve(alignment) assert curve.is_a("IfcPolyline") assert len(curve.Points) == 10 - - -test_create_as_polyline() diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py index 6da7af0690..28de8e9dab 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py @@ -17,11 +17,21 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_create_by_pi_method(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -61,6 +71,3 @@ def test_create_by_pi_method(): vertical_layout = ifcopenshell.api.alignment.get_vertical_layout(alignment) vertical_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vertical_layout) assert len(vertical_segment_nest.RelatedObjects) == 10 - - -test_create_by_pi_method() diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py b/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py index e1b0978e1a..1897e3ce71 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py @@ -18,11 +18,20 @@ import math +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + def _test_horizontal() -> ifcopenshell.file: file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -268,10 +277,8 @@ def _test_horizontal_vertical2(file: ifcopenshell.file): assert len(curve.Segments) == 3 +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_append_segment(): file = _test_horizontal() _test_horizontal_vertical() _test_horizontal_vertical2(file) - - -test_append_segment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py b/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py index 20d5f946e8..a491ef8661 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py @@ -17,10 +17,20 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_create_no_geometry(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -62,6 +72,3 @@ def test_create_no_geometry(): ) end = ifcopenshell.api.alignment.create_layout_segment(file, vertical_alignment, design_parameters) assert end == None - - -test_create_no_geometry() diff --git a/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py b/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py index a5af19ebe3..faeb90b342 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py +++ b/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py @@ -23,6 +23,14 @@ import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_distance_along_from_station(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -51,6 +59,3 @@ def test_distance_along_from_station(): # Station 175+25.36 assert ifcopenshell.api.alignment.distance_along_from_station(file, alignment, 17525.36) == pytest.approx(7525.36) - - -test_distance_along_from_station() diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py index 9c7a8718e2..8b0397249e 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py @@ -17,11 +17,21 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_get_alignment(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py b/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py index 0743fa6fd7..e228e47089 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py +++ b/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py @@ -17,11 +17,20 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + def _test_horizontal(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -79,6 +88,7 @@ def _test_horizontal_and_vertical_and_cant(): assert basis_curve.is_a("IfcCompositeCurve") +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_get_basis_curve(): _test_horizontal() _test_horizontal_and_vertical() diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_curve.py b/src/ifcopenshell-python/test/api/alignment/test_get_curve.py index 0229317c3f..5a2f5295d4 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_get_curve.py +++ b/src/ifcopenshell-python/test/api/alignment/test_get_curve.py @@ -16,11 +16,21 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_get_curve(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_layout_curve.py b/src/ifcopenshell-python/test/api/alignment/test_get_layout_curve.py index 1e5326070d..107729052f 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_get_layout_curve.py +++ b/src/ifcopenshell-python/test/api/alignment/test_get_layout_curve.py @@ -16,11 +16,21 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_get_layout_curve(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") diff --git a/src/ifcopenshell-python/test/api/alignment/test_has_zero_length_segment.py b/src/ifcopenshell-python/test/api/alignment/test_has_zero_length_segment.py index 9ce42a817e..56bf630ef7 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_has_zero_length_segment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_has_zero_length_segment.py @@ -16,11 +16,20 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + def _test_horizontal(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -84,10 +93,8 @@ def _test_horizontal_vertical_cant(): assert True == ifcopenshell.api.alignment.has_zero_length_segment(cant) +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_has_zero_length_segment(): _test_horizontal() _test_horizontal_vertical() _test_horizontal_vertical_cant() - - -test_has_zero_length_segment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py index 0864d5a67f..26a70825e1 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py +++ b/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py @@ -17,14 +17,24 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + # other test cases cover the typical vertical by PI method (test_create_alignment_by_pi_method) # this test will focus on the edge cases of no initial tangent run, no final tangent run, and # compound curve (no tangent between curves) +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_horizontal_layout_by_pi_method(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -52,6 +62,3 @@ def test_horizontal_layout_by_pi_method(): assert layout_nest.RelatedObjects[0].is_a("IfcAlignmentHorizontal") segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout_nest.RelatedObjects[0]) assert len(segment_nest.RelatedObjects) == 3 # segments in horizontal layout - - -test_horizontal_layout_by_pi_method() diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py index c3ec6c3831..114e3b97f7 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py @@ -23,6 +23,11 @@ from ifcopenshell.api.alignment._map_alignment_cant_segment import ( _map_alignment_cant_segment, ) +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False def _BlossCurve_100_0_300_1000_1_Meter(file): design_parameters = file.createIfcAlignmentCantSegment( @@ -1896,6 +1901,7 @@ def _VienneseBend_100_0__inf__300_1_Meter(file): assert mapped_segment.ParentCurve.ConstantTerm == pytest.approx(None) +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_map_alignment_cant_segment(): file = ifcopenshell.file(schema="IFC4X3") _BlossCurve_100_0_300_1000_1_Meter(file) @@ -1954,6 +1960,3 @@ def test_map_alignment_cant_segment(): _VienneseBend_100_0__1000__300_1_Meter(file) _VienneseBend_100_0_inf_300_1_Meter(file) _VienneseBend_100_0__inf__300_1_Meter(file) - - -test_map_alignment_cant_segment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py index 191f56a279..1321c352f9 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py @@ -27,6 +27,11 @@ from ifcopenshell.api.alignment._map_alignment_horizontal_segment import ( _map_alignment_horizontal_segment, ) +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False def _BlossCurve_100_0_300_1000_1_Meter(file): design_parameters = file.createIfcAlignmentHorizontalSegment( @@ -2558,6 +2563,7 @@ def _VienneseBend_100_0__inf__300_1_Meter(file): assert mapped_segment.ParentCurve.ConstantTerm == pytest.approx(None) +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_map_alignment_horizontal_segment(): file = ifcopenshell.file(schema="IFC4X3") _BlossCurve_100_0_300_1000_1_Meter(file) @@ -2632,6 +2638,3 @@ def test_map_alignment_horizontal_segment(): _VienneseBend_100_0__1000__300_1_Meter(file) _VienneseBend_100_0_inf_300_1_Meter(file) _VienneseBend_100_0__inf__300_1_Meter(file) - - -test_map_alignment_horizontal_segment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py index fc88aed036..8f334535d1 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py @@ -26,6 +26,11 @@ from ifcopenshell.api.alignment._map_alignment_vertical_segment import ( _map_alignment_vertical_segment, ) +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False def _CircularArc_100_0_10_0_0_0_0_5_1_Meter(file): design_parameters = file.createIfcAlignmentVerticalSegment( @@ -769,6 +774,7 @@ def _ParabolicArc_100_0_10_0__1_0__0_5_1_Meter(file): assert mapped_segment.ParentCurve.CoefficientsY == pytest.approx((10.0, -1.0, 0.0025)) +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_map_alignment_vertical_segment(): file = ifcopenshell.file(schema="IFC4X3") _CircularArc_100_0_10_0_0_0_0_5_1_Meter(file) @@ -797,6 +803,3 @@ def test_map_alignment_vertical_segment(): _ParabolicArc_100_0_10_0__1_0__0_5_1_Meter(file) # VERTICAL CLOTHOID NOT IMPLEMENTED - - -test_map_alignment_vertical_segment() diff --git a/src/ifcopenshell-python/test/api/alignment/test_name_segments.py b/src/ifcopenshell-python/test/api/alignment/test_name_segments.py index 2c9b8fa2ef..fc0afd13a5 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_name_segments.py +++ b/src/ifcopenshell-python/test/api/alignment/test_name_segments.py @@ -17,11 +17,21 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_name_segments(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -54,6 +64,3 @@ def test_name_segments(): for segment in segment_nest.RelatedObjects: assert f"Q{i}" == segment.Name i += 1 - - -test_name_segments() diff --git a/src/ifcopenshell-python/test/api/alignment/test_referent_names.py b/src/ifcopenshell-python/test/api/alignment/test_referent_names.py index d64ea9a3ec..6b83f1f767 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_referent_names.py +++ b/src/ifcopenshell-python/test/api/alignment/test_referent_names.py @@ -23,6 +23,13 @@ import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + @pytest.fixture(scope="module") def default_names_alignment(): file = ifcopenshell.file(schema="IFC4X3") @@ -96,6 +103,7 @@ def callback_alignment(): yield alignment +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_with_default_names(default_names_alignment): referent_nest = ifcopenshell.api.alignment.get_referent_nest(None, default_names_alignment) @@ -104,6 +112,7 @@ def test_with_default_names(default_names_alignment): assert [x in r.Name for x in expected] +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_with_callbacks(callback_alignment): referent_nest = ifcopenshell.api.alignment.get_referent_nest(None, callback_alignment) diff --git a/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py b/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py index 6fc87861db..71cb55c0c4 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py +++ b/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py @@ -17,12 +17,19 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.context import ifcopenshell.api.unit from ifcopenshell.api.alignment._update_curve_segment_transition_code import ( _update_curve_segment_transition_code, ) +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False def _test1(): file = ifcopenshell.file(schema="IFC4X3") @@ -243,9 +250,7 @@ def _test2(): assert clothoid2.Transition == "CONTSAMEGRADIENTSAMECURVATURE" +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_update_curve_segment_transition_code(): _test1() _test2() - - -test_update_curve_segment_transition_code() diff --git a/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py b/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py index a53c162ea9..429c733899 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py +++ b/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py @@ -23,6 +23,14 @@ import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_update_fallback_position(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -67,6 +75,3 @@ def test_update_fallback_position(): (0.22453152656315067, 0.9744668252840736, 0.0) ) assert lp.CartesianPosition.Axis.DirectionRatios == pytest.approx((0.0, 0.0, 1.0)) - - -test_update_fallback_position() diff --git a/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py index bd97d644de..2494bf0e3f 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py +++ b/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py @@ -17,14 +17,24 @@ # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell.api.alignment import ifcopenshell.api.context import ifcopenshell.api.unit +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + # other test cases cover the typical vertical by PI method (test_create_alignment_by_pi_method) # this test will focus on the edge cases of no initial gradient, no final gradient, and # compound vertical curve (no gradient between curves) +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_vertical_layout_by_pi_method(): file = ifcopenshell.file(schema="IFC4X3") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -69,6 +79,3 @@ def test_vertical_layout_by_pi_method(): segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vlayout) assert len(segment_nest.RelatedObjects) == 3 - - -test_vertical_layout_by_pi_method() diff --git a/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py index 143cb32c65..2b4e58f3d6 100644 --- a/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py +++ b/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py @@ -23,6 +23,14 @@ import ifcopenshell.api.cogo import ifcopenshell.api.context +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_add_survey_point(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(Name="Test") diff --git a/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py index 23a61c7655..f998a77afb 100644 --- a/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py +++ b/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py @@ -23,6 +23,14 @@ import ifcopenshell.api.cogo import ifcopenshell.api.context +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_assign_survey_point(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(Name="Test") diff --git a/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py b/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py index 199aa8a4e8..1ea8995440 100644 --- a/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py +++ b/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py @@ -69,6 +69,3 @@ def test_bearing2dd(): with pytest.raises(ValueError, match="Invalid bearing string"): ifcopenshell.api.cogo.bearing2dd("N 45 15 99.5 E") - - -test_bearing2dd() diff --git a/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py index cce8837475..458118a82b 100644 --- a/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py +++ b/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py @@ -23,6 +23,14 @@ import ifcopenshell.api.cogo import ifcopenshell.api.context +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_edit_survey_point(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(Name="Test") diff --git a/src/ifcopenshell-python/test/test_file.py b/src/ifcopenshell-python/test/test_file.py index 713b120d16..393dec05e9 100644 --- a/src/ifcopenshell-python/test/test_file.py +++ b/src/ifcopenshell-python/test/test_file.py @@ -22,6 +22,12 @@ import ifcopenshell import test.bootstrap +try: + ifcopenshell.file(schema="IFC4X3") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + class TestTransaction(test.bootstrap.IFC4): def test_that_nothing_happens_without_a_transaction(self): wall = self.file.createIfcWall() @@ -158,12 +164,14 @@ class TestFile(test.bootstrap.IFC4): assert f.schema_identifier == "IFC4" assert f.schema_version == (4, 0, 0, 0) + @pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_creating_an_ifc4x3_file(self): f = ifcopenshell.file(schema="IFC4X3") assert f.schema == "IFC4X3" assert f.schema_identifier == "IFC4X3_ADD2" assert f.schema_version == (4, 3, 2, 0) + @pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_creating_a_specific_version(self): f = ifcopenshell.file(schema_version=(4, 3, 2, 0)) assert f.schema == "IFC4X3" @@ -288,6 +296,7 @@ class TestFile(test.bootstrap.IFC4): g.assign_header_from(f) assert g.header.file_name.name == "test" +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_schema_identifier(): f = ifcopenshell.file(schema='IFC4X3') assert f.schema_identifier == 'IFC4X3_ADD2' diff --git a/src/ifcopenshell-python/test/util/test_alignment.py b/src/ifcopenshell-python/test/util/test_alignment.py index 91c6ba707f..af401128db 100644 --- a/src/ifcopenshell-python/test/util/test_alignment.py +++ b/src/ifcopenshell-python/test/util/test_alignment.py @@ -16,11 +16,20 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . +import pytest + import ifcopenshell import ifcopenshell.api.unit import ifcopenshell.util.alignment as sta +try: + ifcopenshell.file(schema="IFC4X3_ADD2") + IFC4X3_AVAILABLE = True +except RuntimeError: + IFC4X3_AVAILABLE = False + + def _test_si_stations(): file = ifcopenshell.file(schema="IFC4X3_ADD2") project = file.createIfcProject(GlobalId=ifcopenshell.guid.new(), Name="Test") @@ -77,10 +86,8 @@ def _test_us_stations(): assert s == "-1234+56.79" +@pytest.mark.skipif(not IFC4X3_AVAILABLE, reason="IFC4X3 not available") def test_station_as_string(): _test_si_stations() _test_si_stations_millimeter() _test_us_stations() - - -test_station_as_string() diff --git a/src/ifcparse/file.h b/src/ifcparse/file.h index f4a900b5f8..9be7803a6f 100644 --- a/src/ifcparse/file.h +++ b/src/ifcparse/file.h @@ -358,7 +358,7 @@ public: /// Get the attribute indices corresponding to the list of entity instances /// returned by get_inverse(). - std::vector get_inverse_indices(int instance_id); + std::vector get_inverse_indices_by_id(int instance_id); template typename T::list::ptr get_inverse(int instance_id, int attribute_index) { diff --git a/src/ifcparse/parse.cpp b/src/ifcparse/parse.cpp index 14ebb1a1b4..a49932d8f5 100644 --- a/src/ifcparse/parse.cpp +++ b/src/ifcparse/parse.cpp @@ -2606,7 +2606,7 @@ const ifcopenshell::schema_definition* file::schema() const { return schema_; } -std::vector file::get_inverse_indices(int instance_id) { +std::vector file::get_inverse_indices_by_id(int instance_id) { std::vector return_value; // Mapping of instance id to attribute offset. diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index 36e911b56f..0f8ec22460 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -69,7 +69,6 @@ %rename("_by_type") instances_by_type; %rename("_by_type_excl_subtypes") instances_by_type_excl_subtypes; %rename("get_inverses_by_declaration") get_inverse; -%rename("get_total_inverses_by_id") get_total_inverses; %rename("entity_instance") express::Base; %rename("file") file; // _add() because mixin defined add which adds transaction logic @@ -216,7 +215,7 @@ private: int get_total_inverses(const express::Base& e) { if (auto e_ = e.as()) { - return $self->get_total_inverses(e_.id()); + return $self->get_inverse_indices_by_id(e_.id()).size(); } throw ifcopenshell::exception("Only entities with ids are supported for get_total_inverses. Provided entity: '" + e.declaration().name() + "'."); } @@ -549,7 +548,7 @@ private: } } - std::vector get_inverse(const std::string& a) { + std::vector _get_inverse(const std::string& a) { if ($self->declaration().as_entity()) { return cast_vector($self->as().get_inverse(a)); } else { diff --git a/src/pyodide/demo-app/index.html b/src/pyodide/demo-app/index.html index 98bc440b73..d13e8c6697 100644 --- a/src/pyodide/demo-app/index.html +++ b/src/pyodide/demo-app/index.html @@ -77,7 +77,7 @@ const micropip = pyodide.pyimport("micropip"); await micropip.install("typing-extensions"); document.querySelector("#status2").innerHTML = "Loading IfcOpenShell"; - await micropip.install("wheels/ifcopenshell-0.8.6-cp313-cp313-pyodide_2025_0_wasm32.whl"); + await micropip.install("wheels/ifcopenshell-0.8.3+34a1bc6-cp313-cp313-emscripten_4_0_9_wasm32.whl"); document.body.className = '';