operator
operator

Reputation: 195

Error when loading custom modules in Julia project environment

I want to create Julia environment in a similar way to a conda environment. However, creating a Project.toml with the necessary packages means I am unable to use local/custom modules. I have a basic project structure

- julia_test
    - MyModule.jl
    - main.jl

where MyModule.jl

module MyModule
function f(a, b)
        return (a+b)^2
end
end

and main.jl

using Distributions

using MyModule

function main()
        a = Normal()
        b = rand(a, 2)
        c = MyModule.f(b[1], b[2])
end

main()

Finally set the required environment variable

export JULIA_LOAD_PATH="~/julia_test:$JULIA_LOAD_PATH"

and everything runs fine. However adding a Project.toml

[deps]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"

results in a error when running main.jl

ERROR: LoadError: ArgumentError: Package MyModule not found in current path:
- Run `import Pkg; Pkg.add("MyModule")` to install the MyModule package.

Upvotes: 1

Views: 754

Answers (1)

Matěj Račinský
Matěj Račinský

Reputation: 1804

Julia does not have such powerful "package discovery" as python so you need to be more precise when working with package manager. You can include the module by using

include("MyModule.jl")

instead of

import MyModule

where the "MyModule.jl" is relative path to the main.jl, and that will work.

The thing to notice here is that this is not utilizing the package manager, the include function is just spicy copy-paste.

If you wanted to use it as import MyModule or using MyModule instead of the include, you would need to make a package from MyModule. Contrarily to python, Julia does not discover all modules in JULIA_LOAD_PATH in same manner as python discovers them in PYTHONPATH. The discovery works for packages, not modules.

In order to wrap the MyModule into package, you can generate the skeleton using ] generate MyModule which will generate the following structure (assuming you run it in julia_test)

- julia_test
  - MyModule (this is generated)
    - src
      - MyModule.jl
    - Project.toml
  - MyModule.jl (this is here from earlier)
  - main.jl (this is here from earlier)

and if you move the julia_test/MyModule.jl to julia_test/MyModule/src/MyModule.jl, then you are able to run ] dev MyModule which will add it as development dependency (all changes in MyModule will be reflected similarily to pip install -e <package>).

Then you can call using MyModule or import MyModule and it will work. You should see in julia_test/Manifest.toml the MyModule and its relative path.

In order to add it using ] add MyModule as a package instead of dev, the MyModule would need to be a git repo, because julia allows adding only git repos as packages (dev is the exception).

Also, to make it work, you don't need to modify the JULIA_LOAD_PATH, because the MyModule in ] dev MyModule is the relative path from your working directory.

Upvotes: 3

Related Questions