From d3f46a4ca3ccdbb3ebc79376d79835d443c54478 Mon Sep 17 00:00:00 2001 From: Andy Pai Date: Sat, 4 Oct 2025 13:04:47 -0400 Subject: [PATCH] refactor: migrate from pyright to ty as primary type checker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace pyright with ty (v0.0.1a21) in dev dependencies - Update Makefile: rename typecheck target to use ty - Update documentation (README.md, AGENTS.md) with ty info and alpha warnings - Configure [tool.ty] with strict rules and proper environment settings - Remove integration test marker filter from pre-commit pytest check ty is Astral's Rust-powered type checker. While in alpha, it's suitable for experimentation and provides fast type checking capabilities. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .pre-commit-config.yaml | 2 +- AGENTS.md | 2 ++ Makefile | 4 ++-- README.md | 18 +++++++++++++++++- pyproject.toml | 28 ++++++++++++++++++--------- uv.lock | 42 ++++++++++++++++++++++++++--------------- 6 files changed, 68 insertions(+), 28 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 563a9eb..31d1fd1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: hooks: - id: pytest-check name: pytest-check - entry: bash -c "PYTHONPATH=. uv run pytest --co -q -m \"not integration\"" + entry: bash -c "PYTHONPATH=. uv run pytest --co -q" language: system pass_filenames: false always_run: true diff --git a/AGENTS.md b/AGENTS.md index a56cdd5..24633f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,6 +7,8 @@ This document provides coding guidelines for AI agents working on this Python pr - **Tooling**: Use `uv` for all package management - **Python Version**: 3.13+ - **Package Manager**: uv (fast, modern dependency management) +- **Type Checker**: ty (Astral's fast type checker, alpha stage) - `make typecheck` + - Note: ty is in early development and may have bugs/missing features ## Code Style diff --git a/Makefile b/Makefile index 599da03..7bc14cc 100644 --- a/Makefile +++ b/Makefile @@ -36,8 +36,8 @@ lint: format: uv run ruff format . -typecheck: - uv run pyright +typecheck: ## Run ty type checker + uv run ty check test: ## Run Pytest uv run pytest diff --git a/README.md b/README.md index f03df6d..800d187 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This template is a **lean starting point** for Python projects that use: - ⚙️ Pydantic Settings – typed environment configuration - 📦 uv – fast dependency management / locking - 📝 structlog – structured logging +- 🔍 ty – fast type checking (Rust-powered) --- @@ -56,7 +57,7 @@ This template is a **lean starting point** for Python projects that use: | `make setup` | Install dependencies + pre-commit hooks | | `make format` | Format code with Ruff | | `make lint` | Run Ruff linter | -| `make typecheck` | Run Pyright type checker | +| `make typecheck` | Run ty type checker | | `make test` | Run Pytest | | `make clean` | Remove \*.pyc & cache directories | | `make lock-check` | Assert `uv.lock` is in sync | @@ -108,6 +109,21 @@ Includes: PyTorch, scikit-learn, MLflow, matplotlib, numpy, pandas, and seaborn. --- +## Type Checking with ty + +This template uses [ty](https://github.com/astral-sh/ty), Astral's fast type checker written in Rust. + +**Note:** ty is in alpha and under active development. While production use is not yet recommended, it's suitable for experimentation and early adoption. + +```bash +# Run ty type checker +make typecheck +``` + +Configuration is in `pyproject.toml` under `[tool.ty]`. + +--- + ## License MIT diff --git a/pyproject.toml b/pyproject.toml index fa633ec..99e9559 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,10 +20,10 @@ dependencies = [ dev = [ "ipykernel>=6.30.1", "pre-commit>=4.3.0", - "pyright>=1.1.406", "pytest>=8.4.2", "pytest-cov>=6.2.1", "ruff>=0.13.3", + "ty>=0.0.1a21", ] ml = [ @@ -66,13 +66,23 @@ python_files = ["test_*.py"] addopts = ["-ra"] pythonpath = ["."] -[tool.pyright] -include = ["*.py", "tests"] -exclude = ["**/__pycache__"] -typeCheckingMode = "off" +[tool.ty] +# Astral's ty type checker configuration -reportMissingImports = true -reportMissingTypeStubs = false +[tool.ty.environment] +# Point to your project venv; ty auto-detects .venv but this is explicit & robust. +python = ".venv" +python-version = "3.13" -pythonVersion = "3.13" -pythonPlatform = "All" +[tool.ty.src] +include = ["src", "utils", "tests"] +exclude = ["**/__pycache__", "*.pyc"] +respect-ignore-files = true + +[tool.ty.rules] +# Strict type checking rules +possibly-unresolved-reference = "error" +division-by-zero = "error" + +[tool.ty.terminal] +output-format = "concise" diff --git a/uv.lock b/uv.lock index 445b012..361e6b9 100644 --- a/uv.lock +++ b/uv.lock @@ -1464,19 +1464,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, ] -[[package]] -name = "pyright" -version = "1.1.406" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f7/16/6b4fbdd1fef59a0292cbb99f790b44983e390321eccbc5921b4d161da5d1/pyright-1.1.406.tar.gz", hash = "sha256:c4872bc58c9643dac09e8a2e74d472c62036910b3bd37a32813989ef7576ea2c", size = 4113151, upload-time = "2025-10-02T01:04:45.488Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/a2/e309afbb459f50507103793aaef85ca4348b66814c86bc73908bdeb66d12/pyright-1.1.406-py3-none-any.whl", hash = "sha256:1d81fb43c2407bf566e97e57abb01c811973fdb21b2df8df59f870f688bdca71", size = 5980982, upload-time = "2025-10-02T01:04:43.137Z" }, -] - [[package]] name = "pytest" version = "8.4.2" @@ -1858,10 +1845,10 @@ dependencies = [ dev = [ { name = "ipykernel" }, { name = "pre-commit" }, - { name = "pyright" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "ruff" }, + { name = "ty" }, ] ml = [ { name = "matplotlib" }, @@ -1883,7 +1870,6 @@ requires-dist = [ { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.3.0" }, { name = "pydantic", specifier = ">=2.11.10" }, { name = "pydantic-settings", specifier = ">=2.11.0" }, - { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.406" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.4.2" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.2.1" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.13.3" }, @@ -1892,6 +1878,7 @@ requires-dist = [ { name = "structlog", specifier = ">=25.4.0" }, { name = "torch", marker = "extra == 'ml'", specifier = ">=2.7.1" }, { name = "tqdm", specifier = ">=4.67.1" }, + { name = "ty", marker = "extra == 'dev'", specifier = ">=0.0.1a21" }, ] provides-extras = ["dev", "ml"] @@ -1995,6 +1982,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/28/71/bd20ffcb7a64c753dc2463489a61bf69d531f308e390ad06390268c4ea04/triton-3.3.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3198adb9d78b77818a5388bff89fa72ff36f9da0bc689db2f0a651a67ce6a42", size = 155735832, upload-time = "2025-05-29T23:40:10.522Z" }, ] +[[package]] +name = "ty" +version = "0.0.1a21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/0f/65606ccee2da5a05a3c3362f5233f058e9d29d3c5521697c7ae79545d246/ty-0.0.1a21.tar.gz", hash = "sha256:e941e9a9d1e54b03eeaf9c3197c26a19cf76009fd5e41e16e5657c1c827bd6d3", size = 4263980, upload-time = "2025-09-19T06:54:06.412Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/7a/c87a42d0a45cfa2d5c06c8d66aa1b243db16dc31b25e545fb0263308523b/ty-0.0.1a21-py3-none-linux_armv6l.whl", hash = "sha256:1f276ceab23a1410aec09508248c76ae0989c67fb7a0c287e0d4564994295531", size = 8421116, upload-time = "2025-09-19T06:53:35.029Z" }, + { url = "https://files.pythonhosted.org/packages/99/c2/721bf4fa21c84d4cdae0e57a06a88e7e64fc2dca38820232bd6cbeef644f/ty-0.0.1a21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c3bc66fcae41eff133cfe326dd65d82567a2fb5d4efe2128773b10ec2766819", size = 8512556, upload-time = "2025-09-19T06:53:37.455Z" }, + { url = "https://files.pythonhosted.org/packages/6c/58/b0585d9d61673e864a87e95760dfa2a90ac15702e7612ab064d354f6752a/ty-0.0.1a21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cc0880ec344fbdf736b05d8d0da01f0caaaa02409bd9a24b68d18d0127a79b0e", size = 8109188, upload-time = "2025-09-19T06:53:39.469Z" }, + { url = "https://files.pythonhosted.org/packages/ea/08/edf7b59ba24bb1a1af341207fc5a0106eb1fe4264c1d7fb672c171dd2daf/ty-0.0.1a21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:334d2a212ebf42a0e55d57561926af7679fe1e878175e11dcb81ad8df892844e", size = 8279000, upload-time = "2025-09-19T06:53:41.309Z" }, + { url = "https://files.pythonhosted.org/packages/05/8e/4b5e562623e0aa24a3972510287b4bc5d98251afb353388d14008ea99954/ty-0.0.1a21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8c769987d00fbc33054ff7e342633f475ea10dc43bc60fb9fb056159d48cb90", size = 8243261, upload-time = "2025-09-19T06:53:42.736Z" }, + { url = "https://files.pythonhosted.org/packages/c3/09/6476fa21f9962d5b9c8e8053fd0442ed8e3ceb7502e39700ab1935555199/ty-0.0.1a21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:218d53e7919e885bd98e9196d9cb952d82178b299aa36da6f7f39333eb7400ed", size = 9150228, upload-time = "2025-09-19T06:53:44.242Z" }, + { url = "https://files.pythonhosted.org/packages/d2/96/49c158b6255fc1e22a5701c38f7d4c1b7f8be17a476ce9226fcae82a7b36/ty-0.0.1a21-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:84243455f295ed850bd53f7089819321807d4e6ee3b1cbff6086137ae0259466", size = 9628323, upload-time = "2025-09-19T06:53:45.998Z" }, + { url = "https://files.pythonhosted.org/packages/f4/65/37a8a5cb7b3254365c54b5e10f069e311c4252ed160b86fabd1203fbca5c/ty-0.0.1a21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87a200c21e02962e8a27374d9d152582331d57d709672431be58f4f898bf6cad", size = 9251233, upload-time = "2025-09-19T06:53:48.042Z" }, + { url = "https://files.pythonhosted.org/packages/a3/30/5b06120747da4a0f0bc54a4b051b42172603033dbee0bcf51bce7c21ada9/ty-0.0.1a21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be8f457d7841b7ead2a3f6b65ba668abc172a1150a0f1f6c0958af3725dbb61a", size = 8996186, upload-time = "2025-09-19T06:53:49.753Z" }, + { url = "https://files.pythonhosted.org/packages/af/fc/5aa122536b1acb57389f404f6328c20342242b78513a60459fee9b7d6f27/ty-0.0.1a21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1474d883129bb63da3b2380fc7ead824cd3baf6a9551e6aa476ffefc58057af3", size = 8722848, upload-time = "2025-09-19T06:53:51.566Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c1/456dcc65a149df8410b1d75f0197a31d4beef74b7bb44cce42b03bf074e8/ty-0.0.1a21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0efba2e52b58f536f4198ba5c4a36cac2ba67d83ec6f429ebc7704233bcda4c3", size = 8220727, upload-time = "2025-09-19T06:53:53.753Z" }, + { url = "https://files.pythonhosted.org/packages/a4/86/b37505d942cd68235be5be407e43e15afa36669aaa2db9b6e5b43c1d9f91/ty-0.0.1a21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5dfc73299d441cc6454e36ed0a976877415024143dfca6592dc36f7701424383", size = 8279114, upload-time = "2025-09-19T06:53:55.343Z" }, + { url = "https://files.pythonhosted.org/packages/55/fe/0d9816f36d258e6b2a3d7518421be17c68954ea9a66b638de49588cc2e27/ty-0.0.1a21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba13d03b9e095216ceb4e4d554a308517f28ab0a6e4dcd07cfe94563e4c2c489", size = 8701798, upload-time = "2025-09-19T06:53:57.17Z" }, + { url = "https://files.pythonhosted.org/packages/4e/7a/70539932e3e5a36c54bd5432ff44ed0c301c41a528365d8de5b8f79f4317/ty-0.0.1a21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9463cac96b8f1bb5ba740fe1d42cd6bd152b43c5b159b2f07f8fd629bcdded34", size = 8872676, upload-time = "2025-09-19T06:53:59.357Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/809d85f6982841fe28526ace3b282b0458d0a96bbc6b1a982d9269a5e481/ty-0.0.1a21-py3-none-win32.whl", hash = "sha256:ecf41706b803827b0de8717f32a434dad1e67be9f4b8caf403e12013179ea06a", size = 8003866, upload-time = "2025-09-19T06:54:01.393Z" }, + { url = "https://files.pythonhosted.org/packages/50/16/b3e914cec2a6344d2c30d3780ca6ecd39667173611f8776cecfd1294eab9/ty-0.0.1a21-py3-none-win_amd64.whl", hash = "sha256:7505aeb8bf2a62f00f12cfa496f6c965074d75c8126268776565284c8a12d5dd", size = 8675300, upload-time = "2025-09-19T06:54:02.893Z" }, + { url = "https://files.pythonhosted.org/packages/16/0b/293be6bc19f6da5e9b15e615a7100504f307dd4294d2c61cee3de91198e5/ty-0.0.1a21-py3-none-win_arm64.whl", hash = "sha256:21f708d02b6588323ffdbfdba38830dd0ecfd626db50aa6006b296b5470e52f9", size = 8193800, upload-time = "2025-09-19T06:54:04.583Z" }, +] + [[package]] name = "typing-extensions" version = "4.14.1"