Repository: Textualize/rich
Pull request #2246 (2022-05-03 11:28:45)

Render height fix
## Type of changes

- [x] Bug fix
- [ ] New feature
- [ ] Documentation / docstrings
- [ ] Tests
- [ ] Other

## Checklist

- [x] I've run the latest [black](https://github.com/psf/black) with default args on new code.
- [x] I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
- [x] I've added tests for new code.
- [x] I accept that @willmcgugan may be pedantic in the code review.

## Description

Fixes the following example:

```python
    from rich.console import Console
    from rich.padding import Padding

    console = Console()
    options = console.options.update_height(1)

    padding = Padding("hello", pad=(1, 1, 1, 1))
    console.render_lines(padding, options=options)
```

The height is ending up negative when specified as 1, because we subtract the vertical padding from it (1-2 = -1). It gets passed to `itertools.islice` in `render_lines` as the "stop" argument, and that bombs out.

codecov-commenter: # [Codecov](https://codecov.io/gh/Textualize/rich/pull/2246?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#2246](https://codecov.io/gh/Textualize/rich/pull/2246?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (49d4c92) into [master](https://codecov.io/gh/Textualize/rich/commit/14d47c9e8c20f6502be1f601000904b4a4538c1c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (14d47c9) will **decrease** coverage by `3.05%`.
> The diff coverage is `100.00%`.

> :exclamation: Current head 49d4c92 differs from pull request most recent head 8d8532d. Consider uploading reports for the commit 8d8532d to get more accurate results

```diff
@@            Coverage Diff             @@
##           master    #2246      +/-   ##
==========================================
- Coverage   98.88%   95.83%   -3.06%     
==========================================
  Files          73       73              
  Lines        7629     7659      +30     
==========================================
- Hits         7544     7340     -204     
- Misses         85      319     +234     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `95.83% <100.00%> (-3.06%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/Textualize/rich/pull/2246?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [rich/console.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC9jb25zb2xlLnB5) | `96.67% <100.00%> (-2.11%)` | :arrow_down: |
| [rich/\_windows\_renderer.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC9fd2luZG93c19yZW5kZXJlci5weQ==) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [rich/\_win32\_console.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC9fd2luMzJfY29uc29sZS5weQ==) | `3.19% <0.00%> (-88.30%)` | :arrow_down: |
| [rich/\_lru\_cache.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC9fbHJ1X2NhY2hlLnB5) | `95.23% <0.00%> (-4.77%)` | :arrow_down: |
| [rich/traceback.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC90cmFjZWJhY2sucHk=) | `98.68% <0.00%> (-0.88%)` | :arrow_down: |
| [rich/\_export\_format.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC9fZXhwb3J0X2Zvcm1hdC5weQ==) | `100.00% <0.00%> (ø)` | |
| [rich/terminal\_theme.py](https://codecov.io/gh/Textualize/rich/pull/2246/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmljaC90ZXJtaW5hbF90aGVtZS5weQ==) | `100.00% <0.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Textualize/rich/pull/2246?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Textualize/rich/pull/2246?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Last update [da3d59d...8d8532d](https://codecov.io/gh/Textualize/rich/pull/2246?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bb99793..e14a3690 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Changed
 
 - Change SVG export to create a simpler SVG
+- Fix render_lines crash when render height was negative https://github.com/Textualize/rich/pull/2246
 
 ## [12.3.0] - 2022-04-26
 
diff --git a/rich/console.py b/rich/console.py
index 82fc6084..2f685c87 100644
--- a/rich/console.py
+++ b/rich/console.py
@@ -1327,6 +1327,11 @@ class Console:
             _rendered = self.render(renderable, render_options)
             if style:
                 _rendered = Segment.apply_style(_rendered, style)
+
+            render_height = render_options.height
+            if render_height is not None:
+                render_height = max(0, render_height)
+
             lines = list(
                 islice(
                     Segment.split_and_crop_lines(
@@ -1336,7 +1341,7 @@ class Console:
                         pad=pad,
                     ),
                     None,
-                    render_options.height,
+                    render_height,
                 )
             )
             if render_options.height is not None:


Test patch:
diff --git a/tests/test_console.py b/tests/test_console.py
index 42d07d0e..aa92cc42 100644
--- a/tests/test_console.py
+++ b/tests/test_console.py
@@ -20,6 +20,7 @@ from rich.console import (
 )
 from rich.control import Control
 from rich.measure import measure_renderables
+from rich.padding import Padding
 from rich.pager import SystemPager
 from rich.panel import Panel
 from rich.region import Region
@@ -862,3 +863,18 @@ def test_reset_height():
     expected = "╭──────────────────╮\n│ ╭──────────────╮ │\n│ │ foo          │ │\n│ ╰──────────────╯ │\n│ ╭──────────────╮ │\n│ │ bar          │ │\n│ ╰──────────────╯ │\n│                  │\n│                  │\n│                  │\n│                  │\n╰──────────────────╯\n"
 
     assert result == expected
+
+
+def test_render_lines_height_minus_vertical_pad_is_negative():
+    # https://github.com/Textualize/textual/issues/389
+    console = Console(
+        force_terminal=True,
+        color_system="truecolor",
+        width=20,
+        height=40,
+        legacy_windows=False,
+    )
+    options = console.options.update_height(1)
+
+    # Ensuring that no exception is raised...
+    console.render_lines(Padding("hello", pad=(1, 0)), options=options)