diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a062181..f59f176d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ 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). +## [4.2.1] - 2020-07-29 + +### Added + +- Added show_time and show_level parameters to RichHandler https://github.com/willmcgugan/rich/pull/182 + +### Fixed + +- Fixed progress.track iterator exiting early https://github.com/willmcgugan/rich/issues/189 +- Added workaround for Python bug https://bugs.python.org/issue37871, fixing https://github.com/willmcgugan/rich/issues/186 + +### Changed + +- Set overflow=fold for log messages https://github.com/willmcgugan/rich/issues/190 + ## [4.2.0] - 2020-07-27 ### Fixed diff --git a/rich/__main__.py b/rich/__main__.py index 86d3a3bb..e5db07f7 100644 --- a/rich/__main__.py +++ b/rich/__main__.py @@ -177,5 +177,10 @@ if __name__ == "__main__": # pragma: no cover start = process_time() console.print(test_card) taken = round((process_time() - start) * 1000.0, 1) - print(console.file.getvalue()) # type: ignore + + text = console.file.getvalue() + # https://bugs.python.org/issue37871 + for offset in range(0, len(text), 8192): + print(text[offset : offset + 8192], end="") + print(f"rendered in {taken}ms") diff --git a/rich/console.py b/rich/console.py index 9354a7ca..d8b517f3 100644 --- a/rich/console.py +++ b/rich/console.py @@ -1,4 +1,5 @@ import inspect +import io import os import platform import shutil @@ -983,7 +984,14 @@ class Console: else: text = self._render_buffer() if text: - self.file.write(text) + if WINDOWS: # pragma: no cover + # https://bugs.python.org/issue37871 + CHUNK_SIZE = 8192 + write = self.file.write + for offset in range(0, len(text), CHUNK_SIZE): + write(text[offset : offset + CHUNK_SIZE]) + else: + self.file.write(text) self.file.flush() def _render_buffer(self) -> str: diff --git a/rich/logging.py b/rich/logging.py index 2504b13c..4f5b6de6 100644 --- a/rich/logging.py +++ b/rich/logging.py @@ -24,6 +24,8 @@ class RichHandler(Handler): level (int, optional): Log level. Defaults to logging.NOTSET. console (:class:`~rich.console.Console`, optional): Optional console instance to write logs. Default will use a global console instance writing to stdout. + show_time (bool, optional): Show a column for the time. Defaults to True. + show_level (bool, optional): Show a column for the level. Defaults to True. show_path (bool, optional): Show the path to the original log call. Defaults to True. enable_link_path (bool, optional): Enable terminal link of path column to file. Defaults to True. highlighter (Highlighter, optional): Highlighter to style log messages, or None to use ReprHighlighter. Defaults to None. diff --git a/rich/progress.py b/rich/progress.py index 75bf0b04..38b40d6e 100644 --- a/rich/progress.py +++ b/rich/progress.py @@ -1,46 +1,45 @@ +import io +import sys from abc import ABC, abstractmethod from collections import deque from collections.abc import Sized from dataclasses import dataclass, field from datetime import timedelta -import io from math import ceil -import sys -from time import monotonic, perf_counter from threading import Event, RLock, Thread +from time import monotonic, perf_counter from typing import ( + IO, + TYPE_CHECKING, Any, Callable, Deque, Dict, Iterable, Iterator, - IO, List, - Optional, NamedTuple, + NewType, + Optional, Sequence, Tuple, TypeVar, - TYPE_CHECKING, - NewType, Union, ) -from . import get_console +from . import filesize, get_console from .bar import Bar from .console import ( Console, ConsoleRenderable, JustifyMethod, + RenderableType, RenderGroup, RenderHook, - RenderableType, ) from .control import Control from .highlighter import Highlighter from .jupyter import JupyterMixin -from . import filesize from .live_render import LiveRender from .style import StyleType from .table import Table @@ -766,7 +765,6 @@ class Progress(JupyterMixin, RenderHook): refresh (bool): Force a refresh of progress information. Default is False. **fields (Any): Additional data fields required for rendering. """ - current_time = self.get_time() with self._lock: task = self._tasks[task_id] completed_start = task.completed @@ -782,19 +780,21 @@ class Progress(JupyterMixin, RenderHook): if visible is not None: task.visible = visible task.fields.update(fields) - update_completed = task.completed - completed_start + + if refresh: + self.refresh() + + current_time = self.get_time() old_sample_time = current_time - self.speed_estimate_period _progress = task._progress popleft = _progress.popleft while _progress and _progress[0].timestamp < old_sample_time: popleft() - while len(_progress) > 10: + while len(_progress) > 20: popleft() _progress.append(ProgressSample(current_time, update_completed)) - if refresh: - self.refresh() def advance(self, task_id: TaskID, advance: float = 1) -> None: """Advance task by a number of steps. @@ -997,9 +997,9 @@ if __name__ == "__main__": # pragma: no coverage console = Console() with Progress(console=console, transient=True) as progress: - task1 = progress.add_task(" [red]Downloading", total=1000) - task2 = progress.add_task(" [green]Processing", total=1000) - task3 = progress.add_task(" [yellow]Thinking", total=1000, start=False) + task1 = progress.add_task("[red]Downloading", total=1000) + task2 = progress.add_task("[green]Processing", total=1000) + task3 = progress.add_task("[yellow]Thinking", total=1000, start=False) while not progress.finished: progress.update(task1, advance=0.5)