Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,8 @@ column, in which case every column may have different number formatting:

```

`intfmt` works similarly for integers
`intfmt` works similarly for integers, including signed and unsigned NumPy
integer scalars:

>>> print(tabulate([["a",1000],["b",90000]], intfmt=","))
- ------
Expand Down
8 changes: 5 additions & 3 deletions tabulate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io
from itertools import chain, zip_longest as izip_longest
import math
from numbers import Integral
import re
import textwrap
import warnings
Expand Down Expand Up @@ -935,9 +936,10 @@ def _isint(string, inttype=int):
return (
type(string) is inttype
or (
(hasattr(string, "is_integer") or hasattr(string, "__array__"))
and str(type(string)).startswith("<class 'numpy.int")
) # numpy.int64 and similar
type(string).__module__ == "numpy"
and isinstance(string, Integral)
and string.dtype.kind in ("i", "u")
) # NumPy integer scalars, excluding timedelta64
or (
isinstance(string, (bytes, str)) and _isconvertible(inttype, string)
) # integer as string
Expand Down
46 changes: 46 additions & 0 deletions test/test_numpy_integers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""NumPy integer values retain their precision and integer formatting."""

import pytest

from tabulate import tabulate


@pytest.mark.parametrize("input_type", ["list", "numpy", "dataframe"])
@pytest.mark.parametrize("intfmt", [",", "x"])
@pytest.mark.parametrize(
"dtype",
[
"int8",
"int16",
"int32",
"int64",
"uint8",
"uint16",
"uint32",
"uint64",
"longlong",
"ulonglong",
],
)
def test_numpy_integer_formats(input_type, intfmt, dtype):
numpy = pytest.importorskip("numpy")
integer_type = getattr(numpy, dtype)
value = integer_type(numpy.iinfo(integer_type).max)
rows = [[value]]
if input_type == "numpy":
table = numpy.array(rows, dtype=integer_type)
elif input_type == "dataframe":
pandas = pytest.importorskip("pandas")
table = pandas.DataFrame(rows, dtype=integer_type)
else:
table = rows

options = {"tablefmt": "plain", "showindex": False, "intfmt": intfmt, "floatfmt": ".0f"}
assert tabulate(table, **options) == tabulate([[int(value)]], **options)


def test_numpy_duration_is_not_formatted_as_integer():
numpy = pytest.importorskip("numpy")
value = numpy.timedelta64(1, "D")

assert tabulate([[value]], tablefmt="plain", intfmt="x") == str(value)