]> jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/pip/_vendor/rich/measure.py
init: venv aand flask
[dlqueue.git] / venv / lib / python3.11 / site-packages / pip / _vendor / rich / measure.py
1 from operator import itemgetter
2 from typing import TYPE_CHECKING, Callable, NamedTuple, Optional, Sequence
3
4 from . import errors
5 from .protocol import is_renderable, rich_cast
6
7 if TYPE_CHECKING:
8 from .console import Console, ConsoleOptions, RenderableType
9
10
11 class Measurement(NamedTuple):
12 """Stores the minimum and maximum widths (in characters) required to render an object."""
13
14 minimum: int
15 """Minimum number of cells required to render."""
16 maximum: int
17 """Maximum number of cells required to render."""
18
19 @property
20 def span(self) -> int:
21 """Get difference between maximum and minimum."""
22 return self.maximum - self.minimum
23
24 def normalize(self) -> "Measurement":
25 """Get measurement that ensures that minimum <= maximum and minimum >= 0
26
27 Returns:
28 Measurement: A normalized measurement.
29 """
30 minimum, maximum = self
31 minimum = min(max(0, minimum), maximum)
32 return Measurement(max(0, minimum), max(0, max(minimum, maximum)))
33
34 def with_maximum(self, width: int) -> "Measurement":
35 """Get a RenderableWith where the widths are <= width.
36
37 Args:
38 width (int): Maximum desired width.
39
40 Returns:
41 Measurement: New Measurement object.
42 """
43 minimum, maximum = self
44 return Measurement(min(minimum, width), min(maximum, width))
45
46 def with_minimum(self, width: int) -> "Measurement":
47 """Get a RenderableWith where the widths are >= width.
48
49 Args:
50 width (int): Minimum desired width.
51
52 Returns:
53 Measurement: New Measurement object.
54 """
55 minimum, maximum = self
56 width = max(0, width)
57 return Measurement(max(minimum, width), max(maximum, width))
58
59 def clamp(
60 self, min_width: Optional[int] = None, max_width: Optional[int] = None
61 ) -> "Measurement":
62 """Clamp a measurement within the specified range.
63
64 Args:
65 min_width (int): Minimum desired width, or ``None`` for no minimum. Defaults to None.
66 max_width (int): Maximum desired width, or ``None`` for no maximum. Defaults to None.
67
68 Returns:
69 Measurement: New Measurement object.
70 """
71 measurement = self
72 if min_width is not None:
73 measurement = measurement.with_minimum(min_width)
74 if max_width is not None:
75 measurement = measurement.with_maximum(max_width)
76 return measurement
77
78 @classmethod
79 def get(
80 cls, console: "Console", options: "ConsoleOptions", renderable: "RenderableType"
81 ) -> "Measurement":
82 """Get a measurement for a renderable.
83
84 Args:
85 console (~rich.console.Console): Console instance.
86 options (~rich.console.ConsoleOptions): Console options.
87 renderable (RenderableType): An object that may be rendered with Rich.
88
89 Raises:
90 errors.NotRenderableError: If the object is not renderable.
91
92 Returns:
93 Measurement: Measurement object containing range of character widths required to render the object.
94 """
95 _max_width = options.max_width
96 if _max_width < 1:
97 return Measurement(0, 0)
98 if isinstance(renderable, str):
99 renderable = console.render_str(
100 renderable, markup=options.markup, highlight=False
101 )
102 renderable = rich_cast(renderable)
103 if is_renderable(renderable):
104 get_console_width: Optional[
105 Callable[["Console", "ConsoleOptions"], "Measurement"]
106 ] = getattr(renderable, "__rich_measure__", None)
107 if get_console_width is not None:
108 render_width = (
109 get_console_width(console, options)
110 .normalize()
111 .with_maximum(_max_width)
112 )
113 if render_width.maximum < 1:
114 return Measurement(0, 0)
115 return render_width.normalize()
116 else:
117 return Measurement(0, _max_width)
118 else:
119 raise errors.NotRenderableError(
120 f"Unable to get render width for {renderable!r}; "
121 "a str, Segment, or object with __rich_console__ method is required"
122 )
123
124
125 def measure_renderables(
126 console: "Console",
127 options: "ConsoleOptions",
128 renderables: Sequence["RenderableType"],
129 ) -> "Measurement":
130 """Get a measurement that would fit a number of renderables.
131
132 Args:
133 console (~rich.console.Console): Console instance.
134 options (~rich.console.ConsoleOptions): Console options.
135 renderables (Iterable[RenderableType]): One or more renderable objects.
136
137 Returns:
138 Measurement: Measurement object containing range of character widths required to
139 contain all given renderables.
140 """
141 if not renderables:
142 return Measurement(0, 0)
143 get_measurement = Measurement.get
144 measurements = [
145 get_measurement(console, options, renderable) for renderable in renderables
146 ]
147 measured_width = Measurement(
148 max(measurements, key=itemgetter(0)).minimum,
149 max(measurements, key=itemgetter(1)).maximum,
150 )
151 return measured_width