diff --git a/src/bonsai/bonsai/bim/module/patch/operator.py b/src/bonsai/bonsai/bim/module/patch/operator.py index 31bc036ddb..888e1ed1bd 100644 --- a/src/bonsai/bonsai/bim/module/patch/operator.py +++ b/src/bonsai/bonsai/bim/module/patch/operator.py @@ -151,7 +151,7 @@ class UpdateIfcPatchArguments(bpy.types.Operator): new_attr.set_value(arg_info.get("default", new_attr.get_value_default())) return {"FINISHED"} - def pretty_arg_name(self, arg_name: str): + def pretty_arg_name(self, arg_name: str) -> str: words = [] for word in arg_name.split("_"): diff --git a/src/bonsai/bonsai/bim/module/resource/data.py b/src/bonsai/bonsai/bim/module/resource/data.py index 2d43974569..4c7f5f57f4 100644 --- a/src/bonsai/bonsai/bim/module/resource/data.py +++ b/src/bonsai/bonsai/bim/module/resource/data.py @@ -23,6 +23,7 @@ import ifcopenshell.util.constraint import ifcopenshell.util.cost import ifcopenshell.util.date import ifcopenshell.util.resource +from typing import Any def refresh(): @@ -44,11 +45,11 @@ class ResourceData: cls.is_loaded = True @classmethod - def total_resources(cls): + def total_resources(cls) -> int: return len(tool.Ifc.get().by_type("IfcResource")) @classmethod - def resources(cls): + def resources(cls) -> dict[int, dict[str, Any]]: results = {} for resource in tool.Ifc.get().by_type("IfcResource"): base_quantity = None @@ -63,7 +64,7 @@ class ResourceData: if resource.is_a() in ["IfcLaborResource", "IfcConstructionEquipmentResource"]: results[resource.id()]["Productivity"] = {} results[resource.id()]["InheritedProductivity"] = {} - productivity = cls.get_productivity(resource) + productivity = ifcopenshell.util.resource.get_productivity(resource, should_inherit=False) if productivity: results[resource.id()]["Productivity"] = { "id": productivity.get("id"), @@ -71,7 +72,7 @@ class ResourceData: "TimeConsumed": ifcopenshell.util.resource.get_unit_consumed(productivity), "QuantityProducedName": ifcopenshell.util.resource.get_quantity_produced_name(productivity), } - inherited_productivity = cls.get_parent_productivity(resource) + inherited_productivity = ifcopenshell.util.resource.get_parent_productivity(resource) if inherited_productivity: results[resource.id()]["InheritedProductivity"] = { "QuantityProduced": ifcopenshell.util.resource.get_quantity_produced(inherited_productivity), @@ -94,7 +95,7 @@ class ResourceData: return results @classmethod - def sum_person_hours(cls, resource): + def sum_person_hours(cls, resource: ifcopenshell.entity_instance) -> float: sum = 0 nested_resources = ifcopenshell.util.resource.get_nested_resources(resource) for nested_resource in nested_resources or []: @@ -105,7 +106,7 @@ class ResourceData: return round(float(sum), 2) if sum else 0 @classmethod - def get_resource_benchmarks(cls, resource): + def get_resource_benchmarks(cls, resource: ifcopenshell.entity_instance) -> list[dict[str, Any]]: constraints = [] for constraint in ifcopenshell.util.constraint.get_constraints(resource) or []: metrics = [] @@ -121,15 +122,7 @@ class ResourceData: return constraints @classmethod - def get_productivity(cls, resource): - return ifcopenshell.util.resource.get_productivity(resource, should_inherit=False) - - @classmethod - def get_parent_productivity(cls, resource): - return ifcopenshell.util.resource.get_parent_productivity(resource) - - @classmethod - def cost_values(cls): + def cost_values(cls) -> list[dict[str, Any]]: results = [] ifc_id = bpy.context.scene.BIMResourceProperties.active_resource_id if not ifc_id: diff --git a/src/bonsai/bonsai/bim/prop.py b/src/bonsai/bonsai/bim/prop.py index 6c4d6fd045..2bb35c3fce 100644 --- a/src/bonsai/bonsai/bim/prop.py +++ b/src/bonsai/bonsai/bim/prop.py @@ -176,14 +176,14 @@ class MultipleFileSelect(PropertyGroup): single_file: bpy.props.StringProperty(name="Single File Path", description="", update=update_single_file) file_list: bpy.props.CollectionProperty(type=StrProperty) - def set_file_list(self, dirname: str, files: list[str]): + def set_file_list(self, dirname: str, files: list[str]) -> None: self.file_list.clear() for f in files: new = self.file_list.add() new.name = os.path.join(dirname, f) - def layout_file_select(self, layout, filter_glob="", text=""): + def layout_file_select(self, layout: bpy.types.UILayout, filter_glob: str = "", text: str = "") -> None: if len(self.file_list) > 1: layout.label(text=f"{len(self.file_list)} Files Selected") else: diff --git a/src/ifcpatch/ifcpatch/__init__.py b/src/ifcpatch/ifcpatch/__init__.py index f6c1cfb347..7f3a318444 100644 --- a/src/ifcpatch/ifcpatch/__init__.py +++ b/src/ifcpatch/ifcpatch/__init__.py @@ -27,7 +27,7 @@ import inspect import collections import importlib import importlib.util -from typing import Union +from typing import Union, Iterable, Optional, Any __version__ = version = "0.0.0" @@ -114,7 +114,7 @@ def write(output: Union[ifcopenshell.file, str], filepath: str) -> None: def extract_docs( - submodule_name: str, cls_name: str, method_name: str = "__init__", boilerplate_args: typing.Iterable[str] = None + submodule_name: str, cls_name: str, method_name: str = "__init__", boilerplate_args: Optional[Iterable[str]] = None ): """Extract class docstrings and method arguments @@ -137,10 +137,10 @@ def extract_docs( print(f"Error : IFCPatch {str(submodule)} could not load because : {str(e)}") -def _extract_docs(cls, method_name, boilerplate_args): +def _extract_docs(cls: type, method_name: str, boilerplate_args: Union[Iterable[str], None]): inputs = collections.OrderedDict() method = getattr(cls, method_name) - docs = {"class": cls} + docs: dict[str, Any] = {"class": cls} if boilerplate_args is None: boilerplate_args = [] @@ -152,6 +152,7 @@ def _extract_docs(cls, method_name, boilerplate_args): if isinstance(parameter.default, (str, float, int, bool)): inputs[name]["default"] = parameter.default + # Parse data from type hints. type_hints = typing.get_type_hints(method) for input_name in inputs.keys(): type_hint = type_hints.get(input_name, None) @@ -172,6 +173,7 @@ def _extract_docs(cls, method_name, boilerplate_args): else: inputs[input_name]["type"] = type_hint.__name__ + # Parse the docstring. description = "" doc = method.__doc__ if doc is not None: @@ -185,6 +187,7 @@ def _extract_docs(cls, method_name, boilerplate_args): param_name = line.split(":")[1].strip().replace("param ", "") if param_name in inputs: inputs[param_name]["description"] = line.split(":")[2].strip() + # :filter_glob is our special doc-tag. elif line.startswith(":filter_glob"): param_name = line.split(":")[1].strip().replace("filter_glob ", "") if param_name in inputs: diff --git a/src/ifcpatch/ifcpatch/recipes/MergeProjects.py b/src/ifcpatch/ifcpatch/recipes/MergeProjects.py index 372cb039a3..7581f7259a 100644 --- a/src/ifcpatch/ifcpatch/recipes/MergeProjects.py +++ b/src/ifcpatch/ifcpatch/recipes/MergeProjects.py @@ -42,7 +42,6 @@ class Patcher: :param filepaths: The filepath(s) of the second (, third, ...) IFC model to merge into the first. The first model is already specified as the input to IfcPatch. - :type filepaths: list[Union[str, ifcopenshell.file]] :filter_glob filepaths: *.ifc;*.ifczip;*.ifcxml Example: