11import inspect
22import os
33import platform
4- import shutil
54import sys
65import threading
76from abc import ABC , abstractmethod
1211from html import escape
1312from inspect import isclass
1413from itertools import islice
14+ from threading import RLock
1515from time import monotonic
16- from types import FrameType , TracebackType , ModuleType
16+ from types import FrameType , ModuleType , TracebackType
1717from typing import (
1818 IO ,
1919 TYPE_CHECKING ,
2525 Mapping ,
2626 NamedTuple ,
2727 Optional ,
28- Set ,
2928 TextIO ,
3029 Tuple ,
3130 Type ,
@@ -212,6 +211,19 @@ def update_width(self, width: int) -> "ConsoleOptions":
212211 options .min_width = options .max_width = max (0 , width )
213212 return options
214213
214+ def update_height (self , height : int ) -> "ConsoleOptions" :
215+ """Update the height, and return a copy.
216+
217+ Args:
218+ height (int): New height
219+
220+ Returns:
221+ ~ConsoleOptions: New Console options instance.
222+ """
223+ options = self .copy ()
224+ options .max_height = options .height = height
225+ return options
226+
215227 def update_dimensions (self , width : int , height : int ) -> "ConsoleOptions" :
216228 """Update the width and height, and return a copy.
217229
@@ -224,8 +236,7 @@ def update_dimensions(self, width: int, height: int) -> "ConsoleOptions":
224236 """
225237 options = self .copy ()
226238 options .min_width = options .max_width = max (0 , width )
227- options .height = height
228- options .max_height = height
239+ options .height = options .max_height = height
229240 return options
230241
231242
@@ -247,11 +258,12 @@ def __rich_console__(
247258 ...
248259
249260
261+ # A type that may be rendered by Console.
250262RenderableType = Union [ConsoleRenderable , RichCast , str ]
251- """A type that may be rendered by Console."""
252263
264+
265+ # The result of calling a __rich_console__ method.
253266RenderResult = Iterable [Union [RenderableType , Segment ]]
254- """The result of calling a __rich_console__ method."""
255267
256268
257269_null_highlighter = NullHighlighter ()
@@ -464,9 +476,6 @@ def __rich_console__(
464476 yield from self .renderables
465477
466478
467- RenderGroup = Group # TODO: deprecate at some point
468-
469-
470479def group (fit : bool = True ) -> Callable [..., Callable [..., Group ]]:
471480 """A decorator that turns an iterable of renderables in to a group.
472481
@@ -477,7 +486,7 @@ def group(fit: bool = True) -> Callable[..., Callable[..., Group]]:
477486 def decorator (
478487 method : Callable [..., Iterable [RenderableType ]]
479488 ) -> Callable [..., Group ]:
480- """Convert a method that returns an iterable of renderables in to a RenderGroup ."""
489+ """Convert a method that returns an iterable of renderables in to a Group ."""
481490
482491 @wraps (method )
483492 def _replace (* args : Any , ** kwargs : Any ) -> Group :
@@ -489,9 +498,6 @@ def _replace(*args: Any, **kwargs: Any) -> Group:
489498 return decorator
490499
491500
492- render_group = group
493-
494-
495501def _is_jupyter () -> bool : # pragma: no cover
496502 """Check if we're running in a Jupyter notebook."""
497503 try :
@@ -813,12 +819,13 @@ def push_render_hook(self, hook: RenderHook) -> None:
813819 Args:
814820 hook (RenderHook): Render hook instance.
815821 """
816-
817- self ._render_hooks .append (hook )
822+ with self . _lock :
823+ self ._render_hooks .append (hook )
818824
819825 def pop_render_hook (self ) -> None :
820826 """Pop the last renderhook from the stack."""
821- self ._render_hooks .pop ()
827+ with self ._lock :
828+ self ._render_hooks .pop ()
822829
823830 def __enter__ (self ) -> "Console" :
824831 """Own context manager to enter buffer context."""
@@ -1495,9 +1502,8 @@ def control(self, *control: Control) -> None:
14951502 control_codes (str): Control codes, such as those that may move the cursor.
14961503 """
14971504 if not self .is_dumb_terminal :
1498- for _control in control :
1499- self ._buffer .append (_control .segment )
1500- self ._check_buffer ()
1505+ with self :
1506+ self ._buffer .extend (_control .segment for _control in control )
15011507
15021508 def out (
15031509 self ,
@@ -1579,7 +1585,7 @@ def print(
15791585 if overflow is None :
15801586 overflow = "ignore"
15811587 crop = False
1582-
1588+ render_hooks = self . _render_hooks [:]
15831589 with self :
15841590 renderables = self ._collect_renderables (
15851591 objects ,
@@ -1590,7 +1596,7 @@ def print(
15901596 markup = markup ,
15911597 highlight = highlight ,
15921598 )
1593- for hook in self . _render_hooks :
1599+ for hook in render_hooks :
15941600 renderables = hook .process_renderables (renderables )
15951601 render_options = self .options .update (
15961602 justify = justify ,
@@ -1847,6 +1853,8 @@ def log(
18471853 if not objects :
18481854 objects = (NewLine (),)
18491855
1856+ render_hooks = self ._render_hooks [:]
1857+
18501858 with self :
18511859 renderables = self ._collect_renderables (
18521860 objects ,
@@ -1881,7 +1889,7 @@ def log(
18811889 link_path = link_path ,
18821890 )
18831891 ]
1884- for hook in self . _render_hooks :
1892+ for hook in render_hooks :
18851893 renderables = hook .process_renderables (renderables )
18861894 new_segments : List [Segment ] = []
18871895 extend = new_segments .extend
0 commit comments