From 26509386bc8382e2283d3777e38a00e92b12f690 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 27 Nov 2021 19:52:39 +0000 Subject: [PATCH 1/6] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 775a978a..249e4f51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added dynamic_progress.py to examples - Added ConsoleOptions.update_height +- Fixed Padding not respecting height ### Changed From 5eafdbcee2b5429dfaafba9a0ce762c3d2baa0e6 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 28 Nov 2021 12:44:58 +0000 Subject: [PATCH 2/6] version bump --- CHANGELOG.md | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 249e4f51..2835c321 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,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). -## [10.15.0] - Unreleased +## [10.15.0] - 2021-11-28 ### Added diff --git a/pyproject.toml b/pyproject.toml index 5d65e77d..fa524360 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "rich" homepage = "https://github.com/willmcgugan/rich" documentation = "https://rich.readthedocs.io/en/latest/" -version = "10.15.0-alpha3" +version = "10.15.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" authors = ["Will McGugan "] license = "MIT" From 1799d3ba0d29593235b32f21d259ddbb3b7d31c4 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 28 Nov 2021 13:05:03 +0000 Subject: [PATCH 3/6] conditional test --- tests/test_repr.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/test_repr.py b/tests/test_repr.py index c47b76b1..3c2f48a4 100644 --- a/tests/test_repr.py +++ b/tests/test_repr.py @@ -1,10 +1,22 @@ import pytest +import sys from typing import Optional from rich.console import Console import rich.repr +skip_py36 = pytest.mark.skipif( + sys.version_info.minor == 6 and sys.version_info.major == 3, + reason="rendered differently on py3.6", +) + +skip_py37 = pytest.mark.skipif( + sys.version_info.minor == 7 and sys.version_info.major == 3, + reason="rendered differently on py3.7", +) + + @rich.repr.auto class Foo: def __init__(self, foo: str, bar: Optional[int] = None, egg: int = 1): @@ -59,13 +71,21 @@ def test_rich_repr() -> None: assert (repr(Foo("hello", bar=3))) == "Foo('hello', 'hello', bar=3, egg=1)" +@skip_py36 +@skip_py37 def test_rich_repr_positional_only() -> None: - @rich.repr.auto - class PosOnly: - def __init__(self, foo, /): - self.foo = 1 - - p = PosOnly(1) + _locals = locals().copy() + exec( + """\ +@rich.repr.auto +class PosOnly: + def __init__(self, foo, /): + self.foo = 1 + """, + globals(), + _locals, + ) + p = _locals["PosOnly"](1) assert repr(p) == "PosOnly(1)" From aeac63da7a240400c9fc3c334a545f68f4cc9720 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 28 Nov 2021 13:09:08 +0000 Subject: [PATCH 4/6] conditional test --- tests/test_pretty.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_pretty.py b/tests/test_pretty.py index d2e82996..3a4ea6c0 100644 --- a/tests/test_pretty.py +++ b/tests/test_pretty.py @@ -97,6 +97,7 @@ def test_small_width(): assert result == expected +@skip_py36 def test_broken_repr(): class BrokenRepr: def __repr__(self): From 86032f6354411f0088f8e691edd96bfbe4a101aa Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 28 Nov 2021 16:00:04 +0000 Subject: [PATCH 5/6] exclude 36 --- tests/test_pretty.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_pretty.py b/tests/test_pretty.py index 3a4ea6c0..ab83d930 100644 --- a/tests/test_pretty.py +++ b/tests/test_pretty.py @@ -109,6 +109,7 @@ def test_broken_repr(): assert result == expected +@skip_py36 def test_broken_getattr(): class BrokenAttr: def __getattr__(self, name): From 32eb5465ea4e2a5882308b2efe763c61705e1374 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 28 Nov 2021 16:22:51 +0000 Subject: [PATCH 6/6] from_ansi method --- rich/text.py | 24 ++++++++++++++---------- tests/test_text.py | 7 ++++--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/rich/text.py b/rich/text.py index c49e152b..288cb6d1 100644 --- a/rich/text.py +++ b/rich/text.py @@ -254,10 +254,10 @@ class Text(JupyterMixin): end: str = "\n", tab_size: Optional[int] = 8, ) -> "Text": - """Create a Text object from pre-formatted ANSI. + """Create a Text object from a string containing ANSI escape codes. Args: - text (str): A string containing ANSI color codes. + text (str): A string containing escape codes. style (Union[str, Style], optional): Base style for text. Defaults to "". justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None. overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None. @@ -267,14 +267,18 @@ class Text(JupyterMixin): """ from .ansi import AnsiDecoder - decoded_text = AnsiDecoder().decode_line(text) - decoded_text.justify = justify - decoded_text.overflow = overflow - decoded_text.no_wrap = no_wrap - decoded_text.end = end - decoded_text.tab_size = tab_size - decoded_text.stylize(style) - return decoded_text + joiner = Text( + "\n", + justify=justify, + overflow=overflow, + no_wrap=no_wrap, + end=end, + tab_size=tab_size, + style=style, + ) + decoder = AnsiDecoder() + result = joiner.join(line for line in decoder.decode(text)) + return result @classmethod def styled( diff --git a/tests/test_text.py b/tests/test_text.py index 6eecb9ee..63f128e5 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -97,11 +97,12 @@ def test_from_markup(): def test_from_ansi(): text = Text.from_ansi("Hello, \033[1mWorld!\033[0m") - text2 = Text.from_ansi("Hello, \033[1mWorld!\033[0m", style="red") assert str(text) == "Hello, World!" assert text._spans == [Span(7, 13, Style(bold=True))] - assert str(text2) == "Hello, World!" - assert text2._spans == [Span(7, 13, Style(bold=True)), Span(0, 13, "red")] + + text = Text.from_ansi("Hello, \033[1m\nWorld!\033[0m") + assert str(text) == "Hello, \nWorld!" + assert text._spans == [Span(8, 14, Style(bold=True))] def test_copy():