Skip to content

Commit 9b5f72a

Browse files
cbrnrPragnyaKhandelwal
authored andcommitted
Fix CLAUDE.md (#14044)
1 parent 26cc5e1 commit 9b5f72a

2 files changed

Lines changed: 141 additions & 138 deletions

File tree

AGENTS.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to AI coding agents when working with code in this repository.
4+
5+
## What this is
6+
7+
MNE-Python is a large open-source library for exploring, analyzing, and visualizing human
8+
neurophysiological data (MEG, EEG, sEEG, ECoG, fNIRS, etc.): I/O for dozens of vendor formats,
9+
preprocessing, source estimation, time-frequency, connectivity, statistics, decoding, and 2D/3D
10+
visualization.
11+
12+
## AI-assistance policy (read first)
13+
14+
This project has an explicit policy on AI-generated contributions:
15+
16+
@CONTRIBUTING.md
17+
18+
19+
## Common commands
20+
21+
Install an editable dev environment (see `pyproject.toml` dependency groups):
22+
```bash
23+
pip install -e ".[test_extra,doc]" # or use `uv sync` with the [dependency-groups] in pyproject.toml
24+
pre-commit install --install-hooks
25+
```
26+
27+
Lint / format (ruff, codespell, yamllint, rstcheck, toml-sort, zizmor — all via pre-commit):
28+
```bash
29+
make ruff # alias for `pre-commit run -a`
30+
```
31+
32+
Run tests:
33+
```bash
34+
# whole suite (slow; needs the testing dataset, fetched automatically via pooch)
35+
pytest -m "not ultraslowtest" mne
36+
37+
# a single test file / test / by keyword
38+
pytest mne/tests/test_evoked.py::test_io_evoked --verbose
39+
pytest mne/tests/test_evoked.py -k test_io_evoked --verbose
40+
41+
# fetch datasets explicitly if needed
42+
python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
43+
python -c "import mne; mne.datasets.sample.data_path(verbose=True)"
44+
45+
# useful flags: -x (stop on first failure), --pdb, --durations=5,
46+
# --cov=mne.viz --cov-report=term-missing (see which lines are covered)
47+
```
48+
49+
Docstring / doctest checks:
50+
```bash
51+
pytest mne/tests/test_docstring_parameters.py
52+
make test-doc # runs doctests across doc/ (requires sample + testing datasets, generally only needed when changing example code in doc/ itself)
53+
```
54+
55+
Build the docs (Sphinx + sphinx-gallery, in `doc/`):
56+
```bash
57+
PATTERN=some_regex_pattern make -C doc html-pattern # can choose some_regex_pattern to subselect relevant examples and tutorials to run
58+
make -C doc html # full build, takes about an hour, generally only needed if changing docs extensively
59+
```
60+
61+
Other:
62+
```bash
63+
make nesting # import-nesting checks (mne/tests/test_import_nesting.py)
64+
make clean # remove build artifacts, __pycache__, *.pyc/*.so
65+
```
66+
67+
There is no separate "build" step for the library itself beyond the editable install (pure
68+
Python + hatchling/hatch-vcs for versioning from git tags).
69+
70+
## Architecture
71+
72+
### Lazy public API via stub files
73+
`mne/__init__.py` uses `lazy_loader.attach_stub` against `mne/__init__.pyi` — the `.pyi` file is
74+
the actual source of truth for what's in `mne.__all__` and lazily importable, not the `.py` file.
75+
Many subpackages (`mne/io`, `mne/utils`, etc.) follow the same `__init__.py` + `__init__.pyi`
76+
pattern. When adding a new public function/class, it typically needs to be added to the relevant
77+
`__init__.pyi` (and, for docs, to `doc/python_reference.rst`) as well as implemented.
78+
79+
### I/O readers: one subpackage per format
80+
`mne/io/<format>/` (ant, array, artemis123, bci2k, besa, boxy, brainvision, bti, cnt, ctf, curry,
81+
edf, eeglab, egi, eximia, eyelink, fieldtrip, fil, hitachi, kit, mef, nedf, neuralynx, nicolet,
82+
nihon, nirx, nsx, persyst, snirf, ...) each implement a `read_raw_<format>` function and a
83+
format-specific `Raw<Format>` subclass of `BaseRaw` (`mne/io/base.py`). `mne/io/_read_raw.py`
84+
provides the generic `read_raw()` dispatcher. New format support follows this same shape: a
85+
subpackage with a reader function + `BaseRaw` subclass + its own `tests/` dir with small
86+
synthetic/testing-dataset-backed fixtures.
87+
88+
### FIF internals live in `mne/_fiff`, not `mne/io/fiff`
89+
Neuromag FIF is MNE's native format and many core objects (`Info`, projections, compensators,
90+
channel picking, tag/tree reading) depend on it, so that logic was pulled out of `mne/io/` into
91+
`mne/_fiff/` (private) to avoid import cycles and because it's used well beyond raw I/O.
92+
`mne/io/_fiff_wrap.py` re-exports select `mne._fiff` symbols for backward compatibility (some
93+
were previously public under `mne.io`).
94+
95+
### Core data containers and mixins
96+
`BaseRaw` (`mne/io/base.py`), `Epochs`/`BaseEpochs` (`mne/epochs.py`), and `Evoked`
97+
(`mne/evoked.py`) are the central objects; shared behavior (channel picking/renaming, filtering,
98+
cropping, projections, export) lives in mixins under `mne/channels/`, `mne/filter.py`,
99+
`mne/utils/mixin.py`, etc. and is composed via multiple inheritance rather than duplicated per
100+
class.
101+
102+
### Shared/templated docstrings
103+
Common parameter descriptions live in a central dict in `mne/utils/docs.py` and are spliced into
104+
function/method docstrings via the `@fill_doc` decorator + `%(param_name)s` placeholders — grep
105+
for `docdict[` / `@fill_doc` before writing out a parameter docstring by hand, it's likely already
106+
defined.
107+
108+
### Changelog is per-PR fragment files (towncrier), not a single hand-edited file
109+
User-facing changes need a file `doc/changes/dev/<PR-number>.<type>.rst` (types: `notable`,
110+
`dependency`, `bugfix`, `apichange`, `newfeature`, `other` — see `doc/development/contributing.rst`
111+
"Describe your changes in the changelog" section for full guidance). These get aggregated into
112+
`doc/changes/dev.rst` at release time; don't edit `doc/changes/dev.rst` or the versioned
113+
`doc/changes/vX.Y.rst` files directly for new changes. New contributors must also add themselves
114+
to `doc/changes/names.inc` (build fails otherwise) and are credited with `:newcontrib:` in their
115+
changelog entry instead of a plain name link.
116+
117+
## Code conventions (beyond what ruff enforces)
118+
119+
- Classes: `CamelCase`. Functions/variables: `snake_case`, no abbreviated names like `nsamples`.
120+
- Docstrings: numpydoc style with a few local deviations — no "optional" on kwargs with defaults,
121+
`str | None` instead of "str or None", no `Raises`/`Warns` sections, citations via
122+
`sphinxcontrib-bibtex` (`:footcite:`/`footbibliography::`, keys defined in `doc/references.bib`).
123+
- Cross-reference liberally in docstrings/docs using Sphinx roles (`:func:`, `:class:`, `:meth:`,
124+
`:attr:`, `:mod:`, `:ref:`) — but note an API element must appear in `doc/python_reference.rst`
125+
for the cross-reference to resolve.
126+
- Imports: Use absolute imports for new code (historical relative imports are tolerated in
127+
existing code). Optional/heavy deps (matplotlib, scipy, sklearn, pandas, ...) are imported lazily
128+
inside the function/method that needs them, not at module level.
129+
- Methods mutate in place and return `self`; module-level functions return copies.
130+
- No bare `*args`/`**kwargs` in signatures; no nested functions/methods (use private
131+
module-level functions instead).
132+
- Visualization: add a function in `mne.viz` and have the corresponding object method
133+
(e.g. `Epochs.plot`) call it, not the reverse. All viz functions take a `show` bool. Default
134+
colormap is `RdBu_r` for signed/zero-centered data, `Reds` otherwise.
135+
- Deprecations use the `@mne.utils.deprecated` decorator (functions/classes) or
136+
`mne.utils.warn(..., FutureWarning)` (parameters); add a test asserting the warning fires, and
137+
grep for internal call sites to update immediately rather than at end-of-cycle.
138+
- Prefer the `testing` dataset over `sample`/other large datasets in tests (smaller, faster).
139+
- Prefer to keep unit tests compact and add to existing tests when possible. The full test suite takes about an hour on CIs, so minimizing test time (for CIs) and test verbosity (for reviewers) is important.
140+
- When new functionality is added, it is good in general to add it somewhere in an example (`examples/`) or a tutorial (`tutorials/`) to help with discoverability and documentation.

CLAUDE.md

Lines changed: 1 addition & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,3 @@
11
# CLAUDE.md
22

3-
This file provides guidance to AI coding agents when working with code in this repository.
4-
5-
## What this is
6-
7-
MNE-Python is a large open-source library for exploring, analyzing, and visualizing human
8-
neurophysiological data (MEG, EEG, sEEG, ECoG, fNIRS, etc.): I/O for dozens of vendor formats,
9-
preprocessing, source estimation, time-frequency, connectivity, statistics, decoding, and 2D/3D
10-
visualization.
11-
12-
## AI-assistance policy (read first)
13-
14-
This project has an explicit policy on AI-generated contributions:
15-
16-
@CONTRIBUTING.md
17-
18-
19-
## Common commands
20-
21-
Install an editable dev environment (see `pyproject.toml` dependency groups):
22-
```bash
23-
pip install -e ".[test_extra,doc]" # or use `uv sync` with the [dependency-groups] in pyproject.toml
24-
pre-commit install --install-hooks
25-
```
26-
27-
Lint / format (ruff, codespell, yamllint, rstcheck, toml-sort, zizmor — all via pre-commit):
28-
```bash
29-
make ruff # alias for `pre-commit run -a`
30-
```
31-
32-
Run tests:
33-
```bash
34-
# whole suite (slow; needs the testing dataset, fetched automatically via pooch)
35-
pytest -m "not ultraslowtest" mne
36-
37-
# a single test file / test / by keyword
38-
pytest mne/tests/test_evoked.py::test_io_evoked --verbose
39-
pytest mne/tests/test_evoked.py -k test_io_evoked --verbose
40-
41-
# fetch datasets explicitly if needed
42-
python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
43-
python -c "import mne; mne.datasets.sample.data_path(verbose=True)
44-
45-
# useful flags: -x (stop on first failure), --pdb, --durations=5,
46-
# --cov=mne.viz --cov-report=term-missing (see which lines are covered)
47-
```
48-
49-
Docstring / doctest checks:
50-
```bash
51-
pytest mne/tests/test_docstring_parameters.py
52-
make test-doc # runs doctests across doc/ (requires sample + testing datasets, generally only needed when changing example code in doc/ itself)
53-
```
54-
55-
Build the docs (Sphinx + sphinx-gallery, in `doc/`):
56-
```bash
57-
PATTERN=some_regex_pattern make -C doc html-pattern # can choose some_regex_pattern to subselect relevant examples and tutorials to run
58-
make -C doc html # full build, takes about an hour, generally only needed if changing docs extensively
59-
```
60-
61-
Other:
62-
```bash
63-
make nesting # import-nesting checks (mne/tests/test_import_nesting.py)
64-
make clean # remove build artifacts, __pycache__, *.pyc/*.so
65-
```
66-
67-
There is no separate "build" step for the library itself beyond the editable install (pure
68-
Python + hatchling/hatch-vcs for versioning from git tags).
69-
70-
## Architecture
71-
72-
### Lazy public API via stub files
73-
`mne/__init__.py` uses `lazy_loader.attach_stub` against `mne/__init__.pyi` — the `.pyi` file is
74-
the actual source of truth for what's in `mne.__all__` and lazily importable, not the `.py` file.
75-
Many subpackages (`mne/io`, `mne/utils`, etc.) follow the same `__init__.py` + `__init__.pyi`
76-
pattern. When adding a new public function/class, it typically needs to be added to the relevant
77-
`__init__.pyi` (and, for docs, to `doc/python_reference.rst`) as well as implemented.
78-
79-
### I/O readers: one subpackage per format
80-
`mne/io/<format>/` (ant, array, artemis123, bci2k, besa, boxy, brainvision, bti, cnt, ctf, curry,
81-
edf, eeglab, egi, eximia, eyelink, fieldtrip, fil, hitachi, kit, mef, nedf, neuralynx, nicolet,
82-
nihon, nirx, nsx, persyst, snirf, ...) each implement a `read_raw_<format>` function and a
83-
format-specific `Raw<Format>` subclass of `BaseRaw` (`mne/io/base.py`). `mne/io/_read_raw.py`
84-
provides the generic `read_raw()` dispatcher. New format support follows this same shape: a
85-
subpackage with a reader function + `BaseRaw` subclass + its own `tests/` dir with small
86-
synthetic/testing-dataset-backed fixtures.
87-
88-
### FIF internals live in `mne/_fiff`, not `mne/io/fiff`
89-
Neuromag FIF is MNE's native format and many core objects (`Info`, projections, compensators,
90-
channel picking, tag/tree reading) depend on it, so that logic was pulled out of `mne/io/` into
91-
`mne/_fiff/` (private) to avoid import cycles and because it's used well beyond raw I/O.
92-
`mne/io/_fiff_wrap.py` re-exports select `mne._fiff` symbols for backward compatibility (some
93-
were previously public under `mne.io`).
94-
95-
### Core data containers and mixins
96-
`BaseRaw` (`mne/io/base.py`), `Epochs`/`BaseEpochs` (`mne/epochs.py`), and `Evoked`
97-
(`mne/evoked.py`) are the central objects; shared behavior (channel picking/renaming, filtering,
98-
cropping, projections, export) lives in mixins under `mne/channels/`, `mne/filter.py`,
99-
`mne/utils/mixin.py`, etc. and is composed via multiple inheritance rather than duplicated per
100-
class.
101-
102-
### Shared/templated docstrings
103-
Common parameter descriptions live in a central dict in `mne/utils/docs.py` and are spliced into
104-
function/method docstrings via the `@fill_doc` decorator + `%(param_name)s` placeholders — grep
105-
for `docdict[` / `@fill_doc` before writing out a parameter docstring by hand, it's likely already
106-
defined.
107-
108-
### Changelog is per-PR fragment files (towncrier), not a single hand-edited file
109-
User-facing changes need a file `doc/changes/dev/<PR-number>.<type>.rst` (types: `notable`,
110-
`dependency`, `bugfix`, `apichange`, `newfeature`, `other` — see `doc/development/contributing.rst`
111-
"Describe your changes in the changelog" section for full guidance). These get aggregated into
112-
`doc/changes/dev.rst` at release time; don't edit `doc/changes/dev.rst` or the versioned
113-
`doc/changes/vX.Y.rst` files directly for new changes. New contributors must also add themselves
114-
to `doc/changes/names.inc` (build fails otherwise) and are credited with `:newcontrib:` in their
115-
changelog entry instead of a plain name link.
116-
117-
## Code conventions (beyond what ruff enforces)
118-
119-
- Classes: `CamelCase`. Functions/variables: `snake_case`, no abbreviated names like `nsamples`.
120-
- Docstrings: numpydoc style with a few local deviations — no "optional" on kwargs with defaults,
121-
`str | None` instead of "str or None", no `Raises`/`Warns` sections, citations via
122-
`sphinxcontrib-bibtex` (`:footcite:`/`footbibliography::`, keys defined in `doc/references.bib`).
123-
- Cross-reference liberally in docstrings/docs using Sphinx roles (`:func:`, `:class:`, `:meth:`,
124-
`:attr:`, `:mod:`, `:ref:`) — but note an API element must appear in `doc/python_reference.rst`
125-
for the cross-reference to resolve.
126-
- Imports: Use absolute imports for new code (historical relative imports are tolerated in
127-
existing code). Optional/heavy deps (matplotlib, scipy, sklearn, pandas, ...) are imported lazily
128-
inside the function/method that needs them, not at module level.
129-
- Methods mutate in place and return `self`; module-level functions return copies.
130-
- No bare `*args`/`**kwargs` in signatures; no nested functions/methods (use private
131-
module-level functions instead).
132-
- Visualization: add a function in `mne.viz` and have the corresponding object method
133-
(e.g. `Epochs.plot`) call it, not the reverse. All viz functions take a `show` bool. Default
134-
colormap is `RdBu_r` for signed/zero-centered data, `Reds` otherwise.
135-
- Deprecations use the `@mne.utils.deprecated` decorator (functions/classes) or
136-
`mne.utils.warn(..., FutureWarning)` (parameters); add a test asserting the warning fires, and
137-
grep for internal call sites to update immediately rather than at end-of-cycle.
138-
- Prefer the `testing` dataset over `sample`/other large datasets in tests (smaller, faster).
139-
- Prefer to keep unit tests compact and add to existing tests when possible. The full test suite takes about an hour on CIs, so minimizing test time (for CIs) and test verbosity (for reviewers) is important.
140-
- When new functionality is added, it is good in general to add it somewhere in an example (`examples/`) or a tutorial (`tutorials/`) to help with discoverability and documentation.
3+
See @AGENTS.md for guidance on working with this repository.

0 commit comments

Comments
 (0)