From 49d0e0e7e1c2a15b09a40fbe94471e2745b3a882 Mon Sep 17 00:00:00 2001 From: David Brochart Date: Tue, 30 Mar 2021 21:17:15 +0200 Subject: [PATCH 1/3] Fix typo --- rich/live.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rich/live.py b/rich/live.py index 0746d7a5b4..f00b55245c 100644 --- a/rich/live.py +++ b/rich/live.py @@ -39,7 +39,7 @@ class Live(JupyterMixin, RenderHook): console (Console, optional): Optional Console instance. Default will an internal Console instance writing to stdout. screen (bool, optional): Enable alternate screen mode. Defaults to False. auto_refresh (bool, optional): Enable auto refresh. If disabled, you will need to call `refresh()` or `update()` with refresh flag. Defaults to True - refresh_per_second (float, optional): Number of times per second to refresh the live display. Defaults to 1. + refresh_per_second (float, optional): Number of times per second to refresh the live display. Defaults to 4. transient (bool, optional): Clear the renderable on exit (has no effect when screen=True). Defaults to False. redirect_stdout (bool, optional): Enable redirection of stdout, so ``print`` may be used. Defaults to True. redirect_stderr (bool, optional): Enable redirection of stderr. Defaults to True. From ebfab2ddcb45a16b3a6f0cbfabb66cd5a6b576be Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 2 Apr 2021 11:29:48 +0100 Subject: [PATCH 2/3] better Jupyter support --- rich/console.py | 2 +- rich/jupyter.py | 37 ++++++++++++++++++++----------------- rich/layout.py | 2 -- rich/pretty.py | 8 +++++--- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/rich/console.py b/rich/console.py index c01aee3d6e..71fa0809ef 100644 --- a/rich/console.py +++ b/rich/console.py @@ -1681,7 +1681,7 @@ def _check_buffer(self) -> None: if self.is_jupyter: # pragma: no cover from .jupyter import display - display(self._buffer) + display(self._buffer, self._render_buffer(self._buffer[:])) del self._buffer[:] else: text = self._render_buffer(self._buffer[:]) diff --git a/rich/jupyter.py b/rich/jupyter.py index 9101ce143a..c4d665690c 100644 --- a/rich/jupyter.py +++ b/rich/jupyter.py @@ -1,11 +1,9 @@ -from typing import Iterable, List, TYPE_CHECKING +from typing import Iterable, List from . import get_console from .segment import Segment from .terminal_theme import DEFAULT_TERMINAL_THEME -if TYPE_CHECKING: - from .console import RenderableType JUPYTER_HTML_FORMAT = """\
{code}
@@ -15,28 +13,33 @@ class JupyterRenderable: """A shim to write html to Jupyter notebook.""" - def __init__(self, html: str) -> None: + def __init__(self, html: str, text: str) -> None: self.html = html + self.text = text - @classmethod - def render(cls, rich_renderable: "RenderableType") -> str: - console = get_console() - segments = console.render(rich_renderable, console.options) - html = _render_segments(segments) - return html - - def _repr_html_(self) -> str: - return self.html + def _repr_mimebundle_(self, include, exclude, **kwargs): + data = {"text/plain": self.text, "text/html": self.html} + if include: + data = {k: v for (k, v) in data.items() if k in include} + if exclude: + data = {k: v for (k, v) in data.items() if k not in exclude} + return data class JupyterMixin: """Add to an Rich renderable to make it render in Jupyter notebook.""" - def _repr_html_(self) -> str: + def _repr_mimebundle_(self, include, exclude, **kwargs): console = get_console() segments = list(console.render(self, console.options)) # type: ignore html = _render_segments(segments) - return html + text = console._render_buffer(segments) + data = {"text/plain": text, "text/html": html} + if include: + data = {k: v for (k, v) in data.items() if k in include} + if exclude: + data = {k: v for (k, v) in data.items() if k not in exclude} + return data def _render_segments(segments: Iterable[Segment]) -> str: @@ -64,12 +67,12 @@ def escape(text: str) -> str: return html -def display(segments: Iterable[Segment]) -> None: +def display(segments: Iterable[Segment], text: str) -> None: """Render segments to Jupyter.""" from IPython.display import display as ipython_display html = _render_segments(segments) - jupyter_renderable = JupyterRenderable(html) + jupyter_renderable = JupyterRenderable(html, text) ipython_display(jupyter_renderable) diff --git a/rich/layout.py b/rich/layout.py index c8aab23b5d..21057828e2 100644 --- a/rich/layout.py +++ b/rich/layout.py @@ -14,8 +14,6 @@ Union, ) -from typing_extensions import Literal - from ._ratio import ratio_resolve from .align import Align from .console import Console, ConsoleOptions, RenderableType, RenderResult diff --git a/rich/pretty.py b/rich/pretty.py index 7c9f8e1ae8..7903b2cc28 100644 --- a/rich/pretty.py +++ b/rich/pretty.py @@ -4,7 +4,6 @@ from array import array from collections import Counter, defaultdict, deque from dataclasses import dataclass, fields, is_dataclass -import inspect from itertools import islice from typing import ( TYPE_CHECKING, @@ -27,7 +26,7 @@ from .abc import RichRenderable from .cells import cell_len from .highlighter import ReprHighlighter -from .jupyter import JupyterRenderable +from .jupyter import JupyterMixin, JupyterRenderable from .measure import Measurement from .text import Text @@ -99,6 +98,9 @@ def ipy_display_hook(value: Any) -> None: # pragma: no cover if console.is_jupyter and any(attr.startswith("_repr_") for attr in dir(value)): return + if hasattr(value, "_repr_mimebundle_"): + return + # certain renderables should start on a new line if isinstance(value, ConsoleRenderable): console.line() @@ -130,7 +132,7 @@ def ipy_display_hook(value: Any) -> None: # pragma: no cover sys.displayhook = display_hook -class Pretty: +class Pretty(JupyterMixin): """A rich renderable that pretty prints an object. Args: From 6f0eae2f5bdfe797ff96d93a2940cfd8e977a92c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 3 Apr 2021 10:43:48 +0100 Subject: [PATCH 3/3] version bump --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c81dcb26a..24f0ddfec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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.1.0] - 2020-04-03 + +### Fixed + +- Fixed support for jupyter qtconsole and similar Jupyter environments + ## [10.0.1] - 2021-03-30 ### Fixed diff --git a/pyproject.toml b/pyproject.toml index 2eea086485..159ea59356 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.0.1" +version = "10.1.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" authors = ["Will McGugan "] license = "MIT"