JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.87k stars 5.49k forks source link

REPLExt: no method matching repl_init(::REPL.LineEditREPL) when loading packages in REPL mode. #56216

Open ndgnuh opened 1 month ago

ndgnuh commented 1 month ago

Behaviour

When loading some packages in REPL, REPLExt throws an exception.

Expected behaviour

No exception thrown?

Reproduce

To reproduce:

  1. julia-release --startup-file=no -t 1
  2. using IJulia (or other packages)

Packages that reproduce the bug:

Packages that don't reproduce the bug:

Version info:

Julia Version 1.11.1
Commit 8f5b7ca12ad (2024-10-16 10:53 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 16 × AMD Ryzen 7 4800H with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, znver2)
Threads: 16 default, 0 interactive, 8 GC (on 16 virtual cores)
Environment:
  JULIA_NUM_THREADS = 16
  LD_LIBRARY_LOADPATH = /opt/wine-staging/lib64:/opt/wine-staging/lib:/opt/nvim-linux64/lib:/opt/containerd/lib:
  JULIA_CUDA_USE_BINARYBUILDER = true
  JULIA_DEPOT_PATH = /home/<my-user>/.cache/julia

Stack trace

```julia ERROR: InitError: MethodError: no method matching repl_init(::REPL.LineEditREPL) The function `repl_init` exists, but no method is defined for this combination of argument types. Closest candidates are: repl_init(::REPL.AbstractREPL) @ REPLExt ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/Pkg/ext/REPLExt/REPLExt.jl:163 Stacktrace: [1] __init__() @ REPLExt ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/Pkg/ext/REPLExt/REPLExt.jl:305 [2] run_module_init(mod::Module, i::Int64) @ Base ./loading.jl:1336 [3] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String) @ Base ./loading.jl:1324 [4] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{Any}, ignore_native::Nothing; register::Bool) @ Base ./loading.jl:1213 [5] _include_from_serialized (repeats 2 times) @ ./loading.jl:1169 [inlined] [6] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128, stalecheck::Bool; reasons::Dict{String, Int64}, DEPOT_PATH::Vector{String}) @ Base ./loading.jl:1969 [7] _require(pkg::Base.PkgId, env::String) @ Base ./loading.jl:2450 [8] __require_prelocked(uuidkey::Base.PkgId, env::String) @ Base ./loading.jl:2315 [9] #invoke_in_world#3 @ ./essentials.jl:1089 [inlined] [10] invoke_in_world @ ./essentials.jl:1086 [inlined] [11] _require_prelocked(uuidkey::Base.PkgId, env::String) @ Base ./loading.jl:2302 [12] macro expansion @ ./loading.jl:2241 [inlined] [13] macro expansion @ ./lock.jl:273 [inlined] [14] __require(into::Module, mod::Symbol) @ Base ./loading.jl:2198 [15] #invoke_in_world#3 @ ./essentials.jl:1089 [inlined] [16] invoke_in_world @ ./essentials.jl:1086 [inlined] [17] require(into::Module, mod::Symbol) @ Base ./loading.jl:2191 during initialization of module REPLExt ```

Extra information

vtjnash commented 1 month ago

This is either a duplicate of https://github.com/JuliaLang/julia/issues/56091#issuecomment-2420144128 or a Pkg bug (wrongly assuming that active_repl must be assigned exactly to a REPL.AbstractREPL, while Base never made such a promise)

Vortriz commented 1 month ago

I am facing the exact same issue with Plots.jl

KristofferC commented 1 month ago

@vtjnash, how do you add a new REPL mode right now from a package? You keep saying these are bugs but they weren't bugs until the code under it changed and caused the bugs?

zvnkk commented 1 month ago

I added Depot path to move packages from c to d and now i have this error

zvnkk commented 1 month ago

So i deleted everything in new Depot path on d disk and installed only pluto, after running using Pluto command the error is there however when i remove $env:JULIA_DEPOT_PATH = "D:/.julia" from powershell config and return to default c:/usr/.julia folder error goes away. however i want to have .julia on d dist , what to do ?

zvnkk commented 1 month ago

writing using Pkg in startup.jl file worked

ndgnuh commented 1 month ago

So i deleted everything in new Depot path on d disk and installed only pluto, after running using Pluto command the error is there however when i remove $env:JULIA_DEPOT_PATH = "D:/.julia" from powershell config and return to default c:/usr/.julia folder error goes away. however i want to have .julia on d dist , what to do ?

I tried removing the JULIA_DEPOT_PATH. The bug indeed goes away. Therefore, reproducing this bug seems to require adding a custom JULIA_DEPOT_PATH.

IanButterworth commented 3 weeks ago

I just hit this when using a modified version of REPL on nightly, without a custom depot, but I guess it meant REPL was precompiled to the user depot, which might be relevant.

But shouldn't repl_init(::REPL.AbstractREPL) accept LineEditREPL? It feels like we might have two different REPLs loaded..

i.e. I don't think https://github.com/JuliaLang/Pkg.jl/pull/4067 fixes this..

% ./julia --start=no -ie "using REPL"
Precompiling REPL finished.
  1 dependency successfully precompiled in 22 seconds. 6 already precompiled.
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.12.0-DEV.1518 (2024-10-30)
 _/ |\__'_|_|_|\__'_|  |  Commit 599b7ec51a (0 days old master)
|__/                   |

(@v1.12) pkg> Unhandled Task ERROR: InitError: MethodError: no method matching repl_init(::LineEditREPL)
The function `repl_init` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  repl_init(::REPL.AbstractREPL)
   @ REPLExt ~/Documents/GitHub/julia/usr/share/julia/stdlib/v1.12/Pkg/ext/REPLExt/REPLExt.jl:171

Stacktrace:
  [1] __init__()
    @ REPLExt ~/Documents/GitHub/julia/usr/share/julia/stdlib/v1.12/Pkg/ext/REPLExt/REPLExt.jl:314
  [2] run_module_init(mod::Module, i::Int64)
    @ Base ./loading.jl:1418
  [3] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String)
    @ Base ./loading.jl:1406
  [4] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{Any}, ignore_native::Nothing; register::Bool)
    @ Base ./loading.jl:1294
  [5] _include_from_serialized (repeats 2 times)
    @ ./loading.jl:1245 [inlined]
  [6] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128, stalecheck::Bool; reasons::Nothing, DEPOT_PATH::Vector{String})
    @ Base ./loading.jl:2115
  [7] _require_search_from_serialized
    @ ./loading.jl:2009 [inlined]
  [8] macro expansion
    @ ./loading.jl:2775 [inlined]
  [9] macro expansion
    @ ./lock.jl:294 [inlined]
 [10] require_stdlib(package_uuidkey::Base.PkgId, ext::String)
    @ Base ./loading.jl:2760
 [11] load_pkg
    @ ~/Documents/GitHub/julia/usr/share/julia/stdlib/v1.12/REPL/src/Pkg_beforeload.jl:4 [inlined]
 [12] (::REPL.var"#setup_interface##26#setup_interface##27"{REPL.LineEdit.MIState, LineEditREPL, REPL.LineEdit.Prompt})()
    @ REPL ~/Documents/GitHub/julia/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:1457
during initialization of module REPLExt
Andriamanitra commented 3 weeks ago

I started seeing this issue after updating Julia from 1.10 to 1.11.1. In my case the package that triggers it is Plots.jl. My JULIA_DEPOT_PATH is set to ~/Packages/julia.

Julia Version 1.11.1
Commit 8f5b7ca12ad (2024-10-16 10:53 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 24 × AMD Ryzen 9 5900X 12-Core Processor
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, znver3)
Threads: 1 default, 0 interactive, 1 GC (on 24 virtual cores)
Environment:
  JULIA_DEPOT_PATH = /home/mikko/Packages/julia
Stack trace ```jl ERROR: InitError: MethodError: no method matching repl_init(::REPL.LineEditREPL) The function `repl_init` exists, but no method is defined for this combination of argument types. Closest candidates are: repl_init(::REPL.AbstractREPL) @ REPLExt ~/Packages/julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/Pkg/ext/REPLExt/REPLExt.jl:163 Stacktrace: [1] __init__() @ REPLExt ~/Packages/julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/Pkg/ext/REPLExt/REPLExt.jl:305 [2] run_module_init(mod::Module, i::Int64) @ Base ./loading.jl:1336 [3] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String) @ Base ./loading.jl:1324 [4] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{…}, ignore_native::Nothing; register::Bool) @ Base ./loading.jl:1213 [5] _include_from_serialized (repeats 2 times) @ ./loading.jl:1169 [inlined] [6] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128, stalecheck::Bool; reasons::Dict{…}, DEPOT_PATH::Vector{…}) @ Base ./loading.jl:1969 [7] _require(pkg::Base.PkgId, env::String) @ Base ./loading.jl:2450 [8] __require_prelocked(uuidkey::Base.PkgId, env::String) @ Base ./loading.jl:2315 [9] #invoke_in_world#3 @ ./essentials.jl:1089 [inlined] [10] invoke_in_world @ ./essentials.jl:1086 [inlined] [11] _require_prelocked(uuidkey::Base.PkgId, env::String) @ Base ./loading.jl:2302 [12] macro expansion @ ./loading.jl:2241 [inlined] [13] macro expansion @ ./lock.jl:273 [inlined] [14] __require(into::Module, mod::Symbol) @ Base ./loading.jl:2198 [15] #invoke_in_world#3 @ ./essentials.jl:1089 [inlined] [16] invoke_in_world @ ./essentials.jl:1086 [inlined] [17] require(into::Module, mod::Symbol) @ Base ./loading.jl:2191 [18] top-level scope @ ~/Packages/julia/packages/Plots/kLeqV/src/backends.jl:568 [19] eval @ ./boot.jl:430 [inlined] [20] _initialize_backend(pkg::Plots.PlotlyBackend) @ Plots ~/Packages/julia/packages/Plots/kLeqV/src/backends.jl:567 [21] backend(pkg::Plots.PlotlyBackend) @ Plots ~/Packages/julia/packages/Plots/kLeqV/src/backends.jl:245 [22] plotly @ ~/Packages/julia/packages/Plots/kLeqV/src/backends.jl:86 [inlined] [23] plot_standings(get_schedule::typeof(GraphicalNhlStandings.read_cached_schedule)) @ GraphicalNhlStandings ~/coding/GraphicalNhlStandings/src/GraphicalNhlStandings.jl:120 [24] top-level scope @ REPL[2]:1 ```
matthias314 commented 4 days ago

Is this supposed to be fixed in Julia 1.11.2?

I still see this error with the release-1.11 branch when loading for example TerminalPager. If I unset JULIA_DEPOT_PATH, the problem disappears.

IanButterworth commented 4 days ago

Can you share the error message. It should at least be different.

matthias314 commented 4 days ago

Here it is. You are right, it's slightly different.

$ ./julia --startup=no
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.11.1 (2024-11-21)
 _/ |\__'_|_|_|\__'_|  |  release-1.11/229f027675* (fork: 527 commits, 280 days)
|__/                   |

julia> using TerminalPager
ERROR: InitError: MethodError: no method matching _init_pager_repl_mode(::REPL.LineEditREPL)
The function `_init_pager_repl_mode` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  _init_pager_repl_mode(::REPL.AbstractREPL)
   @ TerminalPager /usr/local/julia-depot/packages/TerminalPager/RRlVk/src/repl.jl:158
IanButterworth commented 4 days ago

My guess is we have two versions of REPL loaded and it's interacting badly, but it's really unclear to me.

I also don't understand why this is happening only when you set JULIA_DEPOT_PATH

@vtjnash require_stdlib should be loading the same REPL cache file however JULIA_DEPOT_PATH is set, I believe?

vtjnash commented 4 days ago

You need https://github.com/JuliaLang/julia/pull/55908, which I believe is v1.11.2

IanButterworth commented 4 days ago

The above is on the tip of release-1.11 https://github.com/JuliaLang/julia/commit/229f027675bd360c98f2cd1628e204eeb9e8ab14 so that's either not there or not working

IanButterworth commented 4 days ago

Doesn't appear to be on release-1.11 but the backport label was removed @KristofferC

IanButterworth commented 4 days ago

It was on https://github.com/JuliaLang/julia/pull/56476 but that was, I think, autoclosed (but github doesn't make that clear)

IanButterworth commented 4 days ago

It is on release-1.11 so #55908 didn't fix this.

vtjnash commented 4 days ago

Oh, if you also have JULIA_DEPOT_PATH that excludes stdlib, that is an explicit directive never to load the one in stdlib for the user, so this is working as expected

vtjnash commented 4 days ago

We have a test to make sure this does it correctly with : vs without that: (https://github.com/JuliaLang/julia/pull/55908#issuecomment-2380054511)

IanButterworth commented 4 days ago

So what's the actual reason for the failure here? If the bundled cache isn't loaded because JULIA_DEPOT_PATH is missing :, then... I don't understand.

vtjnash commented 4 days ago

The failure here is a failure of some packages to correctly respect the API of the Base.active_repl value. In particular, it is a private value that is unsafe to access from __init__

matthias314 commented 4 days ago

In case it matters: I'm using

JULIA_DEPOT_PATH = /usr/local/julia-depot

EDIT: Another package where this problem occurs is Cthulhu, see JuliaDebug/Cthulhu.jl#608.

IanButterworth commented 4 days ago
julia> REPL.LineEditREPL <: REPL.AbstractREPL
true

Yet

julia> using TerminalPager
ERROR: InitError: MethodError: no method matching _init_pager_repl_mode(::REPL.LineEditREPL)
The function `_init_pager_repl_mode` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  _init_pager_repl_mode(::REPL.AbstractREPL)
   @ TerminalPager /usr/local/julia-depot/packages/TerminalPager/RRlVk/src/repl.jl:158
vtjnash commented 4 days ago

Yes, while some names may print the same, that won't guarantee they are the same type

vtjnash commented 4 days ago

Once https://github.com/JuliaLang/julia/pull/54654 merges, that will be true even less frequently than it is now

IanButterworth commented 4 days ago

So when there's no trailing : we get two different REPL modules loaded, and errors like this.

When JULIA_DEPOT_PATH isnt set or there's a trailing : we only get one REPL module loaded?

If so, I don't understand why that's desirable.

vtjnash commented 4 days ago

It is the meaning of the : is whether or not the stdlibs are supposed to be available to extended in package code. Without the : the stdlib code is not supposed to be extended as the user has taken that out of their path. However, in no case is extension supposed to occur anyways of stdlibs, as that is documented as being piracy or private

giordano commented 4 days ago

Wasn't that for the load path rather than the depot path?