diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index ad207685e1..d23552506f 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -1050,7 +1050,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): if self.group_name in product_groups_name: return - linked_aggregate_group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), Name=self.group_name) + linked_aggregate_group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), name=self.group_name) ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=[element], group=linked_aggregate_group) def custom_incremental_naming_for_element_assembly(old_to_new): diff --git a/src/blenderbim/blenderbim/bim/module/search/operator.py b/src/blenderbim/blenderbim/bim/module/search/operator.py index 9865e7cd28..c2bc7dba21 100644 --- a/src/blenderbim/blenderbim/bim/module/search/operator.py +++ b/src/blenderbim/blenderbim/bim/module/search/operator.py @@ -215,7 +215,7 @@ class SaveSearch(Operator, tool.Ifc.Operator): group = group[0] group.Description = description else: - group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), Name=self.name, Description=description) + group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), name=self.name, description=description) if results: ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=list(results), group=group) @@ -368,7 +368,7 @@ class SaveColourscheme(Operator, tool.Ifc.Operator): description = json.dumps( {"type": "BBIM_Search", "colourscheme": colourscheme, "colourscheme_query": query} ) - group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), Name=self.name, Description=description) + group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), name=self.name, description=description) def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) diff --git a/src/blenderbim/blenderbim/tool/sequence.py b/src/blenderbim/blenderbim/tool/sequence.py index 17c08f3093..618a678f78 100644 --- a/src/blenderbim/blenderbim/tool/sequence.py +++ b/src/blenderbim/blenderbim/tool/sequence.py @@ -1630,7 +1630,7 @@ class Sequence(blenderbim.core.tool.Sequence): group.Description = json.dumps(description) else: description = json.dumps({"type": "BBIM_AnimationColorScheme", "colourscheme": colour_scheme}) - group = tool.Ifc.run("group.add_group", Name=name, Description=description) + group = tool.Ifc.run("group.add_group", name=name, description=description) return group[0] @classmethod diff --git a/src/ifcopenshell-python/ifcopenshell/api/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/__init__.py index b4311519fc..d3d0b2f475 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/api/__init__.py @@ -67,6 +67,20 @@ def batching_argument_deprecation( return (replace_usecase or usecase_path, settings) +def renamed_arguments_deprecation( + usecase_path: str, settings: dict, arguments_remapped: dict[str, str] +) -> tuple[str, dict]: + for prev_argument, new_argument in arguments_remapped.items(): + if prev_argument in settings: + print( + f"WARNING. `{prev_argument}` argument is deprecated for API method " + f'"{usecase_path}" and should be replaced with `{new_argument}`.' + ) + settings = settings | {new_argument: settings[prev_argument]} + settings.pop(prev_argument) + return (usecase_path, settings) + + ARGUMENTS_DEPRECATION = { "spatial.assign_container": partial( batching_argument_deprecation, prev_argument="product", new_argument="products" @@ -143,6 +157,10 @@ ARGUMENTS_DEPRECATION = { "project.unassign_declaration": partial( batching_argument_deprecation, prev_argument="definition", new_argument="definitions" ), + "group.add_group": partial( + renamed_arguments_deprecation, arguments_remapped={"Name": "name", "Description": "description"} + ), + "layer.add_layer": partial(renamed_arguments_deprecation, arguments_remapped={"Name": "name"}), } diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py index 44553bddcf..bce9ca61bd 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py @@ -23,7 +23,7 @@ from typing import Optional def add_group( - file: ifcopenshell.file, Name: str = "Unnamed", Description: Optional[str] = None + file: ifcopenshell.file, name: str = "Unnamed", description: Optional[str] = None ) -> ifcopenshell.entity_instance: """Adds a new group @@ -37,8 +37,8 @@ def add_group( :param Name: The name of the group. Defaults to "Unnamed" :type Name: str, optional - :param Description: The description of the purpose of the group. - :type Description: str, optional + :param description: The description of the purpose of the group. + :type description: str, optional :return: The newly created IfcGroup :rtype: ifcopenshell.entity_instance @@ -46,11 +46,11 @@ def add_group( .. code:: python - ifcopenshell.api.run("group.add_group", model, Name="Unit 1A") + ifcopenshell.api.run("group.add_group", model, name="Unit 1A") """ settings = { - "Name": Name or "Unnamed", - "Description": Description, + "name": name or "Unnamed", + "description": description, } return file.create_entity( @@ -58,7 +58,7 @@ def add_group( **{ "GlobalId": ifcopenshell.guid.new(), "OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", file), - "Name": settings["Name"], - "Description": settings["Description"], + "Name": settings["name"], + "Description": settings["description"], } ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py index a11b15c6de..0edceb9fa2 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py @@ -42,7 +42,7 @@ def assign_group( .. code:: python - group = ifcopenshell.api.run("group.add_group", model, Name="Furniture") + group = ifcopenshell.api.run("group.add_group", model, name="Furniture") ifcopenshell.api.run("group.assign_group", model, products=model.by_type("IfcFurniture"), group=group) """ diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py index 912b3c30c9..dca5f781f4 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py @@ -36,7 +36,7 @@ def edit_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance, att .. code:: python - group = ifcopenshell.api.run("group.add_group", model, Name="Unit 1A") + group = ifcopenshell.api.run("group.add_group", model, name="Unit 1A") ifcopenshell.api.run("group.edit_group", model, group=group, attributes={"Description": "All furniture and joinery included in the unit"}) """ diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/remove_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/remove_group.py index d17806d6c3..9097e1e229 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/remove_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/remove_group.py @@ -36,7 +36,7 @@ def remove_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance) - .. code:: python - group = ifcopenshell.api.run("group.add_group", model, Name="Unit 1A") + group = ifcopenshell.api.run("group.add_group", model, name="Unit 1A") ifcopenshell.api.run("group.remove_group", model, group=group) """ settings = {"group": group} diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py index c486cceab6..7d181455cc 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py @@ -39,7 +39,7 @@ def unassign_group( .. code:: python - group = ifcopenshell.api.run("group.add_group", model, Name="Furniture") + group = ifcopenshell.api.run("group.add_group", model, name="Furniture") furniture = model.by_type("IfcFurniture") ifcopenshell.api.run("group.assign_group", model, products=furniture, group=group) diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/update_group_products.py b/src/ifcopenshell-python/ifcopenshell/api/group/update_group_products.py index c68992f7a3..dda9ba954d 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/update_group_products.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/update_group_products.py @@ -40,7 +40,7 @@ def update_group_products( .. code:: python - group = ifcopenshell.api.run("group.add_group", model, Name="Furniture") + group = ifcopenshell.api.run("group.add_group", model, name="Furniture") ifcopenshell.api.run("group.update_group_products", model, products=model.by_type("IfcFurniture"), group=group) """ diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py index d3a6c162c8..d09675cabe 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py @@ -19,7 +19,7 @@ import ifcopenshell from typing import Optional -def add_layer(file: ifcopenshell.file, Name: Optional[str] = None) -> ifcopenshell.entity_instance: +def add_layer(file: ifcopenshell.file, name: str = "Unnamed") -> ifcopenshell.entity_instance: """Adds a new layer An IFC layer is like a CAD layer. Portions of an object's geometry @@ -34,13 +34,13 @@ def add_layer(file: ifcopenshell.file, Name: Optional[str] = None) -> ifcopenshe Some software that are still based on layers, such as Tekla or ArchiCAD may also use this layer information for filtering. - :param Name: The name of the layer. Defaults to "Unnamed". - :type Name: str, optional + :param name: The name of the layer. Defaults to "Unnamed". + :type name: str, optional :return: The newly created IfcPresentationLayerAssignment element :rtype: ifcopenshell.entity_instance Example: - ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL-FULL-DIMS-N") + ifcopenshell.api.run("layer.add_layer", model, name="AI-WALL-FULL-DIMS-N") """ - return file.create_entity("IfcPresentationLayerAssignment", Name=Name or "Unnamed") + return file.create_entity("IfcPresentationLayerAssignment", Name=name) diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py index 70926625c3..9c7cbd4c46 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py @@ -59,7 +59,7 @@ def assign_layer( ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall) # Now let's create a layer that contains walls - layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + layer = ifcopenshell.api.run("layer.add_layer", model, name="AI-WALL") # And assign our wall representation item (in this example, there is # only one item) to the layer. diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py index 1590cc4559..9ef941c82d 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py @@ -36,7 +36,7 @@ def edit_layer(file: ifcopenshell.file, layer: ifcopenshell.entity_instance, att .. code:: python - layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + layer = ifcopenshell.api.run("layer.add_layer", model, name="AI-WALL") ifcopenshell.api.run("layer.edit_layer", model, layer=layer, attributes={"Description": "All walls, based on the AIA standard."}) """ diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py index 27b3e80ac1..d576897fd6 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py @@ -33,7 +33,7 @@ def remove_layer(file: ifcopenshell.file, layer: ifcopenshell.entity_instance) - .. code:: python - layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + layer = ifcopenshell.api.run("layer.add_layer", model, name="AI-WALL") ifcopenshell.api.run("layer.remove_layer", model, layer=layer) """ file.remove(layer) diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py index 9418a28ad6..3fde793058 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py @@ -56,7 +56,7 @@ def unassign_layer( ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall) # Now let's create a layer that contains walls - layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + layer = ifcopenshell.api.run("layer.add_layer", model, name="AI-WALL") # And assign our wall representation item (in this example, there is # only one item) to the layer. diff --git a/src/ifcopenshell-python/test/api/group/test_add_group.py b/src/ifcopenshell-python/test/api/group/test_add_group.py new file mode 100644 index 0000000000..49e5379ade --- /dev/null +++ b/src/ifcopenshell-python/test/api/group/test_add_group.py @@ -0,0 +1,37 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2022 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import test.bootstrap +import ifcopenshell.api +import ifcopenshell.util.element + + +class TestAddGroup(test.bootstrap.IFC4): + def test_add_group_no_arguments(self): + group = ifcopenshell.api.run("group.add_group", self.file) + assert group.Name == "Unnamed" + assert group.Description == None + + def test_add_group(self): + group = ifcopenshell.api.run("group.add_group", self.file, name="Name", description="Description") + assert group.Name == "Name" + assert group.Description == "Description" + + +class TestAddGroupIFC2X3(test.bootstrap.IFC2X3, TestAddGroup): + pass diff --git a/src/ifcopenshell-python/test/api/layer/test_add_layer.py b/src/ifcopenshell-python/test/api/layer/test_add_layer.py new file mode 100644 index 0000000000..8889674075 --- /dev/null +++ b/src/ifcopenshell-python/test/api/layer/test_add_layer.py @@ -0,0 +1,34 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2022 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import test.bootstrap +import ifcopenshell.api + + +class TestAddLayer(test.bootstrap.IFC4): + def test_add_layer_no_arguments(self): + layer = ifcopenshell.api.run("layer.add_layer", self.file) + assert layer.Name == "Unnamed" + + def test_assign_additional_items(self): + layer = ifcopenshell.api.run("layer.add_layer", self.file, name="Name") + assert layer.Name == "Name" + + +class TestAddLayerIFC2X3(test.bootstrap.IFC2X3, TestAddLayer): + pass diff --git a/src/ifcopenshell-python/test/api/root/test_remove_product.py b/src/ifcopenshell-python/test/api/root/test_remove_product.py index ebfaa8a4d8..176d39be25 100644 --- a/src/ifcopenshell-python/test/api/root/test_remove_product.py +++ b/src/ifcopenshell-python/test/api/root/test_remove_product.py @@ -409,7 +409,7 @@ class TestRemoveProduct(test.bootstrap.IFC4): def test_removing_orphaned_group_relationships(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - group = ifcopenshell.api.run("group.add_group", self.file, Name="Unit 1A") + group = ifcopenshell.api.run("group.add_group", self.file, name="Unit 1A") ifcopenshell.api.run("group.assign_group", self.file, products=[element], group=group) ifcopenshell.api.run("root.remove_product", self.file, product=element) assert not self.file.by_type("IfcRelAssignsToGroup") diff --git a/src/ifcopenshell-python/test/api/test_api.py b/src/ifcopenshell-python/test/api/test_api.py index 00d33b8b8a..40e2135127 100644 --- a/src/ifcopenshell-python/test/api/test_api.py +++ b/src/ifcopenshell-python/test/api/test_api.py @@ -348,3 +348,14 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4): ) assert get_context(element_type) == None assert len(self.file.by_type("IfcRelDeclares")) == 0 + + @deprecation_check + def test_add_group(self): + group = ifcopenshell.api.run("group.add_group", self.file, Name="Name", Description="Description") + assert group.Name == "Name" + assert group.Description == "Description" + + @deprecation_check + def test_add_layer(self): + layer = ifcopenshell.api.run("layer.add_layer", self.file, Name="Name") + assert layer.Name == "Name"