From d5e890bccd70adcdb81dc67436041c1c9a22f202 Mon Sep 17 00:00:00 2001 From: Stephen Boddy Date: Fri, 10 Jul 2026 22:19:56 +0100 Subject: [PATCH] Fix ty-ios type-check errors (ifcopenshell-python side) poe ty's sequence only reaches ty-ios once ty-bonsai passes, so these never surfaced until now: - util/alignment.py: drop the stale `include_referent=False` kwarg from add_zero_length_segment() - that parameter was removed from the function's signature in 45ea5eb07 but this caller in a different file was missed, leaving a latent TypeError if this code path is ever exercised. - ifcopenshell_wrapper.pyi: add the optional trailing `logger` parameter to parse_ifcxml/open/construct_iterator*, matching the real SWIG signatures in src/ifcwrap/*.i (all declare `Logger& logger = Logger::Root()`) that the hand-maintained stub never picked up. - ifcopenshell/__init__.py: remove a stale `ty: ignore[unknown-argument]` comment that ty confirms is no longer suppressing anything. - assign_cost_item_quantity.py: OPERATORS mixes 2-arg binary operators with the 1-arg `operator.neg` (for ast.USub), but FormulaEvaluator has no visit_UnaryOp so USub can never reach this lookup via visit_BinOp. Suppressed at the call site rather than touching the dict, since this looks like scaffolding for unary-minus support rather than dead code. - Explicit submodule imports (ifcopenshell.geom / api.alignment / util.unit / api.aggregate / api.context / api.spatial) added where accessed but only reachable by accident of import order. --- .../ifcopenshell/__init__.py | 2 +- .../api/alignment/_get_segment_endpoint.py | 1 + .../api/alignment/update_end_point.py | 1 + .../api/alignment/update_fallback_position.py | 1 + .../api/cost/assign_cost_item_quantity.py | 2 +- .../ifcopenshell/ifcopenshell_wrapper.pyi | 18 ++++++++++++------ .../ifcopenshell/util/alignment.py | 2 +- .../alignment/test_create_representation.py | 4 ++++ 8 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/__init__.py b/src/ifcopenshell-python/ifcopenshell/__init__.py index 85b310b9ce..12c6cd6b84 100644 --- a/src/ifcopenshell-python/ifcopenshell/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/__init__.py @@ -231,7 +231,7 @@ def open( kwargs = {"mmap": mmap} if logger is not None: kwargs["logger"] = logger - f = ifcopenshell_wrapper.open(str(path.absolute()), **kwargs) # ty: ignore[unknown-argument] + f = ifcopenshell_wrapper.open(str(path.absolute()), **kwargs) else: f = ifcopenshell_wrapper.open(str(path.absolute()), False, *((logger,) if logger is not None else ())) return file(f) diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_endpoint.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_endpoint.py index 29b2d0be8a..86f07f5a32 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_endpoint.py +++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_endpoint.py @@ -18,6 +18,7 @@ import ifcopenshell.api.alignment +import ifcopenshell.geom from ifcopenshell import entity_instance, ifcopenshell_wrapper from ifcopenshell.api.alignment._map_alignment_segment import _map_alignment_segment from typing import Union diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/update_end_point.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/update_end_point.py index 0349a99783..a772a16c77 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/alignment/update_end_point.py +++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/update_end_point.py @@ -19,6 +19,7 @@ import numpy as np import ifcopenshell +import ifcopenshell.api.alignment import ifcopenshell.util.placement from ifcopenshell import entity_instance diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py index 4d08e1ca83..7d807706e3 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py +++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py @@ -18,6 +18,7 @@ import ifcopenshell import ifcopenshell.util.placement +import ifcopenshell.util.unit from ifcopenshell import entity_instance diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py b/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py index a3a18dc37d..76cdb3187d 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py +++ b/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py @@ -287,7 +287,7 @@ class FormulaEvaluator(ast.NodeVisitor): def visit_BinOp(self, node): left = self.visit(node.left) right = self.visit(node.right) - return OPERATORS[type(node.op)](left, right) + return OPERATORS[type(node.op)](left, right) # ty: ignore[too-many-positional-arguments] def visit_Name(self, node): return self.values[node.id] diff --git a/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi b/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi index 3345eee5a6..20ab01b980 100644 --- a/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi +++ b/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi @@ -1697,10 +1697,16 @@ class uninitialized_tag: ... def arrange_polygons(settings, polygons): ... def clear_schemas(): ... -def construct_iterator(geometry_library, settings, file, num_threads): ... -def construct_iterator_with_include_exclude(geometry_library, settings, file, elems, include, num_threads): ... -def construct_iterator_with_include_exclude_globalid(geometry_library, settings, file, elems, include, num_threads): ... -def construct_iterator_with_include_exclude_id(geometry_library, settings, file, elems, include, num_threads): ... +def construct_iterator(geometry_library, settings, file, num_threads, logger=...): ... +def construct_iterator_with_include_exclude( + geometry_library, settings, file, elems, include, num_threads, logger=... +): ... +def construct_iterator_with_include_exclude_globalid( + geometry_library, settings, file, elems, include, num_threads, logger=... +): ... +def construct_iterator_with_include_exclude_id( + geometry_library, settings, file, elems, include, num_threads, logger=... +): ... def convert_loop_to_function_item(loop): ... def create_box(*args): ... def create_epeck(*args): ... @@ -1717,8 +1723,8 @@ def line_segments_to_polygons(s, eps, segments): ... def map_shape(settings, instance): ... def nary_union(sequence): ... def new_IfcBaseClass(schema_identifier: str, name: str) -> entity_instance: ... -def open(fn: str, readonly: bool = False) -> file: ... -def parse_ifcxml(filename): ... +def open(fn: str, readonly: bool = False, logger=...) -> file: ... +def parse_ifcxml(filename, logger=...): ... def polygons_to_svg(*args): ... def read(data): ... def register_schema(arg1): ... diff --git a/src/ifcopenshell-python/ifcopenshell/util/alignment.py b/src/ifcopenshell-python/ifcopenshell/util/alignment.py index 1b90ac7c5f..db2ba8e54f 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/alignment.py +++ b/src/ifcopenshell-python/ifcopenshell/util/alignment.py @@ -56,7 +56,7 @@ def append_zero_length_segments(file: ifcopenshell.file) -> ifcopenshell.file: for alignment in alignments: layouts = ifcopenshell.api.alignment.get_alignment_layouts(alignment) for layout in layouts: - ifcopenshell.api.alignment.add_zero_length_segment(patched_file, layout, include_referent=False) + ifcopenshell.api.alignment.add_zero_length_segment(patched_file, layout) curve = ifcopenshell.api.alignment.get_layout_curve(layout) if curve: ifcopenshell.api.alignment.add_zero_length_segment(patched_file, curve) diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_representation.py b/src/ifcopenshell-python/test/api/alignment/test_create_representation.py index b491158b3b..0fd0b2dc41 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_create_representation.py +++ b/src/ifcopenshell-python/test/api/alignment/test_create_representation.py @@ -21,8 +21,12 @@ import math import pytest import ifcopenshell +import ifcopenshell.api.aggregate import ifcopenshell.api.alignment +import ifcopenshell.api.context +import ifcopenshell.api.spatial import ifcopenshell.api.unit +import ifcopenshell.util.unit def test_create_representation():