mirror of
https://github.com/Textualize/rich.git
synced 2026-02-06 10:58:48 +00:00
repl
This commit is contained in:
parent
6dfdf1a40c
commit
0d1a172b7c
11
README.md
11
README.md
@ -41,6 +41,17 @@ print("Hello, [bold magenta]World[/bold magenta]!", ":vampire:", locals())
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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
BIN
imgs/repl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 422 KiB |
@ -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
35
tests/test_containers.py
Normal 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
19
tests/test_measure.py
Normal 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
45
tests/test_pretty.py
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user