Symbol is Base.isexported but not Base.isbindingresolved?

Working on Group import hints by ajwheeler · Pull Request #56753 · JuliaLang/julia · GitHub, I was surprised to see that there are cases of symbols s and modules m for which Base.isbindingresolved(m, s) is false, but Base.isexported(m, s) is true. How does this occur?

Welcome! It’s a little funny, but you can export but not define a symbol:

julia> module M
           export foo
       end
Main.M

julia> Base.isbindingresolved(M, :foo)
false

julia> Base.isexported(M, :foo)
true

Thanks! Interesting. What is the reason you would do this?

It’s typically a bug. It’s not immediately an error because we support writing export statements before the definition — and it’s not uncommon for Packages to do this.

Just to add, Aqua.jl can detect this, so it can be used in the tests to prevent merging PRs with undefined exports: Undefined exports · Aqua.jl