about things
1# tooling
2
3ruff for linting and formatting. ty for type checking. pre-commit to enforce both.
4
5## ruff
6
7replaces black, isort, flake8, and dozens of plugins. one tool, fast.
8
9```bash
10uv run ruff format src/ tests/ # format
11uv run ruff check src/ tests/ # lint
12uv run ruff check --fix # lint and auto-fix
13```
14
15### pyproject.toml config
16
17```toml
18[tool.ruff]
19line-length = 88
20
21[tool.ruff.lint]
22fixable = ["ALL"]
23extend-select = [
24 "I", # isort
25 "B", # flake8-bugbear
26 "C4", # flake8-comprehensions
27 "UP", # pyupgrade
28 "SIM", # flake8-simplify
29 "RUF", # ruff-specific
30]
31ignore = [
32 "COM812", # conflicts with formatter
33]
34
35[tool.ruff.lint.per-file-ignores]
36"__init__.py" = ["F401", "I001"] # unused imports ok in __init__
37"tests/**/*.py" = ["S101"] # assert ok in tests
38```
39
40## ty
41
42astral's new type checker. still early but fast and improving.
43
44```bash
45uv run ty check
46```
47
48### pyproject.toml config
49
50```toml
51[tool.ty.src]
52include = ["src", "tests"]
53exclude = ["**/node_modules", "**/__pycache__", ".venv"]
54
55[tool.ty.environment]
56python-version = "3.10"
57
58[tool.ty.rules]
59# start permissive, tighten over time
60unknown-argument = "ignore"
61no-matching-overload = "ignore"
62```
63
64## pre-commit
65
66enforce standards before commits reach the repo.
67
68### .pre-commit-config.yaml
69
70```yaml
71repos:
72 - repo: https://github.com/abravalheri/validate-pyproject
73 rev: v0.24.1
74 hooks:
75 - id: validate-pyproject
76
77 - repo: https://github.com/astral-sh/ruff-pre-commit
78 rev: v0.8.0
79 hooks:
80 - id: ruff-check
81 args: [--fix, --exit-non-zero-on-fix]
82 - id: ruff-format
83
84 - repo: local
85 hooks:
86 - id: type-check
87 name: type check
88 entry: uv run ty check
89 language: system
90 types: [python]
91 pass_filenames: false
92
93 - repo: https://github.com/pre-commit/pre-commit-hooks
94 rev: v5.0.0
95 hooks:
96 - id: no-commit-to-branch
97 args: [--branch, main]
98```
99
100install with:
101
102```bash
103uv run pre-commit install
104```
105
106never use `--no-verify` to skip hooks. fix the issue instead.
107
108## pytest
109
110```toml
111[tool.pytest.ini_options]
112asyncio_mode = "auto"
113asyncio_default_fixture_loop_scope = "function"
114testpaths = ["tests"]
115```
116
117`asyncio_mode = "auto"` means async tests just work - no `@pytest.mark.asyncio` needed.
118
119## alternatives
120
121- [typsht](https://github.com/zzstoatzz/typsht) - parallel type checking across multiple checkers
122- [prek](https://github.com/zzstoatzz/prek) - pre-commit reimplemented in rust
123
124sources:
125- [pdsx/.pre-commit-config.yaml](https://github.com/zzstoatzz/pdsx/blob/main/.pre-commit-config.yaml)
126- [pdsx/pyproject.toml](https://github.com/zzstoatzz/pdsx/blob/main/pyproject.toml)