Skip to content

v0.8.9

Choose a tag to compare

@github-actions github-actions released this 02 Sep 15:15
· 50 commits to master since this release
09bc7f0

πŸ”’ Security β€” tornado 6.5.7 β†’ 6.5.8 (dev dependency)

  • 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.

🧠 Core β€” F-08: strict DataFrame protocol split (finding closed)

  • 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).

🧠 Core β€” F-09: engine-keyed dispatch mapping (finding closed)

  • 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).