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
    No fields configured for issues without a type.

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions