# PrettyTables.jl breaks on non-breaking release

**URL:** https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990
**Category:** General Usage
**Tags:** question, prettytables
**Created:** [December 1, 2023, 11:58am UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990 "2023-12-01T11:58:34Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 1, 2023, 11:58am UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/1 "2023-12-01T11:58:35Z")

</div>

Hello,

I use PrettyTables.jl to print the contents of a struct to the REPL. Sometime between 2.0 and 2.3.1 it stopped working. Here is an example showing it works with 2.0:

**Code**

```julia
using SequentialSamplingModels
dist = WaldMixture(;ν=2.0, η=1.0, α=.5, τ=.130)

```

**Output**

```julia
julia> dist
WaldMixture
┌───────────┬───────┐
│ Parameter │ Value │
├───────────┼───────┤
│ ν │ 2.00 │
│ η │ 1.00 │
│ α │ 0.50 │
│ τ │ 0.13 │
└───────────┴───────┘

```

**Versions**

```julia

(pretty_table_error) pkg> st
Status `~/.julia/dev/sandbox/pretty_table_error/Project.toml`
⌃ [08abe8d2] PrettyTables v2.0.0
  [0e71a2a6] SequentialSamplingModels v0.8.5
Info Packages marked with ⌃ have new versions available and may be upgradable.

```

Now if I upgrade to 2.3.1, the same example stops working:

**Versions**

```julia
(pretty_table_error) pkg> st
Status `~/.julia/dev/sandbox/pretty_table_error/Project.toml`
  [08abe8d2] PrettyTables v2.3.1
  [0e71a2a6] SequentialSamplingModels v0.8.5

```

**Error**

> **Summary**
>
> ```julia
> ERROR: MethodError: no method matching _print_table_with_text_back_end(::PrettyTables.PrintInfo; row_name_column_title::String, row_name_alignment::Symbol, row_names::Vector{Symbol})
> 
> Closest candidates are:
> _print_table_with_text_back_end(::PrettyTables.PrintInfo; alignment_anchor_fallback, alignment_anchor_fallback_override, alignment_anchor_regex, autowrap, body_hlines, body_hlines_format, continuation_row_alignment, crop, crop_subheader, columns_width, display_size, equal_columns_width, ellipsis_line_skip, highlighters, hlines, linebreaks, maximum_columns_width, minimum_columns_width, newline_at_end, overwrite, reserved_display_lines, show_omitted_cell_summary, sortkeys, tf, title_autowrap, title_same_width_as_table, vcrop_mode, vlines, border_crayon, header_crayon, omitted_cell_summary_crayon, row_label_crayon, row_label_header_crayon, row_number_header_crayon, subheader_crayon, text_crayon, title_crayon, T, T) got unsupported keyword arguments "row_name_column_title", "row_name_alignment", "row_names"
> @ PrettyTables ~/.julia/packages/PrettyTables/E8rPJ/src/backends/text/text_backend.jl:11
> 
> Stacktrace:
> [1] kwerr(::NamedTuple{(:row_name_column_title, :row_name_alignment, :row_names), Tuple{String, Symbol, Vector{Symbol}}}, ::Function, ::PrettyTables.PrintInfo)
> @ Base ./error.jl:165
> [2] _print_table(io::IO, data::Any; alignment::Symbol, backend::Val{:auto}, cell_alignment::Nothing, cell_first_line_only::Bool, compact_printing::Bool, formatters::PrettyTables.var"#36#39"{Printf.Format{Base.CodeUnits{UInt8, String}, Tuple{Printf.Spec{Val{'f'}}}}}, header::Tuple{Vector{String}}, header_alignment::Symbol, header_cell_alignment::Nothing, limit_printing::Bool, max_num_of_columns::Int64, max_num_of_rows::Int64, renderer::Symbol, row_labels::Nothing, row_label_alignment::Symbol, row_label_column_title::String, row_number_alignment::Symbol, row_number_column_title::String, show_header::Bool, show_row_number::Bool, show_subheader::Bool, title::String, title_alignment::Symbol, kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:row_name_column_title, :row_name_alignment, :row_names), Tuple{String, Symbol, Vector{Symbol}}}})
> @ PrettyTables ~/.julia/packages/PrettyTables/E8rPJ/src/print.jl:1005
> [3] _print_table
> @ ~/.julia/packages/PrettyTables/E8rPJ/src/print.jl:880 [inlined]
> [4] pretty_table(io::IO, data::Any; header::Vector{String}, kwargs::Base.Pairs{Symbol, Any, NTuple{7, Symbol}, NamedTuple{(:title, :row_name_column_title, :compact_printing, :row_name_alignment, :row_names, :formatters, :alignment), Tuple{String, String, Bool, Symbol, Vector{Symbol}, PrettyTables.var"#36#39"{Printf.Format{Base.CodeUnits{UInt8, String}, Tuple{Printf.Spec{Val{'f'}}}}}, Symbol}}})
> @ PrettyTables ~/.julia/packages/PrettyTables/E8rPJ/src/print.jl:771
> [5] _show(io::IOContext{Base.TTY}, model::WaldMixture{Float64})
> @ SequentialSamplingModels ~/.julia/packages/SequentialSamplingModels/UYgrK/src/utilities.jl:18
> [6] show(io::IOContext{Base.TTY}, #unused#::MIME{Symbol("text/plain")}, model::WaldMixture{Float64})
> @ SequentialSamplingModels ~/.julia/packages/SequentialSamplingModels/UYgrK/src/utilities.jl:2
> [7] (::REPL.var"#55#56"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
> @ REPL ~/julia-1.9.4/share/julia/stdlib/v1.9/REPL/src/REPL.jl:276
> [8] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
> @ REPL ~/julia-1.9.4/share/julia/stdlib/v1.9/REPL/src/REPL.jl:557
> [9] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
> @ REPL ~/julia-1.9.4/share/julia/stdlib/v1.9/REPL/src/REPL.jl:262
> [10] display(d::REPL.REPLDisplay, x::Any)
> @ REPL ~/julia-1.9.4/share/julia/stdlib/v1.9/REPL/src/REPL.jl:281
> [11] display(x::Any)
> @ Base.Multimedia ./multimedia.jl:340
> [12] #invokelatest#2
> @ ./essentials.jl:819 [inlined]
> [13] invokelatest
> @ ./essentials.jl:816 [inlined]
> [14] (::VSCodeServer.var"#67#72"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
> @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/eval.jl:229
> [15] withpath(f::VSCodeServer.var"#67#72"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams}, path::String)
> @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/repl.jl:274
> [16] (::VSCodeServer.var"#66#71"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
> @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/eval.jl:179
> [17] hideprompt(f::VSCodeServer.var"#66#71"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})
> @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/repl.jl:38
> [18] (::VSCodeServer.var"#65#70"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
> @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/eval.jl:150
> [19] with_logstate(f::Function, logstate::Any)
> @ Base.CoreLogging ./logging.jl:514
> [20] with_logger
> @ ./logging.jl:626 [inlined]
> [21] (::VSCodeServer.var"#64#69"{VSCodeServer.ReplRunCodeRequestParams})()
> @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/eval.jl:255
> [22] #invokelatest#2
> @ ./essentials.jl:819 [inlined]
> [23] invokelatest(::Any)
> @ Base ./essentials.jl:816
> [24] macro expansion
> @ ~/.vscode/extensions/julialang.language-julia-1.60.2/scripts/packages/VSCodeServer/src/eval.jl:34 [inlined]
> [25] (::VSCodeServer.var"#62#63")()
> @ VSCodeServer ./task.jl:514
> 
> ```

Does anyone know what is causing the error and how to fix it? In addition, should the version reflect the breaking behavior?

---

<div class="post-metadata">

### Author: ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)
#### Post date: [December 1, 2023, 12:13pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/2 "2023-12-01T12:13:09Z")

</div>

I think `row_name*` keyword parameters changed to `row_label*`

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 1, 2023, 12:24pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/3 "2023-12-01T12:24:03Z")

</div>

> [@greg\_plowman](#):
>
> row\_label

Thank you. It looks like the keyword is `row_labels` (pluralized), `row_name_column_title` → `row_label_column_title`, and `row_name_alignment` → `row_label_alignment`.

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 1, 2023, 12:43pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/4 "2023-12-01T12:43:00Z")

</div>

I opened an [issue](https://github.com/ronisbr/PrettyTables.jl/issues/232) and the author will be releasing some fixes.

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [December 1, 2023, 12:54pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/5 "2023-12-01T12:54:57Z")

</div>

There was a change. At first I though @ronins\_BR wasn’t following semver, or was sloppy (EDIT: actually semver was violated), but I think this is allowed. And he’s doing excellent job following the rules, not doing more than asked, also you can argue with the rules…:

Note, 2.0 was released with breaking changes, clearly marked in the CHANGELOG, e.g.:

> - [![BREAKING](https://camo.githubusercontent.com/911615be3323299aefd875d8084d1361f4b2a28e6727fc715110699f13b208a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f425245414b494e472d7265642e737667)](https://camo.githubusercontent.com/911615be3323299aefd875d8084d1361f4b2a28e6727fc715110699f13b208a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f425245414b494e472d7265642e737667) The default option of `standalone` in HTML backend is new `false` instead of `true`.  
> [probably a typo there, new-\> now.]
> - [![Deprecation](https://camo.githubusercontent.com/6575a598998e4fb1ba7b4a2fc426686765993bcfb016eb23f1c070cac1a816f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4465707265636174696f6e2d6f72616e67652e737667)](https://camo.githubusercontent.com/6575a598998e4fb1ba7b4a2fc426686765993bcfb016eb23f1c070cac1a816f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4465707265636174696f6e2d6f72616e67652e737667) The following options and structures were renamed (the old versions are now deprecated):
> - `HTMLDecoration => HtmlDecoration`
> - […]
> - `row\_name\* =\> row\_label

Note, it doesn’t say breaking for the change since it was still usable (but you should stop using, migrate to the new).

It’s easy to just keep using and not even know of this since julia --depwarn=yes (or error) is no longer the default. So when it eventually gets dropped it may come as a surprise. ~~I think semver allows dropping deprecated in any later minor version~~ , not just major. Would it have been better to state it, or wait until 3.0? ~~Maybe…~~

Or just never drop stuff. That’s what Rick Hickey suggests doing, argues against semver. There’s never a strict need to drop stuff rather than keep synonyms. It may clutter your codebase a bit, could be put into a separate file, disk space is cheap, I would worry more about startup cost, but synonyms could be NOT precompiled.

EDIT: Should have waited until next major to drop deprecated (according to semver rules, while Hickey would argue never):

> **[Semantic Versioning 2.0.0](https://semver.org)**
>
> Semantic Versioning spec and website

> How should I handle deprecating functionality?
> 
> Deprecating existing functionality is a normal part of software development and is often required to make forward progress. When you deprecate part of your public API, you should do two things: (1) update your documentation to let users know about the change, (2) issue a new minor release with the deprecation in place. Before you completely remove the functionality in a new major release there should be at least one minor release that contains the deprecation so that users can smoothly transition to the new API.

> Minor version Y (x.Y.z | x \> 0) MUST be incremented if new, backward compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated.

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 1, 2023, 1:21pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/6 "2023-12-01T13:21:41Z")

</div>

Thanks for clarifying about the warnings not showing by default. That explains why I never saw the deprecation warnings. Does that mean that the deprecation warning was removed sometime in 2.x, which created the appearance of a breaking change mid 2.x?

The only thing that doesn’t quite make sense is that under the release notes, I see \* `row_name* => row_label*` for 2.0, but I don’t see the other keyword changes (there were three I had to make). Maybe the list was incomplete?

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [December 1, 2023, 2:31pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/7 "2023-12-01T14:31:07Z")

</div>

If you run with e.g. --depwarn=error then you would notice all the deprecated functions you actually try to use, from version _2.0_ (i.e. since when deprecation added) on-wards.

It would be good to try such when you do a major upgrade, though note this wasn’t your fault, just that you could have avoided being affected.

> [@Christopher\_Fisher](#):
>
> Does that mean that the deprecation warning was removed sometime in 2.x

Yes, when the deprecated function was removed in some 2.x, it was a breaking change (not strictly in 2.0), that was done by mistake. The warning (if you had enabled them or erroring) would have gone away in that 2.x, since the deprecation is attached to a function and it’s gone. There’s no way to keep it except by NOT removing the function, currently. It might be worthwhile for Julia to have a way of keeping just the warning (for a more helpful error message), but it would mean you would have to keep the function _definition_ around in some form (though might skip the function body), if it’s deemed worthwhile. It seems though you might as well just not remove anything, also keep the body. The body can be rather trivial, just a call to its replacement function…

It was actually a bug to remove in the minor version.

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 1, 2023, 5:50pm UTC](https://discourse.julialang.org/t/prettytables-jl-breaks-on-non-breaking-release/106990/8 "2023-12-01T17:50:19Z")

</div>

Thanks for your explanation. What happened now makes sense. I was not aware that deprecation warnings are turned off by default. In the future, I will turn on the warnings before upgrading to breaking versions of dependencies.
