Skip to content

maxcolwidths isn't properly respected: extra whitespace is added #354

Description

@yurivict

Testcase:

from tabulate import tabulate

headers = ['Header#1', 'Header#2', 'Header#3']
data = []
data.append(['Alpha beta gama zeta omega', 'The weather was exceptionally good that day again', 'The files were concatenated and archived for posterity.'])
data.append(['Delta omega beta alpha nu and the rest', 'The weather was exceptionally good that day', 'They decided to engage in many businesses and all of them were successful.'])

print(tabulate(
    data,
    headers=headers,
    tablefmt='fancy_grid',
    maxcolwidths=[None, None, 8]))

The output:

╒════════════════════════════════════════╤═══════════════════════════════════════════════════╤════════════╕
│ Header#1                               │ Header#2                                          │ Header#3   │
╞════════════════════════════════════════╪═══════════════════════════════════════════════════╪════════════╡
│ Alpha beta gama zeta omega             │ The weather was exceptionally good that day again │ The        │
│                                        │                                                   │ files      │
│                                        │                                                   │ were con   │
│                                        │                                                   │ catenate   │
│                                        │                                                   │ d and      │
│                                        │                                                   │ archived   │
│                                        │                                                   │ for post   │
│                                        │                                                   │ erity.     │
├────────────────────────────────────────┼───────────────────────────────────────────────────┼────────────┤
│ Delta omega beta alpha nu and the rest │ The weather was exceptionally good that day       │ They       │
│                                        │                                                   │ decided    │
│                                        │                                                   │ to         │
│                                        │                                                   │ engage     │
│                                        │                                                   │ in many    │
│                                        │                                                   │ business   │
│                                        │                                                   │ es and     │
│                                        │                                                   │ all of     │
│                                        │                                                   │ them       │
│                                        │                                                   │ were suc   │
│                                        │                                                   │ cessful.   │
╘════════════════════════════════════════╧═══════════════════════════════════════════════════╧════════════╛

The last column in the output has 2 extra spaces.
The data was wrapped at the requested column width of 8, but then 2 extra spaces were added.

This is important because maxcolwidths can be (and is in my case) calculated based on the actual terminal width, and adding extra space makes the table to overflow the terminal.

Version: 0.9.0
Python 3.11 (3.9 works the same way)

Activity

  1. changed the title [-]maxcolwidths isn't properly respected: extra whitespace is left[/-] [+]maxcolwidths isn't properly respected: extra whitespace is added[/+] on Nov 14, 2024
  2. added 2 commits that reference this issue on Jan 28, 2025
    e11e854
    8e5af6f
  3. astanin commented on Mar 5, 2026

    @astanin
    Owner

    I can confirm that the issue is still present in v0.10.0.

    Line breaks are consistent with how Python textwrap.wrap works. 2 margin spaces are added by the grid format. And there are two extra spaces after "catenate", which is already 8 characters long.

    >>> import textwrap
    >>> s = "'The files were concatenated and archived for posterity."
    >>> textwrap.wrap(s, 8)
    ["'The", 'files', 'were con', 'catenate', 'd and', 'archived', 'for post', 'erity.']
    
  4. astanin commented on Mar 5, 2026

    @astanin
    Owner

    On further test, the additional space comes from the long header. With a shorter header, everything is fine.

    ╒════════════════════════════════════════╤═══════════════════════════════════════════════════╤══════════╕
    │ Header#1                               │ Header#2                                          │ H3       │
    ╞════════════════════════════════════════╪═══════════════════════════════════════════════════╪══════════╡
    │ Alpha beta gama zeta omega             │ The weather was exceptionally good that day again │ The      │
    │                                        │                                                   │ files    │
    │                                        │                                                   │ were con │
    │                                        │                                                   │ catenate │
    │                                        │                                                   │ d and    │
    │                                        │                                                   │ archived │
    │                                        │                                                   │ for post │
    │                                        │                                                   │ erity.   │
    ├────────────────────────────────────────┼───────────────────────────────────────────────────┼──────────┤
    │ Delta omega beta alpha nu and the rest │ The weather was exceptionally good that day       │ They     │
    │                                        │                                                   │ decided  │
    │                                        │                                                   │ to       │
    │                                        │                                                   │ engage   │
    │                                        │                                                   │ in many  │
    │                                        │                                                   │ business │
    │                                        │                                                   │ es and   │
    │                                        │                                                   │ all of   │
    │                                        │                                                   │ them     │
    │                                        │                                                   │ were suc │
    │                                        │                                                   │ cessful. │
    ╘════════════════════════════════════════╧═══════════════════════════════════════════════════╧══════════╛
    

    I suspect, that additional padding is added twice to the value in the row headers. Once, in tabulate function, and the other time in _format_table. In your example the header happens to be exactly the width of the column, and padding of fancy_grid is 1 space on both sides. So, instead of adding 2, the library added 2 + 2.

  5. added this to the v0.11.0 milestone on Mar 5, 2026
  6. astanin commented on Mar 5, 2026

    @astanin
    Owner

    A shorter repro example:

    >>> print(tabulate([["foo"],["bar"]], headers="firstrow", tablefmt="grid", maxcolwidths=3))
    +-------+
    | foo   |
    +=======+
    | bar   |
    +-------+
    
  7. self-assigned this
    on Mar 5, 2026
  8. modified the milestones: v0.11.0, v1.0.0 on Mar 10, 2026
  9. astanin commented on Mar 10, 2026

    @astanin
    Owner

    Properly fixing it would change the output of most of the tabulate formats, so it's a breaking change.
    I'm changing milestone to v1.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions