Skip to content

Pre-2.0 quality gate: adopt Ruff + ty, pre-commit, and ship typing metadata (.pyi + py.typed) #72

@kmarchais

Description

@kmarchais

Summary

Before the 2.0 release is finalized, we should adopt Ruff + ty for the Python surface of simcoon, and add typing metadata (.pyi + py.typed) so type checking is actionable and distributable.

This is intentionally a pre-2.0 task because lint/type cleanup is likely to trigger refactors and potential Python API adjustments.

Why this should happen before 2.0

  • Current Python modules contain unresolved names and mixed typing quality that hide real defects.
  • Deferring this to post-2.0 increases the risk of semver-breaking follow-up patches.
  • Pre-commit + CI gates reduce regressions once the 2.0 API surface stabilizes.

Current repository audit (2026-02-09)

Scope explored in this repo:

  • Python package path: python-setup/simcoon (10 .py modules)
  • Pybind extension module: simcoon._core built from simcoon-python-builder/src/python_wrappers/python_module.cpp
  • _core exports are large (167 m.def(...) bindings), so stubs are required for meaningful typing.

Current tooling state:

  • pyproject.toml has no [tool.ruff] configuration.
  • pyproject.toml has no [tool.ty] configuration.
  • No .pre-commit-config.yml in repo.
  • No in-repo .pyi files for simcoon package.
  • No package-level py.typed marker.

Baseline diagnostics captured locally:

  • ruff check python-setup/simcoon --statistics -> 19 errors
    • F821 undefined-name: 11
    • F401 unused-import: 7
    • F403 import-star usage: 1
  • ruff format --check python-setup/simcoon -> 4 files need formatting
  • ty check python-setup/simcoon -> 51 diagnostics

Observed hotspots likely requiring refactor/API decisions:

  • python-setup/simcoon/base.py: references unresolved names (ListBC, ModelingSpace, USE_PYPARDISO, USE_PETSC, spsolve, PETSc).
  • python-setup/simcoon/solver.py: ProblemBase used but not imported.
  • python-setup/simcoon/constant.py: unresolved variable const in apply_constants.
  • python-setup/simcoon/clean_data.py: uses deprecated/removed NumPy aliases (np.int, np.mat).
  • python-setup/simcoon/block.py: runtime type mismatch (control_type annotated as int in Step*, passed as str from Block).

Proposed implementation plan

1) Tooling foundation (pyproject.toml)

  • Add Ruff config:
    • formatter enabled (ruff format)
    • lint rule sets at least E, F, I, UP (expand later if useful)
    • scope initially restricted to python-setup/simcoon
    • temporary per-file ignores only where unavoidable (document each)
  • Add ty config:
    • target minimum supported Python (>=3.10)
    • include package scope first (python-setup/simcoon)
    • explicitly configure exclude for build artifacts/tests/examples as needed

2) Baseline cleanup (minimal behavior changes)

  • Fix Ruff/ty issues that are clear correctness bugs first.
  • Separate purely stylistic format-only changes from semantic refactors.
  • For unresolved optional deps/import paths, prefer explicit guarded imports + clear typing strategy over blanket ignores.

3) Typing metadata for distribution (PEP 561)

  • Add python-setup/simcoon/py.typed.
  • Add at least one .pyi stub file for typed public API exposure.
    • Minimum target: python-setup/simcoon/_core.pyi (compiled extension surface)
    • Consider generating starter stubs (e.g., pybind11-stubgen) and curating manually.
  • Ensure wheel/sdist include .pyi and py.typed (verify via built artifacts, not only source tree).

4) Pre-commit integration

  • Add .pre-commit-config.yml with at least:
    • ruff-format
    • ruff-check (with --fix where safe)
    • ty check (possibly scoped or staged if runtime/build constraints require)
  • Document one-time setup in README/dev docs (pre-commit install).

5) CI enforcement

  • Add a Python quality job in GitHub Actions that runs:
    • ruff format --check
    • ruff check
    • ty check
  • Gate pull requests on this job once baseline is clean.
  • If rollout must be incremental, use a temporary non-blocking phase with explicit deadline to make it required.

Acceptance criteria

  • pyproject.toml contains working Ruff + ty configuration for this repository.
  • .pre-commit-config.yml exists and hooks run successfully on a clean checkout.
  • python-setup/simcoon/py.typed exists and is packaged into wheel + sdist.
  • At least one meaningful .pyi stub file is shipped for public API typing (_core.pyi preferred).
  • CI runs Ruff format check, Ruff lint, and ty check on every PR to master.
  • Baseline errors are either fixed or tracked with narrow, justified ignores (no broad ignore all).

Non-goals for this issue

  • Full typing of every example/tutorial script.
  • Immediate strict typing of all C++/pybind internals beyond public Python API requirements.
  • Refactoring unrelated C++ code paths unless required for Python typing correctness.

Follow-up candidates (separate issues if needed)

  • Expand lint/type coverage to examples/ and selected docs code.
  • Tighten Ruff rule set (B, SIM, PL, etc.) after initial stabilization.
  • Increase ty strictness level once _core stub coverage matures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions