diff --git a/src/bonsai/bonsai/bim/module/attribute/operator.py b/src/bonsai/bonsai/bim/module/attribute/operator.py index 85daf93fef..fdf18efa6f 100644 --- a/src/bonsai/bonsai/bim/module/attribute/operator.py +++ b/src/bonsai/bonsai/bim/module/attribute/operator.py @@ -124,6 +124,7 @@ class EditAttributes(bpy.types.Operator, tool.Ifc.Operator): def edit_attributes_on_obj(self, obj): props = obj.BIMAttributeProperties product = tool.Ifc.get_entity(obj) + assert product def callback(attributes, prop): if prop.name in ("RefLatitude", "RefLongitude"): diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index 35eeb1b916..69c55d6806 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -89,7 +89,7 @@ class OverrideMeshSeparate(bpy.types.Operator, tool.Ifc.Operator): else: self.report({"INFO"}, f"Separating an {item.is_a()} is not supported") - def add_meshlike_item(self, obj): + def add_meshlike_item(self, obj: bpy.types.Object) -> None: props = bpy.context.scene.BIMGeometryProperties obj.show_in_front = True new = props.item_objs.add() @@ -981,7 +981,7 @@ class OverrideDuplicateMove(bpy.types.Operator): self.report({"ERROR"}, lock_error_message(obj.name)) continue elif tool.Geometry.is_representation_item(obj): - OverrideDuplicateMove.duplicate_item(self, obj) + OverrideDuplicateMove.duplicate_item(obj) continue tracked_opening_type = tool.Model.get_tracked_opening_type(obj) @@ -1069,7 +1069,7 @@ class OverrideDuplicateMove(bpy.types.Operator): return old_to_new @staticmethod - def duplicate_item(self, obj): + def duplicate_item(obj: bpy.types.Object) -> None: props = bpy.context.scene.BIMGeometryProperties item = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id) new_item = ifcopenshell.util.element.copy_deep(tool.Ifc.get(), item) diff --git a/src/bonsai/bonsai/bim/module/void/operator.py b/src/bonsai/bonsai/bim/module/void/operator.py index cddc634b2c..e592b58810 100644 --- a/src/bonsai/bonsai/bim/module/void/operator.py +++ b/src/bonsai/bonsai/bim/module/void/operator.py @@ -317,7 +317,7 @@ class EnableEditingBooleans(bpy.types.Operator): representation = ifcopenshell.util.representation.resolve_representation(representation) props.booleans.clear() - def load_boolean(item, level=0): + def load_boolean(item: ifcopenshell.entity_instance, level: int = 0) -> None: new = props.booleans.add() new.name = f"{item.is_a()}/{item.id()}" new.ifc_definition_id = item.id() diff --git a/src/bonsai/bonsai/bim/module/void/prop.py b/src/bonsai/bonsai/bim/module/void/prop.py index e6cf8d21f0..8c6bbaf4e6 100644 --- a/src/bonsai/bonsai/bim/module/void/prop.py +++ b/src/bonsai/bonsai/bim/module/void/prop.py @@ -19,6 +19,7 @@ import bpy from bpy.types import PropertyGroup from bpy.props import PointerProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, EnumProperty +from typing import Union class Boolean(PropertyGroup): @@ -47,6 +48,6 @@ class BIMBooleanProperties(PropertyGroup): ) @property - def active_boolean(self): - if self.booleans and self.active_boolean_index < len(self.booleans): + def active_boolean(self) -> Union[Boolean, None]: + if self.booleans and 0 <= self.active_boolean_index < len(self.booleans): return self.booleans[self.active_boolean_index] diff --git a/src/bonsai/bonsai/core/attribute.py b/src/bonsai/bonsai/core/attribute.py index e60a5bdeb5..6084a57502 100644 --- a/src/bonsai/bonsai/core/attribute.py +++ b/src/bonsai/bonsai/core/attribute.py @@ -16,8 +16,16 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations +from typing import TYPE_CHECKING, Union -def copy_attribute_to_selection(ifc, name=None, value=None, obj=None): +if TYPE_CHECKING: + import bpy + import ifcopenshell + import bonsai.tool as tool + + +def copy_attribute_to_selection(ifc: tool.Ifc, name: str, value: Union[str, None], obj: bpy.types.Object) -> None: element = ifc.get_entity(obj) if element: try: diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index 57536a70bd..3dfeacd1be 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -144,7 +144,7 @@ class Blender(bonsai.core.tool.Blender): return f"{name} {i}" @classmethod - def get_active_object(cls, is_selected: bool = False) -> bpy.types.Object: + def get_active_object(cls, is_selected: bool = False) -> Union[bpy.types.Object, None]: obj = getattr(bpy.context, "active_object", None) or bpy.context.view_layer.objects.active if not is_selected: return obj @@ -319,7 +319,7 @@ class Blender(bonsai.core.tool.Blender): bpy.ops.wm.tool_set_by_id(name=tool_name) @classmethod - def get_shader_editor_context(cls) -> Union[dict, None]: + def get_shader_editor_context(cls) -> Union[dict[str, Any], None]: for screen in bpy.data.screens: for area in screen.areas: if area.type == "NODE_EDITOR": diff --git a/src/ifcopenshell-python/ifcopenshell/util/representation.py b/src/ifcopenshell-python/ifcopenshell/util/representation.py index b4606cff29..8bac694d9e 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/representation.py +++ b/src/ifcopenshell-python/ifcopenshell/util/representation.py @@ -20,7 +20,7 @@ import numpy as np import numpy.typing as npt import ifcopenshell import ifcopenshell.util.placement -from typing import Optional, Union, TypedDict, Literal, Iterator, Iterable +from typing import Optional, Union, TypedDict, Literal, Generator, Sequence CONTEXT_TYPE = Literal["Model", "Plan", "NotDefined"] @@ -112,7 +112,9 @@ def is_representation_of_context( return representation.ContextOfItems.ContextType == context -def get_representations_iter(element: ifcopenshell.entity_instance) -> Iterator[ifcopenshell.entity_instance]: +def get_representations_iter( + element: ifcopenshell.entity_instance, +) -> Generator[ifcopenshell.entity_instance, None, None]: """Get an iterator with element's IfcShapeRepresentations. :param element: An IfcProduct or IfcTypeProduct @@ -144,7 +146,7 @@ def get_representation( return r -def guess_type(items: Iterable[ifcopenshell.entity_instance]) -> str | None: +def guess_type(items: Sequence[ifcopenshell.entity_instance]) -> str | None: """Guesses the appropriate RepresentationType attribute based on a list of items :param items: A list of IfcRepresentationItem, typically in an IfcShapeRepresentation