Skip to content

Commit 203d234

Browse files
authored
Add a hint when failing to import a module in cases where a user might want to use a relative import (#40984)
* Add a hint when failing to import a module in cases where a user might want to use a relative import
1 parent 00a602b commit 203d234

File tree

2 files changed

+96
-3
lines changed

2 files changed

+96
-3
lines changed

base/loading.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,10 +975,20 @@ function require(into::Module, mod::Symbol)
975975
if uuidkey === nothing
976976
where = PkgId(into)
977977
if where.uuid === nothing
978+
hint, dots = begin
979+
if isdefined(into, mod) && getfield(into, mod) isa Module
980+
true, "."
981+
elseif isdefined(parentmodule(into), mod) && getfield(parentmodule(into), mod) isa Module
982+
true, ".."
983+
else
984+
false, ""
985+
end
986+
end
987+
hint_message = hint ? ", maybe you meant `import/using $(dots)$(mod)`" : ""
988+
start_sentence = hint ? "Otherwise, run" : "Run"
978989
throw(ArgumentError("""
979-
Package $mod not found in current path:
980-
- Run `import Pkg; Pkg.add($(repr(String(mod))))` to install the $mod package.
981-
"""))
990+
Package $mod not found in current path$hint_message.
991+
- $start_sentence `import Pkg; Pkg.add($(repr(String(mod))))` to install the $mod package."""))
982992
else
983993
s = """
984994
Package $(where.name) does not have $mod in its dependencies:

test/errorshow.jl

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,3 +803,86 @@ if Sys.isapple() || (Sys.islinux() && Sys.ARCH === :x86_64)
803803
end
804804
end
805805
end # Sys.isapple()
806+
807+
@testset "error message hints relative modules #40959" begin
808+
m = Module()
809+
expr = :(module Foo
810+
module Bar
811+
end
812+
813+
using Bar
814+
end)
815+
try
816+
Base.eval(m, expr)
817+
catch err
818+
err_str = sprint(showerror, err)
819+
@test contains(err_str, "maybe you meant `import/using .Bar`")
820+
end
821+
822+
m = Module()
823+
expr = :(module Foo
824+
Bar = 3
825+
826+
using Bar
827+
end)
828+
try
829+
Base.eval(m, expr)
830+
catch err
831+
err_str = sprint(showerror, err)
832+
@test !contains(err_str, "maybe you meant `import/using .Bar`")
833+
end
834+
835+
m = Module()
836+
expr = :(module Foo
837+
using Bar
838+
end)
839+
try
840+
Base.eval(m, expr)
841+
catch err
842+
err_str = sprint(showerror, err)
843+
@test !contains(err_str, "maybe you meant `import/using .Bar`")
844+
end
845+
846+
m = Module()
847+
expr = :(module Foo
848+
module Bar end
849+
module Buzz
850+
using Bar
851+
end
852+
end)
853+
try
854+
Base.eval(m, expr)
855+
catch err
856+
err_str = sprint(showerror, err)
857+
@test contains(err_str, "maybe you meant `import/using ..Bar`")
858+
end
859+
860+
m = Module()
861+
expr = :(module Foo
862+
Bar = 3
863+
module Buzz
864+
using Bar
865+
end
866+
end)
867+
try
868+
Base.eval(m, expr)
869+
catch err
870+
err_str = sprint(showerror, err)
871+
@test !contains(err_str, "maybe you meant `import/using ..Bar`")
872+
end
873+
874+
m = Module()
875+
expr = :(module Foo
876+
module Bar end
877+
module Buzz
878+
module Bar end
879+
using Bar
880+
end
881+
end)
882+
try
883+
Base.eval(m, expr)
884+
catch err
885+
err_str = sprint(showerror, err)
886+
@test contains(err_str, "maybe you meant `import/using .Bar`")
887+
end
888+
end

0 commit comments

Comments
 (0)