From 88bb41c9a378e457e1f5bba76dc2a2e1f9226b79 Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Wed, 23 Sep 2026 10:40:24 +0200 Subject: [PATCH 1/4] Add Aqua to the suite and a docstring on every exported name Aqua.test_all runs inside its own @testset, so a failing check fails the suite. Particle and ParticleList get docstrings; the docs build checks exported names with checkdocs = :exports. Co-Authored-By: Claude Opus 5.5 --- Project.toml | 4 +++- docs/make.jl | 1 + src/particle.jl | 18 ++++++++++++++++++ src/particle_list.jl | 19 +++++++++++++++++++ test/runtests.jl | 5 +++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d5276e9..b87b61b 100644 --- a/Project.toml +++ b/Project.toml @@ -7,15 +7,17 @@ version = "0.1.2" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" [compat] +Aqua = "0.8" HDF5 = "0.16, 0.17" StaticArrays = "1" Test = "1" julia = "1.10" [extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["HDF5", "StaticArrays", "Test"] +test = ["Aqua", "HDF5", "StaticArrays", "Test"] diff --git a/docs/make.jl b/docs/make.jl index 3a12296..10e9879 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -6,6 +6,7 @@ makedocs(; authors = "Michael Kraus", repo = "https://github.com/JuliaGNI/ParticleMethods.jl/blob/{commit}{path}#L{line}", sitename = "ParticleMethods.jl", + checkdocs = :exports, format = Documenter.HTML(; prettyurls = get(ENV, "CI", "false") == "true", canonical = "https://juliagni.github.io/ParticleMethods.jl", diff --git a/src/particle.jl b/src/particle.jl index fee182d..8683f1a 100644 --- a/src/particle.jl +++ b/src/particle.jl @@ -1,6 +1,24 @@ import Base.hasproperty, Base.getproperty +""" + Particle(state; variables = NamedTuple(), parameters = NamedTuple()) + Particle(DT, len; variables = NamedTuple(), parameters = NamedTuple()) + +A particle with the state vector `state`, or a zero state of element type `DT` and length `len`. + +`variables` maps names to indices or index ranges into `state`, and `parameters` maps names to +values. Each name is a property of the particle: `p.x` is a view into `state` for a variable `x`, +and the stored value for a parameter. The names must not repeat each other or the field names +`state`, `views` and `params`. + +# Example + +```julia +p = Particle(Float64, 7; variables = (x = 1:3, v = 4:6, w = 7)) +p.x # view(p.state, 1:3) +``` +""" struct Particle{T, ST <: AbstractVector{T}, VT <: NamedTuple, PT <: NamedTuple} state::ST views::VT diff --git a/src/particle_list.jl b/src/particle_list.jl index 6ec242e..d3c3893 100644 --- a/src/particle_list.jl +++ b/src/particle_list.jl @@ -7,6 +7,25 @@ _sort_names(::NamedTuple{N, T}) where {N, T} = Tuple(sort([N...])) _sort_ntuple(nt::NamedTuple) = NamedTuple{_sort_names(nt)}(nt) +""" + ParticleList(list::AbstractMatrix; variables = NamedTuple(), parameters = NamedTuple()) + ParticleList(DT, np, nd; variables = NamedTuple(), parameters = NamedTuple()) + ParticleList(x, v, w; parameters = NamedTuple()) + ParticleList(h5::H5DataStore, path = "/") + ParticleList(fpath::AbstractString, path = "/") + +A list of particles, stored as the columns of the matrix `list`. Each column is the state of one +particle, and `pl[i]` is that particle as a [`Particle`](@ref). + +`variables` maps names to row indices or row ranges of `list`, and `parameters` maps names to +values. Each name is a property of the list: `pl.x` is a view into the rows of a variable `x` for +all particles, and the stored value for a parameter. + +The second form makes a zero list of element type `DT` with `np` particles of `nd` components. +The third form stacks positions `x`, velocities `v` and weights `w`, and defines the variables +`x`, `v`, `z` (positions and velocities) and `w`. The last two forms read a list that `h5save` +wrote, from a group `path` of an HDF5 file or from the file at `fpath`. +""" struct ParticleList{T, ST <: AbstractMatrix{T}, VT <: NamedTuple, PT <: NamedTuple, PART <: AbstractVector, VART <: NamedTuple, IND <: NamedTuple} list::ST diff --git a/test/runtests.jl b/test/runtests.jl index 590cc45..6e0ce4b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,14 @@ using ParticleMethods using Test +using Aqua: Aqua using StaticArrays: MVector @testset "ParticleMethods.jl" begin + @testset "Aqua" begin + Aqua.test_all(ParticleMethods) + end + @testset "Particles" begin include("particle_tests.jl") end From 3e40831031b1575db94c339e2e5cd6f3ccf0b645 Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Wed, 23 Sep 2026 10:49:41 +0200 Subject: [PATCH 2/4] Add a docstring to the ParticleMethods module Julia counts the module name as exported, so it needs a docstring for every exported name to carry one. Base.Docs.undocumented_names is now empty. Co-Authored-By: Claude Opus 5.5 --- src/ParticleMethods.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ParticleMethods.jl b/src/ParticleMethods.jl index f2f7a85..67b86ca 100644 --- a/src/ParticleMethods.jl +++ b/src/ParticleMethods.jl @@ -1,3 +1,9 @@ +""" + ParticleMethods + +Data structures for particles and particle lists: [`Particle`](@ref) and +[`ParticleList`](@ref), with named access to parts of the state and to parameters. +""" module ParticleMethods using HDF5 From e781f8083297c566eead085b4784eeae10bc39ac Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Wed, 23 Sep 2026 11:30:56 +0200 Subject: [PATCH 3/4] Keep Documenter's default checkdocs, and record the Aqua and docstring work checkdocs = :exports narrows the check to exported names, and Documenter 1.19.0 walks only Docs.meta, so an export without a docstring passes under either setting. The default :all checks at least as many names, so the narrower setting goes. The docs build passes with it. The CHANGELOG records Aqua and the three new docstrings. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 8 ++++++++ docs/make.jl | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d10ea2..bcdb6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,14 @@ first entry is written. - **`Base.iterate(pl::ParticleList, state)` forwards to `pl.particles`.** One method covers the first and the later steps, and the state is the state of `iterate` over the particle vector: the index of the next particle, not of the last one. +- **Aqua.jl 0.8 added as a test dependency.** `Aqua.test_all(ParticleMethods)` runs inside + its own `@testset "Aqua"` in `test/runtests.jl`, so a failing check fails the suite. All + 11 checks pass with Aqua 0.8.18, among them undefined exports, piracy, ambiguities and + stale dependencies. +- **Docstrings written for the module, `Particle` and `ParticleList`.** These were the only + exported names without one (`eachparticle` had one). + `Base.Docs.undocumented_names(ParticleMethods)` is now empty, and the library page renders + all four. ### Bug Fixes diff --git a/docs/make.jl b/docs/make.jl index 10e9879..3a12296 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -6,7 +6,6 @@ makedocs(; authors = "Michael Kraus", repo = "https://github.com/JuliaGNI/ParticleMethods.jl/blob/{commit}{path}#L{line}", sitename = "ParticleMethods.jl", - checkdocs = :exports, format = Documenter.HTML(; prettyurls = get(ENV, "CI", "false") == "true", canonical = "https://juliagni.github.io/ParticleMethods.jl", From c3588fa41ad8d58432e4448437902c122d2d987d Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Wed, 23 Sep 2026 11:35:42 +0200 Subject: [PATCH 4/4] State the name rule in the ParticleList docstring The constructor asserts that variable and parameter names are disjoint from each other and from the struct's field names. The Particle docstring already states its rule; ParticleList's now does too. Co-Authored-By: Claude Opus 5.5 --- src/particle_list.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/particle_list.jl b/src/particle_list.jl index d3c3893..50ef860 100644 --- a/src/particle_list.jl +++ b/src/particle_list.jl @@ -19,7 +19,8 @@ particle, and `pl[i]` is that particle as a [`Particle`](@ref). `variables` maps names to row indices or row ranges of `list`, and `parameters` maps names to values. Each name is a property of the list: `pl.x` is a view into the rows of a variable `x` for -all particles, and the stored value for a parameter. +all particles, and the stored value for a parameter. The names must not repeat each other or the +field names `list`, `views`, `params`, `particles`, `variables` and `indices`. The second form makes a zero list of element type `DT` with `np` particles of `nd` components. The third form stacks positions `x`, velocities `v` and weights `w`, and defines the variables