From d830b45434e8187541c2232d3b329503af85f5ee Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 9 Sep 2024 21:01:08 -0400 Subject: [PATCH] Fix `pkgdir` for extensions (#55720) Fixes https://github.com/JuliaLang/julia/issues/55719 --------- Co-authored-by: Max Horn <241512+fingolfin@users.noreply.github.com> (cherry picked from commit 99b8868ff563eded17376b3f90ffc1637222f2c6) --- base/loading.jl | 16 +++++++++++++++- test/loading.jl | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index 164ee21501287..db95a12fab047 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -536,6 +536,8 @@ package root. To get the root directory of the package that implements the current module the form `pkgdir(@__MODULE__)` can be used. +If an extension module is given, the root of the parent package is returned. + ```julia-repl julia> pkgdir(Foo) "/path/to/Foo.jl" @@ -551,7 +553,19 @@ function pkgdir(m::Module, paths::String...) rootmodule = moduleroot(m) path = pathof(rootmodule) path === nothing && return nothing - return joinpath(dirname(dirname(path)), paths...) + original = path + path, base = splitdir(dirname(path)) + if base == "src" + # package source in `../src/Foo.jl` + elseif base == "ext" + # extension source in `../ext/FooExt.jl` + elseif basename(path) == "ext" + # extension source in `../ext/FooExt/FooExt.jl` + path = dirname(path) + else + error("Unexpected path structure for module source: $original") + end + return joinpath(path, paths...) end function get_pkgversion_from_path(path) diff --git a/test/loading.jl b/test/loading.jl index 6c08d50ba17d4..e8175a8acf810 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -1004,6 +1004,16 @@ end end @testset "Extensions" begin + test_ext = """ + function test_ext(parent::Module, ext::Symbol) + _ext = Base.get_extension(parent, ext) + _ext isa Module || error("expected extension \$ext to be loaded") + _pkgdir = pkgdir(_ext) + _pkgdir == pkgdir(parent) != nothing || error("unexpected extension \$ext pkgdir path: \$_pkgdir") + _pkgversion = pkgversion(_ext) + _pkgversion == pkgversion(parent) || error("unexpected extension \$ext version: \$_pkgversion") + end + """ depot_path = mktempdir() try proj = joinpath(@__DIR__, "project", "Extensions", "HasDepWithExtensions.jl") @@ -1014,6 +1024,7 @@ end cmd = """ $load_distr begin + $ew $test_ext $ew push!(empty!(DEPOT_PATH), $(repr(depot_path))) using HasExtensions $ew using HasExtensions @@ -1021,6 +1032,7 @@ end $ew HasExtensions.ext_loaded && error("ext_loaded set") using HasDepWithExtensions $ew using HasDepWithExtensions + $ew test_ext(HasExtensions, :Extension) $ew Base.get_extension(HasExtensions, :Extension).extvar == 1 || error("extvar in Extension not set") $ew HasExtensions.ext_loaded || error("ext_loaded not set") $ew HasExtensions.ext_folder_loaded && error("ext_folder_loaded set") @@ -1070,11 +1082,12 @@ end test_ext_proj = """ begin + $test_ext using HasExtensions using ExtDep - Base.get_extension(HasExtensions, :Extension) isa Module || error("expected extension to load") + test_ext(HasExtensions, :Extension) using ExtDep2 - Base.get_extension(HasExtensions, :ExtensionFolder) isa Module || error("expected extension to load") + test_ext(HasExtensions, :ExtensionFolder) end """ for compile in (`--compiled-modules=no`, ``)