From 52a2ec213a5a39e85974cb7ae44351f8f5088ee7 Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:03:25 +0300 Subject: [PATCH 1/7] Resolve calibration type rebinding diagnostics --- src/rtichoke/calibration/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rtichoke/calibration/__init__.py b/src/rtichoke/calibration/__init__.py index f41ee24b..f792ad02 100644 --- a/src/rtichoke/calibration/__init__.py +++ b/src/rtichoke/calibration/__init__.py @@ -75,8 +75,9 @@ def create_calibration_curve_times(*args, **kwargs): # Keep direct imports from rtichoke.calibration.calibration aligned with the -# public package entry points. -_calibration.create_calibration_curve = create_calibration_curve -_calibration.create_calibration_curve_times = create_calibration_curve_times +# public package entry points. setattr preserves the intentional runtime rebinding +# without presenting it to the type checker as an incompatible function assignment. +setattr(_calibration, "create_calibration_curve", create_calibration_curve) +setattr(_calibration, "create_calibration_curve_times", create_calibration_curve_times) __all__ = ["create_calibration_curve", "create_calibration_curve_times"] From 476c6646628f8a469286bc4bf52b1f01660c4319 Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:03:38 +0300 Subject: [PATCH 2/7] Narrow normalized time types --- src/rtichoke/performance_table.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rtichoke/performance_table.py b/src/rtichoke/performance_table.py index 91bbac25..546d9404 100644 --- a/src/rtichoke/performance_table.py +++ b/src/rtichoke/performance_table.py @@ -84,6 +84,7 @@ def create_performance_table_times( boundary; fixed-horizon normalization is handled by the shared time-dependent performance pipeline. """ + normalized_times: np.ndarray | dict[str, np.ndarray] if isinstance(times, dict): normalized_times = { key: np.asarray(value, dtype=float) for key, value in times.items() From 5d6dca44361f13dcf2ade64d312a8281253973bf Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:04:01 +0300 Subject: [PATCH 3/7] Accept NumPy arrays in strata formatting --- src/rtichoke/processing/combinations.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rtichoke/processing/combinations.py b/src/rtichoke/processing/combinations.py index 8262880e..07316217 100644 --- a/src/rtichoke/processing/combinations.py +++ b/src/rtichoke/processing/combinations.py @@ -64,10 +64,10 @@ def create_strata_combinations(stratified_by: str, by: float, breaks) -> pl.Data def format_strata_column( - lower_bound: list[float], - upper_bound: list[float], - include_lower_bound: list[bool], - include_upper_bound: list[bool], + lower_bound: Sequence[float] | np.ndarray, + upper_bound: Sequence[float] | np.ndarray, + include_lower_bound: Sequence[bool] | np.ndarray, + include_upper_bound: Sequence[bool] | np.ndarray, decimals: int = 3, ) -> list[str]: return [ From 2e376630ad82248796a5633853a65f99eef13614 Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:04:32 +0300 Subject: [PATCH 4/7] Narrow Polars scalar types for Great Tables --- src/rtichoke/performance_table_great_tables.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rtichoke/performance_table_great_tables.py b/src/rtichoke/performance_table_great_tables.py index 410c22be..ae97b4de 100644 --- a/src/rtichoke/performance_table_great_tables.py +++ b/src/rtichoke/performance_table_great_tables.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections.abc import Sequence +from typing import cast import numpy as np import polars as pl @@ -225,11 +226,13 @@ def render_performance_table_great_tables( locations=loc.body(columns="Model", rows=rows), ) - lift_max = float(data.get_column("lift").drop_nulls().max() or 1.0) + lift_max = float( + cast(float | int, data.get_column("lift").drop_nulls().max() or 1.0) + ) nb_max = 1.0 if "net_benefit" in data.columns: nb = data.get_column("net_benefit").drop_nulls().abs().max() - nb_max = float(nb or 1.0) + nb_max = float(cast(float | int, nb or 1.0)) for row_index in range(data.height): ppcr_value = data[row_index, "ppcr"] From 4009bc9774fe5776751d2e6aa84fead3f2cc7dc1 Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:05:00 +0300 Subject: [PATCH 5/7] Narrow Reactable typing boundaries --- src/rtichoke/performance_table_reactable.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/rtichoke/performance_table_reactable.py b/src/rtichoke/performance_table_reactable.py index 1a332982..6e53aa17 100644 --- a/src/rtichoke/performance_table_reactable.py +++ b/src/rtichoke/performance_table_reactable.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections.abc import Sequence +from typing import Any, cast import htmltools as html import numpy as np @@ -141,10 +142,13 @@ def render_performance_table_reactable( if sort_columns: data = data.sort(sort_columns) - lift_max = data.get_column("lift").drop_nulls().max() or 1.0 - nb_max = 1.0 + lift_max = cast(float | int, data.get_column("lift").drop_nulls().max() or 1.0) + nb_max: float | int = 1.0 if "net_benefit" in data.columns: - nb_max = data.get_column("net_benefit").drop_nulls().abs().max() or 1.0 + nb_max = cast( + float | int, + data.get_column("net_benefit").drop_nulls().abs().max() or 1.0, + ) models = ( data.get_column("Model").unique(maintain_order=True).to_list() @@ -302,6 +306,6 @@ def matrix_style(colors: tuple[str, str, str]): compact=True, striped=True, highlight=True, - details=confusion_matrix, + details=cast(Any, confusion_matrix), show_sort_icon=False, ) From e725f6cafeefcb5e6f0149f0ca48f6f26652c3d3 Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:06:16 +0300 Subject: [PATCH 6/7] Preserve normalized time key type --- src/rtichoke/performance_table.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/rtichoke/performance_table.py b/src/rtichoke/performance_table.py index 546d9404..8f236d73 100644 --- a/src/rtichoke/performance_table.py +++ b/src/rtichoke/performance_table.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections.abc import Sequence -from typing import Dict, Literal, Union +from typing import Dict, Literal, Union, cast import numpy as np import polars as pl @@ -86,9 +86,10 @@ def create_performance_table_times( """ normalized_times: np.ndarray | dict[str, np.ndarray] if isinstance(times, dict): - normalized_times = { - key: np.asarray(value, dtype=float) for key, value in times.items() - } + normalized_times = cast( + dict[str, np.ndarray], + {key: np.asarray(value, dtype=float) for key, value in times.items()}, + ) else: normalized_times = np.asarray(times, dtype=float) From a7651225ada2fb8aae9d7cd8116abaa5a4ce0278 Mon Sep 17 00:00:00 2001 From: Uriah Finkel Date: Thu, 20 Aug 2026 22:07:12 +0300 Subject: [PATCH 7/7] Enforce ty in package CI --- .github/workflows/python-package.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 3d555e91..d44b53a4 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -34,8 +34,7 @@ jobs: - name: Check format run: uv run ruff format --check . - - name: Check types (non-blocking) - continue-on-error: true + - name: Check types run: uv run ty check src/rtichoke - name: Build package