Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
87ec67a
Add tools/docstring_diet.py to slim private docstrings
jtravs Nov 12, 2026
3c91766
Slim private docstrings in solprop.stepper
jtravs Nov 12, 2026
194950a
Slim private docstrings in solprop.calibration
jtravs Nov 12, 2026
84c4915
Shorten _accurate's docstring by hand, as the slimming left it
jtravs Nov 12, 2026
afcc2d7
Slim private docstrings in solprop.modes
jtravs Nov 12, 2026
476697c
Slim private docstrings in solprop.translate
jtravs Nov 12, 2026
ffbfe0c
Slim private docstrings in solprop.driver
jtravs Nov 12, 2026
a077ef5
Shorten two driver summaries by hand, as the slimming left them
jtravs Nov 12, 2026
03f6ad9
Slim private docstrings in solprop's top-level modules
jtravs Nov 12, 2026
de55c23
Restore conventions, refusals and reasons in solprop's top-level priv…
jtravs Nov 12, 2026
5621d75
Slim private docstrings in solprop.processing
jtravs Nov 12, 2026
58ba563
Restore conventions, ranges and refusal reasons in solprop.modes priv…
jtravs Nov 12, 2026
011f287
Slim private docstrings in solprop.coupling
jtravs Nov 12, 2026
485295f
Restore the zero-frequency limit rule in solprop.processing private docs
jtravs Nov 12, 2026
ce0574c
Restore resume, retention and unit notes in solprop.driver private docs
jtravs Nov 12, 2026
9b30ab1
Slim private docstrings in solprop.plotting
jtravs Nov 12, 2026
ed8c44e
Slim private docstrings in solprop.output
jtravs Nov 12, 2026
096af3a
Restore a layout note, a platform note and a hash reason in solprop.o…
jtravs Nov 12, 2026
615b3a5
Slim private docstrings in solprop.service
jtravs Nov 12, 2026
eb340ba
Restore flags, conventions and reasons in solprop.coupling private docs
jtravs Nov 12, 2026
8fb0ae5
Restore why the scan reader is picklable in solprop.service private docs
jtravs Nov 12, 2026
873f602
Slim private docstrings in solprop.nonlinear
jtravs Nov 12, 2026
cf2bf9e
Slim private docstrings in solprop.recipe
jtravs Nov 12, 2026
7790961
Shorten _length_fraction's summary and rename solve_pin's closure by …
jtravs Nov 12, 2026
cea21d0
Restore conventions and reasons in solprop.translate private docs
jtravs Nov 12, 2026
1a40933
Slim private docstrings in solprop.backends
jtravs Nov 12, 2026
2f46f19
Restore flags, conventions and warnings in solprop.nonlinear private …
jtravs Nov 12, 2026
84d7228
Slim private docstrings in solprop.physdata
jtravs Nov 12, 2026
a1d62cc
Test engineering's None and NaN text, which a dropped doctest covered
jtravs Nov 12, 2026
09964fd
Restore warning policies and conventions in solprop.physdata private …
jtravs Nov 12, 2026
9ec0de3
Slim private docstrings in solprop_native
jtravs Nov 12, 2026
4f79d9c
Restore flags, layouts and policies in solprop_native private docs
jtravs Nov 12, 2026
615c1fa
Restore conventions and reasons in solprop.backends private docs
jtravs Nov 12, 2026
10a8076
Keep the dropped private doctests' checks as unit tests
jtravs Nov 12, 2026
986c489
Merge the top-level, processing and plotting docstring slimming
jtravs Nov 12, 2026
f8c565c
Merge the translate and backends docstring slimming
jtravs Nov 12, 2026
189bdae
Capitalise Stokes and Cartesian in two slimmed docstrings
jtravs Nov 12, 2026
49455d6
Merge the driver, output, service and recipe docstring slimming
jtravs Nov 12, 2026
67e0332
Restore Taylor's capital in three solprop.driver bullets
jtravs Nov 12, 2026
9a7e359
Merge the driver capitalisation fix
jtravs Nov 12, 2026
7acf8f3
Restore capitals the slimming lowered in group C bullets
jtravs Nov 12, 2026
768078c
Merge the modes, coupling, nonlinear, physdata and native docstring s…
jtravs Nov 12, 2026
9f3b6f8
Give public properties one-line summaries, no Returns sections
jtravs Nov 12, 2026
f6c6c39
Fold units into property summaries and drop restated returns
jtravs Nov 12, 2026
12ce9d9
Tighten the size ratchets to the slimmed docstrings
jtravs Nov 12, 2026
4d6c7f1
Remove the docstring diet tool; the size ratchet holds the rule
jtravs Nov 12, 2026
32a5e28
Narrow two new tests' types for basedpyright
jtravs Nov 12, 2026
efd194a
Merge the lean-rules review fixes
jtravs Nov 12, 2026
3756084
Merge main (frozen copies, lean rules) into the docstring diet
jtravs Nov 12, 2026
23eb149
Drop docstring bullets that only restate the annotation
jtravs Nov 12, 2026
c03684d
Give the native public properties the one-line property docstring
jtravs Nov 12, 2026
89ff772
Give the Protocol property stubs noun-phrase summaries
jtravs Nov 12, 2026
4e90a96
Name the effective-area path's unit once
jtravs Nov 12, 2026
2333c64
Test the even chunk and the display tail the diet's examples showed
jtravs Nov 12, 2026
e1c4ba4
Keep the name of the closure gnlse_source returns
jtravs Nov 12, 2026
f258410
Say when a nested function takes a leading underscore
jtravs Nov 12, 2026
a2a7b7b
Start four property summaries with "The" so numpydoc reads no verb
jtravs Nov 12, 2026
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
12 changes: 7 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,15 @@ validity range is cited to its primary source; say what you verified and what yo
as doctests ⚙. A frozen dataclass documents its fields under `Attributes`. A public
property has a one-line docstring naming the quantity and unit, with
`# numpydoc ignore=RT01` on the `def` line.
- **Private code** — any name with a single-underscore component, which numpydoc skips ⚙;
a nested function's name starts with an underscore, so it is private too — has no
`Parameters`, `Returns`, `Yields`, `Raises` or `Examples` sections (`poe size-check`
caps those left ⚙): one summary line, then only what
- **Private code** — any name with a single-underscore component, which numpydoc skips ⚙
— has no `Parameters`, `Returns`, `Yields`, `Raises` or `Examples` sections
(`poe size-check` caps those left ⚙): one summary line, then only what
the signature and annotations don't say — a unit, a valid range, a condition, a
convention, or why it exists. A function whose name and signature say everything needs
no docstring; a non-obvious inner function gets a one-line comment.
no docstring; a non-obvious inner function gets a one-line comment. A nested function
is private. numpydoc still checks one without a leading underscore, so a nested
function that takes parameters or returns a value is named with a leading underscore
unless it is returned to callers.
- Comments explain **why**, never **what**: the physics (or the page with the derivation),
the numerics (why this quadrature, cutoff or tolerance; where precision is lost), sign,
unit and normalisation choices, references (DOI, equation), and anything a reader would
Expand Down
4 changes: 2 additions & 2 deletions docs/dev/tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ files and functions; `noqa` comments by rule; private names imported across pack
`__all__` lines; cloned code (windows of 50 tokens seen twice, with names renamed and as
written) with the file pairs that share most; and ruff's complexity counts. A name is
private by exactly the rule numpydoc's validation excludes (a single-underscore component
of `module.qualname`), so the report and `poe docstrings` agree; a nested function is private
when its name starts with an underscore, as `AGENTS.md` asks.
of `module.qualname`), so the report and `poe docstrings` agree; both count a nested
function as private only when its name starts with an underscore.

`poe size-check`, in `poe check` and CI's static job, holds `src/solprop` to the ratchets in
`tools/size_budget.toml`: the number of private docstrings with numpydoc sections, a
Expand Down
17 changes: 2 additions & 15 deletions native/src/solprop_native/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,16 +875,6 @@ def _source_digest(root: Path) -> str:
``CMakeLists.txt`` and each C++ source and header under ``src`` and ``include``, the
paths relative to `root` and sorted bytewise, and the digest is the SHA-256 of the
record.

Parameters
----------
root
The ``native`` directory of a checkout.

Returns
-------
str
The digest in lowercase hexadecimal.
"""
paths = ["CMakeLists.txt"]
for folder in ("src", "include"):
Expand All @@ -905,11 +895,8 @@ def _source_digest(root: Path) -> str:
def _checkout_digest() -> str | None:
"""Return this editable checkout's source digest, computed once per process.

Returns
-------
str or None
The digest, or ``None`` for an installed wheel, which has no sources beside it
and which solprop's metadata pins to its own version.
- Returns: the digest, or ``None`` for an installed wheel, which has no sources
beside it and which solprop's metadata pins to its own version.
"""
root = Path(__file__).parents[2]
return _source_digest(root) if (root / "CMakeLists.txt").is_file() else None
Expand Down
8 changes: 1 addition & 7 deletions native/src/solprop_native/_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,7 @@ def record(self) -> dict[str, object]:

@classmethod
def read(cls, data: Mapping[str, object]) -> AllocationClass:
"""Read a class written by :meth:`record`.

Raises
------
ValueError
When `data` is not a class.
"""
"""Read a class written by :meth:`record`."""
try:
kinds = data["kinds"]
quota = data.get("quota")
Expand Down
52 changes: 8 additions & 44 deletions native/src/solprop_native/_budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,9 @@ def _read_cgroup_cpus(root: Path) -> int | None:
def cores_in_masks(masks: Sequence[int], cpus: Sequence[int]) -> int:
"""Count the cores, given as CPU bitmasks, that hold any of ``cpus``.

Parameters
----------
masks : sequence of int
One bitmask per physical core: bit ``n`` set when CPU ``n`` is one of its
hardware threads.
cpus : sequence of int
The CPU indices the process may run on.

Returns
-------
int
The number of cores holding at least one of ``cpus``.
- ``masks``: one bitmask per physical core: bit ``n`` set when CPU ``n`` is one of
its hardware threads.
- Returns: the number of cores holding at least one of ``cpus``.
"""
wanted = sum(1 << cpu for cpu in cpus)
return sum(1 for mask in masks if mask & wanted)
Expand All @@ -118,17 +109,8 @@ def cores_in_masks(masks: Sequence[int], cpus: Sequence[int]) -> int:
def _linux_cores(cpus: Sequence[int], root: Path) -> int | None:
"""Count the distinct (package, core) pairs of ``cpus`` in a sysfs CPU tree.

Parameters
----------
cpus : sequence of int
The CPU indices the process may run on.
root : Path
The sysfs CPU directory, ``/sys/devices/system/cpu`` on a running system.

Returns
-------
int or None
The number of physical cores, or ``None`` if any CPU's topology is unreadable.
- Returns: the number of physical cores, or ``None`` if any CPU's topology is
unreadable.
"""
pairs: set[tuple[str, str]] = set()
for cpu in cpus:
Expand All @@ -148,15 +130,7 @@ def _linux_cores(cpus: Sequence[int], root: Path) -> int | None:
def _windows_cores(cpus: Sequence[int]) -> int | None: # pragma: no cover - Windows
"""Count the physical cores holding ``cpus`` from Windows' processor table.

Parameters
----------
cpus : sequence of int
The CPU indices the process may run on (processor group 0).

Returns
-------
int or None
The number of physical cores, or ``None`` if the table cannot be read.
- Returns: the number of physical cores, or ``None`` if the table cannot be read.
"""
import ctypes

Expand Down Expand Up @@ -198,18 +172,8 @@ def physical_cores(
reads each CPU's package and core from ``root``; Windows asks the kernel. macOS on
Apple silicon has one thread per core, so the CPUs are the cores.

Parameters
----------
cpus : sequence of int
The CPU indices the process may run on.
root : Path, optional
The sysfs CPU directory, read on Linux.

Returns
-------
int or None
The number of physical cores, or ``None`` on other platforms or when the
topology cannot be read.
- Returns: the number of physical cores, or ``None`` on other platforms or when the
topology cannot be read.
"""
if sys.platform.startswith("linux"):
return _linux_cores(cpus, root)
Expand Down
39 changes: 7 additions & 32 deletions native/src/solprop_native/_counters.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,11 @@ def march(
) -> None:
"""Count one native march call from its returned rows.

Parameters
----------
kind : str
The march, ``adams_march`` or ``rk_march``.
reason : str
The call's ``march::Reason``, by name.
rows : numpy.ndarray
The call's attempt rows, the accepted flag in column 3.
due : dict
Accepted steps from the call's start to each piece of the driver's work,
by name, as the call's ``host_step`` bound was formed.
read_at : float or None
The transverse edge's next read, if the call was bounded by one.
- ``kind``: the march, ``adams_march`` or ``rk_march``.
- ``rows``: the call's attempt rows, the accepted flag in column 3.
- ``due``: accepted steps from the call's start to each piece of the driver's
work, by name, as the call's ``host_step`` bound was formed.
- ``read_at``: the transverse edge's next read, if the call was bounded by one.
"""
accepted = int(np.count_nonzero(rows[:, 3])) if rows.size else 0
self.march_calls[kind] += 1
Expand Down Expand Up @@ -191,25 +183,8 @@ def session_batch(
) -> None:
"""Count one batch a native session returned from ``advance``.

Parameters
----------
event : str
Its event's kind: ``observation``, ``snapshot``, ``warning``,
``terminal``, or ``progress:`` and its cause.
attempts : int
The attempts its chunk carries.
accepted : int
The accepted steps among them.
rows : int, optional
The periodic rows its chunk carries.
evaluations : int, optional
The statistics evaluations it carries: its rows and its plane statistics.
plane : bool, optional
Whether it is an observation after the launch.
march : str, optional
The session's march, for its native march calls.
calls : int, optional
The native march calls the ``advance`` made.
- ``event``: its event's kind: ``observation``, ``snapshot``, ``warning``,
``terminal``, or ``progress:`` and its cause.
"""
self.returns[f"session_{event}"] += 1
self.march_attempts += attempts
Expand Down
Loading
Loading