Skip to content

Do not crash when the deduced cell type rejects the raw value under maxcolwidths (#359, #448) - #506

Open
thejedi433 wants to merge 1 commit into
astanin:masterfrom
thejedi433:fix/wrap-text-cast-crash
Open

thejedi433 wants to merge 1 commit into
astanin:masterfrom
thejedi433:fix/wrap-text-cast-crash

Conversation

@thejedi433

Copy link
Copy Markdown

Problem

_wrap_text_to_colwidths() classifies each cell with _type() and then applies the returned constructor to the raw value before wrapping. _type() strips ANSI escapes and recognizes thousands separators while classifying, but int()/float() reject those raw strings, so maxcolwidths crashes on values that render fine without it:

>>> tabulate([["1,000"]], maxcolwidths=10)
ValueError: invalid literal for int() with base 10: '1,000'

>>> tabulate([["\x1b[31m3\x1b[0m"]], maxcolwidths=10)   # issue #359
ValueError: invalid literal for int() with base 10: '\x1b[31m3\x1b[0m'

Separately, the call _type(cell, numparse) passes the flag positionally into has_invisible, so numparse keeps its default True and disable_numparse=True is silently ignored on this path — int("100,120") raises (issue #448, a regression of the #305/#362 fix).

Fix

Pass numparse as a keyword, and keep the original text when the deduced constructor refuses the raw value. Wrapped rendering now matches unwrapped rendering instead of crashing:

>>> tabulate([["1,000"]], maxcolwidths=10) == tabulate([["1,000"]])
True

The except is scoped to the cast only (ValueError/TypeError), so genuine type-deduction behavior is unchanged for every cell the constructors accept (1.50 still normalizes to 1.5, ints still right-align, etc.).

This supersedes #444 (closed; it special-cased ANSI detection instead of handling the cast failure, and covered neither the thousands-separator crash nor the disable_numparse positional bug). It includes the keyword-passing fix of #471/#473 as a subset plus the crash-class fixes they do not cover (1,000 and colored strings with default numparse still crash with keyword-only passing).

Testing

  • 4 regression tests in test/test_regression.py, each verified to fail on pristine 268615a and pass with the fix.
  • Full suite green: 326 passed, 60 skipped (pytest --doctest-modules, Python 3.11/3.13 both exercised via the fork CI matrix).
  • ruff check / ruff format --check report no new findings (the 10 pre-existing ISC001 warnings in the untouched files are unchanged from baseline).

Closes #359
Closes #448

…axcolwidths

_wrap_text_to_colwidths() classifies a cell with _type() and applies the
returned constructor to the RAW value before wrapping. _type() strips
ANSI escapes and recognizes thousands separators when classifying, but
int()/float() reject those raw strings:

- int("\x1b[31m3\x1b[0m")  (issue astanin#359, ANSI-colored numeric string)
- int("1,000")           (thousands separator, integer-looking)
- float("1,000.5")       (thousands separator, float-looking)

The positional _type(cell, numparse) call also filled has_invisible
instead of numparse, so disable_numparse was silently ignored on this
path and int("100,120") raised (issue astanin#448).

Pass numparse as a keyword and keep the original text when the
constructor refuses the raw value, so wrapped rendering matches
unwrapped rendering instead of crashing.

Fixes astanin#359
Fixes astanin#448
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

problem in tabulate 0.10.0 on python 3.11.12 with cell values like "100,120" type error when using maxcolwidths with colored strings

1 participant