AGENTS.md · statsmodels/statsmodels
AGENTS.md from statsmodels/statsmodels: 312 lines covering Project snapshot, Environment setup, Code style & linting, Docstrings & documentation and more.
Template by statsmodels
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/statsmodels/statsmodels/main/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: prompt-engineering
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 312 lines
- File
AGENTS.md
Sections
- Project snapshot
- Environment setup
- Code style & linting
- Docstrings & documentation
- Testing conventions
- New estimator / model architecture
- Git / commit conventions
- Pull requests: the AI disclosure is mandatory
- Working in this repo as an agent
First lines (shown under the repo's BSD-3-Clause license)
# AGENTS.md
Guidance for coding agents (and humans) contributing to `statsmodels`. This
file is a practical supplement to [CONTRIBUTING.md](CONTRIBUTING.md) and
the [developer docs](https://www.statsmodels.org/devel/dev/index.html) —
read those too, but treat this as the checklist for "will this actually get
merged."
## Project snapshot
- Pure-Python core with a few Cython extensions (Kalman filter code in
`statsmodels/tsa/statespace/_*.pyx`, etc.). Most new statistical code is
pure Python.
- Cython extensions are built via `meson`/`ninja` (see
`pyproject.toml` `[tool.meson-python]` section). Cython extensions
are accepted only when the performance gain over pure Python is significant.
- Build backend is `meson-python`; the package is normally developed via an
**editable install** so pure-Python edits are picked up immediately.
- Target Python: `py310`+ (see `[tool.ruff] target-version` /
`[tool.black] target-version` in `pyproject.toml`).
- Upstream repo is `statsmodels/statsmodels`; when linking issues/PRs in
commit messages or docs, link that repo, not a personal fork.
- Ensure features taken from upstream packages, `numpy`, `scipy`, `pandas`, etc.,
are compatible with the minimum versions in `pyproject.toml` and `requirements.txt`.
## Environment setup
```bash
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt
python -m pip install -e . --no-build-isolation
```
Using an editable install mean changes in both Python and Cython are live
immediately; Cython extensions are rebuilt automatically on import
if the source `.pyx` file is newer than the compiled `.so` or `.dll` file.
## Code style & linting
- Formatting: `ruff` (line-length 88, `py310` target, isort-equivalent import sorting via
`[tool.ruff.lint.isort]`). Import sections: `future`, `compat`,
`standard-library`, `third-party`, `first-party`, `local-folder` — with
`statsmodels.compat` treated as its own `compat` section.
- `ruff check .` must pass when run from the repo root.
- `black` (line-length 88) is acceptable for auto-formatting, but not required.
Only use `black` to format changes to files, or in new files. Do not use `black` to
wholesale reformat existing files.
- Comments must be in English. This covers code comments, test comments, and
docstrings. Do not leave comments in another language in the diff; translate
them or remove them.
## Docstrings & documentation
- Every public function, class, method, and attribute needs a numpydoc
docstring (numpy docstring standard, not Google/Sphinx style).
- New public functionality must be:
1. Exported from the relevant `api.py` if the module has one (e.g. new
`tsa` models go in `statsmodels/tsa/api.py`, matching how `VAR`,
`SVAR`, `VARMAX` are exposed there) — burying a new class only inside
an internal module path is a common reason reviewers bounce a PR.
2. Added to the Sphinx docs — find the relevant `docs/source/*.rst` file
(e.g. `docs/source/vector_ar.rst` for VAR-family models) and add an
`autosummary` entry.
3. Noted in the current release notes file under `docs/source/release/`
(currently `version0.15.0.rst` — check for the highest-numbered
unreleased `versionX.Y.Z.rst`).
- If it's a substantial new feature, an example notebook is strongly encouraged.
(see the "Add an example" step in `CONTRIBUTING.md`).
### Docstring type conventions
Distilled from a repo-wide numpydoc type-correctness pass (2026-08). These
govern the `Parameters`/`Returns`/`Attributes` *type* field specifically —
apply them whenever writing or reviewing a docstring, not just during a
dedicated cleanup:
- **Verify against the actual code, don't pattern-match.** The most common
real bug in this codebase's docstrings is a type that describes what
"sounds right" for the parameter's name rather than what the
implementation actually does with it (coercion, indexing, arithmetic).
Read the function body before writing or trusting a type string.
- **`array_like` vs `ndarray` vs `sequence of X`:**
- `array_like` — the value is coerced (`np.asarray`/`np.array(...)`) and
then used with real array semantics (arithmetic, broadcasting,
`.shape`/`.ndim`, or passed into another `array_like`-typed call).
- `ndarray` — genuinely restricted to an already-constructed numpy array
(no coercion happens; `.shape`/`.ndim`/fancy-indexing used directly on
the raw parameter, or a plain list would raise).
- `sequence of X` (or `list of X` if genuinely list-only) — the value is
only ever iterated, indexed, or `len()`'d, never given real array
treatment. Don't default to `array_like` just because a parameter
accepts "more than a bare `ndarray`" — check which of the three is
actually true.
- `Returns`/`Attributes` describe the concrete output/stored type, never
the `Parameters`-side acceptance convention — a value that's always a
real `ndarray`/`Series`/`DataFrame` by the time it's returned should
say so, even if the same name accepts `array_like` as an input.
- **No bracket-subscript container types.** `list[int]`, `array_like[int]`,
`dict[str, int]`, `tuple[float]` are all wrong — use prose:
`list of int`, `array_like of int`, `dict of str to int`,
`tuple of float`.
- **`, optional` is the only default marker.** Every parameter with a
default ends its type string with `, optional`; don't also write
`, default: X` or restate the default value in the type field — the
default belongs in prose, in the description below the type line.
- **Don't write `None or X, optional`** when `None` is just the ordinary
default sentinel — `, optional` already conveys that `None` is accepted.
Write plain `X, optional`. Keep the explicit `None or X` form only when
`None` triggers genuinely different downstream behavior (a distinct code
path, not just "the code checks `is None`" — check whether it *branches*
meaningfully).
- **Curly braces `{...}` are for literal value enumerations only**, never
for type unions — `{int, str}` should be `int or str`. A real string-enum
parameter (validated with `raise ValueError` against exact literal
values, e.g. `trend`, `method`) should list the actual accepted values,
not an approximation. Inside the braces, use plain quoted values with no
backtick markup: `{"n", "co"}` is correct, `` {``"n"``, ``"co"``} `` is
wrong (redundant RST markup once the value is already quoted inside
braces).
- `bool` not `boolean`; `str` not `string`; `callable` not
`function`/`class`.
- The canonical type string for an RNG-seeding parameter (after the
`seed`→`rng` migration) is exactly:
`rng : int, array_like of int, numpy.random.Generator, or numpy.random.RandomState, optional`
— no `None` in the list (redundant with `, optional`), no curly braces.
If the parameter actually flows into something narrower (e.g. a legacy
`scipy` `seed=` kwarg that rejects `array_like of int`), use the
narrower, verified form instead of the full canonical one.
- Standard numpydoc section headers only: `Parameters`, `Returns`,
`Yields`, `Raises`, `Warns`, `Other Parameters`, `Attributes`, `Methods`,
`See Also`, `Notes`, `References`, `Examples`, `Warnings`. Don't invent
new section names (`Restrictions`, `Column order`, etc.) — fold that
content into `Notes`. Section-underline length must match the header
text length exactly (this repo's own docstring tooling expects an exact
match, not just RST's "underline ≥ header length" minimum).
- Every documented parameter/attribute/return must actually exist in the
current signature/implementation, and every real parameter should be
documented — check both directions, since signatures drift out of sync
with docstrings over time (a stale copy-pasted name from a sibling
method is a very common real bug, not just a style nit).
- A real, non-docstring bug found while auditing docstrings (dead
parameters, unused kwargs, wrong operator precedence, etc.) belongs in
its own `BUG:` commit — don't fold a behavior fix into a `DOC:` commit,
and don't silently "fix" the docstring to match buggy behavior without
flagging the underlying bug.
## Testing conventions
- Tests live in a `tests/` subpackage next to the code
(`statsmodels/<area>/tests/test_*.py`). Reference values from other
packages (R, Stata, SAS, a prior statsmodels version) go in a sibling
`tests/results/` directory — document *where* each reference value came
from and why it might not match exactly.
- The preferred style is pure modern `pytest` with `pytest.mark.parametrize`
for multiple cases, and `pytest` fixtures for shared setup.
- Avoid `unittest.TestCase` style for new tests.
- Statistical/numerical claims should be validated against an existing
package or known closed-form result wherever possible (this project
follows a test-driven-development norm for new models/statistical
functions) — an internal-consistency-only test suite (e.g. "shape isSignals
- Stars
- 11,710
- Forks
- 3,646
- Open issues
- 2,610
- Last commit (this folder)
- Oct 24, 2026 (4 days ago)
- Last release
- Aug 27, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- BSD-3-Clause
- Repository
- github.com/statsmodels/statsmodels
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Cite this page
AGENTS.md · statsmodels/statsmodels. Agent Mart. https://agentmart.dev/templates/statsmodels-statsmodels-agents-md (last updated 2026-10-24)