From c9d8c7aef0724c1153f310128f30e876ad189a08 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Thu, 25 Jun 2026 08:31:27 -0400 Subject: [PATCH 1/4] QA: run_qa v1.6 form + ExplicitImports Convert the hand-rolled test/qa/qa.jl Aqua + ExplicitImports body to the SciMLTesting 1.6 `run_qa` form with `explicit_imports = true`. - Aqua: `Aqua.test_all(...; ambiguities = false)` + a separate `test_ambiguities(...; recursive = false)` becomes `aqua_kwargs = (; ambiguities = (; recursive = false))`, preserving the intent (no recursive ambiguities sweep into deps, only the package's own). - ExplicitImports: now runs all six checks (the prior body ran only three and never the two public-API checks). The newly-surfaced public-API findings are other packages' not-yet-public names, ignored with documented per-source lists (SciMLBase / Base / LuxCore / Lux.LuxOps / CommonSolve). No @test_broken needed: 0 hard fails on lts and latest. - Doctests testset kept as-is (run_qa does not cover doctests). - Deps: qa env drops ExplicitImports (transitive via SciMLTesting), plus the now-unused SafeTestsets and SciMLSensitivity; keeps Aqua (the ambiguities child-process check needs Aqua a direct dep); SciMLTesting compat -> "1.6". Root Project.toml drops the now-unused ExplicitImports test extra and bumps SciMLTesting compat -> "1.6". Verified locally against released SciMLTesting 1.6.0 (no dev-from-branch): Quality Assurance 17/17 + Doctests 1/1, 0 Fail/Error/Broken on Julia 1.10 (lts) and Julia 1.12 (the "1" lane). Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 6 ++---- test/qa/Project.toml | 7 +------ test/qa/qa.jl | 47 +++++++++++++++++++++++++++----------------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Project.toml b/Project.toml index c89697d3..74e6a58b 100644 --- a/Project.toml +++ b/Project.toml @@ -29,7 +29,6 @@ CommonSolve = "0.2" ConcreteStructs = "0.2" DiffEqBase = "6.176.0, 7.0" Documenter = "1" -ExplicitImports = "1" FastClosures = "0.3" ForwardDiff = "0.10, 1" Functors = "0.4, 0.5" @@ -51,7 +50,7 @@ PrecompileTools = "1.2.1" Random = "1.10" SciMLBase = "2, 3.3" SciMLSensitivity = "7.43" -SciMLTesting = "1" +SciMLTesting = "1.6" StableRNGs = "1" Static = "1" SteadyStateDiffEq = "2.5.0" @@ -62,7 +61,6 @@ julia = "1.10" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" @@ -82,4 +80,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [targets] -test = ["Aqua", "Documenter", "ExplicitImports", "ForwardDiff", "Functors", "GPUArraysCore", "InteractiveUtils", "LuxCUDA", "LuxTestUtils", "MLDataDevices", "NLsolve", "NonlinearSolve", "OrdinaryDiffEq", "OrdinaryDiffEqAdamsBashforthMoulton", "SafeTestsets", "SciMLSensitivity", "SciMLTesting", "StableRNGs", "Test", "Zygote"] +test = ["Aqua", "Documenter", "ForwardDiff", "Functors", "GPUArraysCore", "InteractiveUtils", "LuxCUDA", "LuxTestUtils", "MLDataDevices", "NLsolve", "NonlinearSolve", "OrdinaryDiffEq", "OrdinaryDiffEqAdamsBashforthMoulton", "SafeTestsets", "SciMLSensitivity", "SciMLTesting", "StableRNGs", "Test", "Zygote"] diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 123b618f..57bbb630 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -2,13 +2,10 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" DeepEquilibriumNetworks = "6748aba7-0e9b-415e-a410-ae3cc0ecb334" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" Lux = "b2108857-7c20-44ae-9111-449ecde12c47" NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" @@ -18,12 +15,10 @@ DeepEquilibriumNetworks = {path = "../.."} [compat] Aqua = "0.8" Documenter = "1" -ExplicitImports = "1" Lux = "1" NonlinearSolve = "4" OrdinaryDiffEq = "6.74, 7" Random = "1.10" -SciMLSensitivity = "7.43" -SciMLTesting = "1" +SciMLTesting = "1.6" Test = "1.10" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 74f3c884..b532db82 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,21 +1,32 @@ -using DeepEquilibriumNetworks, Test - -@testset "Aqua" begin - using Aqua - - Aqua.test_all(DeepEquilibriumNetworks; ambiguities = false) - Aqua.test_ambiguities(DeepEquilibriumNetworks; recursive = false) -end - -@testset "ExplicitImports" begin - import SciMLSensitivity - - using ExplicitImports - - @test check_no_implicit_imports(DeepEquilibriumNetworks) === nothing - @test check_no_stale_explicit_imports(DeepEquilibriumNetworks) === nothing - @test check_all_qualified_accesses_via_owners(DeepEquilibriumNetworks) === nothing -end +using SciMLTesting, DeepEquilibriumNetworks, Test + +run_qa( + DeepEquilibriumNetworks; + explicit_imports = true, + # `Aqua.test_all`'s default ambiguities check recurses into deps and is noisy; run + # it only against this package's own methods (the prior hand-rolled qa.jl disabled + # the recursive sweep and called `test_ambiguities(...; recursive = false)`). + aqua_kwargs = (; ambiguities = (; recursive = false)), + ei_kwargs = (; + # Names accessed as `Mod.name` that are not (yet) public in their owning + # package; tracked here until those packages mark them public on release. + all_qualified_accesses_are_public = (; + ignore = ( + :DEStats, :NLStats, # SciMLBase + :Fix1, # Base + :apply, :initialstates, :replicate, :setup, :update_state, # LuxCore + :getproperty, # Lux.LuxOps + ), + ), + # Names brought in via `using Mod: name` that are not (yet) public in Mod. + all_explicit_imports_are_public = (; + ignore = ( + :AbstractNonlinearAlgorithm, :AbstractODEAlgorithm, :_unwrap_val, # SciMLBase + :solve, # CommonSolve + ), + ), + ), +) @testset "Doctests" begin using Documenter From 172e731e8afb2b6ed2cd891e0236959ed87a8ee8 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Fri, 26 Jun 2026 15:30:40 -0400 Subject: [PATCH 2/4] QA: strip redundant public-API EI ignores (SciMLTesting 1.7 + base-lib make-public) SciMLTesting 1.7.0 runs the two public-API ExplicitImports checks (check_all_qualified_accesses_are_public / check_all_explicit_imports_are_public) only on Julia >= 1.11 (skipped on the lts), and the base libraries SciMLBase 3.24.0 / CommonSolve 0.2.9 / LuxCore 1.5.3 / ArrayInterface 7.26.0 made most of the previously-ignored names public. The per-repo public-API ignore-lists are therefore largely redundant. - Empty both public-API ignore-lists down to only the names that the checks still flag as non-public on Julia 1.12 against the registered releases: - all_qualified_accesses_are_public: keep :DEStats (SciMLBase). Dropped :NLStats (now public, SciMLBase), :Fix1 (now public, Base), :apply/:initialstates/:replicate/:setup/:update_state (now public, LuxCore), :getproperty (now public, Lux.LuxOps). - all_explicit_imports_are_public: keep :AbstractNonlinearAlgorithm, :_unwrap_val (SciMLBase). Dropped :AbstractODEAlgorithm (now public, SciMLBase) and :solve (now public, CommonSolve). - Bump SciMLTesting compat 1.6 -> 1.7 in the root and qa Project.toml so the released 1.7 (with the lts public-check skip) is resolved. Verified against registered releases (no dev), clean depots: - Julia 1.12 (>= 1.11, public checks RUN): Quality Assurance 17/17 pass, 0 Fail/Error/Broken (SciMLBase 3.24.0, CommonSolve 0.2.9, ArrayInterface 7.26.0, LuxCore 1.5.3, SciMLTesting 1.7.0). - Julia 1.10 (lts, public checks SKIPPED by SciMLTesting 1.7): Quality Assurance 15/15 pass (= 17 minus the 2 skipped public-API checks), 0 Fail/Error/Broken. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 +- test/qa/Project.toml | 2 +- test/qa/qa.jl | 19 ++++--------------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/Project.toml b/Project.toml index 74e6a58b..911613e8 100644 --- a/Project.toml +++ b/Project.toml @@ -50,7 +50,7 @@ PrecompileTools = "1.2.1" Random = "1.10" SciMLBase = "2, 3.3" SciMLSensitivity = "7.43" -SciMLTesting = "1.6" +SciMLTesting = "1.7" StableRNGs = "1" Static = "1" SteadyStateDiffEq = "2.5.0" diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 57bbb630..5c7ce842 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -19,6 +19,6 @@ Lux = "1" NonlinearSolve = "4" OrdinaryDiffEq = "6.74, 7" Random = "1.10" -SciMLTesting = "1.6" +SciMLTesting = "1.7" Test = "1.10" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index b532db82..8db08eea 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -8,22 +8,11 @@ run_qa( # the recursive sweep and called `test_ambiguities(...; recursive = false)`). aqua_kwargs = (; ambiguities = (; recursive = false)), ei_kwargs = (; - # Names accessed as `Mod.name` that are not (yet) public in their owning - # package; tracked here until those packages mark them public on release. - all_qualified_accesses_are_public = (; - ignore = ( - :DEStats, :NLStats, # SciMLBase - :Fix1, # Base - :apply, :initialstates, :replicate, :setup, :update_state, # LuxCore - :getproperty, # Lux.LuxOps - ), - ), - # Names brought in via `using Mod: name` that are not (yet) public in Mod. + # SciMLBase internals not yet marked public; tracked until SciMLBase + # exports/declares them public on a future release. + all_qualified_accesses_are_public = (; ignore = (:DEStats,)), # SciMLBase all_explicit_imports_are_public = (; - ignore = ( - :AbstractNonlinearAlgorithm, :AbstractODEAlgorithm, :_unwrap_val, # SciMLBase - :solve, # CommonSolve - ), + ignore = (:AbstractNonlinearAlgorithm, :_unwrap_val), # SciMLBase ), ), ) From 808d81004650c5e29e3874e5b44be91b03137ee7 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Fri, 26 Jun 2026 23:49:57 -0400 Subject: [PATCH 3/4] QA: empty public-API EI ignores for SciMLBase 3.27.0 make-public DEStats and AbstractNonlinearAlgorithm became public in SciMLBase 3.27.0, so drop them from the ExplicitImports public-API ignore lists. The all_qualified_accesses_are_public ignore is now empty (removed). Only _unwrap_val remains in all_explicit_imports_are_public (SciMLBase internal, not yet declared public). No DiffEqBase.X -> SciMLBase.X source migration was needed: src has no qualified DiffEqBase accesses, and DEStats was already accessed as SciMLBase.DEStats. Also add SteadyStateDiffEq to the isolated test/qa env deps. Moving QA into test/qa/ (this PR) dropped it from the env, breaking the src/layers.jl doctest's `using ...SteadyStateDiffEq...` (it was implicitly available in the root test env before, as a direct package dep). Restores the doctest. Verified on Julia 1.12 (public-API checks active, registered SciMLBase 3.27.0 / DiffEqBase 7.6.0 / SciMLTesting 1.7.0): QA 17/17 + Doctests 1/1. Verified on Julia 1.10 (public-API checks skipped per SciMLTesting >=1.11 gate): QA 15/15 + Doctests 1/1. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- test/qa/Project.toml | 2 ++ test/qa/qa.jl | 9 +++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 5c7ce842..496c3cfb 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -7,6 +7,7 @@ NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" +SteadyStateDiffEq = "9672c7b4-1e72-59bd-8a11-6ac3964bc41f" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [sources] @@ -20,5 +21,6 @@ NonlinearSolve = "4" OrdinaryDiffEq = "6.74, 7" Random = "1.10" SciMLTesting = "1.7" +SteadyStateDiffEq = "2.5.0" Test = "1.10" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 8db08eea..8b90e100 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -8,12 +8,9 @@ run_qa( # the recursive sweep and called `test_ambiguities(...; recursive = false)`). aqua_kwargs = (; ambiguities = (; recursive = false)), ei_kwargs = (; - # SciMLBase internals not yet marked public; tracked until SciMLBase - # exports/declares them public on a future release. - all_qualified_accesses_are_public = (; ignore = (:DEStats,)), # SciMLBase - all_explicit_imports_are_public = (; - ignore = (:AbstractNonlinearAlgorithm, :_unwrap_val), # SciMLBase - ), + # `_unwrap_val` is a SciMLBase internal not marked public; tracked until + # SciMLBase exports/declares it public on a future release. + all_explicit_imports_are_public = (; ignore = (:_unwrap_val,)), # SciMLBase ), ) From 4fbc182d03a1b1ffd59bd35982716cbde6b8228c Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Mon, 29 Jun 2026 06:52:47 -0400 Subject: [PATCH 4/4] QA: eliminate last EI ignore via local _unwrap_val The only remaining ExplicitImports exception was `all_explicit_imports_are_public = (; ignore = (:_unwrap_val,))`. `SciMLBase._unwrap_val` is a `_`-prefixed internal that will not be made public, so instead of ignoring it, reproduce it locally (it is trivially `_unwrap_val(::Val{B}) where {B} = B; _unwrap_val(B) = B`) and drop the SciMLBase import of it. With that, all six EI checks pass with no ignore lists at all, so the entire `ei_kwargs` block is removed. Verified on Julia 1.12.6 against released SciMLBase 3.30.0 / SciMLTesting 1.7.0 / ExplicitImports 1.15.0: run_qa Quality Assurance 17/17 pass, 0 fail/error/broken; all 6 EI checks (no_implicit_imports, no_stale_explicit_imports, all_explicit_imports_are_public, all_qualified_accesses_are_public, both via_owners) pass clean. Co-Authored-By: Chris Rackauckas --- src/DeepEquilibriumNetworks.jl | 2 +- src/utils.jl | 6 ++++++ test/qa/qa.jl | 5 ----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/DeepEquilibriumNetworks.jl b/src/DeepEquilibriumNetworks.jl index 2f2a1950..22f103f3 100644 --- a/src/DeepEquilibriumNetworks.jl +++ b/src/DeepEquilibriumNetworks.jl @@ -10,7 +10,7 @@ using FastClosures: @closure using Random: Random, AbstractRNG, randn! using SciMLBase: SciMLBase, AbstractNonlinearAlgorithm, AbstractODEAlgorithm, NonlinearSolution, ODESolution, ODEFunction, ODEProblem, - SteadyStateProblem, _unwrap_val + SteadyStateProblem using SciMLSensitivity: SteadyStateAdjoint, GaussAdjoint, ZygoteVJP using Static: StaticSymbol, StaticInt, known, static diff --git a/src/utils.jl b/src/utils.jl index 9e45f5f0..c5707ebb 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,3 +1,9 @@ +# Mirror of SciMLBase's internal `_unwrap_val` (a `_`-prefixed internal that will not be +# made public). Reproduced locally so `Val`-wrapped depth/scale specs can be unwrapped +# without depending on a non-public binding. +_unwrap_val(::Val{B}) where {B} = B +_unwrap_val(B) = B + @generated function split_and_reshape(x::AbstractMatrix, ::Val{idxs}, ::Val{shapes}) where { idxs, shapes, } diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 8b90e100..3c799470 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -7,11 +7,6 @@ run_qa( # it only against this package's own methods (the prior hand-rolled qa.jl disabled # the recursive sweep and called `test_ambiguities(...; recursive = false)`). aqua_kwargs = (; ambiguities = (; recursive = false)), - ei_kwargs = (; - # `_unwrap_val` is a SciMLBase internal not marked public; tracked until - # SciMLBase exports/declares it public on a future release. - all_explicit_imports_are_public = (; ignore = (:_unwrap_val,)), # SciMLBase - ), ) @testset "Doctests" begin