Skip to content

Commit a89be9d

Browse files
mag-asteraclaude
andcommitted
style(runs): NumPy-style docstrings + frozen dataclasses
Aligns the new sampleworks.runs module with project style policy (AGENTS.md L7 and L338): - Add NumPy-style docstrings (summary, Parameters, Returns, Raises) to every public and private function/class across schema.py, loader.py, runner.py, and cli.py. - Mark Job, Preset, JobInvocation, and _RunningJob as @DataClass(frozen=True). Behavior is preserved: Preset.effective_args already returns a fresh dict, and the runner mutates that local copy rather than the Preset itself. All 32 unit tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d5d065a commit a89be9d

4 files changed

Lines changed: 553 additions & 18 deletions

File tree

src/sampleworks/runs/cli.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@
1212

1313

1414
def main(argv: list[str] | None = None) -> int:
15+
"""Entry point for the ``sampleworks-runs`` console script.
16+
17+
Parameters
18+
----------
19+
argv : list of str or None, optional
20+
Command-line arguments excluding the program name. When ``None``
21+
(the default), :mod:`argparse` reads from :data:`sys.argv`.
22+
23+
Returns
24+
-------
25+
int
26+
Exit code suitable for ``sys.exit``: ``0`` on success, non-zero on
27+
job failure or fatal CLI error.
28+
"""
1529
parser = _build_parser()
1630
args = parser.parse_args(argv)
1731

@@ -36,6 +50,13 @@ def main(argv: list[str] | None = None) -> int:
3650

3751

3852
def _build_parser() -> argparse.ArgumentParser:
53+
"""Construct the :mod:`argparse` parser for ``sampleworks-runs``.
54+
55+
Returns
56+
-------
57+
argparse.ArgumentParser
58+
Parser covering preset selection, overrides, and execution flags.
59+
"""
3960
parser = argparse.ArgumentParser(
4061
prog="sampleworks-runs",
4162
description=(
@@ -78,6 +99,26 @@ def _build_parser() -> argparse.ArgumentParser:
7899

79100

80101
def _filter_only(preset: Preset, only: str) -> Preset:
102+
"""Return a new :class:`Preset` containing only the named jobs.
103+
104+
Parameters
105+
----------
106+
preset : Preset
107+
Source preset.
108+
only : str
109+
Comma-separated list of job names to keep.
110+
111+
Returns
112+
-------
113+
Preset
114+
New preset with the same ``description``, ``defaults``, and
115+
``shared_args`` and only the filtered jobs.
116+
117+
Raises
118+
------
119+
SystemExit
120+
If any name in ``only`` does not match a job in ``preset``.
121+
"""
81122
names = [n.strip() for n in only.split(",") if n.strip()]
82123
keep = [j for j in preset.jobs if j.name in names]
83124
missing = set(names) - {j.name for j in keep}
@@ -93,6 +134,13 @@ def _filter_only(preset: Preset, only: str) -> Preset:
93134

94135

95136
def _print_show(preset: Preset) -> None:
137+
"""Print a human-readable rendering of a resolved preset to stdout.
138+
139+
Parameters
140+
----------
141+
preset : Preset
142+
Resolved preset to display (used by ``--show``).
143+
"""
96144
print(f"name: {preset.name}")
97145
if preset.description:
98146
print(f"description: {preset.description}")
@@ -112,6 +160,23 @@ def _print_show(preset: Preset) -> None:
112160

113161

114162
def _default_results_dir(preset: Preset) -> str:
163+
"""Pick a sensible default ``--results-dir`` when none is given.
164+
165+
Order of preference:
166+
1. The preset's ``[defaults]`` ``RESULTS_DIR``.
167+
2. The ``RESULTS_DIR`` environment variable.
168+
3. ``./grid_search_results``.
169+
170+
Parameters
171+
----------
172+
preset : Preset
173+
Resolved preset (its ``defaults`` have already been merged with env).
174+
175+
Returns
176+
-------
177+
str
178+
Path to use as the run's root output directory.
179+
"""
115180
return (
116181
preset.defaults.get("RESULTS_DIR")
117182
or os.environ.get("RESULTS_DIR")

0 commit comments

Comments
 (0)