diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0187705 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: Release + +on: + push: + tags: + - '*' + +jobs: + pypi-publish: + if: startsWith(github.ref, 'refs/tags') + name: Upload release to PyPI + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/tabulate-slip39 + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + - name: Build + run: | + python -m pip install --upgrade pip + python -m pip install setuptools build + python -m build -s + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/HOWTOPUBLISH b/HOWTOPUBLISH index 29c4545..bd78db2 100644 --- a/HOWTOPUBLISH +++ b/HOWTOPUBLISH @@ -1,4 +1,5 @@ # update contributors and CHANGELOG in README +python -m pip install pre-commit python -m pre_commit run -a # and then commit changes tox -e py39-extra,py310-extra,py311-extra,py312-extra,py313-extra # tag version release @@ -6,10 +7,9 @@ python -m build -s # this will update tabulate/version.py python -m pip install . # install tabulate in the current venv python -m pip install -r benchmark/requirements.txt python benchmark/benchmark.py # then update README -# move tag to the last commit +# move tag to the last commit: eg. +git tag v0.10.4 python -m build -s # update tabulate/version.py python -m build -nswx . git push # wait for all CI builds to succeed git push --tags # if CI builds succeed -twine upload --repository-url https://test.pypi.org/legacy/ dist/* -twine upload dist/* diff --git a/README.md b/README.md index f3d0fa9..41f2a94 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ python-tabulate =============== +> This is a temporary upgrade shim for https://github.com/astanin/python-tabulate + +> Install `tabulate` via `python -m pip install tabulate-slip39`, +> until the upstream https://pypi.org/project/tabulate is upgraded + + Pretty-print tabular data in Python, a library and a command-line utility. @@ -503,10 +509,10 @@ format: >>> print(tabulate(table, headers, tablefmt="asciidoc")) [cols="8<,7>",options="header"] |==== -| item | qty -| spam | 42 -| eggs | 451 -| bacon | 0 +| item | qty +| spam | 42 +| eggs | 451 +| bacon | 0 |==== ``` diff --git a/pyproject.toml b/pyproject.toml index 4144f9b..67c5429 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2.0", "setuptools_scm[toml]>=3.4.3"] build-backend = "setuptools.build_meta" [project] -name = "tabulate" +name = "tabulate-slip39" authors = [{name = "Sergey Astanin", email = "s.astanin@gmail.com"}] license = {text = "MIT"} description = "Pretty-print tabular data" diff --git a/tabulate/__init__.py b/tabulate/__init__.py index b15d7f0..f491325 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1623,7 +1623,9 @@ 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 +1648,11 @@ 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 _isnumber(cell) + else _type(cell, numparse)(cell) ) wrapped = [ "\n".join(wrapper.wrap(line)) @@ -2247,7 +2253,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 +2267,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) diff --git a/tox.ini b/tox.ini index 9605e79..51f0100 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ # for testing and it is disabled by default. [tox] -envlist = lint, py{38, 39, 310, 311, 312, 313} +envlist = lint, py{39, 310, 311, 312, 313} isolated_build = True [gh] @@ -33,12 +33,6 @@ commands = python -m pre_commit run -a deps = pre-commit -[testenv:py38] -basepython = python3.8 -commands = pytest -v --doctest-modules --ignore benchmark {posargs} -deps = - pytest - [testenv:py38-extra] basepython = python3.8 commands = pytest -v --doctest-modules --ignore benchmark {posargs}