fredrikekre / Literate.jl

Simple package for literate programming in Julia
https://fredrikekre.github.io/Literate.jl
Other
543 stars 64 forks source link

UndefVarError occurs while execution of generated notebook #213

Closed ArseniyKholod closed 1 year ago

ArseniyKholod commented 1 year ago

I've generated a documentation with Literate.jl. make.jl is executed:

using Literate
Literate.markdown(joinpath(".","src","test.jl"), ".")
Literate.notebook(joinpath(".","src","test.jl"), ".";)

with src/test.jl:

using Trixi, Plots 
trixi_include(joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"))
plot(sol)

And UndefVarError with the sol variable occurs, the sol is defined in the file joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"). The full Stacktrace see at very bottom.

The trixi_include does nothing else as calls the Base.include with default Main module.

function trixi_include(mod::Module, elixir::AbstractString; kwargs...)
  # Print information on potential wait time only in non-parallel case
  if !mpi_isparallel()
    @info "You just called `trixi_include`. Julia may now compile the code, please be patient."
  end
  Base.include(ex -> replace_assignments(insert_maxiters(ex); kwargs...), mod, elixir)
end

trixi_include(elixir::AbstractString; kwargs...) = trixi_include(Main, elixir; kwargs...)

If I just execute the src/test.jl (meaning without using Literate.notebook ). Code works perfectly.

I found out, that adding @__MODULE__ to src/test.jl solves that issue: New src/test.jl:

using Trixi, Plots 
trixi_include(@__MODULE__,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"))
plot(sol)

1) Is it known behavior? 2) Is there way around adding @__MODULE__?

Error Stacktrace:

[ Info: executing notebook `test.ipynb`
┌ Error: error when executing notebook based on input file: `D:\work\test\Module\src\test.jl`
└ @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:748
ERROR: LoadError: LoadError: UndefVarError: var not defined
in expression starting at D:\work\test\Module\test.ipynb:2
when executing the following code block from inputfile `D:\work\test\Module\src\test.jl`

```julia
using Trixi, Plots
trixi_include(Main.var,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"))
plot(sol)

Stacktrace:
  [1] error(s::String)
    @ Base .\error.jl:35
  [2] execute_block(sb::Module, block::String; inputfile::String, fake_source::String)
    @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:866
  [3] execute_notebook(nb::Dict{Any, Any}; inputfile::String, fake_source::String)
    @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:764
  [4] (::Literate.var"#38#40"{Dict{String, Any}})()
    @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:744
  [5] cd(f::Literate.var"#38#40"{Dict{String, Any}}, dir::String)
    @ Base.Filesystem .\file.jl:101
  [6] jupyter_notebook(chunks::Vector{Literate.Chunk}, config::Dict{String, Any})
    @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:743
  [7] notebook(inputfile::String, outputdir::String; config::Dict{Any, Any}, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:680
  [8] notebook(inputfile::String, outputdir::String)
    @ Literate C:\Users\Lenovo\.julia\packages\Literate\VQn4b\src\Literate.jl:674
  [9] top-level scope
    @ D:\work\test\Module\make.jl:3
 [10] include(fname::String)
    @ Base.MainInclude .\client.jl:476
 [11] top-level scope
    @ REPL[8]:1
in expression starting at D:\work\test\Module\make.jl:3
fredrikekre commented 1 year ago

Is it known behavior?

It is known in the sense that code is not evaluated in Main (by design) but rather in a separate module.

Is there way around adding @MODULE?

Not from the LIterate side. The fact that include_trixi defaults to main is either a feature or design flaw that you would have to discuss with Trixi developers. (A more intuitive behavior, IMO, would be to use a macro and default to the callers current module instead of Main, for example.)