]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/pip/_vendor/rich/progress_bar.py
2 from functools
import lru_cache
3 from time
import monotonic
4 from typing
import Iterable
, List
, Optional
6 from .color
import Color
, blend_rgb
7 from .color_triplet
import ColorTriplet
8 from .console
import Console
, ConsoleOptions
, RenderResult
9 from .jupyter
import JupyterMixin
10 from .measure
import Measurement
11 from .segment
import Segment
12 from .style
import Style
, StyleType
14 # Number of characters before 'pulse' animation repeats
18 class ProgressBar(JupyterMixin
):
19 """Renders a (progress) bar. Used by rich.progress.
22 total (float, optional): Number of steps in the bar. Defaults to 100. Set to None to render a pulsing animation.
23 completed (float, optional): Number of steps completed. Defaults to 0.
24 width (int, optional): Width of the bar, or ``None`` for maximum width. Defaults to None.
25 pulse (bool, optional): Enable pulse effect. Defaults to False. Will pulse if a None total was passed.
26 style (StyleType, optional): Style for the bar background. Defaults to "bar.back".
27 complete_style (StyleType, optional): Style for the completed bar. Defaults to "bar.complete".
28 finished_style (StyleType, optional): Style for a finished bar. Defaults to "bar.finished".
29 pulse_style (StyleType, optional): Style for pulsing bars. Defaults to "bar.pulse".
30 animation_time (Optional[float], optional): Time in seconds to use for animation, or None to use system time.
35 total
: Optional
[float] = 100.0,
37 width
: Optional
[int] = None,
39 style
: StyleType
= "bar.back",
40 complete_style
: StyleType
= "bar.complete",
41 finished_style
: StyleType
= "bar.finished",
42 pulse_style
: StyleType
= "bar.pulse",
43 animation_time
: Optional
[float] = None,
46 self
.completed
= completed
50 self
.complete_style
= complete_style
51 self
.finished_style
= finished_style
52 self
.pulse_style
= pulse_style
53 self
.animation_time
= animation_time
55 self
._pulse
_segments
: Optional
[List
[Segment
]] = None
57 def __repr__(self
) -> str:
58 return f
"<Bar {self.completed!r} of {self.total!r}>"
61 def percentage_completed(self
) -> Optional
[float]:
62 """Calculate percentage complete."""
63 if self
.total
is None:
65 completed
= (self
.completed
/ self
.total
) * 100.0
66 completed
= min(100, max(0.0, completed
))
69 @lru_cache(maxsize
=16)
70 def _get_pulse_segments(
78 """Get a list of segments to render a pulse animation.
81 List[Segment]: A list of segments, one segment per character.
83 bar
= "-" if ascii
else "━"
84 segments
: List
[Segment
] = []
85 if color_system
not in ("standard", "eight_bit", "truecolor") or no_color
:
86 segments
+= [Segment(bar
, fore_style
)] * (PULSE_SIZE
// 2)
87 segments
+= [Segment(" " if no_color
else bar
, back_style
)] * (
88 PULSE_SIZE
- (PULSE_SIZE
// 2)
92 append
= segments
.append
94 fore_style
.color
.get_truecolor()
96 else ColorTriplet(255, 0, 255)
99 back_style
.color
.get_truecolor()
101 else ColorTriplet(0, 0, 0)
107 from_triplet
= Color
.from_triplet
109 for index
in range(PULSE_SIZE
):
110 position
= index
/ PULSE_SIZE
111 fade
= 0.5 + cos((position
* pi
* 2)) / 2.0
112 color
= blend_rgb(fore_color
, back_color
, cross_fade
=fade
)
113 append(_Segment(bar
, _Style(color
=from_triplet(color
))))
116 def update(self
, completed
: float, total
: Optional
[float] = None) -> None:
117 """Update progress with new values.
120 completed (float): Number of steps completed.
121 total (float, optional): Total number of steps, or ``None`` to not change. Defaults to None.
123 self
.completed
= completed
124 self
.total
= total
if total
is not None else self
.total
127 self
, console
: Console
, width
: int, ascii
: bool = False
128 ) -> Iterable
[Segment
]:
129 """Renders the pulse animation.
132 console (Console): Console instance.
133 width (int): Width in characters of pulse animation.
136 RenderResult: [description]
139 Iterator[Segment]: Segments to render pulse
141 fore_style
= console
.get_style(self
.pulse_style
, default
="white")
142 back_style
= console
.get_style(self
.style
, default
="black")
144 pulse_segments
= self
._get
_pulse
_segments
(
145 fore_style
, back_style
, console
.color_system
, console
.no_color
, ascii
=ascii
147 segment_count
= len(pulse_segments
)
149 monotonic() if self
.animation_time
is None else self
.animation_time
151 segments
= pulse_segments
* (int(width
/ segment_count
) + 2)
152 offset
= int(-current_time
* 15) % segment_count
153 segments
= segments
[offset
: offset
+ width
]
156 def __rich_console__(
157 self
, console
: Console
, options
: ConsoleOptions
160 width
= min(self
.width
or options
.max_width
, options
.max_width
)
161 ascii
= options
.legacy_windows
or options
.ascii_only
162 should_pulse
= self
.pulse
or self
.total
is None
164 yield from self
._render
_pulse
(console
, width
, ascii
=ascii
)
167 completed
: Optional
[float] = (
168 min(self
.total
, max(0, self
.completed
)) if self
.total
is not None else None
171 bar
= "-" if ascii
else "━"
172 half_bar_right
= " " if ascii
else "╸"
173 half_bar_left
= " " if ascii
else "╺"
175 int(width
* 2 * completed
/ self
.total
)
176 if self
.total
and completed
is not None
179 bar_count
= complete_halves
// 2
180 half_bar_count
= complete_halves
% 2
181 style
= console
.get_style(self
.style
)
182 is_finished
= self
.total
is None or self
.completed
>= self
.total
183 complete_style
= console
.get_style(
184 self
.finished_style
if is_finished
else self
.complete_style
188 yield _Segment(bar
* bar_count
, complete_style
)
190 yield _Segment(half_bar_right
* half_bar_count
, complete_style
)
192 if not console
.no_color
:
193 remaining_bars
= width
- bar_count
- half_bar_count
194 if remaining_bars
and console
.color_system
is not None:
195 if not half_bar_count
and bar_count
:
196 yield _Segment(half_bar_left
, style
)
199 yield _Segment(bar
* remaining_bars
, style
)
201 def __rich_measure__(
202 self
, console
: Console
, options
: ConsoleOptions
205 Measurement(self
.width
, self
.width
)
206 if self
.width
is not None
207 else Measurement(4, options
.max_width
)
211 if __name__
== "__main__": # pragma: no cover
213 bar
= ProgressBar(width
=50, total
=100)
217 console
.show_cursor(False)
218 for n
in range(0, 101, 1):
221 console
.file.write("\r")
223 console
.show_cursor(True)