diff --git a/dvc/commands/ls/__init__.py b/dvc/commands/ls/__init__.py index d409d7ec22..190a5918d3 100644 --- a/dvc/commands/ls/__init__.py +++ b/dvc/commands/ls/__init__.py @@ -109,8 +109,6 @@ def _build_tree_structure( def show_tree(entries, with_color=False, with_size=False, with_hash=False): - import tabulate - rows = _build_tree_structure( entries, with_color=with_color, @@ -119,13 +117,7 @@ def show_tree(entries, with_color=False, with_size=False, with_hash=False): ) colalign = ("right",) if with_size else None - - _orig = tabulate.PRESERVE_WHITESPACE - tabulate.PRESERVE_WHITESPACE = True - try: - ui.table(rows, colalign=colalign) - finally: - tabulate.PRESERVE_WHITESPACE = _orig + ui.table(rows, colalign=colalign, preserve_whitespace=True) class CmdList(CmdBaseNoRepo): diff --git a/dvc/ui/__init__.py b/dvc/ui/__init__.py index 260e945fc3..2df6ab45cc 100644 --- a/dvc/ui/__init__.py +++ b/dvc/ui/__init__.py @@ -289,7 +289,7 @@ def error_console(self) -> "RichConsole": return console.Console(stderr=True) - def table( + def table( # noqa: PLR0913 self, data: "TableData", headers: Optional["Headers"] = None, @@ -301,6 +301,7 @@ def table( row_styles: Optional[Sequence["Styles"]] = None, borders: Union[bool, str] = False, colalign: Optional[tuple[str, ...]] = None, + preserve_whitespace: bool = False, ) -> None: from dvc.ui import table as t @@ -329,6 +330,7 @@ def table( pager=pager, force=force, colalign=colalign, + preserve_whitespace=preserve_whitespace, ) def status(self, status: str, **kwargs: Any) -> "Status": diff --git a/dvc/ui/table.py b/dvc/ui/table.py index f0156d266b..156b7fdfae 100644 --- a/dvc/ui/table.py +++ b/dvc/ui/table.py @@ -30,19 +30,37 @@ def plain_table( pager: bool = False, force: bool = True, colalign: Optional[tuple[str, ...]] = None, + preserve_whitespace: bool = False, ) -> None: + import tabulate as tabulate_mod from funcy import nullcontext + from packaging.version import Version from tabulate import tabulate - text: str = tabulate( - data, - headers if headers is not None else (), - tablefmt="github" if markdown else "plain", - disable_numparse=True, - # None will be shown as "" by default, overriding - missingval="-", - colalign=colalign, - ) + # NOTE: tabulate 0.10.0+ supports preserve_whitespace as a kwarg, + # while 0.9.0 only respects the global PRESERVE_WHITESPACE. + kwargs: dict = {} + _orig = tabulate_mod.PRESERVE_WHITESPACE + if preserve_whitespace: + if Version(tabulate_mod.__version__) >= Version("0.10"): + kwargs["preserve_whitespace"] = True + else: + tabulate_mod.PRESERVE_WHITESPACE = True + + try: + text: str = tabulate( + data, + headers if headers is not None else (), + tablefmt="github" if markdown else "plain", + disable_numparse=True, + # None will be shown as "" by default, overriding + missingval="-", + colalign=colalign, + **kwargs, + ) + finally: + tabulate_mod.PRESERVE_WHITESPACE = _orig + if markdown: # NOTE: md table is incomplete without the trailing newline text += "\n"