How to call the original Base.show function extended in DataFrames.jl while overriding it?

I’m using the DataFrames.jl package and I want to change the default behavior of show(), I want to print all the rows and columns without passing additional arguments because I want it to work seamlessly while calling display()

Therefore my question is similar to this but slightly different and I’m not sure what path to take.

As far as I know I have 3 options:

  • extend display()
  • apply this solutionNot applicable since DataFrams.jl is extending Base.show thus i can’t just invoke the DataFrame’s version of show
  • use irtools

Do you have any suggestion?

You just need to overwrite show if you are just doing this for yourself.

julia> struct A end

julia> A()
A()

julia> Base.show(io::IO, ::MIME"text/plain", ::A) = println("A is an emtpy struct")

julia> A()
A is an emtpy struct


julia> Base.show(io::IO, ::MIME"text/plain", ::A) = println("A() is an emtpy struct")

julia> A()
A() is an emtpy struct


help?> show

If you are trying to do for others, then you should create a struct that wraps a DataFrame and then modify the show method for that struct as above.

See Types · The Julia Language

no that’s not enough because the DataFrames.jl show function is way complicated and I clearly don’t want to rewrite the whole thing I just want to change the parameters it uses by default.

I found out how to accomplish it with Base.invoke_in_world:

module Y
function Base.show(::Val{:test})
    println("TEST Y")
end
end

module X
w = Base.get_world_counter()
function Base.show(::Val{:test})
    println("TEST X")
    Base.invoke_in_world(w, Base.show, Val(:test))
end
end

show(Val(:test))
# Result:
# TEST X
# TEST Y

Here’s how I’ve overwritten the extended Base.show method from DataFrames.jl:

df_show_formatters = (v, i::Int, j::Int) -> (typeof(v) <: DateTime ? Dates.format(v, "dd-mm-yyyy HH:MM") : v)
w = Base.get_world_counter()

function Base.show(io::IO, mime::MIME"text/plain", df::AbstractDataFrame; kwargs...)

    write(io, "Additional output here\n\n")

    Base.invoke_in_world(w, Base.show,
        io,
        mime,
        df;
        allcols=true,
        allrows=true,
        formatters=df_show_formatters,
        kwargs...
    )
end

function Base.show(io::IO, mime::MIME"text/html", df::AbstractDataFrame; kwargs...)
    Base.invoke_in_world(w, Base.show,
        io,
        mime,
        df;
        max_num_of_columns=-1,
        max_num_of_rows=-1,
        formatters=df_show_formatters,
        table_style=Dict(
            "white-space" => "nowrap"
        ),
        kwargs...
    )
end

This works both in the REPL and Jupyter, I’m using it to pretty format DateTime cells, avoid word wrapping in HTML and show all the df content by default

Here is a comparison before and after the change in jupyter:
Before
image
image

After
image
image