diff --git a/src/blenderbim/blenderbim/bim/module/classification/operator.py b/src/blenderbim/blenderbim/bim/module/classification/operator.py
index 08020cef76..fa35886176 100644
--- a/src/blenderbim/blenderbim/bim/module/classification/operator.py
+++ b/src/blenderbim/blenderbim/bim/module/classification/operator.py
@@ -88,7 +88,7 @@ class AddManualClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
reference = ifcopenshell.api.run(
"classification.add_reference",
tool.Ifc.get(),
- product=product,
+ products=[product],
classification=classification,
identification="X",
name="Unnamed",
@@ -358,15 +358,18 @@ class AddClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
classification = element
break
- for obj in objects:
- ifc_definition_id = tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context)
- if not ifc_definition_id:
- continue
+ ifc_file = tool.Ifc.get()
+ products = [
+ ifc_file.by_id(ifc_definition_id)
+ for obj in objects
+ if (ifc_definition_id := tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context))
+ ]
+ if products:
ifcopenshell.api.run(
"classification.add_reference",
tool.Ifc.get(),
reference=IfcStore.classification_file.by_id(self.reference),
- product=tool.Ifc.get().by_id(ifc_definition_id),
+ products=products,
classification=classification,
)
@@ -414,7 +417,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
reference = ifcopenshell.api.run(
"classification.add_reference",
tool.Ifc.get(),
- product=element,
+ products=[element],
classification=classification,
identification=bsdd_classification.reference_code,
name=bsdd_classification.name,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/__init__.py
index 8f7b82351c..7c739cf71b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/__init__.py
@@ -87,6 +87,9 @@ ARGUMENTS_DEPRECATION = {
"material.unassign_material": partial(
batching_argument_deprecation, prev_argument="product", new_argument="products"
),
+ "classification.add_reference": partial(
+ batching_argument_deprecation, prev_argument="product", new_argument="products"
+ ),
}
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py b/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py
index 320825e335..9057f7a25f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py
@@ -17,12 +17,24 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
+import ifcopenshell.api
+import ifcopenshell.util.element
import ifcopenshell.util.schema
+from typing import Optional, Union
class Usecase:
- def __init__(self, file, product=None, reference=None, identification=None, name=None, classification=None, is_lightweight=True):
- """Adds a new classification reference and assigns it to a product
+ def __init__(
+ self,
+ file: ifcopenshell.file,
+ products: list[ifcopenshell.entity_instance],
+ reference: Optional[ifcopenshell.entity_instance] = None,
+ identification: Optional[str] = None,
+ name: Optional[str] = None,
+ classification: Optional[ifcopenshell.entity_instance] = None,
+ is_lightweight=True,
+ ):
+ """Adds a new classification reference and assigns it to the list of products
A classification reference is a single entry such as "Pr_12_23_34" that
is part of an external classification system (such as Uniclass or
@@ -33,7 +45,7 @@ class Usecase:
resources such as profiles, documents, libraries, and so on.
Classification references can be added in two ways. Option 1) specify a
- custom arbitrary reference, where you have the manually specify the
+ custom arbitrary reference, where you have to manually specify the
identification (e.g. "Pr_12_23_45") and name (e.g. "Door Products").
Option 2) add a reference from an IFC classification library. The latter
is preferred if you are using a common classification system such as
@@ -52,13 +64,13 @@ class Usecase:
assigned to both the type and an occurrence, then the assignment at the
occurrence will override the type classification.
- :param product: The IFC object, property, or resource you want to
+ :param product: The list of IFC objects, properties, or resources you want to
associate the classification reference to.
- :type product: ifcopenshell.entity_instance.entity_instance
+ :type product: list[ifcopenshell.entity_instance.entity_instance]
:param reference: The classification reference entity taken from an
IFC classification library. If you supply this parameter, you will
use option 2.
- :type product: ifcopenshell.entity_instance.entity_instance, optional
+ :type reference: ifcopenshell.entity_instance.entity_instance, optional
:param identification: If you choose option 1 and do not specify a
reference, you may manually specify an identification code. The code
is typically a short identifier and may have punctuation to separate
@@ -70,7 +82,7 @@ class Usecase:
:param classification: The IfcClassification entity in your IFC model
(not the library, if you are doing option 2) that the reference is
part of.
- :type product: ifcopenshell.entity_instance.entity_instance
+ :type classification: ifcopenshell.entity_instance.entity_instance
:param is_lightweight: If you are doing option 2, choose whether or not
to only add that particular reference (lighweight) or also add all
of its parent references in the classification hierarchy (not
@@ -81,8 +93,12 @@ class Usecase:
is generally unnecessary. Using lightweight classifications are
recommended and is the default.
:type is_lightweight: bool, optional
+
+ :raises TypeError: If file is IFC2X3 and `products` has non-IfcRoot elements.
+
:return: The newly added IfcClassificationReference
- :rtype: ifcopenshell.entity_instance.entity_instance
+ or `None` if `products` was empty list.
+ :rtype: Union[ifcopenshell.entity_instance.entity_instance, None]
Example:
@@ -93,7 +109,7 @@ class Usecase:
classification = ifcopenshell.api.run("classification.add_classification",
model, classification="MyCustomClassification")
ifcopenshell.api.run("classification.add_reference", model,
- product=wall_type, classification=classification,
+ products=[wall_type], classification=classification,
identification="W_01", name="Interior Walls")
# Option 2: adding a popular classification from a library
@@ -104,12 +120,12 @@ class Usecase:
reference = [r for r in library.by_type("IfcClassificationReference")
if r.Identification == "XYZ"][0]
ifcopenshell.api.run("classification.add_reference", model,
- product=wall_type, classification=classification,
+ products=[wall_type], classification=classification,
reference=reference)
"""
self.file = file
self.settings = {
- "product": product,
+ "products": products,
"reference": reference,
"identification": identification,
"name": name,
@@ -117,8 +133,27 @@ class Usecase:
"is_lightweight": is_lightweight,
}
- def execute(self):
- self.is_rooted = self.settings["product"].is_a("IfcRoot")
+ def execute(self) -> Union[ifcopenshell.entity_instance, None]:
+ if not self.settings["products"]:
+ return
+
+ if self.settings["reference"]:
+ referenced = ifcopenshell.util.element.get_referenced_elements(self.settings["reference"])
+ if set(self.settings["products"]).issubset(referenced):
+ # nothing to do, all elements already have this reference assigned
+ return self.settings["reference"]
+
+ self.rooted_products: set[ifcopenshell.entity_instance] = set()
+ self.non_rooted_products: set[ifcopenshell.entity_instance] = set()
+ for product in self.settings["products"]:
+ if product.is_a("IfcRoot"):
+ self.rooted_products.add(product)
+ else:
+ self.non_rooted_products.add(product)
+
+ if self.non_rooted_products and self.file.schema == "IFC2X3":
+ raise TypeError(f"Cannot add reference to non-IfcRoot element in IFC2X3: {self.non_rooted_products}.")
+
if self.settings["reference"]:
return self.add_from_library()
return self.add_from_identification()
@@ -134,14 +169,10 @@ class Usecase:
else:
reference.Identification = self.settings["identification"]
- relationship = self.get_existing_relationship(reference)
- if relationship:
- self.add_to_existing_relationship(relationship)
- else:
- self.add_new_relationship(reference)
+ self.update_relationships(reference)
return reference
- def add_from_library(self):
+ def add_from_library(self) -> ifcopenshell.entity_instance:
if hasattr(self.settings["reference"], "ItemReference"):
identification = self.settings["reference"].ItemReference # IFC2X3
else:
@@ -155,8 +186,9 @@ class Usecase:
old_referenced_source = self.settings["reference"].ReferencedSource
self.settings["reference"].ReferencedSource = None
else:
+ classification_name = self.settings["classification"].Name
existing_classification = [
- c for c in self.file.by_type("IfcClassification") if c.Name == self.settings["classification"].Name
+ c for c in self.file.by_type("IfcClassification") if c.Name == classification_name
]
reference = migrator.migrate(self.settings["reference"], self.file)
@@ -174,15 +206,10 @@ class Usecase:
for element in to_delete:
self.file.remove(element)
- relationship = self.get_existing_relationship(reference)
- if relationship:
- self.add_to_existing_relationship(relationship)
- else:
- self.add_new_relationship(reference)
-
+ self.update_relationships(reference)
return reference
- def get_existing_reference(self, identification):
+ def get_existing_reference(self, identification: Optional[str] = None) -> Union[ifcopenshell.entity_instance, None]:
for reference in self.file.by_type("IfcClassificationReference"):
if self.file.schema == "IFC2X3":
if reference.ItemReference == identification:
@@ -191,39 +218,39 @@ class Usecase:
if reference.Identification == identification:
return reference
- def add_new_relationship(self, reference):
- if self.is_rooted:
- self.file.create_entity(
- "IfcRelAssociatesClassification",
- GlobalId=ifcopenshell.guid.new(),
- RelatedObjects=[self.settings["product"]],
- RelatingClassification=reference,
- )
- else:
- self.file.create_entity(
- "IfcExternalReferenceRelationship",
- RelatingReference=reference,
- RelatedResourceObjects=[self.settings["product"]],
- )
-
- def add_to_existing_relationship(self, rel):
- if self.is_rooted:
- related_objects = set(rel.RelatedObjects)
- related_objects.add(self.settings["product"])
- rel.RelatedObjects = list(related_objects)
- else:
- related_objects = set(rel.RelatedResourceObjects)
- related_objects.add(self.settings["product"])
- rel.RelatedResourceObjects = list(related_objects)
-
- def get_existing_relationship(self, reference):
- if self.is_rooted:
+ def update_relationships(self, reference: ifcopenshell.entity_instance) -> None:
+ root_rel, non_root_rel = None, None
+ if self.rooted_products:
if self.file.schema == "IFC2X3":
for rel in self.file.by_type("IfcRelAssociatesClassification"):
if rel.RelatingClassification == reference:
- return rel
- elif reference.ClassificationRefForObjects:
- return reference.ClassificationRefForObjects[0]
- elif self.file.schema != "IFC2X3":
- if reference.ExternalReferenceForResources:
- return reference.ExternalReferenceForResources[0]
+ root_rel = rel
+ break
+ else:
+ root_rel = next(iter(reference.ClassificationRefForObjects), None)
+
+ if root_rel:
+ related_objects = set(root_rel.RelatedObjects) | self.rooted_products
+ root_rel.RelatedObjects = list(related_objects)
+ ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": root_rel})
+ else:
+ self.file.create_entity(
+ "IfcRelAssociatesClassification",
+ OwnerHistory=ifcopenshell.api.run("owner.create_owner_history", self.file),
+ GlobalId=ifcopenshell.guid.new(),
+ RelatedObjects=list(self.rooted_products),
+ RelatingClassification=reference,
+ )
+
+ if self.non_rooted_products:
+ # NOTE: Only Ifc4+. Ifc2x3 is already handled by raising TypeError
+ non_root_rel = next(iter(reference.ExternalReferenceForResources), None)
+ if non_root_rel:
+ related_objects = set(non_root_rel.RelatedResourceObjects) | self.non_rooted_products
+ non_root_rel.RelatedResourceObjects = list(related_objects)
+ else:
+ self.file.create_entity(
+ "IfcExternalReferenceRelationship",
+ RelatingReference=reference,
+ RelatedResourceObjects=list(self.non_rooted_products),
+ )
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py b/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py
index 48b55b3740..b91989a1ae 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py
@@ -44,7 +44,7 @@ class Usecase:
classification = ifcopenshell.api.run("classification.add_classification",
model, classification="MyCustomClassification")
reference = ifcopenshell.api.run("classification.add_reference", model,
- product=wall_type, classification=classification,
+ products=[wall_type], classification=classification,
identification="W_01", name="Interior Walls")
ifcopenshell.api.run("classification.remove_reference", model,
reference=reference, product=wall_type)
diff --git a/src/ifcopenshell-python/test/api/classification/test_add_reference.py b/src/ifcopenshell-python/test/api/classification/test_add_reference.py
index 7cf5722b8f..ed52b05d35 100644
--- a/src/ifcopenshell-python/test/api/classification/test_add_reference.py
+++ b/src/ifcopenshell-python/test/api/classification/test_add_reference.py
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import pytest
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.classification
@@ -23,85 +24,127 @@ import ifcopenshell.util.classification
class TestAddReference(test.bootstrap.IFC4):
def test_adding_a_reference(self):
+ is_ifc2x3 = self.file.schema == "IFC2X3"
+
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
+ element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element, element2],
identification="X",
name="Foobar",
classification=result,
)
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
- assert references[0].Identification == "X"
+ assert getattr(references[0], "ItemReference" if is_ifc2x3 else "Identification") == "X"
assert references[0].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
- element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
- ifcopenshell.api.run(
- "classification.add_reference",
- self.file,
- product=element2,
- identification="X",
- name="Foobar",
- classification=result,
+ references2 = list(ifcopenshell.util.classification.get_references(element))
+ assert len(references2) == 1
+ assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "X"
+ assert references2[0].Name == "Foobar"
+ assert references2[0] == references[0]
+
+ rel = next(
+ rel
+ for rel in self.file.by_type("IfcRelAssociatesClassification")
+ if rel.RelatingClassification == references[0]
)
- assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X"
- assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
- assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
+ assert len(rel.RelatedObjects) == 2
def test_adding_a_library_based_reference(self):
+ is_ifc2x3 = self.file.schema == "IFC2X3"
+
library = ifcopenshell.file()
classification = library.createIfcClassification(Name="Name")
reference = library.createIfcClassificationReference(Identification="1", ReferencedSource=classification)
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
+ element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification=classification)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element, element2],
reference=reference,
classification=result,
)
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
- assert references[0].Identification == "1"
+ assert getattr(references[0], "ItemReference" if is_ifc2x3 else "Identification") == "1"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
- def test_adding_a_reference_to_a_resource(self):
+ references2 = list(ifcopenshell.util.classification.get_references(element2))
+ assert len(references2) == 1
+ assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "1"
+ assert references2[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
+ assert references[0] == references2[0]
+
+ rel = next(
+ rel
+ for rel in self.file.by_type("IfcRelAssociatesClassification")
+ if rel.RelatingClassification == references[0]
+ )
+ assert len(rel.RelatedObjects) == 2
+
+ def test_adding_a_reference_to_a_resource_and_to_a_root(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = self.file.createIfcMaterial()
+ element2 = self.file.createIfcCostValue()
+ element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
- ifcopenshell.api.run(
- "classification.add_reference",
- self.file,
- product=element,
- identification="X",
- name="Foobar",
- classification=result,
- )
+
+ if self.file.schema == "IFC2X3":
+ with pytest.raises(TypeError):
+ ifcopenshell.api.run(
+ "classification.add_reference",
+ self.file,
+ products=[element, element2, element3],
+ identification="X",
+ name="Foobar",
+ classification=result,
+ )
+ return
+ else:
+ ifcopenshell.api.run(
+ "classification.add_reference",
+ self.file,
+ products=[element, element2, element3],
+ identification="X",
+ name="Foobar",
+ classification=result,
+ )
+
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
assert references[0].Identification == "X"
assert references[0].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
- element2 = self.file.createIfcCostValue()
- ifcopenshell.api.run(
- "classification.add_reference",
- self.file,
- product=element2,
- identification="X",
- name="Foobar",
- classification=result,
- )
- assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X"
- assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
- assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
+ references2 = list(ifcopenshell.util.classification.get_references(element2))
+ assert references2[0].Identification == "X"
+ assert references2[0].Name == "Foobar"
+ assert references2[0] == references[0]
+
+ references3 = list(ifcopenshell.util.classification.get_references(element3))
+ assert references3[0].Identification == "X"
+ assert references3[0].Name == "Foobar"
+ assert references3[0] == references[0]
assert len(self.file.by_type("IfcExternalReferenceRelationship")[0].RelatedResourceObjects) == 2
+ rel = next(
+ rel
+ for rel in self.file.by_type("IfcRelAssociatesClassification")
+ if rel.RelatingClassification == references[0]
+ )
+ assert len(rel.RelatedObjects) == 1
+
+
+class TestAddReferenceIFC2X3(test.bootstrap.IFC2X3, TestAddReference):
+ pass
diff --git a/src/ifcopenshell-python/test/api/classification/test_remove_classification.py b/src/ifcopenshell-python/test/api/classification/test_remove_classification.py
index 3652d6e8c8..fb3537ddf2 100644
--- a/src/ifcopenshell-python/test/api/classification/test_remove_classification.py
+++ b/src/ifcopenshell-python/test/api/classification/test_remove_classification.py
@@ -34,7 +34,7 @@ class TestRemoveClassification(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -51,7 +51,7 @@ class TestRemoveClassification(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
diff --git a/src/ifcopenshell-python/test/api/classification/test_remove_reference.py b/src/ifcopenshell-python/test/api/classification/test_remove_reference.py
index 597317f3bb..63ae287aa3 100644
--- a/src/ifcopenshell-python/test/api/classification/test_remove_reference.py
+++ b/src/ifcopenshell-python/test/api/classification/test_remove_reference.py
@@ -29,7 +29,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -45,7 +45,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -62,7 +62,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -70,7 +70,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference2 = ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element2,
+ products=[element2],
identification="X",
name="Foobar",
classification=result,
diff --git a/src/ifcopenshell-python/test/api/test_api.py b/src/ifcopenshell-python/test/api/test_api.py
index 779d1238f2..7910cf9739 100644
--- a/src/ifcopenshell-python/test/api/test_api.py
+++ b/src/ifcopenshell-python/test/api/test_api.py
@@ -18,6 +18,7 @@
import test.bootstrap
import ifcopenshell.api
+import ifcopenshell.util.classification
import ifcopenshell.util.element
import ifcopenshell.util.system
from datetime import datetime
@@ -186,3 +187,35 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
assert len(self.file.by_type("IfcRelAssociatesMaterial")) == 0
assert len(self.file.by_type("IfcWall")) == 1
assert len(self.file.by_type("IfcMaterial")) == 1
+
+ @deprecation_check
+ def test_adding_a_reference(self):
+ ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
+ element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
+ result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
+ ifcopenshell.api.run(
+ "classification.add_reference",
+ self.file,
+ product=element,
+ identification="X",
+ name="Foobar",
+ classification=result,
+ )
+ references = list(ifcopenshell.util.classification.get_references(element))
+ assert len(references) == 1
+ assert references[0].Identification == "X"
+ assert references[0].Name == "Foobar"
+ assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
+
+ element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
+ ifcopenshell.api.run(
+ "classification.add_reference",
+ self.file,
+ product=element2,
+ identification="X",
+ name="Foobar",
+ classification=result,
+ )
+ assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X"
+ assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
+ assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
diff --git a/src/ifcopenshell-python/test/util/test_classification.py b/src/ifcopenshell-python/test/util/test_classification.py
index d394f8056b..7fe054e1e3 100644
--- a/src/ifcopenshell-python/test/util/test_classification.py
+++ b/src/ifcopenshell-python/test/util/test_classification.py
@@ -34,14 +34,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
reference=reference1,
classification=classification,
)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
reference=reference2,
classification=classification,
)
@@ -54,7 +54,7 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -74,14 +74,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
reference=reference1,
classification=classification,
)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element_type,
+ products=[element_type],
reference=reference2,
classification=classification,
)
@@ -103,14 +103,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
reference=reference1,
classification=classification,
)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element_type,
+ products=[element_type],
reference=reference2,
classification=classification,
)
diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py
index d8ba4bb174..571511d39f 100644
--- a/src/ifcopenshell-python/test/util/test_selector.py
+++ b/src/ifcopenshell-python/test/util/test_selector.py
@@ -225,7 +225,7 @@ class TestFilterElements(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
- product=element,
+ products=[element],
identification="X",
name="Foobar",
classification=result,
diff --git a/src/ifctester/test/test_facet.py b/src/ifctester/test/test_facet.py
index bd89a00946..ddee91ab36 100644
--- a/src/ifctester/test/test_facet.py
+++ b/src/ifctester/test/test_facet.py
@@ -706,24 +706,24 @@ class TestClassification:
element0 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
element1 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab")
ifcopenshell.api.run(
- "classification.add_reference", ifc, product=element1, reference=ref1, classification=system_a
+ "classification.add_reference", ifc, products=[element1], reference=ref1, classification=system_a
)
element11 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcColumn")
ifcopenshell.api.run(
- "classification.add_reference", ifc, product=element11, reference=ref11, classification=system_a
+ "classification.add_reference", ifc, products=[element11], reference=ref11, classification=system_a
)
element22 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam")
ifcopenshell.api.run(
"classification.add_reference",
ifc,
- product=element22,
+ products=[element22],
reference=ref22,
classification=system_a,
is_lightweight=False,
)
material = ifc.createIfcMaterial(Name="Material")
ifcopenshell.api.run(
- "classification.add_reference", ifc, product=material, reference=ref1, classification=system_a
+ "classification.add_reference", ifc, products=[material], reference=ref1, classification=system_a
)
facet = Classification(system="Foobar")
@@ -810,15 +810,15 @@ class TestClassification:
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
ifcopenshell.api.run(
- "classification.add_reference", ifc, product=wall, reference=ref11, classification=system_a
+ "classification.add_reference", ifc, products=[wall], reference=ref11, classification=system_a
)
ifcopenshell.api.run(
- "classification.add_reference", ifc, product=wall_type, reference=ref22, classification=system_a
+ "classification.add_reference", ifc, products=[wall_type], reference=ref22, classification=system_a
)
system_b = ifcopenshell.api.run("classification.add_classification", ifc, classification=system_b)
ifcopenshell.api.run(
- "classification.add_reference", ifc, product=wall_type, reference=refx, classification=system_b
+ "classification.add_reference", ifc, products=[wall_type], reference=refx, classification=system_b
)
facet = Classification(system="Foobar", value="11")