Skip to content

Commit 11c0022

Browse files
committed
table improvements
1 parent a7396aa commit 11c0022

12 files changed

+76
-21
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.0.1] - 2020-06-30
9+
10+
### Added
11+
12+
- Added box.ASCII2
13+
- Added markup argument to logging extra
14+
15+
### Changed
16+
17+
- Setting a non-None width now implies expand=True
18+
819
## [3.0.0] - 2020-06-28
920

1021
### Changed

docs/source/logging.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@ Here's an example of how to set up a rich logger::
1414
)
1515

1616
log = logging.getLogger("rich")
17-
log.info("Hello, World!")
17+
log.info("Hello, World!")
18+
19+
Rich logs won't process console markup by default, but you can enable markup per log statement with the ``extras`` argument as follows::
20+
21+
log.error("[bold red blink]Server is shutting down![/]", extras={"markup": True})
22+
23+
There are a number of options you can use to configure logging output, see the :class:`~rich.logging.RichHandler` reference for details.

docs/source/progress.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,9 @@ When you add a task it is automatically *started*, which means it will show a pr
8080
Auto refresh
8181
~~~~~~~~~~~~
8282

83-
By default, the progress information will refresh 10 times a second. Refreshing at a predictable rate can make numbers more readable if they are updating quickly. Auto refresh can also prevent excessive rendering to the terminal.
83+
By default, the progress information will refresh 10 times a second. You can set the refresh rate with the ``refresh_per_second`` argument on the :class:`~rich.progress.Progress` constructor. You should set this to something lower than 10 if you know your updates will not be that frequent.
8484

85-
You can set the refresh rate with the ``refresh_per_second`` argument on the :class:`~rich.progress.Progress` constructor. You could set this to something lower than 10 if you know your updates will not be that frequent.
86-
87-
You can disable auto-refresh by setting ``auto_refresh=False`` on the constructor and call :meth:`~rich.progress.Progress.refresh` manually when there are updates to display.
85+
You might want to disable auto-refresh entirely if your updates are not very frequent, which you can do by setting ``auto_refresh=False`` on the constructor. If you disable auto-refresh you will need to call :meth:`~rich.progress.Progress.refresh` manually after updating your task(s).
8886

8987
Columns
9088
~~~~~~~

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "rich"
33
homepage = "https://github.com/willmcgugan/rich"
44
documentation = "https://rich.readthedocs.io/en/latest/"
5-
version = "3.0.0"
5+
version = "3.0.1"
66
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
77
authors = ["Will McGugan <willmcgugan@gmail.com>"]
88
license = "MIT"

rich/bar.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,19 @@ def __rich_console__(
170170
complete_style = console.get_style(
171171
self.complete_style if self.completed < self.total else self.finished_style
172172
)
173+
_Segment = Segment
173174
if bar_count:
174-
yield Segment(bar * bar_count, complete_style)
175+
yield _Segment(bar * bar_count, complete_style)
175176
if half_bar_count:
176-
yield Segment(half_bar_right * half_bar_count, complete_style)
177+
yield _Segment(half_bar_right * half_bar_count, complete_style)
177178

178179
remaining_bars = width - bar_count - half_bar_count
179180
if remaining_bars:
180181
if not half_bar_count and bar_count:
181-
yield Segment(half_bar_left, style)
182+
yield _Segment(half_bar_left, style)
182183
remaining_bars -= 1
183184
if remaining_bars:
184-
yield Segment(bar * remaining_bars, style)
185+
yield _Segment(bar * remaining_bars, style)
185186

186187
def __rich_measure__(self, console: Console, max_width: int) -> Measurement:
187188
return (

rich/box.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,19 @@ def get_bottom(self, widths: Iterable[int]) -> str:
156156
"""
157157
)
158158

159+
ASCII2: Box = Box(
160+
"""\
161+
+-++
162+
| ||
163+
+-++
164+
| ||
165+
+-++
166+
+-++
167+
| ||
168+
+-++
169+
"""
170+
)
171+
159172
SQUARE: Box = Box(
160173
"""\
161174
┌─┬┐
@@ -330,6 +343,7 @@ def get_bottom(self, widths: Iterable[int]) -> str:
330343
"""
331344
)
332345

346+
# Map Boxes that don't render with raster fonts on to equivalent that do
333347
LEGACY_WINDOWS_SUBSTITUTIONS = {
334348
ROUNDED: SQUARE,
335349
MINIMAL_HEAVY_HEAD: MINIMAL,
@@ -379,6 +393,7 @@ def get_safe_box(box: Optional[Box], legacy_windows: bool) -> Optional[Box]:
379393

380394
BOXES = [
381395
"ASCII",
396+
"ASCII2",
382397
"SQUARE",
383398
"MINIMAL",
384399
"MINIMAL_HEAVY_HEAD",
@@ -400,9 +415,8 @@ def get_safe_box(box: Optional[Box], legacy_windows: bool) -> Optional[Box]:
400415
columns = Columns(expand=True, padding=2)
401416
for box_name in BOXES:
402417
table = Table(
403-
width=80, show_footer=True, style="dim", border_style="not dim", expand=True
418+
show_footer=True, style="dim", border_style="not dim", expand=True
404419
)
405-
spaces = " " * 10
406420
table.add_column("Header 1", "Footer 1")
407421
table.add_column("Header 2", "Footer 2")
408422
table.add_row("Cell", "Cell")

rich/console.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ def _check_buffer(self) -> None:
927927
text = self._render_buffer()
928928
if text:
929929
self.file.write(text)
930-
self.file.flush()
930+
self.file.flush()
931931

932932
def _render_buffer(self) -> str:
933933
"""Render buffered output, and clear buffer."""

rich/measure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def span(self) -> int:
2121

2222
def normalize(self) -> "Measurement":
2323
minimum, maximum = self
24-
minimum = max(0, minimum)
24+
minimum = min(max(0, minimum), maximum)
2525
return Measurement(minimum, max(minimum, maximum))
2626

2727
def with_maximum(self, width: int) -> "Measurement":

rich/progress.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ def process_renderables(
832832

833833
task1 = progress.add_task(" [red]Downloading", total=1000)
834834
task2 = progress.add_task(" [green]Processing", total=1000)
835-
task3 = progress.add_task(" [yellow]Thinking", total=1000, start=False)
835+
# task3 = progress.add_task(" [yellow]Thinking", total=1000, start=False)
836836

837837
while not progress.finished:
838838
progress.update(task1, advance=0.5)

rich/table.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class Table(JupyterMixin):
101101
padding (PaddingDimensions, optional): Padding for cells (top, right, bottom, left). Defaults to (0, 1).
102102
collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to False.
103103
pad_edge (bool, optional): Enable padding of edge cells. Defaults to True.
104-
expand (bool, optional): Expand the table to fit the available space if ``True`` otherwise the table width will be auto-calculated. Defaults to False.
104+
expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False.
105105
show_header (bool, optional): Show a header row. Defaults to True.
106106
show_footer (bool, optional): Show a footer row. Defaults to False.
107107
show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.
@@ -153,7 +153,7 @@ def __init__(
153153
self.safe_box = safe_box
154154
self._padding = Padding.unpack(padding)
155155
self.pad_edge = pad_edge
156-
self.expand = expand
156+
self._expand = expand
157157
self.show_header = show_header
158158
self.show_footer = show_footer
159159
self.show_edge = show_edge
@@ -195,6 +195,16 @@ def grid(
195195
pad_edge=pad_edge,
196196
)
197197

198+
@property
199+
def expand(self) -> int:
200+
"""Setting a non-None self.width implies expand."""
201+
return self._expand or self.width is not None
202+
203+
@expand.setter
204+
def expand(self, expand: bool) -> None:
205+
"""Set expand."""
206+
self._expand = expand
207+
198208
@property
199209
def _extra_width(self) -> int:
200210
"""Get extra width to add to cell content."""
@@ -231,9 +241,15 @@ def __rich_measure__(self, console: "Console", max_width: int) -> Measurement:
231241
measurements = [
232242
_measure_column(console, column, max_width) for column in self.columns
233243
]
234-
minimum_width = sum(measurement.minimum for measurement in measurements)
235-
maximum_width = sum(measurement.maximum for measurement in measurements)
236-
return Measurement(minimum_width + extra_width, maximum_width + extra_width)
244+
minimum_width = (
245+
sum(measurement.minimum for measurement in measurements) + extra_width
246+
)
247+
maximum_width = (
248+
sum(measurement.maximum for measurement in measurements) + extra_width
249+
if (self.width is None)
250+
else self.width
251+
)
252+
return Measurement(minimum_width, maximum_width)
237253

238254
@property
239255
def padding(self) -> Tuple[int, int, int, int]:

tests/test_style.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ def test_parse():
101101
Style.parse("link")
102102

103103

104+
def test_link_id():
105+
assert Style().link_id == ""
106+
assert Style.parse("").link_id == ""
107+
assert Style.parse("red").link_id == ""
108+
style = Style.parse("red link https://example.org")
109+
assert isinstance(style.link_id, str)
110+
assert len(style.link_id) > 1
111+
112+
104113
def test_get_html_style():
105114
expected = "color: #7f7fbf; background-color: #800000; font-weight: bold; font-style: italic; text-decoration: underline; text-decoration: line-through; text-decoration: overline"
106115
assert (

tests/test_table.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def render_tables():
6161
console.print(table)
6262

6363
table.width = 20
64-
assert Measurement.get(console, table, 80) == Measurement(46, 52)
64+
assert Measurement.get(console, table, 80) == Measurement(20, 20)
6565
console.print(table)
6666

6767
return console.file.getvalue()

0 commit comments

Comments
 (0)