Skip to content

Conversation

@nickrobinson251
Copy link
Member

Adds a new keyword from (name TDB) to the functions check_all_qualified_accesses_are_public and check_all_explicit_imports_are_public, which allows specifying which dependencies we want to include in the check.

The use-case is migrating a codebase to use only public APIs, and wanting to incrementally lock-in the progress made.

E.g. suppose MyPackage depends on many packages, including LinearAlgebra and DataStructures, and uses non-public functions from all of them. First we'd like to update MyPackage to use only the public API of LinearAlgebra.jl, then add the test:

check_all_explicit_imports_are_public(MyPackage; from=(LinearAlgebra,))

then update MyPackage to only use public API of DataStructures.jl and update the test to be:

check_all_explicit_imports_are_public(MyPackage; from=(LinearAlgebra, DataStructures))

and so on until finally the test can become simply

check_all_explicit_imports_are_public(MyPackage)

Right now incremental test coverage is possible on an "opt-out" basis, using ignore and/or skip as appropriate, but this PR adds the ability to test on an "opt-in" basis.

Our actual use-case is slightly more involved: we have N internal packages MyPkg1, MyPkg2, ..., MyPkgN, with dependencies between them, and many packages don't even declare a public API (no export or public), so we'd like to go through and (i) give MyPkg1 a public API, and (ii) update all MyPkgX packages to only use that API and lock that in, which is why we want to "opt-in" a package at a time

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a from keyword parameter to check_all_qualified_accesses_are_public and check_all_explicit_imports_are_public functions, allowing users to restrict public name checks to only specific modules. Instead of checking all qualified accesses or imports, users can now target only accesses/imports from particular modules (e.g., DataFrames, LinearAlgebra).

Key changes:

  • Added from::Tuple=() parameter to both check functions
  • Implemented filtering logic to keep only items from specified modules when from is non-empty
  • Added documentation and test cases for the new functionality

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/checks.jl Added from parameter and filtering logic to both check_all_qualified_accesses_are_public and check_all_explicit_imports_are_public functions, plus documentation
test/runtests.jl Added test cases verifying the from parameter filters to only specified modules

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

src/checks.jl Outdated
Comment on lines 416 to 420
for from_mod in from
filter!(problematic) do row
return row.accessing_from == from_mod
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't quite look right, isn't this the intersection of from, not the union?

Copy link
Member

@ericphanson ericphanson Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 min old PR and I'm scooped by a robot :(. at least reassuring we both noticed it.

edit: though its explanation of the issue does not seem to be quite correct

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops. Thanks! Fixed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also copilot wrote this code, so it should really have a word with itself)

@nickrobinson251
Copy link
Member Author

Is it okay to allow this to work with Symbols as well as Modules, like

check_all_explicit_imports_are_public(MyPackage; from=(:LinearAlgebra, :DataStructures))

?

And is there a nice way to do that? (Other than something like row.accessing_from in from || Symbol(row.accessing_from) in Symbol.(from))

That way for my use-case I could write a test helper that hardcodes the list, like (:LinearAlgebra, :DataStructures), and have all packages use this helper regardless of if they actually depend on LinearAlgebra and DataStructures (i.e. if you depend on these, you must only be using public names)

@ericphanson
Copy link
Member

We don't allow symbols for modules anywhere else, so I'd rather not. In your tests though you could add a line to get the modules from a symbol list (with eval I guess) when they're loaded.

@ericphanson
Copy link
Member

if you pass from=(X,) should also verify accesses from X.Y? eg X.Y._foo. or

using X: Y
Y._foo

? i think probably yes, so we would need to see if accessing_from is a submodule of any module in from. I think we do have some helpers for submodules used elsewhere to help with this. We should also test this case.

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.

3 participants