Skip to content

Commit 4d3809e

Browse files
authored
Merge pull request #313 from gschizas/master
Fix column wrapping breaking with None values (fixes #312)
2 parents 74885be + 815bfa5 commit 4d3809e

3 files changed

Lines changed: 58 additions & 8 deletions

File tree

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ widechars = ["wcwidth"]
3232
[project.scripts]
3333
tabulate = "tabulate:_main"
3434

35-
[tool.setuptools]
36-
packages = ["tabulate"]
35+
# [tool.setuptools]
36+
# packages = ["tabulate"]
3737

38-
[tool.setuptools_scm]
39-
write_to = "tabulate/version.py"
38+
# [tool.setuptools_scm]
39+
# write_to = "tabulate/version.py"

tabulate/__init__.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,7 @@ def _normalize_tabular_data(tabular_data, headers, showindex="default"):
16381638
return rows, headers, headers_pad
16391639

16401640

1641-
def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True, break_long_words=_BREAK_LONG_WORDS, break_on_hyphens=_BREAK_ON_HYPHENS):
1641+
def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True, missingval=_DEFAULT_MISSINGVAL, break_long_words=_BREAK_LONG_WORDS, break_on_hyphens=_BREAK_ON_HYPHENS):
16421642
if len(list_of_lists):
16431643
num_cols = len(list_of_lists[0])
16441644
else:
@@ -1656,7 +1656,13 @@ def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True, break_long
16561656

16571657
if width is not None:
16581658
wrapper = _CustomTextWrap(width=width, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens)
1659-
casted_cell = str(cell)
1659+
# Cast based on our internal type handling. Any future custom
1660+
# formatting of types (such as datetimes) may need to be more
1661+
# explicit than just `str` of the object. Also doesn't work for
1662+
# custom floatfmt/intfmt, nor with any missing/blank cells.
1663+
casted_cell = (
1664+
missingval if cell is None else str(cell) if cell == '' or _isnumber(cell) else _type(cell, numparse)(cell)
1665+
)
16601666
wrapped = [
16611667
"\n".join(wrapper.wrap(line))
16621668
for line in casted_cell.splitlines()
@@ -2258,7 +2264,7 @@ def tabulate(
22582264

22592265
numparses = _expand_numparse(disable_numparse, num_cols)
22602266
list_of_lists = _wrap_text_to_colwidths(
2261-
list_of_lists, maxcolwidths, numparses=numparses, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens
2267+
list_of_lists, maxcolwidths, numparses=numparses, missingval=missingval, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens
22622268
)
22632269

22642270
if maxheadercolwidths is not None:
@@ -2272,7 +2278,7 @@ def tabulate(
22722278

22732279
numparses = _expand_numparse(disable_numparse, num_cols)
22742280
headers = _wrap_text_to_colwidths(
2275-
[headers], maxheadercolwidths, numparses=numparses, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens
2281+
[headers], maxheadercolwidths, numparses=numparses, missingval=missingval, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens
22762282
)[0]
22772283

22782284
# empty values in the first column of RST tables should be escaped (issue #82)

test/test_textwrapper.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,50 @@ def test_wrap_datetime():
222222
assert_equal(expected, result)
223223

224224

225+
def test_wrap_none_value():
226+
"""TextWrapper: Show that None can be wrapped without crashing"""
227+
data = [["First Entry", None], ["Second Entry", None]]
228+
headers = ["Title", "Value"]
229+
result = tabulate(data, headers=headers, tablefmt="grid", maxcolwidths=[7, 5])
230+
231+
expected = [
232+
"+---------+---------+",
233+
"| Title | Value |",
234+
"+=========+=========+",
235+
"| First | |",
236+
"| Entry | |",
237+
"+---------+---------+",
238+
"| Second | |",
239+
"| Entry | |",
240+
"+---------+---------+",
241+
]
242+
expected = "\n".join(expected)
243+
assert_equal(expected, result)
244+
245+
246+
def test_wrap_none_value_with_missingval():
247+
"""TextWrapper: Show that None can be wrapped without crashing and with a missing value"""
248+
data = [["First Entry", None], ["Second Entry", None]]
249+
headers = ["Title", "Value"]
250+
result = tabulate(
251+
data, headers=headers, tablefmt="grid", maxcolwidths=[7, 5], missingval="???"
252+
)
253+
254+
expected = [
255+
"+---------+---------+",
256+
"| Title | Value |",
257+
"+=========+=========+",
258+
"| First | ??? |",
259+
"| Entry | |",
260+
"+---------+---------+",
261+
"| Second | ??? |",
262+
"| Entry | |",
263+
"+---------+---------+",
264+
]
265+
expected = "\n".join(expected)
266+
assert_equal(expected, result)
267+
268+
225269
def test_wrap_optional_bool_strs():
226270
"""TextWrapper: Show that str bools and None can be wrapped without crashing"""
227271
data = [

0 commit comments

Comments
 (0)