|
| 1 | +# AGENTS.md |
| 2 | +Guidance for coding agents working in `openapi-spec-validator`. |
| 3 | + |
| 4 | +## Project Snapshot |
| 5 | +- Language: Python (3.10-3.14) |
| 6 | +- Tooling: Poetry, pytest, mypy, black, isort, flake8, deptry, pre-commit, tox |
| 7 | +- Main package: `openapi_spec_validator/` |
| 8 | +- Tests: `tests/integration/`, `tests/bench/` |
| 9 | +- Docs: Sphinx in `docs/` |
| 10 | + |
| 11 | +## Setup |
| 12 | +- Keep venv in-project: `poetry config virtualenvs.in-project true` |
| 13 | +- Install dev deps: `poetry install --with dev` |
| 14 | +- Install docs deps: `poetry install --with docs` |
| 15 | + |
| 16 | +## Build Commands |
| 17 | +- Build artifacts: `poetry build` |
| 18 | +- Legacy build path: `make dist-build` |
| 19 | +- Clean build/test artifacts: `make cleanup` |
| 20 | + |
| 21 | +## Test Commands |
| 22 | +- Full tests: `poetry run pytest` |
| 23 | +- Multi-Python matrix locally: `tox` |
| 24 | +- One file: `poetry run pytest tests/integration/test_main.py` |
| 25 | +- One test function: `poetry run pytest tests/integration/test_main.py::test_version` |
| 26 | +- One parametrized case: |
| 27 | + `poetry run pytest 'tests/integration/validation/test_validators.py::TestLocalOpenAPIv30Validator::test_valid[petstore.yaml]'` |
| 28 | +- By keyword: `poetry run pytest -k "schema_v31"` |
| 29 | +- Exclude network tests: `poetry run pytest -m "not network"` |
| 30 | +- Run only network tests: `poetry run pytest -m network` |
| 31 | +- Fast focused test without default addopts (no coverage/junit): |
| 32 | + `poetry run pytest -o addopts='' tests/integration/test_main.py::test_version` |
| 33 | + |
| 34 | +## Lint, Format, Type, Dependencies |
| 35 | +- Format: `poetry run black . && poetry run isort .` |
| 36 | +- Format check only: `poetry run black --check . && poetry run isort --check-only .` |
| 37 | +- Lint: `poetry run flake8` |
| 38 | +- Types: `poetry run mypy` |
| 39 | +- Dependency check: `poetry run deptry .` |
| 40 | +- Pre-commit setup: `pre-commit install` |
| 41 | +- Run all hooks: `pre-commit run --all-files` |
| 42 | + |
| 43 | +## Docs |
| 44 | +- CI-equivalent docs build: |
| 45 | + `poetry run python -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs docs/_build/html -n -W` |
| 46 | + |
| 47 | +## Style Rules (from repo config + code) |
| 48 | + |
| 49 | +### Formatting |
| 50 | +- Black is authoritative formatter. |
| 51 | +- Line length is 79 (`tool.black.line-length = 79`, flake8 79). |
| 52 | +- isort uses `profile = black` and `force_single_line = true`. |
| 53 | +- Keep one imported symbol per line for `from x import y` style blocks. |
| 54 | + |
| 55 | +### Imports |
| 56 | +- Use absolute imports from `openapi_spec_validator...`. |
| 57 | +- Order import groups: stdlib, third-party, first-party. |
| 58 | +- Avoid wildcard imports. |
| 59 | +- Keep imports explicit and deterministic under isort. |
| 60 | + |
| 61 | +### Typing |
| 62 | +- Mypy is strict (`[tool.mypy] strict = true`). |
| 63 | +- Add annotations to all new/modified functions and methods. |
| 64 | +- Prefer built-in generics (`list[str]`, `dict[str, int]`) and `X | None`. |
| 65 | +- Avoid broad `Any`; if unavoidable, keep scope minimal. |
| 66 | +- Existing ignores are for external libs only; do not add broad ignores casually. |
| 67 | + |
| 68 | +### Naming |
| 69 | +- Modules/files: `snake_case`. |
| 70 | +- Variables/functions: `snake_case`. |
| 71 | +- Classes: `PascalCase`. |
| 72 | +- Constants: `UPPER_SNAKE_CASE`. |
| 73 | +- Test functions: `test_*` and behavior-focused names. |
| 74 | + |
| 75 | +### Error Handling |
| 76 | +- Raise specific exceptions in library code. |
| 77 | +- Preserve public exception behavior unless change is intentional and tested. |
| 78 | +- CLI in `openapi_spec_validator/__main__.py` currently uses: |
| 79 | + - exit code 1 for read/validation failures |
| 80 | + - exit code 2 for unexpected runtime failures |
| 81 | +- Keep deprecation warnings consistent with current message patterns. |
| 82 | +- Do not discard useful validation context when propagating errors. |
| 83 | + |
| 84 | +### Tests and Markers |
| 85 | +- Use pytest assertions directly (`assert ...`). |
| 86 | +- Reuse helpers in `tests/integration/conftest.py`. |
| 87 | +- Mark network-dependent tests with `@pytest.mark.network`. |
| 88 | +- Prefer integration tests near affected behavior (`validation`, `shortcuts`, `versions`, CLI). |
| 89 | +- If behavior changes, add/adjust tests in the same PR. |
| 90 | + |
| 91 | +## CI Expectations |
| 92 | +- Main CI test workflow runs on Python 3.10-3.14 and ubuntu/windows. |
| 93 | +- Core checks are: |
| 94 | + 1. `poetry run pytest` |
| 95 | + 2. `poetry run mypy` |
| 96 | + 3. `poetry run deptry .` |
| 97 | +- Pre-commit hooks include: pyupgrade (`--py310-plus`), black, isort, flake8. |
| 98 | +- Docs CI installs `--with docs` and runs Sphinx with `-n -W` (warnings are failures). |
| 99 | + |
| 100 | +## Compatibility Notes |
| 101 | +- Project keeps deprecated compatibility paths (e.g., old flags and shortcuts). |
| 102 | +- Avoid removing aliases or changing warning behavior without explicit instruction. |
| 103 | +- Keep CLI/user-facing strings stable unless tests are updated accordingly. |
| 104 | + |
| 105 | +## Cursor/Copilot Instructions Check |
| 106 | +- `.cursor/rules/`: not present |
| 107 | +- `.cursorrules`: not present |
| 108 | +- `.github/copilot-instructions.md`: not present |
| 109 | +- If these files appear later, treat them as higher-priority agent instructions and update this file. |
| 110 | + |
| 111 | +## Agent Working Agreement |
| 112 | +- Keep diffs minimal and scoped. |
| 113 | +- Do not modify unrelated files. |
| 114 | +- Prefer targeted tests first, then full suite when needed. |
| 115 | +- Run formatter/lint/type checks for code changes before finishing. |
| 116 | +- Maintain backward compatibility unless task explicitly requests breaking change. |
| 117 | + |
| 118 | +## Handy Paths |
| 119 | +- Package entrypoint: `openapi_spec_validator/__main__.py` |
| 120 | +- API shortcuts: `openapi_spec_validator/shortcuts.py` |
| 121 | +- Validators: `openapi_spec_validator/validation/validators.py` |
| 122 | +- Reader utilities: `openapi_spec_validator/readers.py` |
| 123 | +- Integration tests: `tests/integration/` |
| 124 | +- Pyproject config: `pyproject.toml` |
| 125 | +- Tox config: `tox.ini` |
| 126 | +- Pre-commit config: `.pre-commit-config.yaml` |
| 127 | + |
| 128 | +## Quick Local Validation Recipe |
| 129 | +Run this sequence before handoff: |
| 130 | +1. `poetry run black . && poetry run isort .` |
| 131 | +2. `poetry run flake8` |
| 132 | +3. `poetry run mypy` |
| 133 | +4. `poetry run pytest -m "not network"` |
| 134 | +5. Add targeted network test runs only if your change touches URL/network behavior. |
| 135 | + |
| 136 | +## Practical Execution Notes |
| 137 | +- Pytest defaults from `pyproject.toml` include coverage and junit outputs. |
| 138 | +- For quick iterations, prefer `-o addopts=''` with a specific node id. |
| 139 | +- Keep command output readable; avoid noisy full-suite runs unless needed. |
| 140 | +- For CLI behavior changes, prioritize tests in `tests/integration/test_main.py`. |
| 141 | +- For validator behavior changes, prioritize `tests/integration/validation/`. |
| 142 | +- For version detection changes, prioritize `tests/integration/test_versions.py`. |
| 143 | + |
| 144 | +## Commit/PR Hygiene for Agents |
| 145 | +- Keep changes scoped to the requested task. |
| 146 | +- Do not bundle formatting-only churn with behavior changes unless requested. |
| 147 | +- Mention any intentionally preserved deprecated behavior in PR notes. |
| 148 | +- If you change user-visible messages, update tests in the same change. |
0 commit comments