typing: modernize Generator annotations

`None, None` assumed by default.
Though this was introduced in Python 3.13, before 3.13 it only breaks if we'd do `typing.Generator[T]` (which is deprecated) -`collections.abc.Generator[T]` works fine, it seems it never had an arity check.
This commit is contained in:
Andrej730
2026-09-02 15:42:12 +05:00
parent 261d2ce9a2
commit 4eb093eefa
11 changed files with 25 additions and 31 deletions
+1 -1
View File
@@ -179,7 +179,7 @@ def format_debug_info(info: dict[str, Any]) -> str:
return text.strip() return text.strip()
def get_binaries(path: Path) -> Generator[Path, None, None]: def get_binaries(path: Path) -> Generator[Path]:
yield from path.glob("**/*.pyd") yield from path.glob("**/*.pyd")
yield from path.glob("**/*.dll") yield from path.glob("**/*.dll")
# pyradiance is using .so files on windows for some reason. # pyradiance is using .so files on windows for some reason.
+3 -5
View File
@@ -94,9 +94,7 @@ class Array(bonsai.core.tool.Array):
return array_objects return array_objects
@classmethod @classmethod
def get_all_children_objects( def get_all_children_objects(cls, parent_element: ifcopenshell.entity_instance) -> Generator[bpy.types.Object]:
cls, parent_element: ifcopenshell.entity_instance
) -> Generator[bpy.types.Object, None, None]:
for array_modifier in cls.get_modifiers_data(parent_element): for array_modifier in cls.get_modifiers_data(parent_element):
yield from cls.get_children_objects(array_modifier) yield from cls.get_children_objects(array_modifier)
@@ -128,12 +126,12 @@ class Array(bonsai.core.tool.Array):
return tool.Ifc.get_object(parent_element) return tool.Ifc.get_object(parent_element)
@classmethod @classmethod
def get_modifiers_data(cls, parent_element: ifcopenshell.entity_instance) -> Generator[dict[str, Any], None, None]: def get_modifiers_data(cls, parent_element: ifcopenshell.entity_instance) -> Generator[dict[str, Any]]:
array_pset = ifcopenshell.util.element.get_pset(parent_element, "BBIM_Array") array_pset = ifcopenshell.util.element.get_pset(parent_element, "BBIM_Array")
yield from json.loads(array_pset["Data"]) yield from json.loads(array_pset["Data"])
@classmethod @classmethod
def get_children_objects(cls, modifier_data: dict[str, Any]) -> Generator[bpy.types.Object, None, None]: def get_children_objects(cls, modifier_data: dict[str, Any]) -> Generator[bpy.types.Object]:
child_guid: str child_guid: str
for child_guid in modifier_data["children"]: for child_guid in modifier_data["children"]:
child_obj = tool.Blender.get_object_from_guid(child_guid) child_obj = tool.Blender.get_object_from_guid(child_guid)
+2 -2
View File
@@ -2161,7 +2161,7 @@ class Blender(bonsai.core.tool.Blender):
return cls.get_internal_data_dir() / relative_path return cls.get_internal_data_dir() / relative_path
@classmethod @classmethod
def get_data_dir_paths(cls, relative_dir_path: Union[str, Path], glob_pattern: str) -> Generator[Path, None, None]: def get_data_dir_paths(cls, relative_dir_path: str | Path, glob_pattern: str) -> Generator[Path]:
"""Return paths based on glob pattern from the provided path in data folder. """Return paths based on glob pattern from the provided path in data folder.
Return paths from internal data folder first and then paths from the user data folder (if it exists).""" Return paths from internal data folder first and then paths from the user data folder (if it exists)."""
custom_path = cls.get_user_data_dir() / relative_dir_path custom_path = cls.get_user_data_dir() / relative_dir_path
@@ -2681,7 +2681,7 @@ class Blender(bonsai.core.tool.Blender):
@classmethod @classmethod
@contextlib.contextmanager @contextlib.contextmanager
def bonsai_crash_txt(cls, s: str = "") -> Generator[Path, Any, None]: def bonsai_crash_txt(cls, s: str = "") -> Generator[Path, Any]:
"""Create a temporary bonsai.crash.txt file the with current traceback. """Create a temporary bonsai.crash.txt file the with current traceback.
Useful in case Blender crash might occur too unexpectedly (e.g. #6686), Useful in case Blender crash might occur too unexpectedly (e.g. #6686),
+1 -1
View File
@@ -562,7 +562,7 @@ class Cost(bonsai.core.tool.Cost):
@classmethod @classmethod
def get_schedule_cost_items( def get_schedule_cost_items(
cls, cost_schedule: ifcopenshell.entity_instance cls, cost_schedule: ifcopenshell.entity_instance
) -> Generator[ifcopenshell.entity_instance, None, None]: ) -> Generator[ifcopenshell.entity_instance]:
return ifcopenshell.util.cost.get_schedule_cost_items(cost_schedule) return ifcopenshell.util.cost.get_schedule_cost_items(cost_schedule)
@classmethod @classmethod
+2 -2
View File
@@ -150,7 +150,7 @@ class Geometry(bonsai.core.tool.Geometry):
@classmethod @classmethod
@contextmanager @contextmanager
def batch_host_recut(cls) -> Generator[None, None, None]: def batch_host_recut(cls) -> Generator[None]:
"""Coalesce host body work — `recut_host` and `update_host_representation` """Coalesce host body work — `recut_host` and `update_host_representation`
calls inside the with-block enqueue by voided element id. On the outermost calls inside the with-block enqueue by voided element id. On the outermost
exit: every host's `update_representation` runs first (writes Blender mesh exit: every host's `update_representation` runs first (writes Blender mesh
@@ -2093,7 +2093,7 @@ class Geometry(bonsai.core.tool.Geometry):
return use_immediate_repr return use_immediate_repr
@classmethod @classmethod
def get_openings(cls, element: ifcopenshell.entity_instance) -> Generator[ifcopenshell.entity_instance, None, None]: def get_openings(cls, element: ifcopenshell.entity_instance) -> Generator[ifcopenshell.entity_instance]:
"""Get element openings as IfcRelVoidsElements. """Get element openings as IfcRelVoidsElements.
Use `.RelatedOpeningElement` to get the opening element. Use `.RelatedOpeningElement` to get the opening element.
+2 -2
View File
@@ -258,14 +258,14 @@ class Spatial(bonsai.core.tool.Spatial):
] ]
@classmethod @classmethod
def get_selected_products(cls) -> Generator[ifcopenshell.entity_instance, None, None]: def get_selected_products(cls) -> Generator[ifcopenshell.entity_instance]:
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
entity = tool.Ifc.get_entity(obj) entity = tool.Ifc.get_entity(obj)
if entity and entity.is_a("IfcProduct"): if entity and entity.is_a("IfcProduct"):
yield entity yield entity
@classmethod @classmethod
def get_selected_product_types(cls) -> Generator[ifcopenshell.entity_instance, None, None]: def get_selected_product_types(cls) -> Generator[ifcopenshell.entity_instance]:
for obj in tool.Blender.get_selected_objects(): for obj in tool.Blender.get_selected_objects():
entity = tool.Ifc.get_entity(obj) entity = tool.Ifc.get_entity(obj)
if entity and entity.is_a("IfcTypeProduct"): if entity and entity.is_a("IfcTypeProduct"):
+1 -1
View File
@@ -879,7 +879,7 @@ def get_coordinate_elements(ifc_file: ifcopenshell.file) -> list[dict[str, Any]]
return results return results
def get_coordinate_data_(element: ifcopenshell.entity_instance) -> Generator[dict[str, Any], None, None]: def get_coordinate_data_(element: ifcopenshell.entity_instance) -> Generator[dict[str, Any]]:
M_TRANSLATION = (slice(0, 3), 3) M_TRANSLATION = (slice(0, 3), 3)
element_name = val(element.Name) element_name = val(element.Name)
element_class = element.is_a() element_class = element.is_a()
+1 -1
View File
@@ -855,7 +855,7 @@ class file_mixin:
self.transaction.unbatch() self.transaction.unbatch()
return self.unbatch() return self.unbatch()
def __iter__(self) -> Generator[ifcopenshell.entity_instance, None, None]: def __iter__(self) -> Generator[ifcopenshell.entity_instance]:
return iter(self[id] for id in self.entity_names()) return iter(self[id] for id in self.entity_names())
def assign_header_from(self, other: ifcopenshell.file) -> None: def assign_header_from(self, other: ifcopenshell.file) -> None:
@@ -377,7 +377,7 @@ class iterator(ifcopenshell_wrapper.iterator):
def get(self): def get(self):
return wrap_shape_creation(self.settings, ifcopenshell_wrapper.iterator.get(self)) return wrap_shape_creation(self.settings, ifcopenshell_wrapper.iterator.get(self))
def __iter__(self) -> Generator[IteratorOutput, None, None]: def __iter__(self) -> Generator[IteratorOutput]:
if self.initialize(): if self.initialize():
while True: while True:
yield self.get() yield self.get()
@@ -621,18 +621,14 @@ def map_shape(settings: settings, inst: entity_instance) -> ifcopenshell_wrapper
@overload @overload
def consume_iterator(it: iterator, with_progress: Literal[False] = False) -> Generator[IteratorOutput, None, None]: ... def consume_iterator(it: iterator, with_progress: Literal[False] = False) -> Generator[IteratorOutput]: ...
@overload @overload
def consume_iterator( def consume_iterator(it: iterator, with_progress: Literal[True]) -> Generator[tuple[int, IteratorOutput]]: ...
it: iterator, with_progress: Literal[True]
) -> Generator[tuple[int, IteratorOutput], None, None]: ...
@overload @overload
def consume_iterator( def consume_iterator(it: iterator, with_progress: bool) -> Generator[IteratorOutput | tuple[int, IteratorOutput]]: ...
it: iterator, with_progress: bool
) -> Generator[Union[IteratorOutput, tuple[int, IteratorOutput]], None, None]: ...
def consume_iterator( def consume_iterator(
it: iterator, with_progress: bool = False it: iterator, with_progress: bool = False
) -> Generator[Union[IteratorOutput, tuple[int, IteratorOutput]], None, None]: ) -> Generator[IteratorOutput | tuple[int, IteratorOutput]]:
if it.initialize(): if it.initialize():
while True: while True:
if with_progress: if with_progress:
@@ -656,7 +652,7 @@ def iterate(
with_progress: Literal[False] = False, with_progress: Literal[False] = False,
geometry_library: GEOMETRY_LIBRARY = "opencascade", geometry_library: GEOMETRY_LIBRARY = "opencascade",
logger=None, logger=None,
) -> Generator[IteratorOutput, None, None]: ... ) -> Generator[IteratorOutput]: ...
@overload @overload
def iterate( def iterate(
settings: settings, settings: settings,
@@ -668,7 +664,7 @@ def iterate(
with_progress: Literal[True] = True, with_progress: Literal[True] = True,
geometry_library: GEOMETRY_LIBRARY = "opencascade", geometry_library: GEOMETRY_LIBRARY = "opencascade",
logger=None, logger=None,
) -> Generator[tuple[int, IteratorOutput], None, None]: ... ) -> Generator[tuple[int, IteratorOutput]]: ...
@overload @overload
def iterate( def iterate(
settings: settings, settings: settings,
@@ -680,7 +676,7 @@ def iterate(
with_progress: bool = False, with_progress: bool = False,
geometry_library: GEOMETRY_LIBRARY = "opencascade", geometry_library: GEOMETRY_LIBRARY = "opencascade",
logger=None, logger=None,
) -> Generator[Union[IteratorOutput, tuple[int, IteratorOutput]], None, None]: ... ) -> Generator[IteratorOutput | tuple[int, IteratorOutput]]: ...
def iterate( def iterate(
settings: settings, settings: settings,
file_or_filename: Union[file, str], file_or_filename: Union[file, str],
@@ -691,7 +687,7 @@ def iterate(
with_progress: bool = False, with_progress: bool = False,
geometry_library: GEOMETRY_LIBRARY = "opencascade", geometry_library: GEOMETRY_LIBRARY = "opencascade",
logger=None, logger=None,
) -> Generator[Union[IteratorOutput, tuple[int, IteratorOutput]], None, None]: ) -> Generator[IteratorOutput | tuple[int, IteratorOutput]]:
"""Get a geometry iterator for the provided file.""" """Get a geometry iterator for the provided file."""
it = iterator(settings, file_or_filename, num_threads, include, exclude, geometry_library) it = iterator(settings, file_or_filename, num_threads, include, exclude, geometry_library)
yield from consume_iterator(it, with_progress=with_progress) yield from consume_iterator(it, with_progress=with_progress)
@@ -1940,7 +1940,7 @@ def has_property(product: ifcopenshell.entity_instance, property_name: str) -> b
return any(property_name in quantities.keys() for quantities in qtos.values()) return any(property_name in quantities.keys() for quantities in qtos.values())
def get_openings(element: ifcopenshell.entity_instance) -> Generator[ifcopenshell.entity_instance, None, None]: def get_openings(element: ifcopenshell.entity_instance) -> Generator[ifcopenshell.entity_instance]:
"""Get element openings as IfcRelVoidsElements. """Get element openings as IfcRelVoidsElements.
Use `.RelatedOpeningElement` to get the opening element. Use `.RelatedOpeningElement` to get the opening element.
@@ -118,7 +118,7 @@ def is_representation_of_context(
def get_representations_iter( def get_representations_iter(
element: ifcopenshell.entity_instance, element: ifcopenshell.entity_instance,
) -> Generator[ifcopenshell.entity_instance, None, None]: ) -> Generator[ifcopenshell.entity_instance]:
"""Get an iterator with element's IfcShapeRepresentations. """Get an iterator with element's IfcShapeRepresentations.
:param element: An IfcProduct or IfcTypeProduct :param element: An IfcProduct or IfcTypeProduct
@@ -341,7 +341,7 @@ def resolve_items(
def resolve_base_items( def resolve_base_items(
representation: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance,
) -> Generator[ifcopenshell.entity_instance, None, None]: ) -> Generator[ifcopenshell.entity_instance]:
"""Resolve representation to it's base items resolving mapped items and boolean results to it's operands.""" """Resolve representation to it's base items resolving mapped items and boolean results to it's operands."""
queue: list[ifcopenshell.entity_instance] = list(representation.Items) queue: list[ifcopenshell.entity_instance] = list(representation.Items)
while queue: while queue: