From 26b2a7d5843deb2cd787175890f22207cb0dcf76 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 27 Feb 2025 18:14:01 +0500 Subject: [PATCH] typing --- .../bonsai/bim/module/patch/operator.py | 24 ++++++++++++------- src/bonsai/bonsai/bim/module/patch/prop.py | 12 ++++++++-- src/bonsai/bonsai/bim/module/patch/ui.py | 3 +-- src/bonsai/bonsai/bim/operator.py | 8 ++++++- src/bonsai/bonsai/tool/patch.py | 10 +++++++- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/patch/operator.py b/src/bonsai/bonsai/bim/module/patch/operator.py index 6438b57246..280724cb00 100644 --- a/src/bonsai/bonsai/bim/module/patch/operator.py +++ b/src/bonsai/bonsai/bim/module/patch/operator.py @@ -25,7 +25,10 @@ import bonsai.tool as tool import bonsai.core.patch as core import bonsai.bim.handler from pathlib import Path -from typing import cast +from typing import cast, TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.prop import AttributeDataType class SelectIfcPatchInput(bpy.types.Operator): @@ -36,7 +39,8 @@ class SelectIfcPatchInput(bpy.types.Operator): filepath: bpy.props.StringProperty(subtype="FILE_PATH") def execute(self, context): - context.scene.BIMPatchProperties.ifc_patch_input = self.filepath + props = tool.Patch.get_patch_props() + props.ifc_patch_input = self.filepath return {"FINISHED"} def invoke(self, context, event): @@ -52,7 +56,8 @@ class SelectIfcPatchOutput(bpy.types.Operator): filepath: bpy.props.StringProperty(subtype="FILE_PATH") def execute(self, context): - context.scene.BIMPatchProperties.ifc_patch_output = self.filepath + props = tool.Patch.get_patch_props() + props.ifc_patch_output = self.filepath return {"FINISHED"} def invoke(self, context, event): @@ -67,7 +72,7 @@ class ExecuteIfcPatch(bpy.types.Operator): @classmethod def poll(cls, context): - props = context.scene.BIMPatchProperties + props = tool.Patch.get_patch_props() if props.ifc_patch_recipes == "-": cls.poll_message_set("No recipe selected.") return False @@ -77,7 +82,7 @@ class ExecuteIfcPatch(bpy.types.Operator): return True def execute(self, context): - props = context.scene.BIMPatchProperties + props = tool.Patch.get_patch_props() recipe_name = props.ifc_patch_recipes arguments = [] @@ -121,7 +126,7 @@ class UpdateIfcPatchArguments(bpy.types.Operator): if self.recipe == "-": print("No Recipe Selected. Impossible to load arguments") return {"FINISHED"} - patch_args = context.scene.BIMPatchProperties.ifc_patch_args_attr + patch_args = tool.Patch.get_patch_props().ifc_patch_args_attr patch_args.clear() docs = ifcpatch.extract_docs(self.recipe, "Patcher", "__init__", ("src", "file", "logger", "args")) if docs and "inputs" in docs: @@ -141,14 +146,15 @@ class UpdateIfcPatchArguments(bpy.types.Operator): data_type = [dt for dt in data_type if dt != "NoneType"][0] - new_attr.data_type = { + data_types: dict[str, AttributeDataType] = { "Literal": "enum", "file": "file", "str": "string", "float": "float", "int": "integer", "bool": "boolean", - }[data_type] + } + new_attr.data_type = data_types[data_type] new_attr.name = self.pretty_arg_name(arg_name) if new_attr.data_type == "enum": new_attr.enum_items = json.dumps(arg_info.get("enum_items", [])) @@ -211,7 +217,7 @@ class ExtractSelectedElements(bpy.types.Operator): bl_options = {"REGISTER", "UNDO"} def execute(self, context): - props = context.scene.BIMPatchProperties + props = tool.Patch.get_patch_props() recipe_name = props.ifc_patch_recipes if recipe_name != "ExtractElements": diff --git a/src/bonsai/bonsai/bim/module/patch/prop.py b/src/bonsai/bonsai/bim/module/patch/prop.py index f491cb7ed4..e12da9e722 100644 --- a/src/bonsai/bonsai/bim/module/patch/prop.py +++ b/src/bonsai/bonsai/bim/module/patch/prop.py @@ -33,6 +33,7 @@ from bpy.props import ( FloatVectorProperty, CollectionProperty, ) +from typing import TYPE_CHECKING, Literal, Union ifcpatchrecipes_enum = [] @@ -43,7 +44,7 @@ def purge(): ifcpatchrecipes_enum = [] -def get_ifcpatch_recipes(self, context): +def get_ifcpatch_recipes(self: "BIMPatchProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]: global ifcpatchrecipes_enum if len(ifcpatchrecipes_enum) < 1: # Have to add a blank entry because otherwise default recipe might be not loaded @@ -61,7 +62,7 @@ def get_ifcpatch_recipes(self, context): return ifcpatchrecipes_enum -def update_ifc_patch_recipe(self, context): +def update_ifc_patch_recipe(self: "BIMPatchProperties", context: bpy.types.Context) -> None: bpy.ops.bim.update_ifc_patch_arguments(recipe=self.ifc_patch_recipes) @@ -75,3 +76,10 @@ class BIMPatchProperties(PropertyGroup): name="Load from Memory", description="Use IFC file currently loaded in Bonsai", ) + + if TYPE_CHECKING: + ifc_patch_recipes_enum: Union[Literal["-"], str] + ifc_patch_input: str + ifc_patch_output: str + ifc_patch_args_attr: bpy.types.bpy_prop_collection_idprop[Attribute] + should_load_from_memory: bool diff --git a/src/bonsai/bonsai/bim/module/patch/ui.py b/src/bonsai/bonsai/bim/module/patch/ui.py index 539544055d..03822642a9 100644 --- a/src/bonsai/bonsai/bim/module/patch/ui.py +++ b/src/bonsai/bonsai/bim/module/patch/ui.py @@ -36,8 +36,7 @@ class BIM_PT_patch(bpy.types.Panel): layout.use_property_split = True layout.use_property_decorate = False - scene = context.scene - props = scene.BIMPatchProperties + props = tool.Patch.get_patch_props() row = layout.row() prop_with_search(row, props, "ifc_patch_recipes") diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index 9b0d38c5ab..1690b9497f 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -38,7 +38,10 @@ from mathutils import Vector, Euler from math import radians from pathlib import Path from collections import namedtuple -from typing import List, Iterable, Union +from typing import List, Iterable, Union, TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.prop import MultipleFileSelect class SetTab(bpy.types.Operator): @@ -186,6 +189,9 @@ class BIM_OT_multiple_file_selector(bpy.types.Operator): filter_glob: bpy.props.StringProperty(default="*", options={"HIDDEN"}) filepath: bpy.props.StringProperty(subtype="FILE_PATH") + if TYPE_CHECKING: + file_props: MultipleFileSelect + @classmethod def poll(cls, context): return getattr(context, "file_props", None) is not None diff --git a/src/bonsai/bonsai/tool/patch.py b/src/bonsai/bonsai/tool/patch.py index 356a5001de..dcfea3bf64 100644 --- a/src/bonsai/bonsai/tool/patch.py +++ b/src/bonsai/bonsai/tool/patch.py @@ -16,14 +16,22 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations import bpy import ifcopenshell import ifcpatch import bonsai.core.tool -from typing import Any +from typing import Any, TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.module.patch.prop import BIMPatchProperties class Patch(bonsai.core.tool.Patch): + @classmethod + def get_patch_props(cls) -> BIMPatchProperties: + return bpy.context.scene.BIMPatchProperties + @classmethod def run_migrate_patch(cls, infile: str, outfile: str, schema: str) -> None: output = ifcpatch.execute(