Is this allowed?
module PackageProblem
function __init__()
@eval begin
struct NewType
a::Float64
end
const b = NewType(1.0)
end
end
The package loads fine
julia> using PackageProblem
julia> PackageProblem.b
PackageProblem.NewType(1.0)
but Aqua.jl gives this error message:
ERROR: LoadError: InitError: Evaluation into the closed module `PackageProblem` breaks incremental compilation because the side effects will not be permanent. This is likely due to some other module mutating `PackageProblem` with `eval` during precompilation - don't do this.
You get a similar error if you create another package, pkg2
, and use the package manager to add PackageProblem
as a dependency to pkg2
.
(pkg2) pkg> add ..\PackageProblem\\
...
Precompiling project...
✗ pkg2
1 dependency successfully precompiled in 2 seconds
1 dependency errored.
For a report of the errors see `julia> err`. To retry use `pkg> precompile`
julia> err
...
PkgPrecompileError: The following 1 direct dependency failed to precompile:...
ERROR: LoadError: InitError: Evaluation into the closed module `PackageProblem` breaks incremental compilation because the side effects will not be permanent. This is likely due to some other module mutating `PackageProblem` with `eval` during precompilation - don't do this.
If you want your package usable as a dependency is it forbidden to add new types to it in the __init__
function? Or is there a way to do the eval that doesn’t run afoul of precompilation rules?
If it is forbidden then would it be okay to have another function that adds types to the package like this:
function user_init()
@eval PackageProblem begin ...(type defs here)... end
end
which the user calls after the package has been loaded? Or does this also mess up precompilation, perhaps in a way that Aqua.jl doesn’t detect?
In this MWE it obviously is more sensible to define the type and const outside of the __init__
function. But, for my application the types and consts can only be determined when the package is loaded so they either have to be defined in the __init__
function or afterward in the user_init
function.