From e6ee547128ba3a5bb9e83afeede17cec02d52db5 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Mon, 21 Mar 2022 01:42:10 -0700 Subject: [PATCH] Add show methods (#30) --- src/Try.jl | 3 +-- src/function.jl | 29 +++++++++++++++++++++++------ src/show.jl | 30 ++++++++++++++++++++++++++++++ test/TryTests/src/TryTests.jl | 1 + test/TryTests/src/test_show.jl | 20 ++++++++++++++++++++ 5 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 test/TryTests/src/test_show.jl diff --git a/src/Try.jl b/src/Try.jl index e4cabfc..cc5ecdd 100644 --- a/src/Try.jl +++ b/src/Try.jl @@ -55,11 +55,10 @@ include("ExternalDocstrings.jl") using .ExternalDocstrings: @define_docstrings include("core.jl") -include("show.jl") include("errortrace.jl") include("function.jl") - include("branch.jl") +include("show.jl") end # module Internal diff --git a/src/function.jl b/src/function.jl index ed42a26..b6d8248 100644 --- a/src/function.jl +++ b/src/function.jl @@ -27,17 +27,34 @@ macro define_function(name::Symbol) end |> esc end -(fn::Tryable)(args...; kwargs...) = Err(Try.NotImplementedError(fn, args, kwargs)) +(fn::Tryable)(args...; kwargs...) = Err(Try.NotImplementedError(fn, args, values(kwargs))) -struct NotImplementedError{T} <: Try.NotImplementedError end +struct NotImplementedError{F,Args<:Tuple,Kwargs<:NamedTuple} <: Try.NotImplementedError + f::F + args::Args + kwargs::Kwargs +end # TODO: check if it is better to "type-erase" -# TODO: don't ignore kwargs? +# TODO: don't capture values? + +asnamedtuple(kwargs::NamedTuple) = kwargs +asnamedtuple(kwargs) = (; kwargs...) -Try.NotImplementedError(f, args, _kwargs) = - NotImplementedError{Tuple{_typesof(f, args...)...}}() +Try.NotImplementedError( + f, + args::Tuple, + kwargs::Union{NamedTuple,Iterators.Pairs} = NamedTuple(), +) = NotImplementedError(f, args, asnamedtuple(kwargs)) _typesof() = () _typesof(::Type{Head}, tail...) where {Head} = (Type{Head}, _typesof(tail...)...) _typesof(head, tail...) = (typeof(head), _typesof(tail...)...) -# TODO: show methods +Base.print(io::IO, fn::Tryable) = print(io, nameof(fn)) +Base.show(io::IO, fn::Tryable) = print(io, nameof(fn)) + +function Base.show(io::IO, ::MIME"text/plain", fn::Tryable) + print(io, nameof(fn)) + n = length(methods(fn)) + print(io, " (tryable function with ", n, " method", n == 1 ? "" : "s", ")") +end diff --git a/src/show.jl b/src/show.jl index fa6ec57..6ade7ad 100644 --- a/src/show.jl +++ b/src/show.jl @@ -15,3 +15,33 @@ function Base.show(io::IO, ::MIME"text/plain", err::Err) showerror(io, ex, simplify_backtrace(err.backtrace)) end end + +# TODO: simplify arguments when they are too long +function Base.showerror(io::IO, ex::NotImplementedError) + print(io, "Not Implemented: ") + show(io, ex.f) + print(io, '(') + let isfirst = true + for a in ex.args + if isfirst + isfirst = false + else + print(io, ", ") + end + show(IOContext(io, :compact => true, :limit => true), a) + end + end + let isfirst = true + for (k, v) in pairs(ex.kwargs) + if isfirst + isfirst = false + print(io, "; ") + else + print(io, ", ") + end + print(io, k, " = ") + show(IOContext(io, :compact => true, :limit => true), v) + end + end + print(io, ')') +end diff --git a/test/TryTests/src/TryTests.jl b/test/TryTests/src/TryTests.jl index b39dd58..3ab410d 100644 --- a/test/TryTests/src/TryTests.jl +++ b/test/TryTests/src/TryTests.jl @@ -4,6 +4,7 @@ include("test_base.jl") include("test_errortrace.jl") include("test_tools.jl") include("test_inferrability.jl") +include("test_show.jl") include("test_doctest.jl") end # module TryTests diff --git a/test/TryTests/src/test_show.jl b/test/TryTests/src/test_show.jl new file mode 100644 index 0000000..bf2d312 --- /dev/null +++ b/test/TryTests/src/test_show.jl @@ -0,0 +1,20 @@ +module TestShow + +using Test +using Try + +Try.@function dummy + +function test_tryable() + @test string(dummy) == "dummy" + @test sprint(show, dummy) == "dummy" + @test sprint(show, "text/plain", dummy) == "dummy (tryable function with 1 method)" +end + +function test_notimplementederror() + ex = Try.NotImplementedError(identity, (1, 2, 3), (a = 4, b = 5)) + msg = sprint(showerror, ex) + @test occursin("identity(1, 2, 3; a = 4, b = 5)", msg) +end + +end # module