astanin / python-tabulate

Pretty-print tabular data in Python, a library and a command-line utility. Repository migrated from bitbucket.org/astanin/python-tabulate.
https://pypi.org/project/tabulate/
MIT License
2.08k stars 162 forks source link

FutureWarning if a table cell is a numpy array #287

Open alugowski opened 12 months ago

alugowski commented 12 months ago
import numpy as np
from tabulate import tabulate

data = [[np.ones(1)]]

print(tabulate(data))

Yields this warning from numpy:

/Users/enos/temp/venv/lib/python3.10/site-packages/tabulate/__init__.py:107: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  (len(row) >= 1 and row[0] == SEPARATING_LINE)
-
1
-

The cause is that the line detection function,

def _is_separating_line(row):
    row_type = type(row)
    is_sl = (row_type == list or row_type == str) and (
        (len(row) >= 1 and row[0] == SEPARATING_LINE)
        or (len(row) >= 2 and row[1] == SEPARATING_LINE)
    )
    return is_sl

performs the == operation. This is generally correct, but with numpy (and also other array packages) an == does elementwise comparisons and not object-level. This should still yield the correct answer, just inefficiently and numpy in particular emits that warning.

The fix is simple. Replace the == with is:

        (len(row) >= 1 and row[0] is SEPARATING_LINE)
        or (len(row) >= 2 and row[1] is SEPARATING_LINE)

The is should also be a tiny bit faster, too.

alugowski commented 12 months ago

Correction, this is now an error in the newest numpy:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

The fix is the same.