pyproject: flip ty rules to error-by-default, review all new rules added since version bump

This commit is contained in:
Andrej730
2026-07-15 11:18:00 +05:00
parent c013b9aca7
commit 8718db63da
16 changed files with 94 additions and 110 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ IFC_CONNECTED_TYPE = Union[bpy.types.Material, bpy.types.Object]
class OperationData(TypedDict):
id: int
guid: NotRequired[str]
obj: str
obj: NotRequired[str]
class EditObjectOperationData(TypedDict):
@@ -18,7 +18,7 @@
import json
from pathlib import Path
from typing import TYPE_CHECKING, cast
from typing import TYPE_CHECKING
import bpy
import ifcopenshell
@@ -122,8 +122,8 @@ class ExecuteIfcPatch(bpy.types.Operator):
if props.should_load_from_memory and tool.Ifc.get():
args["file"] = tool.Ifc.get()
else:
args["input"] = cast(str, props.ifc_patch_input)
args["file"] = cast(ifcopenshell.file, ifcopenshell.open(props.ifc_patch_input))
args["input"] = props.ifc_patch_input
args["file"] = ifcopenshell.open(props.ifc_patch_input)
# Store this in case the patch recipe resets the Blender session, such as by loading a new project.
ifc_patch_output = props.ifc_patch_output or props.ifc_patch_input
@@ -71,7 +71,11 @@ class LoadByDirection(TypedDict):
ProcessedLoad = TypedDict(
"ProcessedLoad",
{"linear loads": LoadByDirection, "max linear load": float, "discrete loads": list[list[DiscreteConfigItem]]},
{
"linear loads": dict[str, LoadByDirection] | None,
"max linear load": float,
"discrete loads": list[list[DiscreteConfigItem]],
},
)
@@ -845,13 +849,16 @@ class ShaderInfo:
v = l1[1] + fac * (pos - l1[0])
return v
def interpolate(self, pos: float, loadinfo: list[LoadConfigItem], start: int, end: int, key: str) -> np.ndarray:
def interpolate(self, pos: float, loadinfo: list[LoadConfigItem], start: int, end: int) -> np.ndarray:
"""interpolate the result vectors between load poits"""
result = np.zeros(6)
for i in range(6):
value1 = [loadinfo[start]["pos"], loadinfo[start][key][i]] # [position, force_component]
value2 = [loadinfo[end]["pos"], loadinfo[end][key][i]] # [position, force_component]
result[i] = self.interp1d(value1, value2, pos) # interpolated [position, force_component]
# [position, force_component]
value1 = [loadinfo[start]["pos"], loadinfo[start]["load values"][i]]
# [position, force_component]
value2 = [loadinfo[end]["pos"], loadinfo[end]["load values"][i]]
# interpolated [position, force_component]
result[i] = self.interp1d(value1, value2, pos)
return result
def get_before_and_after(self, pos: float, load_config_list: list[list[LoadConfigItem]]) -> dict[str, list[float]]:
@@ -895,8 +902,8 @@ class ShaderInfo:
load_before += config[end]["load values"]
elif end - start == 1:
load_before += self.interpolate(pos, config, start, end, "load values")
load_after += self.interpolate(pos, config, start, end, "load values")
load_before += self.interpolate(pos, config, start, end)
load_after += self.interpolate(pos, config, start, end)
start += 1
end -= 1
return_value = {"before": load_before.tolist(), "after": load_after.tolist()}
+1 -2
View File
@@ -33,7 +33,6 @@ from typing import (
Optional,
TypeGuard,
Union,
cast,
get_args,
)
@@ -2187,7 +2186,7 @@ class Geometry(bonsai.core.tool.Geometry):
setattr(item, attribute.name, attribute.get_value())
if item.is_a("IfcSweptAreaSolid"):
item_profile = cast(str, props.item_profile)
item_profile = props.item_profile
profile = item.SweptArea
profile_name: Union[str, None] = profile.ProfileName
if item_profile == "-":
-1
View File
@@ -197,7 +197,6 @@ class Loader(bonsai.core.tool.Loader):
cls, blender_material: bpy.types.Material, surface_style: ifcopenshell.entity_instance
) -> None:
surface_style = cls.surface_style_to_dict(surface_style)
surface_style: dict[str, Any]
cls.create_surface_style_shading(blender_material, surface_style)
+1 -1
View File
@@ -232,7 +232,7 @@ class Raycast(bonsai.core.tool.Raycast):
return final_2d, v2
@classmethod
def intersect_mouse_2d_bounding_box(cls, mouse_pos: tuple[int, int], bbox: list[float, float, float, float]):
def intersect_mouse_2d_bounding_box(cls, mouse_pos: tuple[int, int], bbox: list[float]):
x, y = mouse_pos
xmin, xmax, ymin, ymax = bbox
+2 -2
View File
@@ -30,7 +30,7 @@ from collections.abc import Generator
from inspect import signature
from math import radians
from pathlib import Path
from typing import Any, Union
from typing import Any, Union, cast
import bpy
import ifcopenshell
@@ -140,7 +140,7 @@ class PanelSpy:
else:
props = kwargs.get("data")
name = kwargs.get("property")
props: bpy.types.bpy_struct
props = cast(bpy.types.bpy_struct, props)
text = kwargs.get("text", props.bl_rna.properties[name].name)
icon = kwargs.get("icon", None)
prop_type = props.bl_rna.properties[name].type
+7 -1
View File
@@ -82,6 +82,11 @@ MAIN_CSV_HEADER_COLUMNS.extend(
)
class CostRate(TypedDict):
Schedule: str | None
RateID: str | None
class CostItem(TypedDict):
children: list[CostItem]
ifc: NotRequired[ifcopenshell.entity_instance]
@@ -97,6 +102,7 @@ class CostItem(TypedDict):
Property: Union[str, None]
Query: Union[str, None]
CostRate: CostRate | None
Formula: Union[str, None]
# QuantityClass: Union[str, None]
@@ -239,7 +245,7 @@ class Csv2Ifc:
cost_values = float(cost_values) if cost_values else None
if self.has_rates:
cost_rate = {
cost_rate: CostRate = {
"Schedule": row[(self.headers["RateSchedule"])] if "RateSchedule" in self.headers else None,
"RateID": row[(self.headers["RateID"])] if "RateID" in self.headers else None,
}
+3 -2
View File
@@ -26,7 +26,8 @@ import logging
import os
import time
from collections import Counter
from typing import Optional, TypedDict, Union
from typing import Optional, Union
from typing_extensions import TypedDict
import ifcopenshell
import ifcopenshell.util.cost
@@ -35,7 +36,7 @@ import ifcopenshell.util.element
import ifcopenshell.util.unit
class CostItem(TypedDict):
class CostItem(TypedDict, extra_items=float):
# Exported columns.
Index: int
Hierarchy: str
+1
View File
@@ -17,6 +17,7 @@ classifiers = [
]
dependencies = [
"ifcopenshell",
"typing_extensions",
]
[project.optional-dependencies]
+2
View File
@@ -53,6 +53,8 @@ class ClashResult(TypedDict):
p1: list[float]
p2: list[float]
distance: float
# Added by `Clasher.smart_group_clashes`.
smart_group: NotRequired[int]
class ClashSet(TypedDict):
@@ -473,7 +473,6 @@ class ShapeBuilder:
if arc_points and self.file.schema == "IFC2X3":
raise Exception("Arcs are not supported for IFC2X3.")
points: np.ndarray
points = np.array(points)
if position_offset is not None:
points = points + position_offset
@@ -635,7 +634,6 @@ class ShapeBuilder:
diff = (0.01, 0.01) * diff_sign
middle_point = points[0] + diff
points: list[VectorType]
points = [points[0], middle_point, points[1]]
points = [ifc_safe_vector_type(p) for p in points]
seg = self.file.createIfcArcIndex((1, 2, 3))
+3 -6
View File
@@ -184,7 +184,7 @@ class PatcherDoc(TypedDict):
class InputDoc(TypedDict):
name: str
description: str
type: Union[str, list[str]]
type: NotRequired[Union[str, list[str]]]
default: NotRequired[Any]
generic_type: NotRequired[str]
enum_items: NotRequired[list[str]]
@@ -201,7 +201,7 @@ def _extract_docs(cls: type, method_name: str, boilerplate_args: Union[Sequence[
for name, parameter in signature.parameters.items():
if name == "self" or name in boilerplate_args:
continue
input_doc: InputDoc = {"name": name}
input_doc: InputDoc = {"name": name, "description": "Undocumented"}
inputs[name] = input_doc
if isinstance(parameter.default, (str, float, int, bool)):
input_doc["default"] = parameter.default
@@ -267,10 +267,6 @@ def _extract_docs(cls: type, method_name: str, boilerplate_args: Union[Sequence[
assert is_valid_filter_glob(filter_glob), f"Invalid filter_glob pattern: '{filter_glob}'."
inputs[param_name]["filter_glob"] = filter_glob
for param_name in inputs:
if "description" not in inputs[param_name]:
inputs[param_name]["description"] = "Undocumented"
docs = PatcherDoc(
class_=cls,
description=doc_description,
@@ -309,6 +305,7 @@ def parse_docstring(docstring: str) -> DocstringData:
line = line[1:]
if line.startswith(PREFIXES):
prefix = line.split(" ")[0]
assert prefix in PREFIXES, f"Invalid line: '{line}'."
current_section = prefix
match_ = re.match(rf"{prefix}\s+(\w+):\s+(.*)", line)
assert match_, f"Invalid line: '{line}'."
+19 -3
View File
@@ -24,6 +24,7 @@ import os
import re
import sys
from typing import Literal, Optional, TypedDict, Union
from typing_extensions import NotRequired
import ifcopenshell
import ifcopenshell.util.element
@@ -96,6 +97,12 @@ class ResultsSpecification(TypedDict):
applicability: list[str]
requirements: list[ResultsRequirement]
# Filled in by `Html.report()`.
is_prohibited: NotRequired[bool]
has_requirements: NotRequired[bool]
has_omitted_applicable: NotRequired[bool]
total_omitted_applicable: NotRequired[int]
class ResultsRequirement(TypedDict):
facet_type: str
@@ -111,6 +118,15 @@ class ResultsRequirement(TypedDict):
total_fail: int
percent_pass: ResultsPercent
# Filled in by `Html.report()`.
total_failed_entities: NotRequired[int]
total_omitted_failures: NotRequired[int]
has_omitted_failures: NotRequired[bool]
total_passed_entities: NotRequired[int]
total_omitted_passes: NotRequired[int]
has_omitted_passes: NotRequired[bool]
instructions: NotRequired[str | None]
# use different syntax because of the "class" key
ResultsEntity = TypedDict(
@@ -244,7 +260,7 @@ class Txt(Console):
class Json(Reporter):
def __init__(self, ids: Ids, hide_skipped=False):
super().__init__(ids)
self.results = Results()
self.results = Results() # ty:ignore[missing-typed-dict-key]
self.results["hide_skipped"] = hide_skipped
def report(self) -> Results:
@@ -410,7 +426,7 @@ class Json(Reporter):
"id": e.id(),
"global_id": getattr(e, "GlobalId", None),
"tag": getattr(e, "Tag", None),
}
} # ty:ignore[missing-typed-dict-key]
)
for e in specification.applicable_entities
]
@@ -428,7 +444,7 @@ class Json(Reporter):
"id": e.id(),
"global_id": getattr(e, "GlobalId", None),
"tag": getattr(e, "Tag", None),
}
} # ty:ignore[missing-typed-dict-key]
)
for e in requirement.passed_entities
]
+11 -1
View File
@@ -15,7 +15,17 @@ classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
]
dependencies = ["ifcopenshell", "python-dateutil", "xmlschema", "numpy", "odfpy", "pystache", "bcf-client", "flask"]
dependencies = [
"ifcopenshell",
"python-dateutil",
"xmlschema",
"numpy",
"odfpy",
"pystache",
"bcf-client",
"flask",
"typing_extensions",
]
[project.optional-dependencies]
advanced = [