From 76d11eb92ff8a68792b787da715528ecc2419b57 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Thu, 25 Jun 2026 08:11:08 -0400 Subject: [PATCH 1/4] QA: run_qa v1.6 form + ExplicitImports Convert the hand-rolled test/qa/qa.jl (manual Aqua sub-checks + JET @test_broken markers) to the SciMLTesting 1.6 run_qa form with ExplicitImports enabled. - run_qa(MethodOfLines; explicit_imports = true, ...) replaces the manual Aqua.test_* / JET @test_broken body. - Aqua: the five genuine findings from #574 (ambiguities, undefined_exports, stale_deps, deps_compat, piracies) are preserved as aqua_broken; the passing sub-checks run via Aqua.test_all. - JET: the 10 errors previously tracked in #574 no longer reproduce on the current ModelingToolkit 11 / SciMLBase 3 stack (report_package returns no reports), so JET.test_package now runs as a hard check (un-broken). - ExplicitImports: - no_stale_explicit_imports: FIXED by removing 9 genuinely-unused explicit imports (variable, parameters, varmap_to_vars, setname, rename, cardinalize_eqs!, make_pdesys_compatible, parse_bcs, generate_system). - no_implicit_imports: ~80 names reach the module via heavy `using `; making them explicit is a large risky refactor, kept ei_broken pending #574. - the owners / public checks pass with per-check ignore-lists for other packages' non-public / re-exported names (PDEBase, Symbolics, ModelingToolkit(Base), SciMLBase, IfElse, RuntimeGeneratedFunctions, Base). test/qa/Project.toml: SciMLTesting compat -> "1.6"; drop Aqua/SafeTestsets/Pkg (Aqua/ExplicitImports come transitively via SciMLTesting, and the ambiguities sub-check that needs Aqua as a direct dep is disabled here). Verified locally on Julia 1.10 against released SciMLTesting 1.6.0: QA group 9 Pass, 6 Broken, 0 Fail, 0 Error. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- src/MethodOfLines.jl | 10 ++--- test/qa/Project.toml | 7 +--- test/qa/qa.jl | 96 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 82 insertions(+), 31 deletions(-) diff --git a/src/MethodOfLines.jl b/src/MethodOfLines.jl index 0eb00db1f..692e256bf 100644 --- a/src/MethodOfLines.jl +++ b/src/MethodOfLines.jl @@ -3,13 +3,12 @@ using LinearAlgebra using SciMLBase using DiffEqBase using ModelingToolkit -using ModelingToolkit: variable, get_unknowns, - parameters, varmap_to_vars, get_eqs, get_bcs, get_dvs, +using ModelingToolkit: get_unknowns, + get_eqs, get_bcs, get_dvs, get_ivs using SymbolicIndexingInterface using SymbolicUtils, Symbolics -using Symbolics: unwrap, symbolic_linear_solve, expand_derivatives, diff2term, setname, - rename +using Symbolics: unwrap, symbolic_linear_solve, expand_derivatives, diff2term using SymbolicUtils: operation, arguments, iscall, getmetadata, unwrap_const using IfElse using StaticArrays @@ -26,8 +25,7 @@ using PDEBase: unitindices, unitindex, remove, insert, sym_dot, VariableMap, dep d_orders, vcat!, update_varmap!, get_ops # staggered changes -using PDEBase: cardinalize_eqs!, make_pdesys_compatible, parse_bcs, generate_system, - Interval +using PDEBase: Interval using PDEBase: error_analysis, add_metadata! # To Extend diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 49fa6a491..5302c1eec 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,9 +1,6 @@ [deps] -Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" MethodOfLines = "94925ecb-adb7-4558-8ed8-f975c56a0bf4" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" @@ -11,9 +8,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" MethodOfLines = {path = "../.."} [compat] -Aqua = "0.8" JET = "0.9,0.10,0.11" -SafeTestsets = "0.0.1, 0.1" -SciMLTesting = "1" +SciMLTesting = "1.6" Test = "1" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 187bb6898..0e54c8679 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,20 +1,78 @@ -using MethodOfLines, Aqua, JET, Test +using SciMLTesting, MethodOfLines, Test +using JET -# Aqua/JET findings tracked at https://github.com/SciML/MethodOfLines.jl/issues/574 -@testset "Aqua" begin - # Passing sub-checks run normally. - Aqua.test_unbound_args(MethodOfLines) - Aqua.test_project_extras(MethodOfLines) - Aqua.test_persistent_tasks(MethodOfLines) - - # Failing sub-checks marked broken pending fixes. - @test_broken false # Aqua ambiguities: 48 method ambiguities — see https://github.com/SciML/MethodOfLines.jl/issues/574 - @test_broken false # Aqua undefined_exports: MethodOfLines.grid_align — see https://github.com/SciML/MethodOfLines.jl/issues/574 - @test_broken false # Aqua stale_deps: OrdinaryDiffEq — see https://github.com/SciML/MethodOfLines.jl/issues/574 - @test_broken false # Aqua deps_compat: LinearAlgebra has no compat entry — see https://github.com/SciML/MethodOfLines.jl/issues/574 - @test_broken false # Aqua piracies: PDEBase.AbstractBoundary/InterfaceBoundary call ops in interface_boundary.jl — see https://github.com/SciML/MethodOfLines.jl/issues/574 -end - -@testset "JET" begin - @test_broken false # JET: 10 possible errors (DiscreteSpace fields, otherderivmaps, staggered_discretize) — see https://github.com/SciML/MethodOfLines.jl/issues/574 -end +# Aqua/JET/ExplicitImports findings tracked at +# https://github.com/SciML/MethodOfLines.jl/issues/574 +run_qa( + MethodOfLines; + explicit_imports = true, + # Aqua sub-checks with genuine findings, marked broken pending fixes (issue #574): + # :ambiguities — 48 method ambiguities involving MethodOfLines methods + # :undefined_exports — MethodOfLines.grid_align (a kwarg/field name, not a binding) + # :stale_deps — OrdinaryDiffEq declared but not loaded (uses split subpackages) + # :deps_compat — LinearAlgebra has no [compat] entry + # :piracies — call-operator methods on PDEBase.InterfaceBoundary / + # PDEBase.AbstractBoundary in interface_boundary.jl + aqua_broken = (:ambiguities, :undefined_exports, :stale_deps, :deps_compat, :piracies), + # JET: the 10 possible errors previously tracked in #574 no longer reproduce on the + # current ModelingToolkit 11 / SciMLBase 3 stack, so JET.test_package runs as a hard + # check (jet_broken left at its default of false). + # ExplicitImports per-check ignore-lists (names owned by / non-public in other + # packages; they become clean once those packages export/declare-public these names). + ei_kwargs = (; + all_explicit_imports_via_owners = (; + ignore = ( + :Interval, # owner IntervalSets, re-exported by PDEBase + :get_bcs, :get_dvs, :get_eqs, # owner ModelingToolkitBase, re-exported by ModelingToolkit + :get_ivs, :get_unknowns, + :unwrap, # owner SymbolicUtils, re-exported by Symbolics + ), + ), + all_qualified_accesses_via_owners = (; + ignore = ( + :ProblemTypeCtx, # owner ModelingToolkitBase, accessed via ModelingToolkit + :unwrap, # owner SymbolicUtils, accessed via Symbolics + ), + ), + all_explicit_imports_are_public = (; + ignore = ( + # non-public in PDEBase: + :Interval, :add_metadata!, :error_analysis, :get_ops, :insert, :remove, + :sym_dot, :unitindex, :unitindices, :update_varmap!, :vcat!, + # non-public in Symbolics: + :diff2term, :unwrap, + # non-public in ModelingToolkit: + :get_bcs, :get_dvs, :get_eqs, :get_ivs, :get_unknowns, + ), + ), + all_qualified_accesses_are_public = (; + ignore = ( + # non-public in Base: + :var"@propagate_inbounds", :AbstractCartesianIndex, :OneTo, + # non-public in SciMLBase: + :AbstractDiscretizationMetadata, :AbstractODESolution, :AbstractPDESolution, + :PDESolution, :observed, + # non-public in PDEBase: + :EquationState, :cardinalize_eqs!, :check_boundarymap, + :construct_differential_discretizer, :construct_disc_state, + :construct_discrete_space, :construct_var_equation_mapping, + :discretize_equation!, :generate_ic_defaults, :generate_metadata, + :get_discvars, :get_eqvar, :interface_errors, :parse_bcs, + :should_transform, :transform_pde_system!, + # non-public in ModelingToolkit: + :ProblemTypeCtx, + # non-public in IfElse: + :ifelse, + # non-public in RuntimeGeneratedFunctions: + :init, + # non-public in Symbolics: + :unwrap, :variable, + ), + ), + ), + # no_implicit_imports: ~80 names reach MethodOfLines via `using ` (SciMLBase, + # DiffEqBase, ModelingToolkit, Symbolics, SymbolicUtils, PDEBase, DomainSets, + # Interpolations, ...). Making them all explicit is a large, risky refactor; kept + # broken pending issue #574. + ei_broken = (:no_implicit_imports,), +) From d3396edd13f6cc6674036ed9d12f366f14d35d15 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Thu, 25 Jun 2026 10:54:05 -0400 Subject: [PATCH 2/4] QA: keep JET broken on Julia 1.11/1.12 (jet_broken = true) The v1.6 conversion un-broke JET on the basis that report_package returned no reports, but that was observed on Julia 1.10. On the CI `julia 1` lane (1.11/1.12) JET still finds the same possible errors tracked in #574: DiscreteSpace getproperty `.time`/`.ps` FieldErrors reached via ivs/params, `MethodOfLines.otherderivmaps` not defined, and a possibly-undefined `f_analytic` in MOL_discretization.jl. Restore jet_broken = true so the check is report-only (it auto-flags an Unexpected Pass once JET is clean), matching the original test/qa/qa.jl `@test_broken` for JET. Verified locally on Julia 1.12 against released SciMLTesting 1.6.0 (JET 0.11.5, ModelingToolkit 11.28, SciMLBase 3.22): QA group 8 Pass, 7 Broken, 0 Fail, 0 Error (was 8 Pass, 1 Fail, 6 Broken). Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- test/qa/qa.jl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 0e54c8679..9091b3c40 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -14,9 +14,12 @@ run_qa( # :piracies — call-operator methods on PDEBase.InterfaceBoundary / # PDEBase.AbstractBoundary in interface_boundary.jl aqua_broken = (:ambiguities, :undefined_exports, :stale_deps, :deps_compat, :piracies), - # JET: the 10 possible errors previously tracked in #574 no longer reproduce on the - # current ModelingToolkit 11 / SciMLBase 3 stack, so JET.test_package runs as a hard - # check (jet_broken left at its default of false). + # JET: still reports possible errors on Julia 1.11/1.12 (the CI `julia 1` lane): + # DiscreteSpace getproperty `.time`/`.ps` FieldErrors via ivs/params, + # `MethodOfLines.otherderivmaps` not defined, and `f_analytic` possibly-undefined in + # MOL_discretization.jl. Kept broken pending issue #574. `jet_broken = true` makes the + # check report-only and auto-flags an Unexpected Pass once JET is clean. + jet_broken = true, # ExplicitImports per-check ignore-lists (names owned by / non-public in other # packages; they become clean once those packages export/declare-public these names). ei_kwargs = (; From de0f3c9c36214f01c93847b3c1e1d7c041d75078 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Fri, 26 Jun 2026 16:14:44 -0400 Subject: [PATCH 3/4] QA: trim public-API EI ignores to minimal set (SciMLTesting 1.7 + released base libs) SciMLTesting 1.7.0 now runs check_all_qualified_accesses_are_public / check_all_explicit_imports_are_public only on Julia >= 1.11 (skipped on lts), and the base libs have made many former internals public (SciMLBase 3.24.0, Symbolics 7.29.0, SymbolicUtils 4.36.0, ModelingToolkit 11.29.0, ArrayInterface 7.26.0, CommonSolve 0.2.9). The two public-API ignore-lists in the QA call are therefore largely redundant. Removed 11 now-public entries (verified on Julia 1.12 against the registered releases; the names below are no longer flagged): all_explicit_imports_are_public: unwrap (Symbolics); get_bcs/get_dvs/get_eqs/get_ivs/get_unknowns (ModelingToolkit, now handled via_owners) all_qualified_accesses_are_public: @propagate_inbounds, OneTo (Base); init (RuntimeGeneratedFunctions); unwrap, variable (Symbolics) Kept only the names the public checks still flag as non-public on Julia 1.12: PDEBase internals (not yet made public), SciMLBase AbstractDiscretizationMetadata/AbstractODESolution/AbstractPDESolution/PDESolution/observed, Base AbstractCartesianIndex, ModelingToolkit ProblemTypeCtx, IfElse ifelse, Symbolics diff2term. via_owners ignores, aqua_broken, jet_broken, and ei_broken (no_implicit_imports) are unchanged. Verified: Julia 1.12 QA group = 8 pass / 7 broken / 0 error; Julia 1.10 (lts) unchanged by this edit (the two public-API checks are skipped there by SciMLTesting 1.7). Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- test/qa/qa.jl | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 9091b3c40..8f6a73fbd 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -43,15 +43,13 @@ run_qa( :Interval, :add_metadata!, :error_analysis, :get_ops, :insert, :remove, :sym_dot, :unitindex, :unitindices, :update_varmap!, :vcat!, # non-public in Symbolics: - :diff2term, :unwrap, - # non-public in ModelingToolkit: - :get_bcs, :get_dvs, :get_eqs, :get_ivs, :get_unknowns, + :diff2term, ), ), all_qualified_accesses_are_public = (; ignore = ( # non-public in Base: - :var"@propagate_inbounds", :AbstractCartesianIndex, :OneTo, + :AbstractCartesianIndex, # non-public in SciMLBase: :AbstractDiscretizationMetadata, :AbstractODESolution, :AbstractPDESolution, :PDESolution, :observed, @@ -66,10 +64,6 @@ run_qa( :ProblemTypeCtx, # non-public in IfElse: :ifelse, - # non-public in RuntimeGeneratedFunctions: - :init, - # non-public in Symbolics: - :unwrap, :variable, ), ), ), From 5ae057f345fe2ccfd50d85dd0e6d23ca9f53d70e Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sat, 27 Jun 2026 01:12:07 -0400 Subject: [PATCH 4/4] QA: verify public-API EI ignores against released libs; fix QA(lts) JET Verified the public-API ExplicitImports ignore-lists against the now-released SciMLBase 3.27.0 / DiffEqBase 7.6.0 / SciMLTesting 1.7.0 / Symbolics 7.29.0 / SymbolicUtils 4.36.0 / ModelingToolkit 11.29.0 / PDEBase 0.1.26 (Julia 1.12, no dev). Every name still flagged by the public checks is genuinely non-public in its owner package (confirmed via Base.ispublic and the EI checks run with the lists emptied): SciMLBase AbstractDiscretizationMetadata/AbstractODESolution/ AbstractPDESolution/PDESolution/observed are NOT among the 3.27.0 made-public names, so they stay; likewise the PDEBase internals, IfElse.ifelse, Symbolics.diff2term, ModelingToolkit.ProblemTypeCtx, Base.AbstractCartesianIndex. No DiffEqBase.X -> SciMLBase.X caller migration applies (the source uses whole-module `using` and `SciMLBase.X` qualified accesses already; no DiffEqBase-qualified SciMLBase-owned names exist). The two *_are_public lists are therefore already at their minimal/correct state. Bump test/qa SciMLTesting floor 1.6 -> 1.7 to guarantee the >=1.11 public-API gating (1.6 lacks it; resolving it on the LTS lane would run the public checks on 1.10 and fail). Gate jet_broken to VERSION >= v"1.11": JET (0.9.18) is clean on the LTS (1.10) lane, so `jet_broken = true` produced an Unexpected Pass hard error on QA(lts); JET still reports on 1.11/1.12 where it stays broken. JET now runs as a real passing test on 1.10. Not a silencing: it un-broken-marks JET where it is clean. Verified: QA group EXIT=0 on Julia 1.12 (8 pass, 7 broken, public checks RUN) and Julia 1.10 (7 pass, 6 broken, public checks gated off), 0 hard FAIL on both. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- test/qa/Project.toml | 2 +- test/qa/qa.jl | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 5302c1eec..8ed0c700e 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -9,6 +9,6 @@ MethodOfLines = {path = "../.."} [compat] JET = "0.9,0.10,0.11" -SciMLTesting = "1.6" +SciMLTesting = "1.7" Test = "1" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 8f6a73fbd..58a93c2aa 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -17,9 +17,10 @@ run_qa( # JET: still reports possible errors on Julia 1.11/1.12 (the CI `julia 1` lane): # DiscreteSpace getproperty `.time`/`.ps` FieldErrors via ivs/params, # `MethodOfLines.otherderivmaps` not defined, and `f_analytic` possibly-undefined in - # MOL_discretization.jl. Kept broken pending issue #574. `jet_broken = true` makes the - # check report-only and auto-flags an Unexpected Pass once JET is clean. - jet_broken = true, + # MOL_discretization.jl. Kept broken there pending issue #574. JET is clean on the + # LTS (1.10) lane, so only mark broken on 1.11+; `report_package` auto-flags an + # Unexpected Pass once JET is clean on 1.11+ too. + jet_broken = VERSION >= v"1.11", # ExplicitImports per-check ignore-lists (names owned by / non-public in other # packages; they become clean once those packages export/declare-public these names). ei_kwargs = (;