diff --git a/pyproject.toml b/pyproject.toml index 4144f9b..cdd62d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ -[build-system] -requires = ["setuptools>=61.2.0", "setuptools_scm[toml]>=3.4.3"] -build-backend = "setuptools.build_meta" +# [build-system] +# requires = ["setuptools>=61.2.0", "setuptools_scm[toml]>=3.4.3"] +# build-backend = "setuptools.build_meta" [project] name = "tabulate" @@ -32,8 +32,8 @@ widechars = ["wcwidth"] [project.scripts] tabulate = "tabulate:_main" -[tool.setuptools] -packages = ["tabulate"] +# [tool.setuptools] +# packages = ["tabulate"] -[tool.setuptools_scm] -write_to = "tabulate/version.py" +# [tool.setuptools_scm] +# write_to = "tabulate/version.py" diff --git a/tabulate/__init__.py b/tabulate/__init__.py index b15d7f0..0137f83 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1623,7 +1623,7 @@ def _normalize_tabular_data(tabular_data, headers, showindex="default"): return rows, headers, headers_pad -def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True): +def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True, missingval=_DEFAULT_MISSINGVAL): if len(list_of_lists): num_cols = len(list_of_lists[0]) else: @@ -1646,7 +1646,7 @@ def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True): # explicit than just `str` of the object. Also doesn't work for # custom floatfmt/intfmt, nor with any missing/blank cells. casted_cell = ( - str(cell) if _isnumber(cell) else _type(cell, numparse)(cell) + missingval if cell is None else str(cell) if cell == '' or _isnumber(cell) else _type(cell, numparse)(cell) ) wrapped = [ "\n".join(wrapper.wrap(line)) @@ -2247,7 +2247,7 @@ def tabulate( numparses = _expand_numparse(disable_numparse, num_cols) list_of_lists = _wrap_text_to_colwidths( - list_of_lists, maxcolwidths, numparses=numparses + list_of_lists, maxcolwidths, numparses=numparses, missingval=missingval ) if maxheadercolwidths is not None: @@ -2261,7 +2261,7 @@ def tabulate( numparses = _expand_numparse(disable_numparse, num_cols) headers = _wrap_text_to_colwidths( - [headers], maxheadercolwidths, numparses=numparses + [headers], maxheadercolwidths, numparses=numparses, missingval=missingval )[0] # empty values in the first column of RST tables should be escaped (issue #82) diff --git a/test/test_textwrapper.py b/test/test_textwrapper.py index 8c0a6cc..02dcc41 100644 --- a/test/test_textwrapper.py +++ b/test/test_textwrapper.py @@ -220,3 +220,47 @@ def test_wrap_datetime(): ] expected = "\n".join(expected) assert_equal(expected, result) + + +def test_wrap_none_value(): + """TextWrapper: Show that None can be wrapped without crashing""" + data = [["First Entry", None], ["Second Entry", None]] + headers = ["Title", "Value"] + result = tabulate(data, headers=headers, tablefmt="grid", maxcolwidths=[7, 5]) + + expected = [ + "+---------+---------+", + "| Title | Value |", + "+=========+=========+", + "| First | |", + "| Entry | |", + "+---------+---------+", + "| Second | |", + "| Entry | |", + "+---------+---------+", + ] + expected = "\n".join(expected) + assert_equal(expected, result) + + +def test_wrap_none_value_with_missingval(): + """TextWrapper: Show that None can be wrapped without crashing and with a missing value""" + data = [["First Entry", None], ["Second Entry", None]] + headers = ["Title", "Value"] + result = tabulate( + data, headers=headers, tablefmt="grid", maxcolwidths=[7, 5], missingval="???" + ) + + expected = [ + "+---------+---------+", + "| Title | Value |", + "+=========+=========+", + "| First | ??? |", + "| Entry | |", + "+---------+---------+", + "| Second | ??? |", + "| Entry | |", + "+---------+---------+", + ] + expected = "\n".join(expected) + assert_equal(expected, result)