mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-02 13:04:49 +00:00
pyproject: flip ty rules to error-by-default, review all new rules added since version bump
This commit is contained in:
+26
-78
@@ -79,91 +79,39 @@ ignore = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[tool.ty.rules]
|
[tool.ty.rules]
|
||||||
all = "ignore"
|
all = "error"
|
||||||
|
|
||||||
# Structural rules (no deep type inference needed, easier to adapt).
|
# Structural rules (no deep type inference needed, easier to adapt).
|
||||||
abstract-method-in-final-class = "error"
|
|
||||||
ambiguous-protocol-member = "error"
|
|
||||||
conflicting-declarations = "error"
|
|
||||||
conflicting-metaclass = "error"
|
|
||||||
cyclic-class-definition = "error"
|
|
||||||
cyclic-type-alias-definition = "error"
|
|
||||||
dataclass-field-order = "error"
|
|
||||||
duplicate-base = "error"
|
|
||||||
duplicate-kw-only = "error"
|
|
||||||
empty-body = "error"
|
|
||||||
escape-character-in-forward-annotation = "error"
|
|
||||||
final-on-non-method = "error"
|
|
||||||
final-without-value = "error"
|
|
||||||
ignore-comment-unknown-rule = "error"
|
|
||||||
implicit-concatenated-string-type-annotation = "error"
|
|
||||||
inconsistent-mro = "error"
|
|
||||||
ineffective-final = "error"
|
|
||||||
instance-layout-conflict = "error"
|
|
||||||
invalid-dataclass = "error"
|
|
||||||
invalid-dataclass-override = "error"
|
|
||||||
invalid-enum-member-annotation = "error"
|
|
||||||
invalid-explicit-override = "error"
|
|
||||||
invalid-frozen-dataclass-subclass = "error"
|
|
||||||
invalid-generic-class = "error"
|
|
||||||
invalid-generic-enum = "error"
|
|
||||||
invalid-ignore-comment = "error"
|
|
||||||
invalid-legacy-positional-parameter = "error"
|
|
||||||
invalid-legacy-type-variable = "error"
|
|
||||||
invalid-named-tuple = "error"
|
|
||||||
invalid-newtype = "error"
|
|
||||||
invalid-overload = "error"
|
|
||||||
invalid-paramspec = "error"
|
|
||||||
invalid-protocol = "error"
|
|
||||||
invalid-syntax-in-forward-annotation = "error"
|
|
||||||
invalid-total-ordering = "error"
|
|
||||||
invalid-type-alias-type = "error"
|
|
||||||
invalid-type-checking-constant = "error"
|
|
||||||
invalid-type-guard-definition = "error"
|
|
||||||
invalid-type-variable-bound = "error"
|
|
||||||
invalid-type-variable-constraints = "error"
|
|
||||||
invalid-typed-dict-header = "error"
|
|
||||||
invalid-typed-dict-statement = "error"
|
|
||||||
override-of-final-method = "error"
|
|
||||||
override-of-final-variable = "error"
|
|
||||||
possibly-missing-import = "error"
|
|
||||||
possibly-missing-submodule = "error"
|
|
||||||
# Has false positives due to ty walrus operator bug.
|
# Has false positives due to ty walrus operator bug.
|
||||||
# possibly-unresolved-reference = "error"
|
possibly-unresolved-reference = "ignore"
|
||||||
raw-string-type-annotation = "error"
|
# Maybe later, requires to specify element types for all generics.
|
||||||
redundant-final-classvar = "error"
|
missing-type-argument = "ignore"
|
||||||
shadowed-type-variable = "error"
|
# Conflicts with `bpy` props defined using annotations.
|
||||||
subclass-of-final-class = "error"
|
invalid-type-form = "ignore"
|
||||||
super-call-in-named-tuple-method = "error"
|
|
||||||
unavailable-implicit-super-arguments = "error"
|
|
||||||
unbound-type-variable = "error"
|
|
||||||
undefined-reveal = "error"
|
|
||||||
unresolved-global = "error"
|
|
||||||
unresolved-import = "error"
|
|
||||||
unresolved-reference = "error"
|
|
||||||
unused-ignore-comment = "error"
|
|
||||||
unused-type-ignore-comment = "error"
|
|
||||||
useless-overload-body = "error"
|
|
||||||
|
|
||||||
# Non-structural rules:
|
# Non-structural rules:
|
||||||
deprecated = "error"
|
|
||||||
zero-stepsize-in-slice = "error"
|
|
||||||
possibly-missing-implicit-call = "error"
|
|
||||||
unused-awaitable = "error"
|
|
||||||
|
|
||||||
# Function argument rules:
|
|
||||||
# Conflicts with `ifcopenshell.api.geometry.add_representation` type of callables we have, confusing them with a module.
|
# Conflicts with `ifcopenshell.api.geometry.add_representation` type of callables we have, confusing them with a module.
|
||||||
# call-non-callable = "error"
|
call-non-callable = "ignore"
|
||||||
|
# bpy is missing some context manager implementations.
|
||||||
|
invalid-context-manager = "ignore"
|
||||||
|
# Doesn't go well with `bpy.ops.xxx.yyy`.
|
||||||
|
unresolved-attribute = "ignore"
|
||||||
# Too many false positives.
|
# Too many false positives.
|
||||||
# invalid-argument-type = "error"
|
invalid-argument-type = "ignore"
|
||||||
missing-argument = "error"
|
invalid-method-override = "ignore"
|
||||||
parameter-already-assigned = "error"
|
invalid-assignment = "ignore"
|
||||||
positional-only-parameter-as-kwarg = "error"
|
invalid-parameter-default = "ignore"
|
||||||
too-many-positional-arguments = "error"
|
missing-override-decorator = "ignore"
|
||||||
unknown-argument = "error"
|
invalid-yield = "ignore"
|
||||||
# Has a lot of warnings due to current ty walrus operator issues.
|
invalid-return-type = "ignore"
|
||||||
# index-out-of-bounds = "error"
|
non-callable-init-subclass = "ignore"
|
||||||
# unresolved-attribute = "error"
|
not-iterable = "ignore"
|
||||||
|
possibly-missing-attribute = "ignore"
|
||||||
|
no-matching-overload = "ignore"
|
||||||
|
not-subscriptable = "ignore"
|
||||||
|
unsupported-dynamic-base = "ignore"
|
||||||
|
unsupported-operator = "ignore"
|
||||||
|
type-assertion-failure = "ignore"
|
||||||
|
|
||||||
[tool.ty.environment]
|
[tool.ty.environment]
|
||||||
extra-paths = [
|
extra-paths = [
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ IFC_CONNECTED_TYPE = Union[bpy.types.Material, bpy.types.Object]
|
|||||||
class OperationData(TypedDict):
|
class OperationData(TypedDict):
|
||||||
id: int
|
id: int
|
||||||
guid: NotRequired[str]
|
guid: NotRequired[str]
|
||||||
obj: str
|
obj: NotRequired[str]
|
||||||
|
|
||||||
|
|
||||||
class EditObjectOperationData(TypedDict):
|
class EditObjectOperationData(TypedDict):
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, cast
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
@@ -122,8 +122,8 @@ class ExecuteIfcPatch(bpy.types.Operator):
|
|||||||
if props.should_load_from_memory and tool.Ifc.get():
|
if props.should_load_from_memory and tool.Ifc.get():
|
||||||
args["file"] = tool.Ifc.get()
|
args["file"] = tool.Ifc.get()
|
||||||
else:
|
else:
|
||||||
args["input"] = cast(str, props.ifc_patch_input)
|
args["input"] = props.ifc_patch_input
|
||||||
args["file"] = cast(ifcopenshell.file, ifcopenshell.open(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.
|
# 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
|
ifc_patch_output = props.ifc_patch_output or props.ifc_patch_input
|
||||||
|
|||||||
@@ -71,7 +71,11 @@ class LoadByDirection(TypedDict):
|
|||||||
|
|
||||||
ProcessedLoad = TypedDict(
|
ProcessedLoad = TypedDict(
|
||||||
"ProcessedLoad",
|
"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])
|
v = l1[1] + fac * (pos - l1[0])
|
||||||
return v
|
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"""
|
"""interpolate the result vectors between load poits"""
|
||||||
result = np.zeros(6)
|
result = np.zeros(6)
|
||||||
for i in range(6):
|
for i in range(6):
|
||||||
value1 = [loadinfo[start]["pos"], loadinfo[start][key][i]] # [position, force_component]
|
# [position, force_component]
|
||||||
value2 = [loadinfo[end]["pos"], loadinfo[end][key][i]] # [position, force_component]
|
value1 = [loadinfo[start]["pos"], loadinfo[start]["load values"][i]]
|
||||||
result[i] = self.interp1d(value1, value2, pos) # interpolated [position, force_component]
|
# [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
|
return result
|
||||||
|
|
||||||
def get_before_and_after(self, pos: float, load_config_list: list[list[LoadConfigItem]]) -> dict[str, list[float]]:
|
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"]
|
load_before += config[end]["load values"]
|
||||||
|
|
||||||
elif end - start == 1:
|
elif end - start == 1:
|
||||||
load_before += self.interpolate(pos, config, start, end, "load values")
|
load_before += self.interpolate(pos, config, start, end)
|
||||||
load_after += self.interpolate(pos, config, start, end, "load values")
|
load_after += self.interpolate(pos, config, start, end)
|
||||||
start += 1
|
start += 1
|
||||||
end -= 1
|
end -= 1
|
||||||
return_value = {"before": load_before.tolist(), "after": load_after.tolist()}
|
return_value = {"before": load_before.tolist(), "after": load_after.tolist()}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ from typing import (
|
|||||||
Optional,
|
Optional,
|
||||||
TypeGuard,
|
TypeGuard,
|
||||||
Union,
|
Union,
|
||||||
cast,
|
|
||||||
get_args,
|
get_args,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -2187,7 +2186,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
setattr(item, attribute.name, attribute.get_value())
|
setattr(item, attribute.name, attribute.get_value())
|
||||||
|
|
||||||
if item.is_a("IfcSweptAreaSolid"):
|
if item.is_a("IfcSweptAreaSolid"):
|
||||||
item_profile = cast(str, props.item_profile)
|
item_profile = props.item_profile
|
||||||
profile = item.SweptArea
|
profile = item.SweptArea
|
||||||
profile_name: Union[str, None] = profile.ProfileName
|
profile_name: Union[str, None] = profile.ProfileName
|
||||||
if item_profile == "-":
|
if item_profile == "-":
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ class Loader(bonsai.core.tool.Loader):
|
|||||||
cls, blender_material: bpy.types.Material, surface_style: ifcopenshell.entity_instance
|
cls, blender_material: bpy.types.Material, surface_style: ifcopenshell.entity_instance
|
||||||
) -> None:
|
) -> None:
|
||||||
surface_style = cls.surface_style_to_dict(surface_style)
|
surface_style = cls.surface_style_to_dict(surface_style)
|
||||||
surface_style: dict[str, Any]
|
|
||||||
|
|
||||||
cls.create_surface_style_shading(blender_material, surface_style)
|
cls.create_surface_style_shading(blender_material, surface_style)
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
return final_2d, v2
|
return final_2d, v2
|
||||||
|
|
||||||
@classmethod
|
@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
|
x, y = mouse_pos
|
||||||
xmin, xmax, ymin, ymax = bbox
|
xmin, xmax, ymin, ymax = bbox
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ from collections.abc import Generator
|
|||||||
from inspect import signature
|
from inspect import signature
|
||||||
from math import radians
|
from math import radians
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Union
|
from typing import Any, Union, cast
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
@@ -140,7 +140,7 @@ class PanelSpy:
|
|||||||
else:
|
else:
|
||||||
props = kwargs.get("data")
|
props = kwargs.get("data")
|
||||||
name = kwargs.get("property")
|
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)
|
text = kwargs.get("text", props.bl_rna.properties[name].name)
|
||||||
icon = kwargs.get("icon", None)
|
icon = kwargs.get("icon", None)
|
||||||
prop_type = props.bl_rna.properties[name].type
|
prop_type = props.bl_rna.properties[name].type
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ MAIN_CSV_HEADER_COLUMNS.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CostRate(TypedDict):
|
||||||
|
Schedule: str | None
|
||||||
|
RateID: str | None
|
||||||
|
|
||||||
|
|
||||||
class CostItem(TypedDict):
|
class CostItem(TypedDict):
|
||||||
children: list[CostItem]
|
children: list[CostItem]
|
||||||
ifc: NotRequired[ifcopenshell.entity_instance]
|
ifc: NotRequired[ifcopenshell.entity_instance]
|
||||||
@@ -97,6 +102,7 @@ class CostItem(TypedDict):
|
|||||||
Property: Union[str, None]
|
Property: Union[str, None]
|
||||||
Query: Union[str, None]
|
Query: Union[str, None]
|
||||||
|
|
||||||
|
CostRate: CostRate | None
|
||||||
Formula: Union[str, None]
|
Formula: Union[str, None]
|
||||||
# QuantityClass: Union[str, None]
|
# QuantityClass: Union[str, None]
|
||||||
|
|
||||||
@@ -239,7 +245,7 @@ class Csv2Ifc:
|
|||||||
cost_values = float(cost_values) if cost_values else None
|
cost_values = float(cost_values) if cost_values else None
|
||||||
|
|
||||||
if self.has_rates:
|
if self.has_rates:
|
||||||
cost_rate = {
|
cost_rate: CostRate = {
|
||||||
"Schedule": row[(self.headers["RateSchedule"])] if "RateSchedule" in self.headers else None,
|
"Schedule": row[(self.headers["RateSchedule"])] if "RateSchedule" in self.headers else None,
|
||||||
"RateID": row[(self.headers["RateID"])] if "RateID" in self.headers else None,
|
"RateID": row[(self.headers["RateID"])] if "RateID" in self.headers else None,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from typing import Optional, TypedDict, Union
|
from typing import Optional, Union
|
||||||
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.cost
|
import ifcopenshell.util.cost
|
||||||
@@ -35,7 +36,7 @@ import ifcopenshell.util.element
|
|||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
|
|
||||||
|
|
||||||
class CostItem(TypedDict):
|
class CostItem(TypedDict, extra_items=float):
|
||||||
# Exported columns.
|
# Exported columns.
|
||||||
Index: int
|
Index: int
|
||||||
Hierarchy: str
|
Hierarchy: str
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ classifiers = [
|
|||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ifcopenshell",
|
"ifcopenshell",
|
||||||
|
"typing_extensions",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ class ClashResult(TypedDict):
|
|||||||
p1: list[float]
|
p1: list[float]
|
||||||
p2: list[float]
|
p2: list[float]
|
||||||
distance: float
|
distance: float
|
||||||
|
# Added by `Clasher.smart_group_clashes`.
|
||||||
|
smart_group: NotRequired[int]
|
||||||
|
|
||||||
|
|
||||||
class ClashSet(TypedDict):
|
class ClashSet(TypedDict):
|
||||||
|
|||||||
@@ -473,7 +473,6 @@ class ShapeBuilder:
|
|||||||
if arc_points and self.file.schema == "IFC2X3":
|
if arc_points and self.file.schema == "IFC2X3":
|
||||||
raise Exception("Arcs are not supported for IFC2X3.")
|
raise Exception("Arcs are not supported for IFC2X3.")
|
||||||
|
|
||||||
points: np.ndarray
|
|
||||||
points = np.array(points)
|
points = np.array(points)
|
||||||
if position_offset is not None:
|
if position_offset is not None:
|
||||||
points = points + position_offset
|
points = points + position_offset
|
||||||
@@ -635,7 +634,6 @@ class ShapeBuilder:
|
|||||||
diff = (0.01, 0.01) * diff_sign
|
diff = (0.01, 0.01) * diff_sign
|
||||||
middle_point = points[0] + diff
|
middle_point = points[0] + diff
|
||||||
|
|
||||||
points: list[VectorType]
|
|
||||||
points = [points[0], middle_point, points[1]]
|
points = [points[0], middle_point, points[1]]
|
||||||
points = [ifc_safe_vector_type(p) for p in points]
|
points = [ifc_safe_vector_type(p) for p in points]
|
||||||
seg = self.file.createIfcArcIndex((1, 2, 3))
|
seg = self.file.createIfcArcIndex((1, 2, 3))
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ class PatcherDoc(TypedDict):
|
|||||||
class InputDoc(TypedDict):
|
class InputDoc(TypedDict):
|
||||||
name: str
|
name: str
|
||||||
description: str
|
description: str
|
||||||
type: Union[str, list[str]]
|
type: NotRequired[Union[str, list[str]]]
|
||||||
default: NotRequired[Any]
|
default: NotRequired[Any]
|
||||||
generic_type: NotRequired[str]
|
generic_type: NotRequired[str]
|
||||||
enum_items: NotRequired[list[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():
|
for name, parameter in signature.parameters.items():
|
||||||
if name == "self" or name in boilerplate_args:
|
if name == "self" or name in boilerplate_args:
|
||||||
continue
|
continue
|
||||||
input_doc: InputDoc = {"name": name}
|
input_doc: InputDoc = {"name": name, "description": "Undocumented"}
|
||||||
inputs[name] = input_doc
|
inputs[name] = input_doc
|
||||||
if isinstance(parameter.default, (str, float, int, bool)):
|
if isinstance(parameter.default, (str, float, int, bool)):
|
||||||
input_doc["default"] = parameter.default
|
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}'."
|
assert is_valid_filter_glob(filter_glob), f"Invalid filter_glob pattern: '{filter_glob}'."
|
||||||
inputs[param_name]["filter_glob"] = 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(
|
docs = PatcherDoc(
|
||||||
class_=cls,
|
class_=cls,
|
||||||
description=doc_description,
|
description=doc_description,
|
||||||
@@ -309,6 +305,7 @@ def parse_docstring(docstring: str) -> DocstringData:
|
|||||||
line = line[1:]
|
line = line[1:]
|
||||||
if line.startswith(PREFIXES):
|
if line.startswith(PREFIXES):
|
||||||
prefix = line.split(" ")[0]
|
prefix = line.split(" ")[0]
|
||||||
|
assert prefix in PREFIXES, f"Invalid line: '{line}'."
|
||||||
current_section = prefix
|
current_section = prefix
|
||||||
match_ = re.match(rf"{prefix}\s+(\w+):\s+(.*)", line)
|
match_ = re.match(rf"{prefix}\s+(\w+):\s+(.*)", line)
|
||||||
assert match_, f"Invalid line: '{line}'."
|
assert match_, f"Invalid line: '{line}'."
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from typing import Literal, Optional, TypedDict, Union
|
from typing import Literal, Optional, TypedDict, Union
|
||||||
|
from typing_extensions import NotRequired
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
@@ -96,6 +97,12 @@ class ResultsSpecification(TypedDict):
|
|||||||
applicability: list[str]
|
applicability: list[str]
|
||||||
requirements: list[ResultsRequirement]
|
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):
|
class ResultsRequirement(TypedDict):
|
||||||
facet_type: str
|
facet_type: str
|
||||||
@@ -111,6 +118,15 @@ class ResultsRequirement(TypedDict):
|
|||||||
total_fail: int
|
total_fail: int
|
||||||
percent_pass: ResultsPercent
|
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
|
# use different syntax because of the "class" key
|
||||||
ResultsEntity = TypedDict(
|
ResultsEntity = TypedDict(
|
||||||
@@ -244,7 +260,7 @@ class Txt(Console):
|
|||||||
class Json(Reporter):
|
class Json(Reporter):
|
||||||
def __init__(self, ids: Ids, hide_skipped=False):
|
def __init__(self, ids: Ids, hide_skipped=False):
|
||||||
super().__init__(ids)
|
super().__init__(ids)
|
||||||
self.results = Results()
|
self.results = Results() # ty:ignore[missing-typed-dict-key]
|
||||||
self.results["hide_skipped"] = hide_skipped
|
self.results["hide_skipped"] = hide_skipped
|
||||||
|
|
||||||
def report(self) -> Results:
|
def report(self) -> Results:
|
||||||
@@ -410,7 +426,7 @@ class Json(Reporter):
|
|||||||
"id": e.id(),
|
"id": e.id(),
|
||||||
"global_id": getattr(e, "GlobalId", None),
|
"global_id": getattr(e, "GlobalId", None),
|
||||||
"tag": getattr(e, "Tag", None),
|
"tag": getattr(e, "Tag", None),
|
||||||
}
|
} # ty:ignore[missing-typed-dict-key]
|
||||||
)
|
)
|
||||||
for e in specification.applicable_entities
|
for e in specification.applicable_entities
|
||||||
]
|
]
|
||||||
@@ -428,7 +444,7 @@ class Json(Reporter):
|
|||||||
"id": e.id(),
|
"id": e.id(),
|
||||||
"global_id": getattr(e, "GlobalId", None),
|
"global_id": getattr(e, "GlobalId", None),
|
||||||
"tag": getattr(e, "Tag", None),
|
"tag": getattr(e, "Tag", None),
|
||||||
}
|
} # ty:ignore[missing-typed-dict-key]
|
||||||
)
|
)
|
||||||
for e in requirement.passed_entities
|
for e in requirement.passed_entities
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,7 +15,17 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
|
"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]
|
[project.optional-dependencies]
|
||||||
advanced = [
|
advanced = [
|
||||||
|
|||||||
Reference in New Issue
Block a user