diff --git a/CHANGELOG.md b/CHANGELOG.md index e3c093364..70809ac1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,3 @@ - # Changelog All notable changes to this project will be documented in this file. @@ -6,7 +5,7 @@ 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). -## Unreleased +## [12.0.0] - Unreleased ### Added @@ -15,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added ProgressColumn `MofNCompleteColumn` to display raw `completed/total` column (similar to DownloadColumn, but displays values as ints, does not convert to floats or add bit/bytes units). https://github.com/Textualize/rich/pull/1941 -- Remove Colorama dependency, call Windows Console API from Rich https://github.com/Textualize/rich/pull/1993 +- Replace Colorama with win32 renderer https://github.com/Textualize/rich/pull/1993 - Add support for namedtuples to `Pretty` https://github.com/Textualize/rich/pull/2031 ### Fixed @@ -25,14 +24,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix syntax lexer guessing. - Fixed Pretty measure not respecting expand_all https://github.com/Textualize/rich/issues/1998 - Collapsed definitions for single-character spinners, to save memory and reduce import time. -- Fix print_json indent type in __init__.py +- Fix print_json indent type in **init**.py - Fix error when inspecting object defined in REPL https://github.com/Textualize/rich/pull/2037 - Fix incorrect highlighting of non-indented JSON https://github.com/Textualize/rich/pull/2038 +- Fixed height reset in complex renderables https://github.com/Textualize/rich/issues/2042 ### Changed - Improved support for enum.Flag in ReprHighlighter https://github.com/Textualize/rich/pull/1920 - Tree now respects justify=None, i.e. won't pad to right https://github.com/Textualize/rich/issues/1690 +- Removed rich.tabulate which was marked for deprecation +- Deprecated rich.align.AlignValues in favor of AlignMethod ## [11.2.0] - 2022-02-08 @@ -1661,7 +1663,7 @@ Major version bump for a breaking change to `Text.stylize signature`, which corr - First official release, API still to be stabilized -[Unreleased]: https://github.com/willmcgugan/rich/compare/v11.0.0...HEAD +[unreleased]: https://github.com/willmcgugan/rich/compare/v11.0.0...HEAD [11.2.0]: https://github.com/willmcgugan/rich/compare/v11.1.0...v11.2.0 [11.1.0]: https://github.com/willmcgugan/rich/compare/v11.0.0...v11.1.0 [11.0.0]: https://github.com/willmcgugan/rich/compare/v10.16.1...v11.0.0 diff --git a/rich/align.py b/rich/align.py index 3f605a7b9..c9b7cfa01 100644 --- a/rich/align.py +++ b/rich/align.py @@ -18,7 +18,6 @@ AlignMethod = Literal["left", "center", "right"] VerticalAlignMethod = Literal["top", "middle", "bottom"] -AlignValues = AlignMethod # TODO: deprecate AlignValues class Align(JupyterMixin): diff --git a/rich/console.py b/rich/console.py index 1fa66e4ee..f81896a82 100644 --- a/rich/console.py +++ b/rich/console.py @@ -224,6 +224,16 @@ def update_height(self, height: int) -> "ConsoleOptions": options.max_height = options.height = height return options + def reset_height(self) -> "ConsoleOptions": + """Resets the height to None. + + Returns: + ~ConsoleOptions: New console options instance. + """ + options = self.copy() + options.height = None + return options + def update_dimensions(self, width: int, height: int) -> "ConsoleOptions": """Update the width and height, and return a copy. @@ -1245,6 +1255,7 @@ def render( f"object {render_iterable!r} is not renderable" ) _Segment = Segment + _options = _options.reset_height() for render_output in iter_render: if isinstance(render_output, _Segment): yield render_output diff --git a/rich/layout.py b/rich/layout.py index e25ced675..918e631c2 100644 --- a/rich/layout.py +++ b/rich/layout.py @@ -73,6 +73,7 @@ def __rich_console__( style=self.style, title=self.highlighter(title), border_style="blue", + height=height, ) diff --git a/rich/tabulate.py b/rich/tabulate.py deleted file mode 100644 index ca4fe293a..000000000 --- a/rich/tabulate.py +++ /dev/null @@ -1,51 +0,0 @@ -from collections.abc import Mapping -from typing import Any, Optional -import warnings - -from rich.console import JustifyMethod - -from . import box -from .highlighter import ReprHighlighter -from .pretty import Pretty -from .table import Table - - -def tabulate_mapping( - mapping: "Mapping[Any, Any]", - title: Optional[str] = None, - caption: Optional[str] = None, - title_justify: Optional[JustifyMethod] = None, - caption_justify: Optional[JustifyMethod] = None, -) -> Table: - """Generate a simple table from a mapping. - - Args: - mapping (Mapping): A mapping object (e.g. a dict); - title (str, optional): Optional title to be displayed over the table. - caption (str, optional): Optional caption to be displayed below the table. - title_justify (str, optional): Justify method for title. Defaults to None. - caption_justify (str, optional): Justify method for caption. Defaults to None. - - Returns: - Table: A table instance which may be rendered by the Console. - """ - warnings.warn("tabulate_mapping will be deprecated in Rich v11", DeprecationWarning) - table = Table( - show_header=False, - title=title, - caption=caption, - box=box.ROUNDED, - border_style="blue", - ) - table.title = title - table.caption = caption - if title_justify is not None: - table.title_justify = title_justify - if caption_justify is not None: - table.caption_justify = caption_justify - highlighter = ReprHighlighter() - for key, value in mapping.items(): - table.add_row( - Pretty(key, highlighter=highlighter), Pretty(value, highlighter=highlighter) - ) - return table diff --git a/tests/test_console.py b/tests/test_console.py index 06fb4a835..701ccf740 100644 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -308,7 +308,7 @@ def test_capture(): def test_input(monkeypatch, capsys): - def fake_input(prompt): + def fake_input(prompt=""): console.file.write(prompt) return "bar" @@ -319,18 +319,6 @@ def fake_input(prompt): assert user_input == "bar" -def test_input_legacy_windows(monkeypatch, capsys): - def fake_input(prompt): - console.file.write(prompt) - return "bar" - - monkeypatch.setattr("builtins.input", fake_input) - console = Console(legacy_windows=True) - user_input = console.input(prompt="foo:") - assert capsys.readouterr().out == "foo:" - assert user_input == "bar" - - def test_input_password(monkeypatch, capsys): def fake_input(prompt, stream=None): console.file.write(prompt) @@ -768,3 +756,28 @@ def _mock_isatty(): def test_detect_color_system(): console = Console(_environ={"TERM": "rxvt-unicode-256color"}, force_terminal=True) assert console._detect_color_system() == ColorSystem.EIGHT_BIT + + +def test_reset_height(): + """Test height is reset when rendering complex renderables.""" + # https://github.com/Textualize/rich/issues/2042 + class Panels: + def __rich_console__(self, console, options): + yield Panel("foo") + yield Panel("bar") + + console = Console( + force_terminal=True, + color_system="truecolor", + width=20, + height=40, + legacy_windows=False, + ) + + with console.capture() as capture: + console.print(Panel(Panels()), height=12) + result = capture.get() + print(repr(result)) + expected = "╭──────────────────╮\n│ ╭──────────────╮ │\n│ │ foo │ │\n│ ╰──────────────╯ │\n│ ╭──────────────╮ │\n│ │ bar │ │\n│ ╰──────────────╯ │\n│ │\n│ │\n│ │\n│ │\n╰──────────────────╯\n" + + assert result == expected diff --git a/tests/test_tabulate.py b/tests/test_tabulate.py deleted file mode 100644 index 37e86bfe2..000000000 --- a/tests/test_tabulate.py +++ /dev/null @@ -1,34 +0,0 @@ -import itertools -from rich.style import Style -from rich.table import _Cell -from rich.tabulate import tabulate_mapping - - -def test_tabulate_mapping(): - # TODO: tabulate_mapping may not be needed shortly - table = tabulate_mapping({"foo": "1", "bar": "2"}) - assert len(table.columns) == 2 - assert len(table.columns[0]._cells) == 2 - assert len(table.columns[1]._cells) == 2 - - # add tests for title and caption justification - test_title = "Foo v. Bar" - test_caption = "approximate results" - for title_justify, caption_justify in itertools.product( - [None, "left", "center", "right"], repeat=2 - ): - table = tabulate_mapping( - {"foo": "1", "bar": "2"}, - title=test_title, - caption=test_caption, - title_justify=title_justify, - caption_justify=caption_justify, - ) - expected_title_justify = ( - title_justify if title_justify is not None else "center" - ) - expected_caption_justify = ( - caption_justify if caption_justify is not None else "center" - ) - assert expected_title_justify == table.title_justify - assert expected_caption_justify == table.caption_justify