Skip to content

Add ExplicitImports.jl checks to QA via SciMLTesting run_qa#59

Merged
ChrisRackauckas merged 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:qa-explicit-imports
Jun 27, 2026
Merged

Add ExplicitImports.jl checks to QA via SciMLTesting run_qa#59
ChrisRackauckas merged 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:qa-explicit-imports

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Note

Please ignore this PR until it has been reviewed by @ChrisRackauckas.

What

Wires all six ExplicitImports.jl checks into the QA test group through SciMLTesting's run_qa(...; ExplicitImports = ExplicitImports, explicit_imports = true, ei_kwargs = ...):

  • 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

Violations and how they were resolved (FIX > DECLARE-PUBLIC > IGNORE)

print_explicit_imports(FunctionProperties; report_non_public = true) surfaced exactly two violations, both internal Core accesses inherent to hasbranching, which is a compiler-introspection utility:

Name Where Check Resolution
Core.GotoIfNot using Core: GotoIfNot (src line 3) all_explicit_imports_are_public minimal documented ignore
Core.Typeof Core.Typeof.(x) (src line 47) all_qualified_accesses_are_public minimal documented ignore

Neither can be cleanly fixed:

  • Core.GotoIfNot is the IR node type that hasbranching scans code_typed output for. It is non-public in Core and has no public alias.
  • Core.Typeof builds the dispatch-signature tuple type passed to code_typed. It is not interchangeable with the public typeof: for a type-valued argument x = Int, Core.Typeof(Int) is Type{Int64} (the dispatch signature) while typeof(Int) is DataType. The equivalent Base.typesof is itself non-public, so swapping would just relocate the violation.

Both are therefore added to a minimal, documented per-check ei_kwargs ignore-list (the source line itself is unchanged, so no behavior change). FunctionProperties has no genuinely-public-but-unexported names of its own, so no public/export declarations were needed.

Also in this PR

Folds Aqua and JET into the same run_qa call and drops the two stale @test_broken false placeholders (the #54 workarounds):

Leaving @test_broken false in place would now error as an unexpected pass, so removing the placeholders and running the real checks is the correct fix.

Test deps

  • test/qa/Project.toml: add ExplicitImports (compat 1.15), bump SciMLTesting floor to 1.4 (the release whose run_qa supports ExplicitImports).
  • Root Project.toml: bump SciMLTesting compat floor to 1.4.

Verification (local, Julia 1.12)

GROUP=QA julia --project=. -e 'using Pkg; withenv("GROUP"=>"QA") do; Pkg.test("FunctionProperties"); end':

Test Summary: | Pass  Total   Time
QA/qa.jl      |   18     18  41.6s
     Testing FunctionProperties tests passed

The six ExplicitImports checks individually (with the configured ignores):

Test Summary:                       | Pass  Total  Time
ExplicitImports (6 checks)          |    6      6  2.8s
  no_implicit_imports               |    1      1
  no_stale_explicit_imports         |    1      1
  all_explicit_imports_via_owners   |    1      1
  all_qualified_accesses_via_owners |    1      1
  all_qualified_accesses_are_public |    1      1
  all_explicit_imports_are_public   |    1      1

Runic-clean.

🤖 Generated with Claude Code

ChrisRackauckas and others added 2 commits June 24, 2026 11:49
Wire 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) into the QA group through
SciMLTesting's `run_qa(...; ExplicitImports = ExplicitImports,
explicit_imports = true, ei_kwargs = ...)`.

The four standard checks and `no_implicit_imports` pass with no
configuration. The two public-API checks flag two internal `Core`
accesses inherent to `hasbranching` (a compiler-introspection
utility): `Core.GotoIfNot` (the IR node it scans for) and
`Core.Typeof` (used to build the dispatch signature tuple for
`code_typed`). Neither has a public equivalent — `typeof` differs
from `Core.Typeof` on type-valued arguments and `Base.typesof` is
itself non-public — so they are added to a minimal, documented
per-check ignore-list rather than rewritten.

Also fold Aqua and JET into the same `run_qa` call and drop the two
stale `@test_broken false` placeholders (issues from SciML#54): Aqua now
passes with deps_compat enabled (root Project.toml carries compat for
all test extras) and JET typo-mode passes (Cassette was replaced with
`code_typed` in SciML#55), so those placeholders would now error as
unexpected passes.

Test deps: add ExplicitImports (compat 1.15) to test/qa/Project.toml
and bump SciMLTesting floor to 1.4 (run_qa ExplicitImports support).

Verified locally on Julia 1.12 (`GROUP=QA Pkg.test`): QA group 18/18
pass, all six ExplicitImports checks green.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SciMLTesting 1.5.0 makes Aqua and ExplicitImports its own direct deps and
auto-detects them in run_qa, so the per-repo qa.jl no longer threads those
modules. Collapse the call to its genuine per-repo content:

  - qa.jl imports: `using SciMLTesting, FunctionProperties, JET, Test`
    (drop `using Aqua, ExplicitImports` — now SciMLTesting deps; JET stays
    since its weakdep extension must be loaded to enable the JET check).
  - run_qa: keep `explicit_imports = true` (opt-in; defaults false in 1.5)
    and the per-check `ei_kwargs` ignore-lists for the two `Core` accesses
    inherent to `hasbranching`. Drop the now-auto-detected `Aqua = Aqua`,
    `JET = JET, jet = true`, and `ExplicitImports = ExplicitImports`.
  - test/qa/Project.toml: drop ExplicitImports (now transitive via
    SciMLTesting); bump SciMLTesting floor to 1.5. Root Project.toml
    SciMLTesting compat bumped to 1.5 as well.

Aqua is intentionally KEPT as a direct dep of test/qa/Project.toml even
though it is now also transitive: Aqua's `Method ambiguity` check spawns a
fresh subprocess that does `using Aqua` against this env's active-project
load path, where only direct deps resolve. Dropping it makes that one check
error with "Package Aqua not found in current path" while every other Aqua
check (run in-process via SciMLTesting's own Aqua) and the six
ExplicitImports checks still pass — so Aqua must remain listed here. (A
load-path fix for the ambiguity subprocess belongs upstream in SciMLTesting;
until then the direct-dep entry is required.)

Verified locally against the released SciMLTesting 1.5.0 (GROUP=QA Pkg.test):
QA group 18/18 on both Julia 1.10 (lts) and 1.12 — Aqua 11/11 (incl. Method
ambiguity), JET 1/1, ExplicitImports 6/6. Same checks/coverage as before.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor Author

Converted the QA group to the SciMLTesting 1.5.0 run_qa minimal form (1.5.0 is now released and registered).

qa.jl collapses to:

using SciMLTesting, FunctionProperties, JET, Test
run_qa(FunctionProperties; explicit_imports = true,
    ei_kwargs = (; all_explicit_imports_are_public = (; ignore = (:GotoIfNot,)),
                   all_qualified_accesses_are_public = (; ignore = (:Typeof,))))

Aqua and ExplicitImports are SciMLTesting 1.5 direct deps and are auto-detected, so they are no longer threaded as module args. explicit_imports = true is kept (it defaults to false / opt-in in 1.5). jet auto-detects from using JET. The ei_kwargs ignore-lists for the two Core accesses inherent to hasbranching are retained.

Deps: dropped ExplicitImports from test/qa/Project.toml (now transitive via SciMLTesting); bumped SciMLTesting floor to 1.5 (root + qa env).

Aqua kept as a direct dep on purpose. Dropping Aqua from test/qa/Project.toml makes Aqua's Method ambiguity check error with Package Aqua not found in current path: that check spawns a fresh subprocess via Base.load_path_setup_code() and does using Aqua against the active QA project's load path, where only direct deps resolve. Every other Aqua check runs in-process via SciMLTesting's own Aqua binding and is unaffected, and the six ExplicitImports checks run in-process too — so only the ambiguity subprocess needs Aqua listed here. A load-path fix for that subprocess belongs upstream in SciMLTesting; until then the direct-dep entry stays (documented with a comment in the file).

Verified locally against released SciMLTesting 1.5.0 (GROUP=QA Pkg.test), QA group 18/18 on both Julia 1.10 (lts) and 1.12:

  • Aqua 11/11 (incl. Method ambiguity)
  • JET 1/1
  • ExplicitImports 6/6 (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)

Same checks and coverage as the previous commit. Branch was already current with main (rebase was a no-op). Please ignore until reviewed by @ChrisRackauckas.

@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review June 27, 2026 13:08
@ChrisRackauckas ChrisRackauckas merged commit 8daee52 into SciML:main Jun 27, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants