Skip to content

Convert the one and two argument show methods to MIME"text/plain" methods#3524

Open
andreasnoack wants to merge 1 commit intomainfrom
an/show
Open

Convert the one and two argument show methods to MIME"text/plain" methods#3524
andreasnoack wants to merge 1 commit intomainfrom
an/show

Conversation

@andreasnoack
Copy link
Copy Markdown
Member

Strictly speaking, I consider this a bugfix. "Decorated" multiline output should be handled by a show method for MIME"text/plain" and not the two-argument show method. However, the show method here is very useful and probably used by many downstream packages, so it might cause a temporary ecosystem imbalance if this is released as a non-breaking release. We saw that when fixing the show method for StatsBase's CoefTable. Are there other changes waiting for a breaking release?

@bkamins
Copy link
Copy Markdown
Member

bkamins commented Feb 20, 2026

Thank you for the PR. We do not plan to make breaking releases for this package. However, we can discuss if we can consider this a "bugfix" and do staged introduction of the changes.

For my understanding - what is exactly the bug that we fix with this change. (i.e. what is not working as expected with the current design)?

CC @nalimilan

@bkamins bkamins added the bug label Feb 20, 2026
@bkamins bkamins added this to the 1.8 milestone Feb 20, 2026
@andreasnoack
Copy link
Copy Markdown
Member Author

This is my understanding of https://docs.julialang.org/en/v1/manual/types/#man-custom-pretty-printing is that multi-line output should be delegated to the three-argument show method for MIME"text/plain" and also that the two argument method should ideally produce parseable output (which this PR doesn't resolve).

The immediate reason why I prepared this PR was vector output like the output below, which takes up too much space, is hard to separate the elements, and is a mess in text logs.

julia> fill(DataFrame(x = ones(5)), 5)
5-element Vector{DataFrame}:
 5×1 DataFrame
 Row │ x
     │ Float64
─────┼─────────
   11.0
   21.0
   31.0
   41.0
   51.0
 5×1 DataFrame
 Row │ x
     │ Float64
─────┼─────────
   11.0
   21.0
   31.0
   41.0
   51.0
 5×1 DataFrame
 Row │ x
     │ Float64
─────┼─────────
   11.0
   21.0
   31.0
   41.0
   51.0
 5×1 DataFrame
 Row │ x
     │ Float64
─────┼─────────
   11.0
   21.0
   31.0
   41.0
   51.0
 5×1 DataFrame
 Row │ x
     │ Float64
─────┼─────────
   11.0
   21.0
   31.0
   41.0
   51.0

With this PR, that would be

julia> fill(DataFrame(x = ones(5)), 5)
5-element Vector{DataFrame}:
 DataFrame(AbstractVector[[1.0, 1.0, 1.0, 1.0, 1.0]], DataFrames.Index(Dict(:x => 1), [:x]), nothing, nothing, true)
 DataFrame(AbstractVector[[1.0, 1.0, 1.0, 1.0, 1.0]], DataFrames.Index(Dict(:x => 1), [:x]), nothing, nothing, true)
 DataFrame(AbstractVector[[1.0, 1.0, 1.0, 1.0, 1.0]], DataFrames.Index(Dict(:x => 1), [:x]), nothing, nothing, true)
 DataFrame(AbstractVector[[1.0, 1.0, 1.0, 1.0, 1.0]], DataFrames.Index(Dict(:x => 1), [:x]), nothing, nothing, true)
 DataFrame(AbstractVector[[1.0, 1.0, 1.0, 1.0, 1.0]], DataFrames.Index(Dict(:x => 1), [:x]), nothing, nothing, true)

which can be improved, but is more structured and doesn't ruin text logs.

@andreasnoack andreasnoack force-pushed the an/show branch 4 times, most recently from 89f195c to 1e10e96 Compare February 21, 2026 10:28
@bkamins
Copy link
Copy Markdown
Member

bkamins commented Feb 21, 2026

Regarding the decision - I am OK to mark this PR as a bug fix.
However:

  • @ronisbr - can you please chceck if this does not break anything on your end?
  • @nalimilan - I assume you have experience with the CoefTable change and can judge how we should go about releasing this change

Thank you!

@ronisbr
Copy link
Copy Markdown
Member

ronisbr commented Feb 21, 2026

Hi!

Although I agree that the current way DataFrames print does not follow the convention in the Julia manual, I really think we must treat this as breaking. Anyone, me included, that customizes the output will start to see errors when updating the package. Furthermore, output customization will start to be more verbose.

The only gain, IMHO, is when you have a vector of DataFrames. However, it seems something very unusual.

Finally, if you decide to merge this PR, I highly recommend keeping the actual behavior if the user passes any keyword argument to show. In other words, print the compact version if and only if no keywords are present.

@andreasnoack
Copy link
Copy Markdown
Member Author

andreasnoack commented Feb 21, 2026

I think I agree that, in its current form, this PR is probably too breaking to be considered just a bug fix. I do think it is unfortunate that the (very powerful and well written) show methods in this package don't follow the documentation for extending the show methods so eventually, it would be good to adjust them.

I could try to make this less breaking, but the feasibility of that depends on how people are actually using these custom show methods. If it only because people have been relying on show(::AbstractDataFrame; kwargs) then we could just keep that method for the time being. However, I'm a daily user of DataFrames and never called show explicitly on a DataFrame.

For CoefTable, the issue was that people used it as a part of their own custom show methods, which meant they were calling the the two-argument show method for CoefTable. If something similar is the case for DataFrames then it would cause a lot of breakage. I ended up searching through all packages with JuliaHub's code search to identify packages relying on CoefTable for their show methods and then either fixed the show method or suggested how to do so.

Alternatively, we can just keep this one open until there is an appetite for a major release. At that point, it might be a good idea to also convert all the keyword arguments to fields of the IOContext such that the show methods here fully following the intention of the display machinery.

@nalimilan
Copy link
Copy Markdown
Member

nalimilan commented Feb 23, 2026

I agree that it seems too breaking (for CoefTable there weren't any show methods taking keyword arguments and end users were unlikely to call show directly). I guess we could do what @ronisbr proposed above:

Finally, if you decide to merge this PR, I highly recommend keeping the actual behavior if the user passes any keyword argument to show. In other words, print the compact version if and only if no keywords are present.

Though it would be quite inconsistent so I'm not sure it would be worth it.

The issue isn't easy to resolve even for the next breaking release: requiring users to write show(df, MIME("text/plain"), ...) is a no-go IMO as this has to be convenient. It's kind of weird that it's harder in Julia to get the pretty-printed representation than the parseable representation. Maybe we should introduce a separate method, but in that case it should be shared with other packages.

@andreasnoack
Copy link
Copy Markdown
Member Author

Do users really call show explicitly in interactive use cases? As mentioned above, I use DataFrames on daily basis and I've never called show expect in library code where I don't consider the extra verbosity an issue.

@nalimilan
Copy link
Copy Markdown
Member

Hard to tell, but at least I would think that arguments like allrows=true are often useful.

@ronisbr
Copy link
Copy Markdown
Member

ronisbr commented Feb 23, 2026

Do users really call show explicitly in interactive use cases? As mentioned above, I use DataFrames on daily basis and I've never called show expect in library code where I don't consider the extra verbosity an issue.

We often receive some questions in Discourse asking how the output can be customized. That's was one of the reasons why @bkamins always asked me to add a section "Customizing DataFrames Output" to the manual. Hence, I think the number of people using it is not negligible. Now, with PrettyTables.jl v3 and the ability to add summary rows, I think it will be higher.

@bkamins
Copy link
Copy Markdown
Member

bkamins commented Feb 23, 2026

In general my opinion is that users do ask for customized output in interactive sessions. Also in simple scripts calling show(df) is quite typical.

@bkamins bkamins modified the milestones: 1.8, 2.0 Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants