From 2e714929c98e576072b3c5bfd19330d0efca3f8c Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 1 Aug 2023 15:29:33 -0400 Subject: [PATCH] only limit types in stack traces in the REPL (#50598) fixes #50575 Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> (cherry picked from commit 98222572628fa67d733389cc718f2c70d45d2ea1) --- base/errorshow.jl | 6 ------ base/show.jl | 8 +++----- stdlib/REPL/src/REPL.jl | 17 +++++++++++++++-- stdlib/REPL/test/repl.jl | 11 +++++++++++ test/stacktraces.jl | 5 ++--- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 81f4c9c2ee9e0..2a02747dc2a2b 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -772,9 +772,6 @@ function show_backtrace(io::IO, t::Vector) if haskey(io, :last_shown_line_infos) empty!(io[:last_shown_line_infos]) end - # this will be set to true if types in the stacktrace are truncated - limitflag = Ref(false) - io = IOContext(io, :stacktrace_types_limited => limitflag) # t is a pre-processed backtrace (ref #12856) if t isa Vector{Any} @@ -800,9 +797,6 @@ function show_backtrace(io::IO, t::Vector) # process_backtrace returns a Vector{Tuple{Frame, Int}} show_full_backtrace(io, filtered; print_linebreaks = stacktrace_linebreaks()) end - if limitflag[] - print(io, "\nSome type information was truncated. Use `show(err)` to see complete types.") - end nothing end diff --git a/base/show.jl b/base/show.jl index 45d6a502619db..b259e95e54720 100644 --- a/base/show.jl +++ b/base/show.jl @@ -2557,14 +2557,12 @@ function show_tuple_as_call(out::IO, name::Symbol, sig::Type; print_within_stacktrace(io, ")", bold=true) show_method_params(io, tv) str = String(take!(unwrapcontext(io)[1])) - if get(out, :limit, false)::Bool + typelimitflag = get(out, :stacktrace_types_limited, nothing) + if typelimitflag isa RefValue{Bool} sz = get(out, :displaysize, (typemax(Int), typemax(Int)))::Tuple{Int, Int} str_lim = type_depth_limit(str, max(sz[2], 120)) if sizeof(str_lim) < sizeof(str) - typelimitflag = get(out, :stacktrace_types_limited, nothing) - if typelimitflag !== nothing - typelimitflag[] = true - end + typelimitflag[] = true end str = str_lim end diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 1328a87f1a77d..218f89de798c8 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -285,6 +285,19 @@ function print_response(repl::AbstractREPL, response, show_value::Bool, have_col end return nothing end + +function repl_display_error(errio::IO, @nospecialize errval) + # this will be set to true if types in the stacktrace are truncated + limitflag = Ref(false) + errio = IOContext(errio, :stacktrace_types_limited => limitflag) + Base.invokelatest(Base.display_error, errio, errval) + if limitflag[] + print(errio, "Some type information was truncated. Use `show(err)` to see complete types.") + println(errio) + end + return nothing +end + function print_response(errio::IO, response, show_value::Bool, have_color::Bool, specialdisplay::Union{AbstractDisplay,Nothing}=nothing) Base.sigatomic_begin() val, iserr = response @@ -294,7 +307,7 @@ function print_response(errio::IO, response, show_value::Bool, have_color::Bool, if iserr val = Base.scrub_repl_backtrace(val) Base.istrivialerror(val) || setglobal!(Base.MainInclude, :err, val) - Base.invokelatest(Base.display_error, errio, val) + repl_display_error(errio, val) else if val !== nothing && show_value try @@ -317,7 +330,7 @@ function print_response(errio::IO, response, show_value::Bool, have_color::Bool, try excs = Base.scrub_repl_backtrace(current_exceptions()) setglobal!(Base.MainInclude, :err, excs) - Base.invokelatest(Base.display_error, errio, excs) + repl_display_error(errio, excs) catch e # at this point, only print the name of the type as a Symbol to # minimize the possibility of further errors. diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index f0d5052ff9e32..20f07864a275b 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1659,3 +1659,14 @@ fake_repl() do stdin_write, stdout_read, repl write(stdin_write, '\x04') Base.wait(repltask) end + +fake_repl() do stdin_write, stdout_read, repl + backend = REPL.REPLBackend() + repltask = @async REPL.run_repl(repl; backend) + write(stdin_write, + "a = UInt8(81):UInt8(160); b = view(a, 1:64); c = reshape(b, (8, 8)); d = reinterpret(reshape, Float64, c); sqrteach(a) = [sqrt(x) for x in a]; sqrteach(d)\n\"ZZZZZ\"\n") + txt = readuntil(stdout_read, "ZZZZZ") + write(stdin_write, '\x04') + wait(repltask) + @test contains(txt, "Some type information was truncated. Use `show(err)` to see complete types.") +end diff --git a/test/stacktraces.jl b/test/stacktraces.jl index 882114e71d833..5b17a0ced4058 100644 --- a/test/stacktraces.jl +++ b/test/stacktraces.jl @@ -241,8 +241,7 @@ struct F49231{a,b,c,d,e,f,g} end catch e stacktrace(catch_backtrace()) end - str = sprint(Base.show_backtrace, st, context = (:limit=>true, :color=>true, :displaysize=>(50,105))) - @test endswith(str, "to see complete types.") + str = sprint(Base.show_backtrace, st, context = (:limit=>true, :stacktrace_types_limited => Ref(false), :color=>true, :displaysize=>(50,105))) @test contains(str, "[5] \e[0m\e[1mcollect_to!\e[22m\e[0m\e[1m(\e[22m\e[90mdest\e[39m::\e[0mVector\e[90m{…}\e[39m, \e[90mitr\e[39m::\e[0mBase.Generator\e[90m{…}\e[39m, \e[90moffs\e[39m::\e[0m$Int, \e[90mst\e[39m::\e[0mTuple\e[90m{…}\e[39m\e[0m\e[1m)\e[22m\n\e[90m") st = try @@ -250,6 +249,6 @@ struct F49231{a,b,c,d,e,f,g} end catch e stacktrace(catch_backtrace()) end - str = sprint(Base.show_backtrace, st, context = (:limit=>true, :color=>true, :displaysize=>(50,132))) + str = sprint(Base.show_backtrace, st, context = (:limit=>true, :stacktrace_types_limited => Ref(false), :color=>true, :displaysize=>(50,132))) @test contains(str, "[2] \e[0m\e[1m(::$F49231{Vector, Val{…}, Vector{…}, NTuple{…}, $Int, $Int, $Int})\e[22m\e[0m\e[1m(\e[22m\e[90ma\e[39m::\e[0m$Int, \e[90mb\e[39m::\e[0m$Int, \e[90mc\e[39m::\e[0m$Int\e[0m\e[1m)\e[22m\n\e[90m") end