Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ jobs:
- name: Ruff format
run: ruff format --check src tests

- name: Mypy
run: |
set -o pipefail
mypy 2>&1 | tee mypy.log
if grep -q 'unused section' mypy.log; then
echo "::error::A mypy exemption in pyproject.toml matches nothing. Remove it."
exit 1
fi

- name: Pytest
run: >-
python -m pytest -q
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ build/
*.egg-info/
.env
.env.local
.mypy_cache/
mypy.log
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ python3 -m venv --clear .venv # --clear: a uv-made .venv has no pip
python -m pip install -r requirements-dev.txt
python -m pip install -e .
ruff check src tests
ruff format --check src tests
mypy
pytest -q -m 'not live' --cov=eip_search_v3 --cov-fail-under=90
! git grep --untracked -n -I -P '[\x{2013}\x{2014}]' -- . # CI rejects en/em dashes
```
Expand Down
32 changes: 32 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,38 @@ eip-search = "eip_search_v3.cli:entrypoint"
[tool.setuptools.packages.find]
where = ["src"]

[tool.mypy]
python_version = "3.12"
files = ["src"]
ignore_missing_imports = true
# Report an override that matches nothing, so an exemption cannot outlive the
# errors it was added for. mypy prints that as a note and still exits 0, so the
# CI step greps for it and fails.
warn_unused_configs = true

# Type checking is a ratchet, not an allowlist. Everything is checked by default
# and the exemptions are listed, never the inverse. Listing what IS checked would
# leave every new module unchecked by default, so debt would accumulate silently
# and the list would be the same size in a year. This way new code is checked
# without anyone deciding to check it, and the list below can only shrink.
#
# 7 of 14 modules are exempt, holding 22 errors: cli, client, config, render.common, render.exploit, render.labs, render.vulnerability.
# Most are one shape: a corpus lookup that may return None, then read with .get
# in the renderers. Fixing that properly means giving the lookup a precise return
# type, which is worth doing deliberately rather than inside a tooling change.
# Removing a module from this list plus fixing its errors is the unit of progress.
[[tool.mypy.overrides]]
module = [
"eip_search_v3.cli",
"eip_search_v3.client",
"eip_search_v3.config",
"eip_search_v3.render.common",
"eip_search_v3.render.exploit",
"eip_search_v3.render.labs",
"eip_search_v3.render.vulnerability",
]
ignore_errors = true

[tool.ruff]
# Pin the formatter to the version CI installs. `ruff check` findings are stable
# across releases; `ruff format` output is not, and AGENTS.md tells a maintainer
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ twine>=6,<7
pytest==8.4.2
pytest-cov>=5
ruff==0.16.3
mypy==2.3.1