Skip to content

Commit

Permalink
Merge pull request #18 from richardpaulhudson/master
Browse files Browse the repository at this point in the history
  • Loading branch information
ines authored Dec 6, 2021
2 parents 056d2bd + b7811a2 commit 4cb261c
Show file tree
Hide file tree
Showing 7 changed files with 478 additions and 19 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ Column 1 Column 2 Column 3
| `spacing` | int | Number of spaces between columns. | `3` |
| `aligns` | iterable / unicode | Columns alignments in order. `"l"` (left, default), `"r"` (right) or `"c"` (center). If If a string, value is used for all columns. | `None` |
| `multiline` | bool | If a cell value is a list of a tuple, render it on multiple lines, with one value per line. | `False` |
| `env_prefix` | unicode | Prefix for environment variables, e.g. WASABI_LOG_FRIENDLY. | `"WASABI"` |
| `color_values` | dict | Add or overwrite color values, name mapped to value. | `None` |
| `fg_colors` | iterable | Foreground colors, one per column. None can be specified for individual columns to retain the default background color. | `None` |
| `bg_colors` | iterable | Background colors, one per column. None can be specified for individual columns to retain the default background color. | `None` |
| **RETURNS** | str | The formatted table. | |

#### <kbd>function</kbd> `row`
Expand All @@ -231,9 +235,12 @@ a1 a2 a3
| Argument | Type | Description | Default |
| ----------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `data` | iterable | The individual columns to format. | |
| `widths` | iterable / int / `"auto"` | Column widths, either one integer for all columns or an iterable of values. If "auto", widths will be calculated automatically based on the largest value. | `"auto"` |
| `widths` | list / int / `"auto"` | Column widths, either one integer for all columns or an iterable of values. If "auto", widths will be calculated automatically based on the largest value. | `"auto"` |
| `spacing` | int | Number of spaces between columns. | `3` |
| `aligns` | iterable | Columns alignments in order. `"l"` (left), `"r"` (right) or `"c"` (center). | `None` |
| `aligns` | list | Columns alignments in order. `"l"` (left), `"r"` (right) or `"c"` (center). | `None` |
| `env_prefix` | unicode | Prefix for environment variables, e.g. WASABI_LOG_FRIENDLY. | `"WASABI"` |
| `fg_colors` | list | Foreground colors for the columns, in order. None can be specified for individual columns to retain the default foreground color. | `None` |
| `bg_colors` | list | Background colors for the columns, in order. None can be specified for individual columns to retain the default background color. | `None` |
| **RETURNS** | str | The formatted row. | |

### <kbd>class</kbd> `TracebackPrinter`
Expand Down
29 changes: 22 additions & 7 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ jobs:
strategy:
matrix:
Python27Linux:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '2.7'
Python27LinuxASCII:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '2.7'
LANG: 'en_US.ascii'
LC_ALL: 'en_US.ascii'
Python27LinuxASCIIPython:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '2.7'
PYTHONIOENCODING: 'ascii'
Python27Windows:
Expand All @@ -28,7 +28,7 @@ jobs:
imageName: 'macos-10.14'
python.version: '2.7'
Python35Linux:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '3.5'
Python35Windows:
imageName: 'vs2017-win2016'
Expand All @@ -37,7 +37,7 @@ jobs:
imageName: 'macos-10.14'
python.version: '3.5'
Python36Linux:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '3.6'
Python36Windows:
imageName: 'vs2017-win2016'
Expand All @@ -46,7 +46,7 @@ jobs:
imageName: 'macos-10.14'
python.version: '3.6'
Python37Linux:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '3.7'
Python37Windows:
imageName: 'vs2017-win2016'
Expand All @@ -55,14 +55,29 @@ jobs:
imageName: 'macos-10.14'
python.version: '3.7'
Python38Linux:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-20.04'
python.version: '3.8'
Python38Windows:
imageName: 'vs2017-win2016'
python.version: '3.8'
Python38Mac:
imageName: 'macos-10.14'
python.version: '3.8'
Python39Linux:
imageName: 'ubuntu-20.04'
python.version: '3.9'
Python39Windows:
imageName: 'vs2017-win2016'
python.version: '3.9'
Python39Mac:
imageName: 'macos-10.14'
python.version: '3.9'
Python310Linux:
imageName: 'ubuntu-20.04'
python.version: '3.10'
Python310Windows:
imageName: 'vs2017-win2016'
python.version: '3.10'
maxParallel: 4
pool:
vmImage: $(imageName)
Expand Down
2 changes: 1 addition & 1 deletion wasabi/about.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = "wasabi"
__version__ = "0.8.2"
__version__ = "0.9.0"
__summary__ = "A lightweight console printing and formatting toolkit"
__uri__ = "https://ines.io"
__author__ = "Ines Montani"
Expand Down
7 changes: 5 additions & 2 deletions wasabi/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def text(
title="",
text="",
color=None,
bg_color=None,
icon=None,
spaced=False,
show=True,
Expand All @@ -113,6 +114,7 @@ def text(
title (unicode): The main text to print.
text (unicode): Optional additional text to print.
color (unicode / int): Foreground color.
bg_color (unicode / int): Background color.
icon (unicode): Name of icon to add.
spaced (unicode): Whether to add newlines around the output.
show (bool): Whether to print or not. Can be used to only output
Expand All @@ -123,12 +125,13 @@ def text(
if not show:
return
if self.pretty:
color = self.colors.get(color)
color = self.colors.get(color, color)
bg_color = self.colors.get(bg_color, bg_color)
icon = self.icons.get(icon)
if icon:
title = locale_escape("{} {}".format(icon, title)).strip()
if self.show_color:
title = _color(title, fg=color)
title = _color(title, fg=color, bg=bg_color)
title = wrap(title, indent=0)
if text:
title = "{}\n{}".format(title, wrap(text, indent=0))
Expand Down
68 changes: 61 additions & 7 deletions wasabi/tables.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# coding: utf8
from __future__ import unicode_literals, print_function
import os

from .util import to_string, zip_longest, basestring_
from .util import COLORS
from .util import color as _color
from .util import supports_ansi, to_string, zip_longest, basestring_


ALIGN_MAP = {"l": "<", "r": ">", "c": "^"}
Expand All @@ -17,6 +20,10 @@ def table(
spacing=3,
aligns=None,
multiline=False,
env_prefix="WASABI",
color_values=None,
fg_colors=None,
bg_colors=None,
):
"""Format tabular data.
Expand All @@ -34,8 +41,23 @@ def table(
for all columns.
multiline (bool): If a cell value is a list of a tuple, render it on
multiple lines, with one value per line.
env_prefix (unicode): Prefix for environment variables, e.g.
WASABI_LOG_FRIENDLY.
color_values (dict): Add or overwrite color values, name mapped to value.
fg_colors (iterable): Foreground colors, one per column. None can be specified
for individual columns to retain the default foreground color.
bg_colors (iterable): Background colors, one per column. None can be specified
for individual columns to retain the default background color.
RETURNS (unicode): The formatted table.
"""
if fg_colors is not None or bg_colors is not None:
colors = dict(COLORS)
if color_values is not None:
colors.update(color_values)
if fg_colors is not None:
fg_colors = [colors.get(fg_color, fg_color) for fg_color in fg_colors]
if bg_colors is not None:
bg_colors = [colors.get(bg_color, bg_color) for bg_color in bg_colors]
if isinstance(data, dict):
data = list(data.items())
if multiline:
Expand All @@ -48,7 +70,14 @@ def table(
data = zipped_data
if widths == "auto":
widths = _get_max_widths(data, header, footer, max_col)
settings = {"widths": widths, "spacing": spacing, "aligns": aligns}
settings = {
"widths": widths,
"spacing": spacing,
"aligns": aligns,
"env_prefix": env_prefix,
"fg_colors": fg_colors,
"bg_colors": bg_colors,
}
divider_row = row(["-" * width for width in widths], **settings)
rows = []
if header:
Expand All @@ -64,29 +93,54 @@ def table(
return "\n{}\n".format("\n".join(rows))


def row(data, widths="auto", spacing=3, aligns=None):
def row(
data,
widths="auto",
spacing=3,
aligns=None,
env_prefix="WASABI",
fg_colors=None,
bg_colors=None,
):
"""Format data as a table row.
data (iterable): The individual columns to format.
widths (iterable, int or 'auto'): Column widths, either one integer for all
widths (list, int or 'auto'): Column widths, either one integer for all
columns or an iterable of values. If "auto", widths will be calculated
automatically based on the largest value.
spacing (int): Spacing between columns, in spaces.
aligns (iterable / unicode): Column alignments in order. 'l' (left,
aligns (list / unicode): Column alignments in order. 'l' (left,
default), 'r' (right) or 'c' (center). If a string, value is used
for all columns.
env_prefix (unicode): Prefix for environment variables, e.g.
WASABI_LOG_FRIENDLY.
fg_colors (list): Foreground colors for the columns, in order. None can be
specified for individual columns to retain the default foreground color.
bg_colors (list): Background colors for the columns, in order. None can be
specified for individual columns to retain the default background color.
RETURNS (unicode): The formatted row.
"""
env_log_friendly = os.getenv("{}_LOG_FRIENDLY".format(env_prefix), False)
show_colors = (
supports_ansi()
and not env_log_friendly
and (fg_colors is not None or bg_colors is not None)
)
cols = []
if isinstance(aligns, basestring_): # single align value
aligns = [aligns for _ in data]
if not hasattr(widths, "__iter__"): # single number
if not hasattr(widths, "__iter__") and widths != "auto": # single number
widths = [widths for _ in range(len(data))]
for i, col in enumerate(data):
align = ALIGN_MAP.get(aligns[i] if aligns and i < len(aligns) else "l")
col_width = len(col) if widths == "auto" else widths[i]
tpl = "{:%s%d}" % (align, col_width)
cols.append(tpl.format(to_string(col)))
col = tpl.format(to_string(col))
if show_colors:
fg = fg_colors[i] if fg_colors is not None else None
bg = bg_colors[i] if bg_colors is not None else None
col = _color(col, fg=fg, bg=bg)
cols.append(col)
return (" " * spacing).join(cols)


Expand Down
43 changes: 43 additions & 0 deletions wasabi/tests/test_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,49 @@ def test_printer_custom():
assert warning == "?? {}".format(text)


def test_color_as_int():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, color=220)
if SUPPORTS_ANSI:
assert result == "\x1b[38;5;220mThis is a text.\x1b[0m"
else:
assert result == "This is a text."


def test_bg_color():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, bg_color="red")
print(result)
if SUPPORTS_ANSI:
assert result == "\x1b[48;5;1mThis is a text.\x1b[0m"
else:
assert result == "This is a text."


def test_bg_color_as_int():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, bg_color=220)
print(result)
if SUPPORTS_ANSI:
assert result == "\x1b[48;5;220mThis is a text.\x1b[0m"
else:
assert result == "This is a text."


def test_color_and_bc_color():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, color="green", bg_color="yellow")
print(result)
if SUPPORTS_ANSI:
assert result == "\x1b[38;5;2;48;5;3mThis is a text.\x1b[0m"
else:
assert result == "This is a text."


def test_printer_counts():
p = Printer()
text = "This is a test."
Expand Down
Loading

0 comments on commit 4cb261c

Please sign in to comment.