You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bumped the transitive tornado dev dependency (pulled in via the jupyter
dev group) from 6.5.7 to 6.5.8 via uv lock --upgrade-package tornado,
resolving GHSA-mpf4-983q-p7j4 (HIGH), GHSA-8423-8fgw-73vq (MED), and GHSA-wwv5-g3v4-889x (LOW). Dev-only; no runtime dependency change.
Type-safety restored, zero runtime change:SkyulfDataFrame
(skyulf/engines/protocol.py) no longer declares __getattr__ -> Any,
which had silently disabled type checking on every pd.DataFrame | SkyulfDataFrame union. The protocol is now strict, and two @runtime_checkable sub-protocols carry the engine-specific surface: PandasBackedFrame (.loc, .iloc, .select_dtypes) and PolarsBackedFrame (.with_columns, .filter, .to_polars).
Call sites migrated: pandas/polars-specific attribute access now goes
through cast(PandasBackedFrame, df) / cast(PolarsBackedFrame, df) (or a pd.DataFrame cast) so the checker sees the real attributes β applied in preprocessing/_helpers.py, modeling/base.py, modeling/sklearn_wrapper.py, modeling/_tuning/engine.py, and the
integration tests. dtypes was added to the base protocol (both engines
expose it).
Why it matters: the ~41 .iloc/.loc/.select_dtypes sites that were
previously invisible to the type checker are now checked; a wrong attribute
name on a frame is a compile-time error instead of a runtime AttributeError.
Protocols are erased at runtime, so behavior is unchanged β verified by the
full skyulf-core suite (3584 passed).
Breaking (internal API):apply_dual_engine, fit_dual_engine, and fit_transform_train_dual_engine (skyulf/preprocessing/dispatcher.py)
now take a single mapping keyed by engine name β {"polars": fn_pl, "pandas": fn_pd} β instead of two positional
callables. All 63 node call sites migrated.
Loud failure replaces the silent pandas catch-all: an engine with no
registered implementation raises NotImplementedError (naming the
available keys) before any frame conversion, and an engine with an
implementation but no input-preparation path raises as well β a third
engine (Spark/Dask) can never again be silently collected to the driver.
Adding a third engine is now an additive O(1) dispatcher change.
Guard test repaired:test_no_inline_engine_dispatch pointed at a
nonexistent directory and passed vacuously; it now scans the real skyulf/preprocessing tree (87 files).
Behavior preserved: polars wrapper unwrap/re-wrap, pandas to_pandas()
conversion, failure-log format, and mixed-engine (X, y) rejection.
Deliberately untouched: vectorization/_common.py::apply_text_dual_engine
(intentional pandas-first text path) and the non-dispatcher inline engine
branches (F-08 territory).