bitflicker64 opened a new issue, #364: URL: https://github.com/apache/hugegraph-ai/issues/364
### Search before asking - [x] I had searched in the [feature](https://github.com/apache/hugegraph-ai/issues?q=is%3Aissue+label%3A%22Feature%22) and found no similar feature requirement. ### Feature Description (功能描述) ## Background `mypy` is currently listed as a dev dependency but is not enforced in CI. The config stub in `hugegraph-llm/pyproject.toml` reflects a permissive setup: ```toml [tool.mypy] disable_error_code = ["import-untyped"] # suppress missing stubs for gradio, torch, dgl, etc. check_untyped_defs = true disallow_untyped_defs = false ``` The `import-untyped` suppression is there because many heavy dependencies (`gradio`, `dgl`, `torch`, `litellm`, `ollama`, `faiss-cpu`) lack type stubs, which would otherwise produce a large volume of noise. This project already uses two tools from Astral's Rust-based Python toolchain: - `uv` — package manager - `ruff` — linter and formatter Astral recently released [`ty`](https://github.com/astral-sh/ty), a Rust-based type checker that completes the toolchain. Crucially, **`ty` has no equivalent of mypy's `import-untyped` rule yet** (tracked in [astral-sh/ty#3638](https://github.com/astral-sh/ty/issues/3638)): meaning it won't emit stub-missing errors for those dependencies. Note that `unresolved-import` (a different rule, for modules that can't be found at all) is still enabled, but since CI runs `uv sync` before type checking, installed packages will resolve correctly. --- ## Why ty over mypy | | mypy | ty | |---|---|---| | Speed | Slow (Python) | ~10–100x faster (Rust) | | Toolchain fit | External vendor | Same vendor as `uv` + `ruff` | | Gradual adoption | Possible but painful | First-class design goal | | Config | Complex | Minimal | | Missing stubs noise | Yes (`import-untyped`) | No equivalent rule yet | --- ## Proposal Introduce `ty` in **non-blocking mode**: errors are reported in CI but do not fail the build. This ensures a smooth, incremental rollout. ### Step 1 — Add `ty` as a dev dependency ```toml # pyproject.toml [project.optional-dependencies] dev = [ ... "ty>=0.0.51", # mypy>=1.16.1 ← can be removed once ty is enforced ] ``` ### Step 2 — Translate the existing mypy config to ty The entire `[tool.mypy]` block in `hugegraph-llm/pyproject.toml` translates as follows: | mypy setting | ty equivalent | |---|---| | `disable_error_code = ["import-untyped"]` | Not needed — ty has no `import-untyped` rule yet | | `check_untyped_defs = true` | ty checks unannotated function bodies unconditionally (no config needed) | | `disallow_untyped_defs = false` | ty's default — no config needed | The `[tool.mypy]` block can be removed entirely. Add a minimal ty config to the root `pyproject.toml`: ```toml [tool.ty.rules] # Start permissive; tighten incrementally as errors are fixed ``` ### Step 3 — Add a CI step (non-blocking) Add a step to `.github/workflows/ruff.yml` (or a new `ty.yml`): ```yaml - name: Type check with ty (non-blocking) run: uv run ty check hugegraph-llm/src hugegraph-python-client/src continue-on-error: true ``` `continue-on-error: true` keeps CI green during the ramp-up period while still surfacing diagnostics. ### Step 4 — Fix errors incrementally Contributors fix errors file by file over time. Use ty's suppression syntax for known-unfixable patterns: ```python result = inspect.currentframe().f_back # ty: ignore[possibly-unresolved-reference] ``` > **Note:** ty uses `# ty: ignore[rule]`, **not** `# type: ignore` — these are different syntaxes. Existing `# type: ignore` comments are still respected by ty but will trigger `unused-type-ignore-comment` warnings once the underlying error is gone. ### Step 5 — Enforce and clean up Once the error count reaches zero (or a manageable baseline): 1. Remove `continue-on-error: true` to make the check blocking. 2. Remove `mypy` from dev deps and the `[tool.mypy]` block from `hugegraph-llm/pyproject.toml`. --- ## Notes on ty's default rule set Several rules that could produce high noise are **disabled by default**, which supports incremental adoption: | Rule | Default | Relevant to this codebase | |---|---|---| | `possibly-unresolved-reference` | ignore | dynamic `global` patterns | | `possibly-missing-attribute` | ignore | conditional attribute definitions | | `division-by-zero` | ignore | general | | `missing-type-argument` | ignore | unannotated generics | | `missing-override-decorator` | ignore (preview) | subclass overrides | Rules that **are** enabled by default and will surface real issues: - `empty-body` — flags `...`/`pass` bodies with non-`None` return types. **Exemptions apply** for `@abstractmethod`, `Protocol` methods, `@overload`, and stub files, so legitimate abstract patterns won't be flagged. - `invalid-method-override` — catches Liskov Substitution Principle violations in subclasses. - `unresolved-attribute` — catches `AttributeError`-prone dynamic attribute access. --- ## Known Caveats - **Pre-stable API:** ty is at `0.0.x` with no stable API — consider tight pinning (`ty==0.0.51`) if you want to avoid surprise breakage between releases. - **Dynamic introspection:** `hugegraph-python-client`'s router uses `inspect.currentframe()` and dynamic `setattr`/`getattr`. These are inherently opaque to any static type checker — mark them with `# ty: ignore[...]` rather than attempting to fix. - **Recommended starting scope:** `hugegraph-python-client` and `hugegraph-llm` only. Defer `hugegraph-ml` due to heavy optional deps (DGL, PyTorch) that complicate analysis. ### Are you willing to submit a PR? - [ ] Yes I am willing to submit a PR! ### Code of Conduct - [x] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
