diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d10ea33..d88a0bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,18 @@ jobs: - name: Run tests with coverage run: uv run --all-extras pytest --cov=centimators --cov-report=term + # The lockfile tracks latest narwhals; the declared floor is much older and + # narwhals 1.x exposes typing aliases as runtime strings, which annotations + # can trip on at import time. Smoke-test imports at the floor so a green + # lockfile can't hide a broken install for downstream pins. + test-narwhals-floor: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v4 + - name: Import smoke test on minimum supported narwhals + run: uv run --all-extras --with "narwhals==1.39.0" pytest tests/test_imports.py + lint: runs-on: ubuntu-latest steps: diff --git a/pyproject.toml b/pyproject.toml index a6eb10f..84a0ab2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "centimators" -version = "0.3.4" +version = "0.3.5" description = "essential data transformers and model estimators for ML and data science competitions" readme = "README.md" authors = [ diff --git a/src/centimators/feature_transformers/neutralization.py b/src/centimators/feature_transformers/neutralization.py index a2c47ba..640f31d 100644 --- a/src/centimators/feature_transformers/neutralization.py +++ b/src/centimators/feature_transformers/neutralization.py @@ -1,5 +1,7 @@ """Neutralization transformers for reducing feature exposure.""" +from __future__ import annotations + import warnings import narwhals as nw diff --git a/src/centimators/feature_transformers/penalization.py b/src/centimators/feature_transformers/penalization.py index 68e36de..374f7f2 100644 --- a/src/centimators/feature_transformers/penalization.py +++ b/src/centimators/feature_transformers/penalization.py @@ -1,5 +1,7 @@ """Feature penalization transformers using iterative optimization (requires JAX).""" +from __future__ import annotations + import warnings import narwhals as nw diff --git a/tests/test_imports.py b/tests/test_imports.py new file mode 100644 index 0000000..86fbb0f --- /dev/null +++ b/tests/test_imports.py @@ -0,0 +1,29 @@ +"""Import smoke tests. + +Every module must import cleanly (or fail only with ImportError for optional +dependencies) on every supported narwhals version. Regression guard for the +narwhals 1.x incident where ``IntoSeries | None`` in a runtime-evaluated +signature raised TypeError at import time: narwhals 1.x exposes +``narwhals.typing`` aliases as plain strings at runtime, so any module using +them in annotations must carry ``from __future__ import annotations``. +""" + +import importlib +import pkgutil + +import centimators + + +def test_top_level_import(): + assert hasattr(centimators, "RankTransformer") + + +def test_all_modules_import(): + prefix = centimators.__name__ + "." + for mod_info in pkgutil.walk_packages(centimators.__path__, prefix): + try: + importlib.import_module(mod_info.name) + except ImportError: + # Optional dependencies (jax, dspy, keras, umap) may be absent; + # anything else (e.g. TypeError from annotation evaluation) fails. + continue diff --git a/uv.lock b/uv.lock index 6ea235d..94526e6 100644 --- a/uv.lock +++ b/uv.lock @@ -371,7 +371,7 @@ wheels = [ [[package]] name = "centimators" -version = "0.3.4" +version = "0.3.5" source = { editable = "." } dependencies = [ { name = "narwhals" },