Skip to content

Add ExplicitImports QA checks via SciMLTesting run_qa#41

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

Add ExplicitImports QA checks via SciMLTesting run_qa#41
ChrisRackauckas merged 3 commits into
SciML:masterfrom
ChrisRackauckas-Claude:qa-explicit-imports

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

This PR should be ignored until reviewed by @ChrisRackauckas.

Summary

Wires ExplicitImports.jl into the QA group through SciMLTesting's run_qa (explicit_imports = true), running all six checks and making them pass:

  • Standard: no_implicit_imports, no_stale_explicit_imports, all_explicit_imports_via_owners, all_qualified_accesses_via_owners
  • Public-API: all_qualified_accesses_are_public, all_explicit_imports_are_public

Fixes (FIX > DECLARE-PUBLIC > minimal-IGNORE)

Implicit -> explicit imports (no_implicit_imports): the blanket using Graphs / using DataStructures / using DocStringExtensions / using PrecompileTools (and the SparseArrays extension's blanket usings) are now explicit using X: names. Names owned by Graphs.SimpleGraphs (SimpleDiGraph, SimpleEdge, add_edge!, add_vertex!, rem_edge!) are imported from that owner — which also makes the previously non-public Graphs.SimpleEdge qualified access a public explicit import.

Stale import (no_stale_explicit_imports): the DataStructures v0.18->v0.19 IntDisjointSets->IntDisjointSet rename used import ... IntDisjointSet plus const IntDisjointSet = IntDisjointSets, whose const shadowed the import so it read as stale. Both version branches now alias to a single internal _IntDisjointSet via using ... as, used at the one call site.

Non-public qualified accesses (all_qualified_accesses_are_public): fixed by rewriting where clean —

  • Iterators.filter -> filtered generator (maximal_matching)
  • Iterators.peel -> indexed loop (hypergraph)
  • Base.Fix1(f, x) -> equivalent closures (hypergraph; Fix1 is non-public on the 1.10 LTS)

Ignored (minimal, documented, per-check)

Three remaining accesses are unavoidable, ignored via ei_kwargs on all_qualified_accesses_are_public:

  • Base.OneTo — the vertex-range type returned by 𝑑vertices / condensation-graph vertices; public Base API as of Julia 1.11 but only retroactively marked, so flagged on the 1.10 LTS. Rewriting to UnitRange would change the return type.
  • Base.print_matrix — the only routine for tabular Base.show of a matrix view.
  • Base.typeinfo_implicit — the documented (internal) hook to suppress the element-type header when printing an array of HighlightInt.

Public API declared

None needed: BipartiteGraphs already exports its public names, and the two public-API checks (all_explicit_imports_are_public, all_qualified_accesses_are_public) concern what this package imports from its dependencies, not what it exports.

Test deps

Added ExplicitImports and bumped SciMLTesting to >= 1.4 (its run_qa gained the ExplicitImports option in 1.4.0) in both the main Project.toml and test/qa/Project.toml. JET handling is unchanged.

Verification (local)

Ran on Julia 1.10 (LTS) and Julia 1.11: all six ExplicitImports checks PASS on both.

QA group (GROUP=QA, Julia 1.11):

Test Summary:     | Pass  Total
Quality Assurance |   12     12      # Aqua + 6 ExplicitImports checks
ExplicitImports                     |    6      6
  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

The 2 pre-existing Aqua nits + 1 pre-existing JET @test_broken (tracked in #36) are unchanged. Core suite (539 tests) still passes after the source rewrites.

🤖 Generated with Claude Code

ChrisRackauckas and others added 3 commits June 24, 2026 12:08
Wire ExplicitImports.jl into the QA group through SciMLTesting's `run_qa`
(`explicit_imports = true`), running all six checks: the four standard ones
(no_implicit_imports, no_stale_explicit_imports, all_explicit_imports_via_owners,
all_qualified_accesses_via_owners) and both public-API checks
(all_qualified_accesses_are_public, all_explicit_imports_are_public).

Fixes to make the checks pass:

* Convert the blanket `using Graphs`/`using DataStructures`/`using
  DocStringExtensions`/`using PrecompileTools` (and the extension's blanket
  `using`s) to explicit `using X: names`. Names owned by `Graphs.SimpleGraphs`
  (SimpleDiGraph, SimpleEdge, add_edge!, add_vertex!, rem_edge!) are imported
  from that owner, which also makes the previously non-public `Graphs.SimpleEdge`
  qualified access a public explicit import.
* Resolve the stale `IntDisjointSet` import: the DataStructures v0.18->v0.19
  rename used `import ... IntDisjointSet` plus `const IntDisjointSet =
  IntDisjointSets`, whose const shadowed the import and made it read as stale.
  Both version branches now alias to a single internal name `_IntDisjointSet`
  via `using ... as`, used at the one call site.
* Replace `Iterators.filter` (non-public) with a filtered generator, and
  `Iterators.peel` (non-public) with an indexed loop, in maximal_matching and
  hypergraph respectively.
* Replace `Base.Fix1(f, x)` (non-public on the 1.10 LTS) with equivalent
  closures.

Remaining non-public qualified accesses are unavoidable and ignored per-check
(minimal, documented): `Base.OneTo` (the vertex-range type; public as of Julia
1.11 but only retroactively marked, flagged on the 1.10 LTS), `Base.print_matrix`
(no public matrix-show routine), and `Base.typeinfo_implicit` (documented array-
printing hook).

Test deps: add ExplicitImports and bump SciMLTesting to >=1.4 (run_qa gained the
ExplicitImports option in 1.4.0) in both the main Project.toml and test/qa.

Verified locally on Julia 1.10 (LTS) and 1.11: all six checks pass; the QA group
runs 12 passing QA tests (the two pre-existing Aqua/JET @test_broken nits tracked
in SciML#36 are unchanged). Core test suite (539 tests) still passes.

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 boilerplate collapses:

* qa.jl: drop `using Aqua`/`using ExplicitImports` and the now-redundant
  `Aqua = Aqua`/`ExplicitImports = ExplicitImports` module args. Keep the
  genuine overrides — `aqua_kwargs` (the SciML#36 unbound_args/deps_compat nits),
  `explicit_imports = true` (opt-in in 1.5), and `ei_kwargs` (the documented
  qualified-access ignore-list). `using JET` stays: JET is run in a separate
  `@test_broken` testset, not through `run_qa`.
* Drop ExplicitImports from the test deps (transitive via SciMLTesting now):
  removed from the root [extras]/[compat]/[targets].test and from
  test/qa/[deps]/[compat]. Bump the SciMLTesting [compat] to "1.5".
* Keep Aqua as a direct dep of the test/qa env. Aqua's `ambiguities` check
  spawns a worker process that runs `using Aqua` (via `load_path_setup_code`);
  if Aqua is only transitive (via SciMLTesting) that subprocess hard-errors
  with "Package Aqua not found in current path", erroring the Method-ambiguity
  test. A direct dep keeps the worker able to load it; qa.jl no longer needs to
  `using` it because `run_qa` defaults `Aqua` to SciMLTesting's own dep.

Verified locally against the released SciMLTesting 1.5.0 (Aqua 0.8.16,
ExplicitImports 1.15.0, JET 0.9.18). `GROUP=QA` Pkg.test passes 13/3-broken on
both Julia 1.10 (LTS) and 1.11 — identical to the pre-conversion baseline; the
same six Aqua checks, six ExplicitImports checks, and the JET/Aqua @test_broken
nits run.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ExplicitImports refactor changed precompilation.jl to
`using PrecompileTools: @compile_workload, @setup_workload`, importing only
the macros and not the PrecompileTools module name. On PrecompileTools 1.0.x
the @setup_workload macro expands to `PrecompileTools.@load_preference(...)`,
referencing the bare module name in the caller's scope, which is no longer
bound under the explicit import. This made the Downgrade lane (floor 1.0.0)
fail to precompile with `UndefVarError: PrecompileTools not defined`.

PrecompileTools 1.1.0 made the macros self-contained, so raising the floor to
1.1 keeps the explicit-import form working under downgrade resolution.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review June 27, 2026 13:04
@ChrisRackauckas ChrisRackauckas merged commit 0573d9e into SciML:master Jun 27, 2026
10 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