replaced get_safe_box

This commit is contained in:
Will McGugan 2020-10-08 18:18:25 +01:00
parent a2c29d1b0d
commit 2f331818d0
8 changed files with 79 additions and 51 deletions

View File

@ -5,12 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [8.1.0] - unreleased
## [9.0.0] - unreleased
### Fixed
- Progress download column now displays decimal units
### Added
- Added legacy_windows to ConsoleOptions
### Changed
- Dropped box.get_safe_box function in favor of Box.substitute
## [8.0.0] - 2020-10-03
### Added

View File

@ -157,7 +157,7 @@ class Bar(JupyterMixin):
) -> RenderResult:
width = min(self.width or options.max_width, options.max_width)
ascii = console.legacy_windows or options.ascii_only
ascii = options.legacy_windows or options.ascii_only
if self.pulse:
yield from self._render_pulse(console, width, ascii=ascii)
return

View File

@ -1,9 +1,13 @@
from typing import Iterable, List, Optional, overload
from typing import Iterable, List, Optional, overload, TYPE_CHECKING
from typing_extensions import Literal
from ._loop import loop_last
if TYPE_CHECKING:
from rich.console import ConsoleOptions
class Box:
"""Defines characters to render boxes.
@ -59,6 +63,23 @@ class Box:
def __str__(self) -> str:
return self._box
def substitute(self, options: "ConsoleOptions", safe: bool = True) -> "Box":
"""Substitute this box for another if it won't render due to platform issues.
Args:
safe (bool, optional): Substitute this for another Box if there are known problems
in displaying (currently only relevant on Windows).
Returns:
[Box]: A different Box or the same Box.
"""
box = self
if options.legacy_windows and safe:
box = LEGACY_WINDOWS_SUBSTITUTIONS.get(box, box)
if options.ascii_only:
box = ASCII
return box
def get_top(self, widths: Iterable[int]) -> str:
"""Get the top of a simple box.
@ -204,6 +225,18 @@ SQUARE: Box = Box(
"""
)
SQUARE_DOUBLE_HEAD: Box = Box(
"""\
"""
)
MINIMAL: Box = Box(
"""\
@ -389,37 +422,6 @@ LEGACY_WINDOWS_SUBSTITUTIONS = {
}
@overload
def get_safe_box(box: None, legacy_windows: bool, ascii: bool = False) -> None:
...
@overload
def get_safe_box(box: Box, legacy_windows: bool, ascii: bool = False) -> Box:
...
def get_safe_box(
box: Optional[Box], legacy_windows: bool, ascii: bool = False
) -> Optional[Box]:
"""Substitute Box constants that are unlikely to render in the terminal.
Args:
box (Optional[Box]): A Box instance.
legacy_windows (bool): Enable legacy Windows.
ascii (bool, optional): Allow only ascii characters.
Returns:
Optional[Box]: A Box instance (potentially a new instance).
"""
if box is not None:
if ascii and not box.ascii:
box = ASCII
elif legacy_windows:
box = LEGACY_WINDOWS_SUBSTITUTIONS.get(box, box)
return box
if __name__ == "__main__": # pragma: no cover
from rich.columns import Columns
@ -436,6 +438,7 @@ if __name__ == "__main__": # pragma: no cover
"ASCII2",
"ASCII_DOUBLE_HEAD",
"SQUARE",
"SQUARE_DOUBLE_HEAD",
"MINIMAL",
"MINIMAL_HEAVY_HEAD",
"MINIMAL_DOUBLE_HEAD",

View File

@ -83,6 +83,8 @@ _TERM_COLORS = {"256color": ColorSystem.EIGHT_BIT, "16color": ColorSystem.STANDA
class ConsoleOptions:
"""Options for __rich_console__ method."""
legacy_windows: bool
"""legacy_windows: flat for legacy windows."""
min_width: int
"""Minimum width of renderable."""
max_width: int
@ -606,6 +608,7 @@ class Console:
def options(self) -> ConsoleOptions:
"""Get default console options."""
return ConsoleOptions(
legacy_windows=self.legacy_windows,
min_width=1,
max_width=self.width,
encoding=self.encoding,

View File

@ -1,6 +1,6 @@
from typing import Optional, TYPE_CHECKING
from .box import get_safe_box, Box, SQUARE, ROUNDED
from .box import Box, ROUNDED
from .align import AlignValues
from .jupyter import JupyterMixin
@ -113,11 +113,7 @@ class Panel(JupyterMixin):
width = options.max_width if self.width is None else self.width
safe_box: bool = console.safe_box if self.safe_box is None else self.safe_box # type: ignore
box = (
get_safe_box(self.box, console.legacy_windows, ascii=options.ascii_only)
if safe_box
else self.box
)
box = self.box.substitute(options, safe=safe_box)
title_text = self._title
if title_text is not None:

View File

@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Iterable, List, NamedTuple, Optional, Tuple, U
from . import box, errors
from ._loop import loop_first_last, loop_last
from ._pick import pick_bool
from ._ratio import ratio_distribute, ratio_reduce
from .jupyter import JupyterMixin
from .measure import Measurement
@ -494,6 +495,7 @@ class Table(JupyterMixin):
for width, allow_wrap in zip(widths, wrapable)
)
except ValueError:
1 / 0
second_max_column = 0
column_difference = max_column - second_max_column
ratios = [
@ -609,11 +611,12 @@ class Table(JupyterMixin):
)
)
)
safe_box: bool = console.safe_box if self.safe_box is None else self.safe_box # type: ignore
_box = (
box.get_safe_box(self.box, console.legacy_windows, ascii=options.ascii_only)
if safe_box
else self.box
self.box.substitute(
options, safe=pick_bool(self.safe_box, console.safe_box)
)
if self.box
else None
)
# _box = self.box

View File

@ -1,6 +1,7 @@
import pytest
from rich.box import get_safe_box, ASCII, DOUBLE, ROUNDED, HEAVY, SQUARE
from rich.console import ConsoleOptions
from rich.box import ASCII, DOUBLE, ROUNDED, HEAVY, SQUARE
def test_str():
@ -35,8 +36,18 @@ def test_get_bottom():
assert bottom == "┗━┻━━┻━━━┛"
def test_get_safe_box():
assert get_safe_box(HEAVY, True) == SQUARE
assert get_safe_box(HEAVY, False) == HEAVY
assert get_safe_box(None, True) is None
assert get_safe_box(None, False) is None
def test_box_substitute():
options = ConsoleOptions(
legacy_windows=True,
min_width=1,
max_width=100,
is_terminal=True,
encoding="utf-8",
)
assert HEAVY.substitute(options) == SQUARE
options.legacy_windows = False
assert HEAVY.substitute(options) == HEAVY
options.encoding = "ascii"
assert HEAVY.substitute(options) == ASCII

View File

@ -43,7 +43,11 @@ def test_truecolor_terminal():
def test_console_options_update():
options = ConsoleOptions(
min_width=10, max_width=20, is_terminal=False, encoding="utf-8"
legacy_windows=False,
min_width=10,
max_width=20,
is_terminal=False,
encoding="utf-8",
)
options1 = options.update(width=15)
assert options1.min_width == 15 and options1.max_width == 15