Skip to content

Commit 2ec080d

Browse files
authored
Merge branch 'master' into master
2 parents 7d67fee + 46307a5 commit 2ec080d

16 files changed

+1934
-301
lines changed

.circleci/config.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ jobs:
4545
. venv/bin/activate
4646
tox -e py38-extra
4747
48-
- run:
49-
name: run linting
50-
command: |
51-
. venv/bin/activate
52-
tox -e lint
53-
5448
- store_artifacts:
5549
path: test-reports
5650
destination: test-reports

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/python/black
3-
rev: 19.3b0
3+
rev: 21.12b0
44
hooks:
55
- id: black
66
args: [--safe]

CHANGELOG

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
- 0.8.10: Future version
1+
- 0.8.11: Future version. Drop support for Python 2.7, 3.5, 3.6. New formats. Improve column width options.
2+
- 0.8.10: Python 3.10 support. Bug fixes. Column width parameter.
23
- 0.8.9: Bug fix. Revert support of decimal separators.
34
- 0.8.8: Python 3.9 support, 3.10 ready.
45
New formats: ``unsafehtml``, ``latex_longtable``, ``fancy_outline``.
@@ -11,7 +12,7 @@
1112
- 0.8.6: Bug fixes. Stop supporting Python 3.3, 3.4.
1213
- 0.8.5: Fix broken Windows package. Minor documentation updates.
1314
- 0.8.4: Bug fixes.
14-
- 0.8.3: New formats: `github`. Custom colum alignment. Bug fixes.
15+
- 0.8.3: New formats: `github`. Custom column alignment. Bug fixes.
1516
- 0.8.2: Bug fixes.
1617
- 0.8.1: Multiline data in several output formats.
1718
New ``latex_raw`` format.

README.md

Lines changed: 145 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,15 @@ Supported table formats are:
137137
- "simple"
138138
- "github"
139139
- "grid"
140+
- "simple\_grid"
141+
- "rounded\_grid"
142+
- "double\_grid"
140143
- "fancy\_grid"
144+
- "outline"
145+
- "simple\_outline"
146+
- "rounded\_outline"
147+
- "double\_outline"
148+
- "fancy\_outline"
141149
- "pipe"
142150
- "orgtbl"
143151
- "jira"
@@ -203,7 +211,47 @@ corresponds to the `pipe` format without alignment colons:
203211
| bacon | 0 |
204212
+--------+-------+
205213

206-
`fancy_grid` draws a grid using box-drawing characters:
214+
`simple_grid` draws a grid using single-line box-drawing characters:
215+
216+
>>> print(tabulate(table, headers, tablefmt="simple_grid"))
217+
┌────────┬───────┐
218+
│ item │ qty │
219+
├────────┼───────┤
220+
│ spam │ 42 │
221+
├────────┼───────┤
222+
│ eggs │ 451 │
223+
├────────┼───────┤
224+
│ bacon │ 0 │
225+
└────────┴───────┘
226+
227+
`rounded_grid` draws a grid using single-line box-drawing characters with rounded corners:
228+
229+
>>> print(tabulate(table, headers, tablefmt="rounded_grid"))
230+
╭────────┬───────╮
231+
│ item │ qty │
232+
├────────┼───────┤
233+
│ spam │ 42 │
234+
├────────┼───────┤
235+
│ eggs │ 451 │
236+
├────────┼───────┤
237+
│ bacon │ 0 │
238+
╰────────┴───────╯
239+
240+
`double_grid` draws a grid using double-line box-drawing characters:
241+
242+
>>> print(tabulate(table, headers, tablefmt="double_grid"))
243+
╔════════╦═══════╗
244+
║ item ║ qty ║
245+
╠════════╬═══════╣
246+
║ spam ║ 42 ║
247+
╠════════╬═══════╣
248+
║ eggs ║ 451 ║
249+
╠════════╬═══════╣
250+
║ bacon ║ 0 ║
251+
╚════════╩═══════╝
252+
253+
`fancy_grid` draws a grid using a mix of single and
254+
double-line box-drawing characters:
207255

208256
>>> print(tabulate(table, headers, tablefmt="fancy_grid"))
209257
╒════════╤═══════╕
@@ -216,6 +264,61 @@ corresponds to the `pipe` format without alignment colons:
216264
│ bacon │ 0 │
217265
╘════════╧═══════╛
218266

267+
`outline` is the same as the `grid` format but doesn't draw lines between rows:
268+
269+
>>> print(tabulate(table, headers, tablefmt="outline"))
270+
+--------+-------+
271+
| item | qty |
272+
+========+=======+
273+
| spam | 42 |
274+
| eggs | 451 |
275+
| bacon | 0 |
276+
+--------+-------+
277+
278+
`simple_outline` is the same as the `simple_grid` format but doesn't draw lines between rows:
279+
280+
>>> print(tabulate(table, headers, tablefmt="simple_outline"))
281+
┌────────┬───────┐
282+
│ item │ qty │
283+
├────────┼───────┤
284+
│ spam │ 42 │
285+
│ eggs │ 451 │
286+
│ bacon │ 0 │
287+
└────────┴───────┘
288+
289+
`rounded_outline` is the same as the `rounded_grid` format but doesn't draw lines between rows:
290+
291+
>>> print(tabulate(table, headers, tablefmt="rounded_outline"))
292+
╭────────┬───────╮
293+
│ item │ qty │
294+
├────────┼───────┤
295+
│ spam │ 42 │
296+
│ eggs │ 451 │
297+
│ bacon │ 0 │
298+
╰────────┴───────╯
299+
300+
`double_outline` is the same as the `double_grid` format but doesn't draw lines between rows:
301+
302+
>>> print(tabulate(table, headers, tablefmt="double_outline"))
303+
╔════════╦═══════╗
304+
║ item ║ qty ║
305+
╠════════╬═══════╣
306+
║ spam ║ 42 ║
307+
║ eggs ║ 451 ║
308+
║ bacon ║ 0 ║
309+
╚════════╩═══════╝
310+
311+
`fancy_outline` is the same as the `fancy_grid` format but doesn't draw lines between rows:
312+
313+
>>> print(tabulate(table, headers, tablefmt="fancy_outline"))
314+
╒════════╤═══════╕
315+
│ item │ qty │
316+
╞════════╪═══════╡
317+
│ spam │ 42 │
318+
│ eggs │ 451 │
319+
│ bacon │ 0 │
320+
╘════════╧═══════╛
321+
219322
`presto` is like tables formatted by Presto cli:
220323

221324
>>> print(tabulate(table, headers, tablefmt="presto"))
@@ -646,6 +749,33 @@ a multiline cell, and headers with a multiline cell:
646749

647750
Multiline cells are not well supported for the other table formats.
648751

752+
### Automating Multilines
753+
While tabulate supports data passed in with multiines entries explicitly provided,
754+
it also provides some support to help manage this work internally.
755+
756+
The `maxcolwidths` argument is a list where each entry specifies the max width for
757+
it's respective column. Any cell that will exceed this will automatically wrap the content.
758+
To assign the same max width for all columns, a singular int scaler can be used.
759+
760+
Use `None` for any columns where an explicit maximum does not need to be provided,
761+
and thus no automate multiline wrapping will take place.
762+
763+
The wrapping uses the python standard [textwrap.wrap](https://docs.python.org/3/library/textwrap.html#textwrap.wrap)
764+
function with default parameters - aside from width.
765+
766+
This example demonstrates usage of automatic multiline wrapping, though typically
767+
the lines being wrapped would probably be significantly longer than this.
768+
769+
>>> print(tabulate([["John Smith", "Middle Manager"]], headers=["Name", "Title"], tablefmt="grid", maxcolwidths=[None, 8]))
770+
+------------+---------+
771+
| Name | Title |
772+
+============+=========+
773+
| John Smith | Middle |
774+
| | Manager |
775+
+------------+---------+
776+
777+
778+
649779
Usage of the command line utility
650780
---------------------------------
651781

@@ -688,19 +818,19 @@ At the same time, `tabulate` is comparable to other table
688818
pretty-printers. Given a 10x10 table (a list of lists) of mixed text and
689819
numeric data, `tabulate` appears to be slower than `asciitable`, and
690820
faster than `PrettyTable` and `texttable` The following mini-benchmark
691-
was run in Python 3.8.3 in Windows 10 x64:
821+
was run in Python 3.8.2 in Ubuntu 20.04:
692822

693-
================================= ========== ===========
694-
Table formatter time, μs rel. time
695-
================================= ========== ===========
696-
csv to StringIO 12.5 1.0
697-
join with tabs and newlines 15.6 1.3
698-
asciitable (0.8.0) 191.4 15.4
699-
tabulate (0.8.9) 472.8 38.0
700-
tabulate (0.8.9, WIDE_CHARS_MODE) 789.6 63.4
701-
PrettyTable (0.7.2) 879.1 70.6
702-
texttable (1.6.2) 1352.2 108.6
703-
================================= ========== ===========
823+
================================== ========== ===========
824+
Table formatter time, μs rel. time
825+
================================== ========== ===========
826+
csv to StringIO 9.0 1.0
827+
join with tabs and newlines 10.7 1.2
828+
asciitable (0.8.0) 174.6 19.4
829+
tabulate (0.8.10) 385.0 42.8
830+
tabulate (0.8.10, WIDE_CHARS_MODE) 509.1 56.5
831+
PrettyTable (3.3.0) 827.7 91.9
832+
texttable (1.6.4) 952.1 105.7
833+
================================== ========== ===========
704834

705835

706836
Version history
@@ -767,4 +897,5 @@ Wes Turner, Andrew Tija, Marco Gorelli, Sean McGinnis, danja100,
767897
endolith, Dominic Davis-Foster, pavlocat, Daniel Aslau, paulc,
768898
Felix Yan, Shane Loretz, Frank Busse, Harsh Singh, Derek Weitzel,
769899
Vladimir Vrzić, 서승우 (chrd5273), Georgy Frolov, Christian Cwienk,
770-
Bart Broere, Vilhelm Prytz.
900+
Bart Broere, Vilhelm Prytz, Alexander Gažo, Hugo van Kemenade,
901+
jamescooke, Matt Warner.

appveyor.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
image: Visual Studio 2022
12
environment:
23

34
matrix:
@@ -7,16 +8,13 @@ environment:
78
# The list here is complete (excluding Python 2.6, which
89
# isn't covered by this document) at the time of writing.
910

10-
- PYTHON: "C:\\Python27"
11-
- PYTHON: "C:\\Python35"
12-
- PYTHON: "C:\\Python36"
1311
- PYTHON: "C:\\Python37"
1412
- PYTHON: "C:\\Python38"
15-
- PYTHON: "C:\\Python27-x64"
16-
- PYTHON: "C:\\Python35-x64"
17-
- PYTHON: "C:\\Python36-x64"
13+
- PYTHON: "C:\\Python39"
1814
- PYTHON: "C:\\Python37-x64"
1915
- PYTHON: "C:\\Python38-x64"
16+
- PYTHON: "C:\\Python39-x64"
17+
- PYTHON: "C:\\Python310-x64"
2018

2119
install:
2220
# We need wheel installed to build wheels

benchmark.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,19 @@
1-
# -*- coding: utf-8 -*-
2-
from __future__ import unicode_literals
3-
from __future__ import print_function
41
from timeit import timeit
52
import tabulate
63
import asciitable
74
import prettytable
85
import texttable
96
import sys
10-
import codecs
11-
from platform import python_version_tuple
127

138
setup_code = r"""
149
from csv import writer
15-
try: # Python 2
16-
from StringIO import StringIO
17-
except: # Python 3
18-
from io import StringIO
10+
from io import StringIO
1911
import tabulate
2012
import asciitable
2113
import prettytable
2214
import texttable
2315
2416
25-
import platform
26-
if platform.platform().startswith("Windows") \
27-
and \
28-
platform.python_version_tuple() < ('3','6','0'):
29-
import win_unicode_console
30-
win_unicode_console.enable()
31-
32-
3317
table=[["some text"]+list(range(i,i+9)) for i in range(10)]
3418
3519
@@ -108,14 +92,7 @@ def benchmark(n):
10892
results, ["Table formatter", "time, μs", "rel. time"], "rst", floatfmt=".1f"
10993
)
11094

111-
from platform import platform
112-
113-
if platform().startswith("Windows"):
114-
print(table)
115-
elif python_version_tuple()[0] < "3":
116-
print(codecs.encode(table, "utf-8"))
117-
else:
118-
print(table)
95+
print(table)
11996

12097

12198
if __name__ == "__main__":

setup.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,17 @@
66
from distutils.core import setup
77

88

9-
from platform import python_version_tuple, python_implementation
9+
from platform import python_implementation
1010
import os
1111
import re
1212

13-
# strip links from the descripton on the PyPI
14-
if python_version_tuple()[0] >= "3":
15-
LONG_DESCRIPTION = open("README.md", "r", encoding="utf-8").read()
16-
else:
17-
LONG_DESCRIPTION = open("README.md", "r").read()
13+
# strip links from the description on the PyPI
14+
LONG_DESCRIPTION = open("README.md", encoding="utf-8").read()
1815

1916
# strip Build Status from the PyPI package
2017
try:
21-
if python_version_tuple()[:2] >= ("2", "7"):
22-
status_re = "^Build status\n(.*\n){7}"
23-
LONG_DESCRIPTION = re.sub(status_re, "", LONG_DESCRIPTION, flags=re.M)
18+
status_re = "^Build status\n(.*\n){7}"
19+
LONG_DESCRIPTION = re.sub(status_re, "", LONG_DESCRIPTION, flags=re.M)
2420
except TypeError:
2521
if python_implementation() == "IronPython":
2622
# IronPython doesn't support flags in re.sub (IronPython issue #923)
@@ -29,7 +25,7 @@
2925
raise
3026

3127
install_options = os.environ.get("TABULATE_INSTALL", "").split(",")
32-
libonly_flags = set(["lib-only", "libonly", "no-cli", "without-cli"])
28+
libonly_flags = {"lib-only", "libonly", "no-cli", "without-cli"}
3329
if libonly_flags.intersection(install_options):
3430
console_scripts = []
3531
else:
@@ -38,26 +34,25 @@
3834

3935
setup(
4036
name="tabulate",
41-
version="0.8.10",
37+
version="0.8.11",
4238
description="Pretty-print tabular data",
4339
long_description=LONG_DESCRIPTION,
4440
long_description_content_type="text/markdown",
4541
author="Sergey Astanin",
4642
author_email="s.astanin@gmail.com",
4743
url="https://github.com/astanin/python-tabulate",
4844
license="MIT",
45+
python_requires=">=3.7",
4946
classifiers=[
5047
"Development Status :: 4 - Beta",
5148
"License :: OSI Approved :: MIT License",
5249
"Operating System :: OS Independent",
53-
"Programming Language :: Python :: 2",
54-
"Programming Language :: Python :: 2.7",
5550
"Programming Language :: Python :: 3",
56-
"Programming Language :: Python :: 3.5",
57-
"Programming Language :: Python :: 3.6",
5851
"Programming Language :: Python :: 3.7",
5952
"Programming Language :: Python :: 3.8",
6053
"Programming Language :: Python :: 3.9",
54+
"Programming Language :: Python :: 3.10",
55+
"Programming Language :: Python :: 3 :: Only",
6156
"Topic :: Software Development :: Libraries",
6257
],
6358
py_modules=["tabulate"],

0 commit comments

Comments
 (0)