From 3ccab898a17875bc090a490e05ae01a02f899b13 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 24 Jun 2026 12:00:59 -0400 Subject: [PATCH 1/2] Add ExplicitImports.jl QA via SciMLTesting run_qa (all 6 checks green) Wire LabelledArrays' QA group through SciMLTesting's `run_qa` with the `explicit_imports = true` option, enabling all six ExplicitImports.jl checks (no_implicit_imports, no_stale_explicit_imports, all_explicit_imports_via_owners, all_qualified_accesses_via_owners, all_qualified_accesses_are_public, all_explicit_imports_are_public) and making them pass on both the 1.10 LTS and Julia 1. Fixes (FIX > DECLARE-PUBLIC > minimal-IGNORE): * no_implicit_imports: replace the blanket `using LinearAlgebra, StaticArrays, ArrayInterface` / `using MacroTools` / `using PrecompileTools` with explicit `using X: X, names...` imports (StaticArrays names: MArray, SArray, Size, SOneTo, StaticArray, StaticVector; PrecompileTools: @setup_workload, @compile_workload). * Remove three self-qualified `LabelledArrays.` accesses (LAStyle, symnames, LArray) so the module references its own names directly. * Fix a latent self-referential `where {SOneTo <: SOneTo}` in `Base.reshape` for SLArray (it only resolved because `using StaticArrays` leaked the global `SOneTo` as the typevar bound); now `SOneTo` is explicitly imported and the signature uses the concrete `StaticArrays.SOneTo` UnionAll directly. * deps_compat: add the missing `LinearAlgebra` `[compat]` entry, so that Aqua check now passes (was previously disabled). The remaining non-public qualified accesses are genuine method-extension points or non-public dependency/Base internals with no public alternative; they are ignore-listed per-check (documented + minimal) rather than worked around. Replaces the previous bare Aqua/JET `qa.jl` (which used `@test_broken false` markers) with `run_qa`; the pre-existing Aqua ambiguities/unbound_args/ undefined_exports findings and the JET `setfield!`-on-immutable-LArray finding (all tracked in SciML/LabelledArrays.jl#205) are carried forward via `aqua_kwargs`/JET-opt-out, no longer as `@test_broken`. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 3 +- src/LabelledArrays.jl | 8 ++++-- src/larray.jl | 6 ++-- src/precompilation.jl | 2 +- src/slarray.jl | 5 +--- test/qa/Project.toml | 9 ++++-- test/qa/qa.jl | 67 +++++++++++++++++++++++++++++-------------- 7 files changed, 64 insertions(+), 36 deletions(-) diff --git a/Project.toml b/Project.toml index cd9951d..74fe072 100644 --- a/Project.toml +++ b/Project.toml @@ -21,6 +21,7 @@ ChainRulesCore = "1.26" ChainRulesTestUtils = "1" ForwardDiff = "1.1" InteractiveUtils = "1" +LinearAlgebra = "1" MacroTools = "0.5.16" OrdinaryDiffEq = "6, 7" PreallocationTools = "1.2" @@ -28,7 +29,7 @@ PrecompileTools = "1.2.1" RecursiveArrayTools = "3.54, 4" SafeTestsets = "0.1, 1" SciMLBase = "2, 3" -SciMLTesting = "1" +SciMLTesting = "1.4" StaticArrays = "1.9.18" Test = "1" julia = "1.10" diff --git a/src/LabelledArrays.jl b/src/LabelledArrays.jl index 577aae5..a51c8a9 100644 --- a/src/LabelledArrays.jl +++ b/src/LabelledArrays.jl @@ -1,6 +1,8 @@ module LabelledArrays -using LinearAlgebra, StaticArrays, ArrayInterface +using LinearAlgebra: LinearAlgebra +using StaticArrays: StaticArrays, MArray, SArray, Size, SOneTo, StaticArray, StaticVector +using ArrayInterface: ArrayInterface import RecursiveArrayTools, PreallocationTools, ForwardDiff include("slarray.jl") @@ -21,7 +23,7 @@ include("diffeqarray.jl") end end -using MacroTools +using MacroTools: MacroTools struct PrintWrapper{T, N, F, X <: AbstractArray{T, N}} <: AbstractArray{T, N} f::F @@ -84,7 +86,7 @@ function PreallocationTools.get_tmp( PreallocationTools.enlargediffcache!(dc, nelem) end _x = ArrayInterface.restructure(dc.du, reinterpret(T, view(dc.dual_du, 1:nelem))) - return LabelledArrays.LArray{T, N, D, Syms}(_x) + return LArray{T, N, D, Syms}(_x) end export SLArray, LArray, SLVector, LVector, @SLVector, @LArray, @LVector, @SLArray diff --git a/src/larray.jl b/src/larray.jl index cd806cd..5be8ed2 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -171,8 +171,8 @@ struct LAStyle{T, N, L} <: Broadcast.AbstractArrayStyle{N} end LAStyle{T, N, L}(x::Val{i}) where {T, N, L, i} = LAStyle{T, N, L}() Base.BroadcastStyle(::Type{LArray{T, N, D, L}}) where {T, N, D, L} = LAStyle{T, N, L}() function Base.BroadcastStyle( - ::LabelledArrays.LAStyle{T, N, L}, - ::LabelledArrays.LAStyle{E, N, L} + ::LAStyle{T, N, L}, + ::LAStyle{E, N, L} ) where {T, E, N, L} return LAStyle{promote_type(T, E), N, L}() end @@ -388,7 +388,7 @@ function SLArray( end function Base.vcat(x::LArray, y::LArray) - return LArray{(LabelledArrays.symnames(typeof(x))..., LabelledArrays.symnames(typeof(y))...)}( + return LArray{(symnames(typeof(x))..., symnames(typeof(y))...)}( vcat( x.__x, y.__x diff --git a/src/precompilation.jl b/src/precompilation.jl index 69b7008..86b7c33 100644 --- a/src/precompilation.jl +++ b/src/precompilation.jl @@ -1,4 +1,4 @@ -using PrecompileTools +using PrecompileTools: @setup_workload, @compile_workload @setup_workload begin @compile_workload begin diff --git a/src/slarray.jl b/src/slarray.jl index c423156..4da75d1 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -352,9 +352,6 @@ end function Base.reshape( x::SLArray{S, T, N, L, Syms}, ax::Tuple{SOneTo, Vararg{SOneTo}} - ) where { - S <: Tuple, T, N, L, Syms, - SOneTo <: SOneTo, - } + ) where {S <: Tuple, T, N, L, Syms} return SLArray{S, T, N, L, Syms}(reshape(x.__x, ax)) end diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 34dc3e1..cc73f81 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,8 +1,9 @@ [deps] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" -JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [sources] @@ -10,6 +11,8 @@ LabelledArrays = {path = "../.."} [compat] Aqua = "0.8" -JET = "0.9,0.10,0.11" +ExplicitImports = "1.9" +SafeTestsets = "0.1, 1" +SciMLTesting = "1.4" Test = "1" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 5f13559..2c4b149 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,26 +1,51 @@ using LabelledArrays -using Aqua -using JET -using Test +using Aqua: Aqua +using ExplicitImports: ExplicitImports +using SciMLTesting: SciMLTesting, run_qa -@testset "Aqua" begin - # ambiguities / unbound_args / undefined_exports / deps_compat disabled: - # genuine Aqua findings tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 - Aqua.test_all( - LabelledArrays; +# Aqua: ambiguities / unbound_args / undefined_exports are genuine pre-existing +# findings (method ambiguities, unbound type parameters, and the dead exports +# `@SLSliced`/`@LSliced`/`dimSymbols`/`rowSymbols`/`colSymbols`) tracked in +# https://github.com/SciML/LabelledArrays.jl/issues/205. JET likewise finds the +# `setfield!`-on-immutable-`LArray` dead branch in `setproperty!` (src/larray.jl) +# tracked in the same issue, so JET stays opt-out here. The remaining Aqua checks +# (incl. deps_compat) run and pass. +# +# ExplicitImports ignore-list (all_qualified_accesses_are_public): every entry is a +# non-public name from a dependency (or Base) that LabelledArrays must access by +# qualification because there is no public alternative — either a method-extension +# definition of a non-public function, or a non-public type/function used directly: +# @_propagate_inbounds_meta, print_array, dataids, BroadcastStyle, AbstractArrayStyle, +# Broadcasted -> Base / Base.Broadcast internals (broadcast + indexing machinery) +# @forward -> MacroTools (method forwarding) +# Dual -> ForwardDiff (DiffCache eltype) +# LU, size_tuple -> StaticArrays internals +# can_setindex, ismutable, restructure, undefmatrix -> ArrayInterface trait methods +# enlargediffcache! -> PreallocationTools internal +# The trailing four (@propagate_inbounds, OneTo, elsize, unsafe_convert) are Base names +# that are `public` on Julia 1.11+ but, because the `public` keyword predates the LTS, +# read as non-public to ExplicitImports on the 1.10 LTS — they are ignored only to keep +# the LTS QA lane green; on 1.11+ they are genuinely public. +run_qa( + LabelledArrays; + Aqua = Aqua, + aqua_kwargs = (; ambiguities = false, unbound_args = false, undefined_exports = false, - deps_compat = false, - ) - @test_broken false # Aqua ambiguities: method ambiguities found — tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 - @test_broken false # Aqua unbound_args: unbound type parameters found — tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 - @test_broken false # Aqua undefined_exports: undefined exports found — tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 - @test_broken false # Aqua deps_compat: missing compat (deps + extras) — tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 -end - -@testset "JET" begin - # JET finds setfield! on immutable LArray in setproperty!(::LArray, ::Symbol, ::Any). - # Tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 - @test_broken false # JET: setfield! immutable LArray in setproperty! (src/larray.jl:96) — tracked in https://github.com/SciML/LabelledArrays.jl/issues/205 -end + ), + ExplicitImports = ExplicitImports, + explicit_imports = true, + ei_kwargs = (; + all_qualified_accesses_are_public = (; + ignore = ( + Symbol("@_propagate_inbounds_meta"), Symbol("@forward"), + :AbstractArrayStyle, :BroadcastStyle, :Broadcasted, :Dual, :LU, + :can_setindex, :dataids, :enlargediffcache!, :ismutable, :print_array, + :restructure, :size_tuple, :undefmatrix, + # public on 1.11+, read as non-public on the 1.10 LTS only: + Symbol("@propagate_inbounds"), :OneTo, :elsize, :unsafe_convert, + ), + ), + ), +) From 98359d9acaa44927e1ba6471522bb4ca36e3a430 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 24 Jun 2026 21:20:40 -0400 Subject: [PATCH 2/2] Simplify QA to SciMLTesting v1.5 run_qa minimal form SciMLTesting 1.5.0 makes Aqua and ExplicitImports its own direct dependencies and run_qa auto-detects them, so the per-repo qa.jl collapses to the genuine overrides: * Drop the `Aqua = Aqua` / `ExplicitImports = ExplicitImports` module arguments (auto-detected) and the now-transitive Aqua/ExplicitImports entries from test/qa/Project.toml [deps]/[compat]. * Keep `explicit_imports = true` (still opt-in in v1.5) plus the genuine per-repo `aqua_kwargs` (ambiguities/unbound_args/undefined_exports opt-outs, tracked in #205) and `ei_kwargs` ignore-list. * JET stays opt-out (not loaded), matching prior behavior. * Bump SciMLTesting compat to 1.5 (root + test/qa). Verified locally against the released SciMLTesting 1.5.0 via the CI harness (activate_group_env) on Julia 1.10 and 1.11: Quality Assurance runs the same 14 checks as before (Aqua's 8 + the 6 ExplicitImports checks, no JET) and passes 14/14. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 +- test/qa/Project.toml | 6 +----- test/qa/qa.jl | 11 +++-------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Project.toml b/Project.toml index 74fe072..2c51e95 100644 --- a/Project.toml +++ b/Project.toml @@ -29,7 +29,7 @@ PrecompileTools = "1.2.1" RecursiveArrayTools = "3.54, 4" SafeTestsets = "0.1, 1" SciMLBase = "2, 3" -SciMLTesting = "1.4" +SciMLTesting = "1.5" StaticArrays = "1.9.18" Test = "1" julia = "1.10" diff --git a/test/qa/Project.toml b/test/qa/Project.toml index cc73f81..01a9f5a 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,6 +1,4 @@ [deps] -Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" -ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" @@ -10,9 +8,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" LabelledArrays = {path = "../.."} [compat] -Aqua = "0.8" -ExplicitImports = "1.9" SafeTestsets = "0.1, 1" -SciMLTesting = "1.4" +SciMLTesting = "1.5" Test = "1" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 2c4b149..b1db123 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,15 +1,12 @@ -using LabelledArrays -using Aqua: Aqua -using ExplicitImports: ExplicitImports -using SciMLTesting: SciMLTesting, run_qa +using SciMLTesting, LabelledArrays, Test # Aqua: ambiguities / unbound_args / undefined_exports are genuine pre-existing # findings (method ambiguities, unbound type parameters, and the dead exports # `@SLSliced`/`@LSliced`/`dimSymbols`/`rowSymbols`/`colSymbols`) tracked in # https://github.com/SciML/LabelledArrays.jl/issues/205. JET likewise finds the # `setfield!`-on-immutable-`LArray` dead branch in `setproperty!` (src/larray.jl) -# tracked in the same issue, so JET stays opt-out here. The remaining Aqua checks -# (incl. deps_compat) run and pass. +# tracked in the same issue, so JET stays opt-out here (JET is not loaded). The +# remaining Aqua checks (incl. deps_compat) run and pass. # # ExplicitImports ignore-list (all_qualified_accesses_are_public): every entry is a # non-public name from a dependency (or Base) that LabelledArrays must access by @@ -28,13 +25,11 @@ using SciMLTesting: SciMLTesting, run_qa # the LTS QA lane green; on 1.11+ they are genuinely public. run_qa( LabelledArrays; - Aqua = Aqua, aqua_kwargs = (; ambiguities = false, unbound_args = false, undefined_exports = false, ), - ExplicitImports = ExplicitImports, explicit_imports = true, ei_kwargs = (; all_qualified_accesses_are_public = (;