Bonsai: refuse class-mismatched type assignment

Schema-illegal IfcDoor->IfcWallType pairings parse cleanly but propagate
into operators that fan out by type and eventually crash the wrapper.
Block the pairing at its source: API guard in ifcopenshell.api.type.
assign_type, per-object partition in BIM_OT_assign_type + DuplicateType,
new tool.Type.is_relating_type_compatible helper, AST forward-compat
guard. Files in the wild are still loaded unchanged.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Gorgious56
2026-06-24 08:47:57 +02:00
parent 59383f5010
commit 10ee5aef4f
9 changed files with 416 additions and 4 deletions
@@ -24,6 +24,7 @@ import ifcopenshell.api.owner
import ifcopenshell.api.type
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.type
def assign_type(
@@ -189,6 +190,20 @@ class Usecase:
if not related_objects:
return
# The EXPRESS schema has no WHERE rule pairing RelatingType /
# RelatedObjects classes; the canonical class pairing per schema
# is a buildingSMART implementer agreement, enforced here.
allowed_occurrences = ifcopenshell.util.type.get_applicable_entities(
relating_type.is_a(), schema=self.file.schema
)
mismatched_classes = sorted({o.is_a() for o in related_objects if o.is_a() not in allowed_occurrences})
if mismatched_classes:
raise TypeError(
f"{relating_type.is_a()} cannot type {', '.join(mismatched_classes)} "
f"in schema {self.file.schema} (allowed occurrence classes: "
f"{allowed_occurrences or '<none>'})"
)
ifc2x3 = self.file.schema == "IFC2X3"
related_objects_set = set(related_objects)
if ifc2x3: