Skip to content

Fix crash when wrapping a pandas NA scalar (#429)#432

Open
gaoflow wants to merge 1 commit into
astanin:masterfrom
gaoflow:fix-429-pandas-na-wrap
Open

Fix crash when wrapping a pandas NA scalar (#429)#432
gaoflow wants to merge 1 commit into
astanin:masterfrom
gaoflow:fix-429-pandas-na-wrap

Conversation

@gaoflow

@gaoflow gaoflow commented Jun 14, 2026

Copy link
Copy Markdown

What

Fixes #429: tabulate(df, maxcolwidths=...) raised TypeError: boolean value of NA is ambiguous whenever a cell was a pandas NA scalar (e.g. a float32[pyarrow] column with a missing value).

Why

In _wrap_text_to_colwidths each cell is classified with:

if cell == "" or _isnumber(cell)

For a pandas NA, cell == "" does not return a plain bool — it returns NA, and forcing that to a truth value inside the or raises TypeError: boolean value of NA is ambiguous. So any table with maxcolwidths set crashed on a pd.NA cell.

Fix

Guard the empty-string test with isinstance(cell, str) so only real strings are compared to "". A NA then flows through the normal _type path and renders as <NA> — exactly how plain tabulate (without maxcolwidths) already displays it, so the two paths now agree.

Verified against the issue's exact reproducer (a float32[pyarrow] column): the maxcolwidths output now matches the non-maxcolwidths output, and a NA mixed with real floats still renders the real values correctly.

Tests

Added test_wrap_pandas_na_value in test/test_textwrapper.py (skips if pandas is unavailable). It reproduces the crash on master (TypeError: boolean value of NA is ambiguous at the same line) and passes with the fix. The wrapping/textwrapper test modules are all green.


This change was prepared by an AI agent under my direction; I reviewed and verified it.

In _wrap_text_to_colwidths the empty-string check compared each cell
directly to "". For a pandas NA scalar, cell == "" returns a non-bool
NA whose truthiness then raises "boolean value of NA is ambiguous"
inside the surrounding or, so tabulate crashed whenever maxcolwidths
was set and any cell was pd.NA.

Guard the comparison with isinstance(cell, str) so only real strings are
tested for emptiness; the NA then flows through the normal _type path and
renders as <NA>, matching how plain tabulate (without maxcolwidths)
already displays it.
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.

0.10.0 has improper handling of pd.NA values when the dtype is, e.g., float32[pyarrow]

1 participant