From 85ab74052e05239a39bd9ba55758932c39558300 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 24 Jun 2026 11:31:42 -0400 Subject: [PATCH 1/2] Add ExplicitImports.jl to QA via SciMLTesting run_qa Wire ExplicitImports.jl into the QA group through SciMLTesting 1.4's `run_qa(...; ExplicitImports, explicit_imports=true, ei_kwargs=...)`, running all six 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). Changes: - test/qa/qa.jl: replace the hand-written Aqua/JET testsets with a single run_qa call that keeps Aqua (deps_compat check_extras=false) and JET (target_defined_modules=true), and adds the ExplicitImports checks. - test/qa/Project.toml: add ExplicitImports dep + compat; bump SciMLTesting compat to 1.4 (run_qa's ExplicitImports support). - Project.toml: bump SciMLTesting compat to 1.4; patch version 1.22.2. - src/compat.jl: `Base.isexpr` -> `Base.Meta.isexpr` so the qualified access resolves to the public `Base.Meta` owner (FIX, no ignore needed on any version). Behaviorally identical (Meta.isexpr === Base.isexpr). - ext/ADTypesChainRulesCoreExt.jl: drop unused `NoForwardsMode`/`NoReverseMode` imports (stale-explicit-imports cleanup). Only two unavoidable non-public Base names are ignored, and only in the public-API access check: `broadcastable` (the documented broadcasting hook, non-public in every Julia version) and `depwarn` (non-public on the 1.10 LTS, public on 1.11+). Every other check passes with no ignore-list. Verified locally: QA group 17/17 on Julia 1.10, 1.11, 1.12; all six ExplicitImports checks PASS individually on 1.10 and 1.11; Core tests (Dense/Sparse/Symbols/Legacy/Misc/Public) still pass on 1.11. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 4 ++-- ext/ADTypesChainRulesCoreExt.jl | 1 - src/compat.jl | 2 +- test/qa/Project.toml | 4 +++- test/qa/qa.jl | 30 +++++++++++++++++++++++------- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Project.toml b/Project.toml index fbc4c36..65cb3df 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ADTypes" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" authors = ["Vaibhav Dixit , Guillaume Dalle and contributors"] -version = "1.22.1" +version = "1.22.2" [weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" @@ -18,7 +18,7 @@ ChainRulesCore = "1.0.2" ConstructionBase = "1.5" EnzymeCore = "0.5.3,0.6,0.7,0.8" SafeTestsets = "0.1, 1" -SciMLTesting = "1" +SciMLTesting = "1.4" julia = "1.10" [extras] diff --git a/ext/ADTypesChainRulesCoreExt.jl b/ext/ADTypesChainRulesCoreExt.jl index 7622742..8b67aa5 100644 --- a/ext/ADTypesChainRulesCoreExt.jl +++ b/ext/ADTypesChainRulesCoreExt.jl @@ -2,7 +2,6 @@ module ADTypesChainRulesCoreExt using ADTypes: ADTypes, AutoChainRules using ChainRulesCore: HasForwardsMode, HasReverseMode, - NoForwardsMode, NoReverseMode, RuleConfig # see https://juliadiff.org/ChainRulesCore.jl/stable/rule_author/superpowers/ruleconfig.html diff --git a/src/compat.jl b/src/compat.jl index 472ee09..4e49aac 100644 --- a/src/compat.jl +++ b/src/compat.jl @@ -3,7 +3,7 @@ macro public(ex) return if VERSION >= v"1.11.0-DEV.469" args = ex isa Symbol ? (ex,) : - Base.isexpr(ex, :tuple) ? ex.args : error("Failed to mark $ex as public") + Base.Meta.isexpr(ex, :tuple) ? ex.args : error("Failed to mark $ex as public") esc(Expr(:public, args...)) else nothing diff --git a/test/qa/Project.toml b/test/qa/Project.toml index b5e6ab2..e261c93 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,6 +1,7 @@ [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" @@ -12,8 +13,9 @@ ADTypes = {path = "../.."} [compat] ADTypes = "1" Aqua = "0.8" +ExplicitImports = "1.11" JET = "0.9, 0.10, 0.11" SafeTestsets = "0.1, 1" -SciMLTesting = "1" +SciMLTesting = "1.4" Test = "1" julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl index 47c902d..a57d7d1 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,12 +1,28 @@ using ADTypes using Aqua: Aqua +using ExplicitImports: ExplicitImports using JET: JET +using SciMLTesting: run_qa using Test -@testset "Aqua.jl" begin - Aqua.test_all(ADTypes; deps_compat = (check_extras = false,)) -end - -@testset "JET.jl" begin - JET.test_package(ADTypes, target_defined_modules = true) -end +run_qa( + ADTypes; + Aqua = Aqua, + aqua_kwargs = (; deps_compat = (; check_extras = false)), + JET = JET, + jet = true, + jet_kwargs = (; target_defined_modules = true), + ExplicitImports = ExplicitImports, + explicit_imports = true, + # Two unavoidable non-public `Base` names, ignored only in the public-API access + # check (every other ExplicitImports check passes unignored): + # * `broadcastable` — the documented broadcasting customization hook; + # `Base.broadcastable(ad::AbstractADType) = Ref(ad)` makes AD choices broadcast + # as scalars. `Base` marks it non-public on every Julia version. + # * `depwarn` — `Base.depwarn` is the only way to emit a deprecation warning, and + # it is non-public on the LTS (1.10). It became public in Base on 1.11+, where + # ignoring it is a harmless no-op. + # (`Base.Meta.isexpr` in src/compat.jl was switched off `Base.isexpr` so its access + # resolves to the public `Base.Meta` owner and needs no ignore on any version.) + ei_kwargs = (; all_qualified_accesses_are_public = (; ignore = (:broadcastable, :depwarn))), +) From f99a4a4ca20046d7b24db2a3483ac0f568db429d Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 24 Jun 2026 21:29:27 -0400 Subject: [PATCH 2/2] Migrate run_qa to SciMLTesting 1.5 minimal form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SciMLTesting 1.5.0 makes Aqua and ExplicitImports its own direct deps and auto-detects them, with JET still a weakdep (opt-in via `using JET`). `explicit_imports` stays an explicit opt-in (defaults false). - test/qa/qa.jl: collapse to the minimal form. Imports become `using SciMLTesting, ADTypes, Test` + `using JET`; drop `using Aqua` and `using ExplicitImports`. The run_qa call drops the now-auto-detected `Aqua = Aqua`, `JET = JET`, `jet = true`, and `ExplicitImports = ExplicitImports` module args, keeping only the genuine per-repo overrides (aqua_kwargs, jet_kwargs, explicit_imports = true, ei_kwargs). - test/qa/Project.toml: drop ExplicitImports from [deps]/[compat] (now transitive via SciMLTesting); bump SciMLTesting compat to 1.5. Aqua is kept as a direct dep on purpose: Aqua's ambiguity check spawns a worker subprocess that runs a bare `using Aqua` against the active project, which errors ("Package Aqua not found in current path") if Aqua is only a transitive (manifest-only) dep. JET is kept (the qa runs JET). - Project.toml: bump SciMLTesting compat to 1.5. Verified locally against the released SciMLTesting 1.5.0 (Pkg-resolved, no dev-from-branch): QA group 17/17 on Julia 1.10 and 1.11, running the same checks as before — all Aqua checks (incl. Method ambiguity), the six ExplicitImports checks, and JET.test_package. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 +- test/qa/Project.toml | 4 +--- test/qa/qa.jl | 17 +++++++---------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Project.toml b/Project.toml index 65cb3df..7e67de8 100644 --- a/Project.toml +++ b/Project.toml @@ -18,7 +18,7 @@ ChainRulesCore = "1.0.2" ConstructionBase = "1.5" EnzymeCore = "0.5.3,0.6,0.7,0.8" SafeTestsets = "0.1, 1" -SciMLTesting = "1.4" +SciMLTesting = "1.5" julia = "1.10" [extras] diff --git a/test/qa/Project.toml b/test/qa/Project.toml index e261c93..6d692fc 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,7 +1,6 @@ [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" -ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" @@ -13,9 +12,8 @@ ADTypes = {path = "../.."} [compat] ADTypes = "1" Aqua = "0.8" -ExplicitImports = "1.11" JET = "0.9, 0.10, 0.11" 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 a57d7d1..bcf56e3 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,18 +1,15 @@ -using ADTypes -using Aqua: Aqua -using ExplicitImports: ExplicitImports -using JET: JET -using SciMLTesting: run_qa -using Test +using SciMLTesting, ADTypes, Test +using JET +# Aqua and ExplicitImports are SciMLTesting deps, so they are not imported here. +# Aqua is still listed in this env's `[deps]` (not ExplicitImports): Aqua's ambiguity +# check spawns a worker subprocess that runs a bare `using Aqua` against the active +# project, which only resolves if Aqua is a *direct* dep — a transitive (manifest-only) +# Aqua makes that worker error with "Package Aqua not found in current path". run_qa( ADTypes; - Aqua = Aqua, aqua_kwargs = (; deps_compat = (; check_extras = false)), - JET = JET, - jet = true, jet_kwargs = (; target_defined_modules = true), - ExplicitImports = ExplicitImports, explicit_imports = true, # Two unavoidable non-public `Base` names, ignored only in the public-API access # check (every other ExplicitImports check passes unignored):