From 28b54c869a9ba53878aa0b38b7748e690a50c91d Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Wed, 13 Mar 2024 15:21:26 +0500 Subject: [PATCH] typing --- src/blenderbim/blenderbim/bim/ifc.py | 14 ++++--- src/blenderbim/blenderbim/tool/ifc.py | 40 ++++++++++--------- .../ifcopenshell/api/__init__.py | 21 +++++----- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index ec68020847..93014e6cac 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -29,14 +29,14 @@ import blenderbim.bim.handler import blenderbim.tool as tool from pathlib import Path from blenderbim.tool.brick import BrickStore -from typing import Set, Union +from typing import Set, Union, Optional IFC_CONNECTED_TYPE = Union[bpy.types.Material, bpy.types.Object] class IfcStore: - path = "" + path: str = "" file: ifcopenshell.file = None schema: ifcopenshell.ifcopenshell_wrapper.schema_definition = None cache: ifcopenshell.ifcopenshell_wrapper.HdfSerializer = None @@ -44,11 +44,11 @@ class IfcStore: id_map: dict[int, IFC_CONNECTED_TYPE] = {} guid_map: dict[str, IFC_CONNECTED_TYPE] = {} edited_objs: Set[bpy.types.Object] = set() - pset_template_path = "" + pset_template_path: str = "" pset_template_file: ifcopenshell.file = None - classification_path = "" + classification_path: str = "" classification_file: ifcopenshell.file = None - library_path = "" + library_path: str = "" library_file: ifcopenshell.file = None current_transaction = "" last_transaction = "" @@ -280,7 +280,9 @@ class IfcStore: del IfcStore.guid_map[data["guid"]] @staticmethod - def unlink_element(element: ifcopenshell.entity_instance = None, obj: IFC_CONNECTED_TYPE = None) -> None: + def unlink_element( + element: Optional[ifcopenshell.entity_instance] = None, obj: Optional[IFC_CONNECTED_TYPE] = None + ) -> None: if element is None: try: element = tool.Ifc.get_entity(obj) diff --git a/src/blenderbim/blenderbim/tool/ifc.py b/src/blenderbim/blenderbim/tool/ifc.py index d17c819894..9fa182218a 100644 --- a/src/blenderbim/blenderbim/tool/ifc.py +++ b/src/blenderbim/blenderbim/tool/ifc.py @@ -20,45 +20,47 @@ import os import bpy import numpy as np import ifcopenshell.api +import ifcopenshell.util.element import blenderbim.core.tool import blenderbim.bim.handler import blenderbim.tool as tool -from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE +from typing import Optional, Union, Any class Ifc(blenderbim.core.tool.Ifc): @classmethod - def run(cls, command, **kwargs): + def run(cls, command: str, **kwargs) -> Any: return ifcopenshell.api.run(command, IfcStore.get_file(), **kwargs) @classmethod - def set(cls, ifc): + def set(cls, ifc: ifcopenshell.file) -> None: IfcStore.file = ifc @classmethod - def get(cls): + def get(cls) -> ifcopenshell.file: return IfcStore.get_file() @classmethod - def get_path(cls): + def get_path(cls) -> str: return IfcStore.path @classmethod - def get_schema(cls): + def get_schema(cls) -> str: if IfcStore.get_file(): return IfcStore.get_file().schema @classmethod - def has_changed_shading(cls, obj): + def has_changed_shading(cls, obj: bpy.types.Material) -> bool: checksum = obj.BIMMaterialProperties.shading_checksum return checksum != repr(np.array(obj.diffuse_color).tobytes()) @classmethod - def is_edited(cls, obj): + def is_edited(cls, obj: bpy.types.Object) -> bool: return list(obj.scale) != [1.0, 1.0, 1.0] or obj in IfcStore.edited_objs @classmethod - def is_moved(cls, obj): + def is_moved(cls, obj: bpy.types.Object) -> bool: element = cls.get_entity(obj) if not element or element.is_a("IfcTypeProduct") or element.is_a("IfcProject"): return False @@ -77,7 +79,7 @@ class Ifc(blenderbim.core.tool.Ifc): return IfcStore.get_schema() @classmethod - def get_entity(cls, obj): + def get_entity(cls, obj: bpy.types.Object) -> ifcopenshell.entity_instance: ifc = IfcStore.get_file() props = getattr(obj, "BIMObjectProperties", None) if ifc and props and props.ifc_definition_id: @@ -87,7 +89,7 @@ class Ifc(blenderbim.core.tool.Ifc): pass @classmethod - def get_entity_by_id(cls, entity_id): + def get_entity_by_id(cls, entity_id) -> Union[ifcopenshell.entity_instance, None]: """useful to check whether entity_id is still exists in IFC""" ifc_file = tool.Ifc.get() try: @@ -96,11 +98,11 @@ class Ifc(blenderbim.core.tool.Ifc): return None @classmethod - def get_object(cls, element): + def get_object(cls, element: ifcopenshell.entity_instance) -> IFC_CONNECTED_TYPE: return IfcStore.get_element(element.id()) @classmethod - def rebuild_element_maps(cls): + def rebuild_element_maps(cls) -> None: """Rebuilds the id_map and guid_map When any Blender object is stored outside a Blender PointerProperty, @@ -153,15 +155,15 @@ class Ifc(blenderbim.core.tool.Ifc): blenderbim.bim.handler.subscribe_to(obj, "diffuse_color", blenderbim.bim.handler.color_callback) @classmethod - def link(cls, element, obj): + def link(cls, element: ifcopenshell.entity_instance, obj: IFC_CONNECTED_TYPE) -> None: IfcStore.link_element(element, obj) @classmethod - def edit(cls, obj): + def edit(cls, obj: bpy.types.Object) -> None: IfcStore.edited_objs.add(obj) @classmethod - def finish_edit(cls, obj): + def finish_edit(cls, obj: bpy.types.Object) -> None: try: IfcStore.edited_objs.remove(obj) except: @@ -186,11 +188,13 @@ class Ifc(blenderbim.core.tool.Ifc): return os.path.relpath(uri, ifc_path).replace("\\", "/") @classmethod - def unlink(cls, element=None, obj=None): + def unlink( + cls, element: Optional[ifcopenshell.entity_instance] = None, obj: Optional[IFC_CONNECTED_TYPE] = None + ) -> None: IfcStore.unlink_element(element, obj) @classmethod - def get_all_element_occurrences(cls, element): + def get_all_element_occurrences(cls, element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]: if element.is_a("IfcElementType"): element_type = element occurrences = ifcopenshell.util.element.get_types(element_type) diff --git a/src/ifcopenshell-python/ifcopenshell/api/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/__init__.py index 463d0da85f..3e072a6876 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/api/__init__.py @@ -23,13 +23,14 @@ import numpy import importlib import ifcopenshell import ifcopenshell.api +from typing import Callable, Any pre_listeners = {} post_listeners = {} -def run(usecase_path, ifc_file=None, should_run_listeners=True, **settings): +def run(usecase_path: str, ifc_file: ifcopenshell.file = None, should_run_listeners=True, **settings) -> Any: if should_run_listeners: for listener in pre_listeners.get(usecase_path, {}).values(): listener(usecase_path, ifc_file, settings) @@ -74,42 +75,44 @@ def run(usecase_path, ifc_file=None, should_run_listeners=True, **settings): return result -def add_pre_listener(usecase_path, name, callback): +def add_pre_listener(usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]) -> None: """Add a pre listener :param usecase_path: string, ifcopenshell api use case path :param name: string, name of listener - :param callback: callback function + :param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings` """ pre_listeners.setdefault(usecase_path, {})[name] = callback -def add_post_listener(usecase_path, name, callback): +def add_post_listener(usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]) -> None: """Add a post listener :param usecase_path: string, ifcopenshell api use case path :param name: string, name of listener - :param callback: callback function + :param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings` """ post_listeners.setdefault(usecase_path, {})[name] = callback -def remove_pre_listener(usecase_path, name, callback): +def remove_pre_listener(usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]) -> None: """Remove a pre listener :param usecase_path: string, ifcopenshell api use case path :param name: string, name of listener - :param callback: callback function + :param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings` """ pre_listeners.get(usecase_path, {}).pop(name, None) -def remove_post_listener(usecase_path, name, callback): +def remove_post_listener( + usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None] +) -> None: """Remove a post listener :param usecase_path: string, ifcopenshell api use case path :param name: string, name of listener - :param callback: callback function + :param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings` """ post_listeners.get(usecase_path, {}).pop(name, None)