This commit is contained in:
Will McGugan 2020-08-08 11:47:10 +01:00
parent 6dfdf1a40c
commit 0d1a172b7c
6 changed files with 137 additions and 24 deletions

View File

@ -41,6 +41,17 @@ print("Hello, [bold magenta]World[/bold magenta]!", ":vampire:", locals())
![Hello World](https://github.com/willmcgugan/rich/raw/master/imgs/print.png)
## Rich REPL
Rich can be installed in the Python REPL, so that any data structures will be pretty printed and highlighted.
```python
>>> from rich import pretty
>>> pretty.install()
```
![REPL](https://github.com/willmcgugan/rich/raw/master/imgs/repl.png)
## Using the Console
For more control over rich terminal content, import and construct a [Console](https://rich.readthedocs.io/en/latest/reference/console.html#rich.console.Console) object.

BIN
imgs/repl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

View File

@ -158,7 +158,6 @@ def pretty_repr(
else:
text = Text(repr_text, style)
repr_cache[node_id] = text
visited_set.add(node_id)
return text
comma = Text(", ")
@ -191,30 +190,34 @@ def pretty_repr(
brace_open, brace_close = _BRACES[type(node)]
expanded = level < expand_level
append_text(brace_open)
if isinstance(node, dict):
for last, (key, value) in loop_last(node.items()):
if expanded:
append_line(_Line())
append_text(Text(indent * (level + 1)))
append_text(to_repr_text(key))
append_text(colon)
traverse(value, level + 1)
if not last:
append_text(comma)
else:
for last, value in loop_last(node):
if expanded:
append_line(_Line())
append_text(Text(indent * (level + 1)))
traverse(value, level + 1)
if not last:
append_text(comma)
if expanded:
lines.append(_Line())
append_text(Text.assemble(f"{indent * level}", brace_close))
else:
if not node:
append_text(brace_open)
append_text(brace_close)
else:
append_text(brace_open)
if isinstance(node, dict):
for last, (key, value) in loop_last(node.items()):
if expanded:
append_line(_Line())
append_text(Text(indent * (level + 1)))
append_text(to_repr_text(key))
append_text(colon)
traverse(value, level + 1)
if not last:
append_text(comma)
else:
for last, value in loop_last(node):
if expanded:
append_line(_Line())
append_text(Text(indent * (level + 1)))
traverse(value, level + 1)
if not last:
append_text(comma)
if expanded:
lines.append(_Line())
append_text(Text.assemble(f"{indent * level}", brace_close))
else:
append_text(brace_close)
else:
append_text(to_repr_text(node))

35
tests/test_containers.py Normal file
View File

@ -0,0 +1,35 @@
from rich.console import Console
from rich.containers import Lines, Renderables
from rich.text import Text
def test_renderables_measure():
console = Console()
text = Text("foo")
renderables = Renderables([text])
result = renderables.__rich_measure__(console, console.width)
_min, _max = result
assert _min == 3
assert _max == 3
assert list(renderables) == [text]
def test_renderables_empty():
console = Console()
renderables = Renderables()
result = renderables.__rich_measure__(console, console.width)
_min, _max = result
assert _min == 1
assert _max == 1
def test_lines_rich_console():
console = Console()
lines = Lines([Text("foo")])
result = list(lines.__rich_console__(console, console.options))
assert result == [Text("foo")]

19
tests/test_measure.py Normal file
View File

@ -0,0 +1,19 @@
from rich.text import Text
import pytest
from rich.errors import NotRenderableError
from rich.console import Console
from rich.measure import Measurement
def test_span():
measurement = Measurement(10, 100)
assert measurement.span == 90
def test_no_renderable():
console = Console()
text = Text()
with pytest.raises(NotRenderableError):
Measurement.get(console, None, console.width)

45
tests/test_pretty.py Normal file
View File

@ -0,0 +1,45 @@
import io
import sys
from rich.console import Console
from rich.pretty import install, pretty_repr
def test_install():
console = Console(file=io.StringIO())
dh = sys.displayhook
install(console)
sys.displayhook("foo")
assert console.file.getvalue() == "'foo'\n"
assert sys.displayhook is not dh
def test_pretty():
test = {
"foo": [1, 2, 3, {4, 5, 6, (7, 8, 9)}, {}],
False: "foo",
True: "",
"text": ("Hello World", "foo bar baz egg"),
}
result = pretty_repr(test)
expected = "{\n 'foo': [1, 2, 3, {(7, 8, 9), 4, 5, 6}, {}], \n False: 'foo', \n True: '', \n 'text': ('Hello World', 'foo bar baz egg')\n}"
assert result.plain == expected
def test_small_width():
test = ["Hello world! 12345"]
result = pretty_repr(test, max_width=10)
expected = "[\n 'Hello world! 12345'\n]"
assert result.plain == expected
def test_broken_repr():
class BrokenRepr:
def __repr__(self):
1 / 0
test = [BrokenRepr()]
result = pretty_repr(test)
expected = "[<error in repr: division by zero>]"
assert result.plain == expected