Find path of imported module

Is there a simple way to find out from where a module is imported? I.e. something like

using Foo
path(Foo)
Pkg.dir("Foo")

or

using Foo
Pkg.dir(string(Foo))

should do it.

This works only for packages that are installed by the package manager. In fact the package doesn’t even have to be installed - it just returns the directory + the given name:

julia> Pkg.dir("abcde123")
"/home/sebastian/.julia/v0.5/abcde123"

I also want to handle the case where the module is loaded from somewhere else via LOAD_PATH.

1 Like

Assuming the module folder follows the standard structure and also that the module defines or extends at least one function this should work:

function moduleloc(M::Module)
    for n in names(M, true, true)
        if isdefined(M, n) && getfield(M, n) isa Function
            f = getfield(M, n)
            ms = Iterators.filter(m-> m.module==M, methods(f))
            if !isempty(ms)
                dir = join(split(string(first(ms).file), "/")[1:end-1], "/")
                return dir
            end
        end
    end
    return ""
end
2 Likes

Based on this, but simpler and more robust, consider

dirname(dirname(Base.functionloc(Foo.eval, Tuple{Void})[1]))

This assumes that the module was declared with module rather than baremodule, and uses the fact that the module Foo line is the one credited for the definition of the Foo.eval function (which is defined for all modules).

4 Likes

Thank you both very much for taking the time to even implement these functions for me!