From a438746cb95686d00f73d8b114bfca40a80cee1a Mon Sep 17 00:00:00 2001 From: Chris Rackauckas - Beep Boop Edition Date: Fri, 3 Jul 2026 07:34:31 +0000 Subject: [PATCH] QA: run_qa v1.6 form + ExplicitImports (#86) * QA: run_qa v1.6 form + ExplicitImports Convert test/qa/qa.jl from hand-rolled Aqua + JET to the SciMLTesting 1.6 run_qa form with ExplicitImports enabled (explicit_imports = true). - Aqua and JET keep running (JET hard via run_qa's default test_package). - ExplicitImports: 4 of 6 checks pass clean; the two qualified-access checks pass with per-name ignore lists for SciMLBase-owned names re-exported through DiffEqBase (AbstractODEAlgorithm, AbstractODEProblem, __solve, build_solution, Stats) and the Symbolics-owned MATLABTarget re-exported through ModelingToolkit. - no_implicit_imports is @test_broken (ei_broken) pending the explicit-import refactor of the heavy using/@reexport surface, tracked in #85. test/qa/Project.toml: SciMLTesting compat -> 1.6; ExplicitImports dropped (transitive via SciMLTesting); Aqua kept (ambiguities child-proc needs it a direct dep); JET kept. Local QA group vs released SciMLTesting 1.6.0: 17 pass, 1 broken, 0 fail/error. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) * QA: migrate public SciMLBase accesses + strip public-API EI ignores Now that SciMLBase 3.27.0 makes the abstract problem/algorithm types, build_solution and DEStats public, migrate the qualified accesses in src/ off the DiffEqBase re-exporter onto their SciMLBase owner: DiffEqBase.AbstractODEAlgorithm -> SciMLBase.AbstractODEAlgorithm DiffEqBase.AbstractODEProblem -> SciMLBase.AbstractODEProblem DiffEqBase.build_solution -> SciMLBase.build_solution DiffEqBase.Stats -> SciMLBase.DEStats (canonical public name) Add SciMLBase to [deps]/[compat] (>=3.27). DiffEqBase.__solve stays the solver extension point (SciMLBase-owned but non-public) and MATLABTarget stays reached through ModelingToolkit (Symbolics-owned, non-public). Empty the public-API ExplicitImports ignore lists of the now-public, owner-accessed names, leaving only the genuinely-still-non-public :__solve and :MATLABTarget in all_qualified_accesses_are_public and all_qualified_accesses_via_owners. Bump the qa env SciMLTesting floor to 1.7 (gates the public-API checks to Julia >= 1.11). Verified QA group locally against the registered releases (CI=true so MATLAB.jl loads with dummy deps, matching CI): Julia 1.12 17 pass / 1 broken (no_implicit_imports) / 0 fail with the public checks running; Julia 1.10 15 pass / 1 broken / 0 fail with the public checks skipped. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: ChrisRackauckas-Claude Co-authored-by: Claude Opus 4.8 (1M context) --- Project.toml | 2 ++ src/MATLABDiffEq.jl | 17 +++++++++-------- test/qa/Project.toml | 2 +- test/qa/qa.jl | 39 ++++++++++++++++++++++++++++----------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Project.toml b/Project.toml index af3c612..07a6b4d 100644 --- a/Project.toml +++ b/Project.toml @@ -8,6 +8,7 @@ MATLAB = "10e44e05-a98a-55b3-a45b-ba969058deb6" ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" +SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" [compat] DiffEqBase = "6.122, 7" @@ -17,6 +18,7 @@ ParameterizedFunctions = "5" PrecompileTools = "1.1" Reexport = "0.2, 1.0" SafeTestsets = "0.1, 1" +SciMLBase = "3.27" SciMLTesting = "1" Test = "<0.0.1, 1" julia = "1.10" diff --git a/src/MATLABDiffEq.jl b/src/MATLABDiffEq.jl index 12c0c96..120dba5 100644 --- a/src/MATLABDiffEq.jl +++ b/src/MATLABDiffEq.jl @@ -4,6 +4,7 @@ using Reexport @reexport using DiffEqBase using MATLAB, ModelingToolkit using PrecompileTools +import SciMLBase # MATLAB only supports Float64 arrays. Check if a type is MATLAB-compatible. # Note: We specifically accept standard Julia integer types that MATLAB can convert, @@ -52,7 +53,7 @@ else const mtk_states = ModelingToolkit.states end -abstract type MATLABAlgorithm <: DiffEqBase.AbstractODEAlgorithm end +abstract type MATLABAlgorithm <: SciMLBase.AbstractODEAlgorithm end struct ode23 <: MATLABAlgorithm end struct ode45 <: MATLABAlgorithm end struct ode113 <: MATLABAlgorithm end @@ -63,7 +64,7 @@ struct ode15s <: MATLABAlgorithm end struct ode15i <: MATLABAlgorithm end function DiffEqBase.__solve( - prob::DiffEqBase.AbstractODEProblem{uType, tupType, isinplace}, + prob::SciMLBase.AbstractODEProblem{uType, tupType, isinplace}, alg::AlgType, timeseries = [], ts = [], @@ -151,7 +152,7 @@ function DiffEqBase.__solve( stats = buildDEStats(solstats) - return DiffEqBase.build_solution( + return SciMLBase.build_solution( prob, alg, ts, @@ -162,15 +163,15 @@ function DiffEqBase.__solve( end """ - buildDEStats(solverstats::Dict{String, <:Any}) -> DiffEqBase.Stats + buildDEStats(solverstats::Dict{String, <:Any}) -> SciMLBase.DEStats -Convert MATLAB ODE solver statistics dictionary to DiffEqBase.Stats. +Convert MATLAB ODE solver statistics dictionary to SciMLBase.DEStats. The function extracts statistics from the MATLAB solver output and maps them -to the corresponding fields in DiffEqBase.Stats. Missing keys default to 0. +to the corresponding fields in SciMLBase.DEStats. Missing keys default to 0. """ -function buildDEStats(solverstats::Dict{String, <:Any})::DiffEqBase.Stats - destats = DiffEqBase.Stats(0) +function buildDEStats(solverstats::Dict{String, <:Any})::SciMLBase.DEStats + destats = SciMLBase.DEStats(0) destats.nf = Int(get(solverstats, "nfevals", 0)) destats.nreject = Int(get(solverstats, "nfailed", 0)) destats.naccept = Int(get(solverstats, "nsteps", 0)) diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 820e95a..29ce1d4 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -13,6 +13,6 @@ MATLABDiffEq = {path = "../.."} Aqua = "0.8" JET = "0.9, 0.10, 0.11" SafeTestsets = "0.1, 1" -SciMLTesting = "1" +SciMLTesting = "1.7" Test = "<0.0.1, 1" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index a91975a..42e0e84 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,12 +1,29 @@ -using SafeTestsets +using SciMLTesting, MATLABDiffEq, JET, Test -@safetestset "Aqua" begin - using MATLABDiffEq, Aqua - Aqua.test_all(MATLABDiffEq) -end - -@safetestset "JET static analysis" begin - using MATLABDiffEq, JET, Test - rep = JET.report_package(MATLABDiffEq; target_modules = (MATLABDiffEq,)) - @test length(JET.get_reports(rep)) == 0 -end +run_qa( + MATLABDiffEq; + explicit_imports = true, + ei_kwargs = (; + # DiffEqBase.__solve (SciMLBase-owned) is the documented solver extension + # point re-exported by DiffEqBase, and the Symbolics-owned MATLABTarget is + # reached through ModelingToolkit; both are accessed through a re-exporter + # that is not the owner. + all_qualified_accesses_via_owners = (; + ignore = ( + :__solve, :MATLABTarget, + ), + ), + # Still non-public upstream: __solve (SciMLBase) and MATLABTarget + # (Symbolics). Drop once they are declared public. + all_qualified_accesses_are_public = (; + ignore = ( + :__solve, :MATLABTarget, + ), + ), + ), + # no_implicit_imports: the module deliberately `@reexport using DiffEqBase` + # and `using MATLAB`/`ModelingToolkit`/`PrecompileTools`; making every name + # explicit is a large, risky refactor against heavy deps. Tracked in + # https://github.com/SciML/MATLABDiffEq.jl/issues/85 + ei_broken = (:no_implicit_imports,), +)