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 = '';