diff --git a/base/Base.jl b/base/Base.jl index a8685aa8cc52c..a47a3a5c6459d 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -224,7 +224,7 @@ delete_method(which(Pair{Any,Any}, (Any, Any))) end # The REPL stdlib hooks into Base using this Ref -const REPL_MODULE_REF = Ref{Module}() +const REPL_MODULE_REF = Ref{Module}(Base) include("checked.jl") using .Checked diff --git a/base/client.jl b/base/client.jl index f6b83ecd0f4a0..7fc40d7906879 100644 --- a/base/client.jl +++ b/base/client.jl @@ -416,78 +416,97 @@ function load_REPL() end global active_repl +global active_repl_backend = nothing + +function run_fallback_repl(interactive::Bool) + let input = stdin + if isa(input, File) || isa(input, IOStream) + # for files, we can slurp in the whole thing at once + ex = parse_input_line(read(input, String)) + if Meta.isexpr(ex, :toplevel) + # if we get back a list of statements, eval them sequentially + # as if we had parsed them sequentially + for stmt in ex.args + eval_user_input(stderr, stmt, true) + end + body = ex.args + else + eval_user_input(stderr, ex, true) + end + else + while !eof(input) + if interactive + print("julia> ") + flush(stdout) + end + try + line = "" + ex = nothing + while !eof(input) + line *= readline(input, keep=true) + ex = parse_input_line(line) + if !(isa(ex, Expr) && ex.head === :incomplete) + break + end + end + eval_user_input(stderr, ex, true) + catch err + isa(err, InterruptException) ? print("\n\n") : rethrow() + end + end + end + end + nothing +end + +function run_std_repl(REPL::Module, quiet::Bool, banner::Symbol, history_file::Bool) + term_env = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb") + term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr) + banner == :no || REPL.banner(term, short=banner==:short) + if term.term_type == "dumb" + repl = REPL.BasicREPL(term) + quiet || @warn "Terminal not fully functional" + else + repl = REPL.LineEditREPL(term, get(stdout, :color, false), true) + repl.history_file = history_file + end + # Make sure any displays pushed in .julia/config/startup.jl ends up above the + # REPLDisplay + d = REPL.REPLDisplay(repl) + last_active_repl = @isdefined(active_repl) ? active_repl : nothing + last_active_repl_backend = active_repl_backend + global active_repl = repl + pushdisplay(d) + try + global active_repl = repl + _atreplinit(repl) + REPL.run_repl(repl, backend->(global active_repl_backend = backend)) + finally + popdisplay(d) + active_repl = last_active_repl + active_repl_backend = last_active_repl_backend + end + nothing +end # run the requested sort of evaluation loop on stdio function run_main_repl(interactive::Bool, quiet::Bool, banner::Symbol, history_file::Bool) fallback_repl = parse(Bool, get(ENV, "JULIA_FALLBACK_REPL", "false")) if !fallback_repl && interactive load_InteractiveUtils() - if !isassigned(REPL_MODULE_REF) + REPL = REPL_MODULE_REF[] + if REPL === Base load_REPL() end end - # TODO cleanup REPL_MODULE_REF - if !fallback_repl && interactive && isassigned(REPL_MODULE_REF) - invokelatest(REPL_MODULE_REF[]) do REPL - term_env = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb") - term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr) - banner == :no || REPL.banner(term, short=banner==:short) - if term.term_type == "dumb" - repl = REPL.BasicREPL(term) - quiet || @warn "Terminal not fully functional" - else - repl = REPL.LineEditREPL(term, get(stdout, :color, false), true) - repl.history_file = history_file - end - global active_repl = repl - # Make sure any displays pushed in .julia/config/startup.jl ends up above the - # REPLDisplay - pushdisplay(REPL.REPLDisplay(repl)) - _atreplinit(repl) - REPL.run_repl(repl, backend->(global active_repl_backend = backend)) - end + REPL = REPL_MODULE_REF[] + if !fallback_repl && interactive && REPL !== Base + invokelatest(run_std_repl, REPL, quiet, banner, history_file) else - # otherwise provide a simple fallback if !fallback_repl && interactive && !quiet @warn "REPL provider not available: using basic fallback" LOAD_PATH=join(Base.LOAD_PATH, Sys.iswindows() ? ';' : ':') end - let input = stdin - if isa(input, File) || isa(input, IOStream) - # for files, we can slurp in the whole thing at once - ex = parse_input_line(read(input, String)) - if Meta.isexpr(ex, :toplevel) - # if we get back a list of statements, eval them sequentially - # as if we had parsed them sequentially - for stmt in ex.args - eval_user_input(stderr, stmt, true) - end - body = ex.args - else - eval_user_input(stderr, ex, true) - end - else - while !eof(input) - if interactive - print("julia> ") - flush(stdout) - end - try - line = "" - ex = nothing - while !eof(input) - line *= readline(input, keep=true) - ex = parse_input_line(line) - if !(isa(ex, Expr) && ex.head === :incomplete) - break - end - end - eval_user_input(stderr, ex, true) - catch err - isa(err, InterruptException) ? print("\n\n") : rethrow() - end - end - end - end + run_fallback_repl(interactive) end nothing end diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index b7a17f2e3ee70..1327a1f795d4f 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -610,9 +610,8 @@ function docm(source::LineNumberNode, mod::Module, ex) @nospecialize ex if isexpr(ex, :->) && length(ex.args) > 1 return docm(source, mod, ex.args...) - elseif isassigned(Base.REPL_MODULE_REF) + elseif (REPL = Base.REPL_MODULE_REF[]) !== Base # TODO: this is a shim to continue to allow `@doc` for looking up docstrings - REPL = Base.REPL_MODULE_REF[] return invokelatest(REPL.lookup_doc, ex) else return simple_lookup_doc(ex) diff --git a/base/loading.jl b/base/loading.jl index bd985e431e497..95ab89cd65998 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1121,13 +1121,8 @@ function cache_file_entry(pkg::PkgId) uuid === nothing ? pkg.name : package_slug(uuid) end -# for use during running the REPL precompilation subprocess script, given we don't -# want it to pick up caches that already exist for other optimization levels -const ignore_compiled_cache = PkgId[] - function find_all_in_cache_path(pkg::PkgId, DEPOT_PATH::typeof(DEPOT_PATH)=DEPOT_PATH) paths = String[] - pkg in ignore_compiled_cache && return paths entrypath, entryfile = cache_file_entry(pkg) for path in DEPOT_PATH path = joinpath(path, entrypath) diff --git a/base/show.jl b/base/show.jl index cd8107f8c6125..c1ad45af5cc83 100644 --- a/base/show.jl +++ b/base/show.jl @@ -514,8 +514,8 @@ function _show_default(io::IO, @nospecialize(x)) end function active_module() - isassigned(REPL_MODULE_REF) || return Main REPL = REPL_MODULE_REF[] + REPL === Base && return Main return invokelatest(REPL.active_module)::Module end diff --git a/base/task.jl b/base/task.jl index cd06f0acd7f7d..4f7b1ea979a94 100644 --- a/base/task.jl +++ b/base/task.jl @@ -834,7 +834,7 @@ function task_done_hook(t::Task) end if err && !handled && Threads.threadid() == 1 - if isa(result, InterruptException) && isdefined(Base, :active_repl_backend) && + if isa(result, InterruptException) && active_repl_backend !== nothing && active_repl_backend.backend_task._state === task_state_runnable && isempty(Workqueue) && active_repl_backend.in_eval throwto(active_repl_backend.backend_task, result) # this terminates the task @@ -849,7 +849,7 @@ function task_done_hook(t::Task) # the exception to the REPL task since the current task is done. # issue #19467 if Threads.threadid() == 1 && - isa(e, InterruptException) && isdefined(Base, :active_repl_backend) && + isa(e, InterruptException) && active_repl_backend !== nothing && active_repl_backend.backend_task._state === task_state_runnable && isempty(Workqueue) && active_repl_backend.in_eval throwto(active_repl_backend.backend_task, e) diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index 7b127a343a98c..18e0f86ab578e 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -3,7 +3,7 @@ module LineEdit import ..REPL -using REPL: AbstractREPL, Options +using ..REPL: AbstractREPL, Options using ..Terminals import ..Terminals: raw!, width, height, clear_line, beep diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 2d364931bc253..69d94ec49089a 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -127,7 +127,7 @@ include("options.jl") include("LineEdit.jl") using .LineEdit -import ..LineEdit: +import .LineEdit: CompletionProvider, HistoryProvider, add_history, @@ -752,6 +752,7 @@ struct LatexCompletions <: CompletionProvider end function active_module() # this method is also called from Base isdefined(Base, :active_repl) || return Main + Base.active_repl === nothing && return Main return active_module(Base.active_repl::AbstractREPL) end active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate.active_module @@ -1793,7 +1794,7 @@ module Numbered using ..REPL -__current_ast_transforms() = isdefined(Base, :active_repl_backend) ? Base.active_repl_backend.ast_transforms : REPL.repl_ast_transforms +__current_ast_transforms() = Base.active_repl_backend !== nothing ? Base.active_repl_backend.ast_transforms : REPL.repl_ast_transforms function repl_eval_counter(hp) return length(hp.history) - hp.start_idx @@ -1855,13 +1856,13 @@ end function __current_ast_transforms(backend) if backend === nothing - isdefined(Base, :active_repl_backend) ? Base.active_repl_backend.ast_transforms : REPL.repl_ast_transforms + Base.active_repl_backend !== nothing ? Base.active_repl_backend.ast_transforms : REPL.repl_ast_transforms else backend.ast_transforms end end -function numbered_prompt!(repl::LineEditREPL=Base.active_repl, backend=nothing) +function numbered_prompt!(repl::LineEditREPL=Base.active_repl::LineEditREPL, backend=nothing) n = Ref{Int}(0) set_prompt(repl, n) set_output_prefix(repl, n) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index db8045cde906a..bc8006ec2ed5d 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -295,7 +295,10 @@ function maybe_spawn_cache_PATH() @lock PATH_cache_lock begin PATH_cache_task isa Task && !istaskdone(PATH_cache_task) && return time() < next_cache_update && return - PATH_cache_task = Threads.@spawn REPLCompletions.cache_PATH() + PATH_cache_task = Threads.@spawn begin + REPLCompletions.cache_PATH() + @lock PATH_cache_lock PATH_cache_task = nothing # release memory when done + end Base.errormonitor(PATH_cache_task) end end diff --git a/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl b/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl index 9fcddef2fd484..ffbe32575fea1 100644 --- a/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl +++ b/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl @@ -2,7 +2,7 @@ module TerminalMenus -using REPL: REPL +using ..REPL: REPL function default_terminal(; in::IO=stdin, out::IO=stdout, err::IO=stderr) return REPL.Terminals.TTYTerminal( diff --git a/stdlib/REPL/src/Terminals.jl b/stdlib/REPL/src/Terminals.jl index 821ed224f1829..4f3e99f1d206c 100644 --- a/stdlib/REPL/src/Terminals.jl +++ b/stdlib/REPL/src/Terminals.jl @@ -118,10 +118,8 @@ cmove_line_up(t::UnixTerminal, n) = (cmove_up(t, n); cmove_col(t, 1)) cmove_line_down(t::UnixTerminal, n) = (cmove_down(t, n); cmove_col(t, 1)) cmove_col(t::UnixTerminal, n) = (write(t.out_stream, '\r'); n > 1 && cmove_right(t, n-1)) -const is_precompiling = Ref(false) if Sys.iswindows() function raw!(t::TTYTerminal,raw::Bool) - is_precompiling[] && return true check_open(t.in_stream) if Base.ispty(t.in_stream) run((raw ? `stty raw -echo onlcr -ocrnl opost` : `stty sane`), diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index feeeecbd97165..63a3601dbbae9 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -13,8 +13,6 @@ using Base: with_output_color, mapany, isdeprecated, isexported using Base.Filesystem: _readdirx -import REPL - using InteractiveUtils: subtypes using Unicode: normalize @@ -475,7 +473,7 @@ repl_corrections(s) = repl_corrections(stdout, s) # inverse of latex_symbols Dict, lazily created as needed const symbols_latex = Dict{String,String}() function symbol_latex(s::String) - if isempty(symbols_latex) && isassigned(Base.REPL_MODULE_REF) + if isempty(symbols_latex) for (k,v) in Iterators.flatten((REPLCompletions.latex_symbols, REPLCompletions.emoji_symbols)) symbols_latex[v] = k diff --git a/stdlib/REPL/src/precompile.jl b/stdlib/REPL/src/precompile.jl index b55f825e6a423..7a4044b7f4c6d 100644 --- a/stdlib/REPL/src/precompile.jl +++ b/stdlib/REPL/src/precompile.jl @@ -1,15 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license module Precompile -# Can't use this during incremental: `@eval Module() begin`` import ..REPL -# Prepare this staging area with all the loaded packages available -for (_pkgid, _mod) in Base.loaded_modules - if !(_pkgid.name in ("Main", "Core", "Base", "REPL")) - eval(:(const $(Symbol(_mod)) = $_mod)) - end -end # Ugly hack for our cache file to not have a dependency edge on the FakePTYs file. Base._track_dependencies[] = false @@ -19,93 +12,72 @@ try finally Base._track_dependencies[] = true end -using Base.Meta - -import Markdown -import StyledStrings - -## Debugging options -# Disable parallel precompiles generation by setting `false` -const PARALLEL_PRECOMPILATION = true - -# View the code sent to the repl by setting this to `stdout` -const debug_output = devnull # or stdout - -CTRL_C = '\x03' -CTRL_D = '\x04' -CTRL_R = '\x12' -UP_ARROW = "\e[A" -DOWN_ARROW = "\e[B" - -repl_script = """ -2+2 -print("") -printstyled("a", "b") -display([1]) -display([1 2; 3 4]) -foo(x) = 1 -@time @eval foo(1) -; pwd -$CTRL_C -$CTRL_R$CTRL_C# -? reinterpret -using Ra\t$CTRL_C -\\alpha\t$CTRL_C -\e[200~paste here ;)\e[201~"$CTRL_C -$UP_ARROW$DOWN_ARROW$CTRL_C -123\b\b\b$CTRL_C -\b\b$CTRL_C -f(x) = x03 -f(1,2) -[][1] -Base.Iterators.minimum -cd("complete_path\t\t$CTRL_C -""" - -julia_exepath() = joinpath(Sys.BINDIR, Base.julia_exename()) - -const JULIA_PROMPT = "julia> " -const PKG_PROMPT = "pkg> " -const SHELL_PROMPT = "shell> " -const HELP_PROMPT = "help?> " -blackhole = Sys.isunix() ? "/dev/null" : "nul" -procenv = Dict{String,Any}( - "JULIA_HISTORY" => blackhole, - "JULIA_PROJECT" => nothing, # remove from environment - "JULIA_LOAD_PATH" => "@stdlib", - "JULIA_DEPOT_PATH" => Sys.iswindows() ? ";" : ":", - "TERM" => "", - "JULIA_FALLBACK_REPL" => "0") # Turn REPL.jl on in subprocess - -generate_precompile_statements() = try - # Extract the precompile statements from the precompile file - statements_step = Channel{String}(Inf) - - step = @async mktemp() do precompile_file, precompile_file_h - # Collect statements from running a REPL process and replaying our REPL script - touch(precompile_file) - pts, ptm = open_fake_pty() - # we don't want existing REPL caches to be used so ignore them - setup_cmd = """ - push!(Base.ignore_compiled_cache, Base.PkgId(Base.UUID("3fa0cd96-eef1-5676-8a61-b3b8758bbffb"), "REPL")) - import REPL - REPL.Terminals.is_precompiling[] = true - """ - p = run( - addenv(```$(julia_exepath()) -O0 --trace-compile=$precompile_file - --cpu-target=native --startup-file=no --compiled-modules=existing - --color=yes -i -e "$setup_cmd"```, procenv), - pts, pts, pts; wait=false - ) - Base.close_stdio(pts) - # Prepare a background process to copy output from process until `pts` is closed +let + ## Debugging options + # View the code sent to the repl by setting this to `stdout` + debug_output = devnull # or stdout + + CTRL_C = '\x03' + CTRL_D = '\x04' + CTRL_R = '\x12' + UP_ARROW = "\e[A" + DOWN_ARROW = "\e[B" + + repl_script = """ + 2+2 + print("") + printstyled("a", "b") + display([1]) + display([1 2; 3 4]) + foo(x) = 1 + @time @eval foo(1) + ; pwd + $CTRL_C + $CTRL_R$CTRL_C# + ? reinterpret + using Ra\t$CTRL_C + \\alpha\t$CTRL_C + \e[200~paste here ;)\e[201~"$CTRL_C + $UP_ARROW$DOWN_ARROW$CTRL_C + 123\b\b\b$CTRL_C + \b\b$CTRL_C + f(x) = x03 + f(1,2) + [][1] + Base.Iterators.minimum + cd("complete_path\t\t$CTRL_C + println("done") + """ + + JULIA_PROMPT = "julia> " + PKG_PROMPT = "pkg> " + SHELL_PROMPT = "shell> " + HELP_PROMPT = "help?> " + + blackhole = Sys.isunix() ? "/dev/null" : "nul" + + withenv("JULIA_HISTORY" => blackhole, + "JULIA_PROJECT" => nothing, # remove from environment + "JULIA_LOAD_PATH" => "@stdlib", + "JULIA_DEPOT_PATH" => Sys.iswindows() ? ";" : ":", + "TERM" => "", + "JULIA_FALLBACK_REPL" => "0" # Make sure REPL.jl is turned on + ) do + rawpts, ptm = open_fake_pty() + pts = open(rawpts)::Base.TTY + if Sys.iswindows() + pts.ispty = false + else + # workaround libuv bug where it leaks pts + Base._fd(pts) == rawpts || Base.close_stdio(rawpts) + end + # Prepare a background process to copy output from `ptm` until `pts` is closed output_copy = Base.BufferStream() tee = @async try while !eof(ptm) l = readavailable(ptm) write(debug_output, l) - Sys.iswindows() && (sleep(0.1); yield(); yield()) # workaround hang - probably a libuv issue? write(output_copy, l) end write(debug_output, "\n#### EOF ####\n") @@ -118,9 +90,30 @@ generate_precompile_statements() = try close(ptm) end Base.errormonitor(tee) - repl_inputter = @async begin - # wait for the definitive prompt before start writing to the TTY - readuntil(output_copy, JULIA_PROMPT) + orig_stdin = stdin + orig_stdout = stdout + orig_stderr = stderr + repltask = @task try + Base.run_std_repl(REPL, false, :yes, true) + finally + redirect_stderr(isopen(orig_stderr) ? orig_stderr : devnull) + redirect_stdout(isopen(orig_stdout) ? orig_stdout : devnull) + close(pts) + end + try + Base.REPL_MODULE_REF[] = REPL + redirect_stdin(pts) + redirect_stdout(pts) + redirect_stderr(pts) + REPL.print_qualified_access_warning(Base.Iterators, Base, :minimum) # trigger the warning while stderr is suppressed + try + schedule(repltask) + # wait for the definitive prompt before start writing to the TTY + readuntil(output_copy, JULIA_PROMPT) + finally + redirect_stderr(isopen(orig_stderr) ? orig_stderr : devnull) + end + write(debug_output, "\n#### REPL STARTED ####\n") sleep(0.1) readavailable(output_copy) # Input our script @@ -152,77 +145,21 @@ generate_precompile_statements() = try end write(debug_output, "\n#### COMPLETED - Closing REPL ####\n") write(ptm, "$CTRL_D") - wait(tee) - success(p) || Base.pipeline_error(p) - close(ptm) - write(debug_output, "\n#### FINISHED ####\n") - end - Base.errormonitor(repl_inputter) - - n_step = 0 - precompile_copy = Base.BufferStream() - buffer_reader = @async for statement in eachline(precompile_copy) - push!(statements_step, statement) - n_step += 1 - end - - open(precompile_file, "r") do io - while true - # We need to always call eof(io) for bytesavailable(io) to work - eof(io) && istaskdone(repl_inputter) && eof(io) && break - if bytesavailable(io) == 0 - sleep(0.1) - continue - end - write(precompile_copy, readavailable(io)) - end - end - close(precompile_copy) - wait(buffer_reader) - return :ok - end - !PARALLEL_PRECOMPILATION && wait(step) - bind(statements_step, step) - - # Make statements unique - statements = Set{String}() - # Execute the precompile statements - for statement in statements_step - # Main should be completely clean - occursin("Main.", statement) && continue - Base.in!(statement, statements) && continue - try - ps = Meta.parse(statement) - if !isexpr(ps, :call) - # these are typically comments - @debug "skipping statement because it does not parse as an expression" statement - delete!(statements, statement) - continue - end - popfirst!(ps.args) # precompile(...) - ps.head = :tuple - # println(ps) - ps = eval(ps) - if !precompile(ps...) - @warn "Failed to precompile expression" form=statement _module=nothing _file=nothing _line=0 - end - catch ex - # See #28808 - @warn "Failed to precompile expression" form=statement exception=ex _module=nothing _file=nothing _line=0 + wait(repltask) + finally + close(pts) + redirect_stdin(isopen(orig_stdin) ? orig_stdin : devnull) + redirect_stdout(isopen(orig_stdout) ? orig_stdout : devnull) end + wait(tee) end - - fetch(step) == :ok || throw("Collecting precompiles failed: $(c.excp)") - return nothing -finally - GC.gc(true); GC.gc(false); # reduce memory footprint + write(debug_output, "\n#### FINISHED ####\n") + nothing end -generate_precompile_statements() - -precompile(Tuple{typeof(getproperty), REPL.REPLBackend, Symbol}) -precompile(Tuple{typeof(Base.take!), Base.Channel{Function}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Function}, Function}) -precompile(Tuple{typeof(Core.kwcall), NamedTuple{names, T} where T<:Tuple where names, typeof(REPL.LineEdit.complete_line), REPL.LineEdit.EmptyCompletionProvider, Any}) +precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Any, Int}) +precompile(Tuple{typeof(Base.delete!), Base.Set{Any}, String}) +precompile(Tuple{typeof(Base.:(==)), Char, String}) +precompile(Tuple{typeof(Base.reseteof), Base.TTY}) end # Precompile diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 6427440c9d39e..05db88fa0d8ac 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -9,7 +9,7 @@ using Markdown empty!(Base.Experimental._hint_handlers) # unregister error hints so they can be tested separately -@test isassigned(Base.REPL_MODULE_REF) +@test Base.REPL_MODULE_REF[] === REPL const BASE_TEST_PATH = joinpath(Sys.BINDIR, "..", "share", "julia", "test") isdefined(Main, :FakePTYs) || @eval Main include(joinpath($(BASE_TEST_PATH), "testhelpers", "FakePTYs.jl")) diff --git a/test/ambiguous.jl b/test/ambiguous.jl index 748660cc9c981..d6f69f21bcdce 100644 --- a/test/ambiguous.jl +++ b/test/ambiguous.jl @@ -97,10 +97,7 @@ ambig(x::Union{Char, Int16}) = 's' # Automatic detection of ambiguities -const allowed_undefineds = Set([ - GlobalRef(Base, :active_repl), - GlobalRef(Base, :active_repl_backend), -]) +const allowed_undefineds = Set([]) let Distributed = get(Base.loaded_modules, Base.PkgId(Base.UUID("8ba89e20-285c-5b6f-9357-94700520ee1b"), "Distributed"), diff --git a/test/testhelpers/FakePTYs.jl b/test/testhelpers/FakePTYs.jl index c4dfe416de85a..56ce6dc7d3a49 100644 --- a/test/testhelpers/FakePTYs.jl +++ b/test/testhelpers/FakePTYs.jl @@ -23,10 +23,7 @@ function open_fake_pty() close(pts) pts = fds # convert pts handle to a TTY - #fds = pts.handle - #pts.status = Base.StatusClosed - #pts.handle = C_NULL - #pts = Base.TTY(fds, Base.StatusOpen) + #pts = open(fds)::Base.TTY else O_RDWR = Base.Filesystem.JL_O_RDWR O_NOCTTY = Base.Filesystem.JL_O_NOCTTY @@ -43,8 +40,9 @@ function open_fake_pty() pts = RawFD(fds) # pts = fdio(fds, true) - # pts = Base.Filesystem.File(RawFD(fds)) - # pts = Base.TTY(RawFD(fds); readable = false) + # pts = Base.Filesystem.File(pts) + # pts = Base.TTY(pts) + # pts = Base.open(pts) ptm = Base.TTY(RawFD(fdm)) end return pts, ptm