Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/rich/spinner.py: 23%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

52 statements  

1from typing import cast, List, Optional, TYPE_CHECKING, Union 

2 

3from ._spinners import SPINNERS 

4from .measure import Measurement 

5from .table import Table 

6from .text import Text 

7 

8if TYPE_CHECKING: 

9 from .console import Console, ConsoleOptions, RenderResult, RenderableType 

10 from .style import StyleType 

11 

12 

13class Spinner: 

14 """A spinner animation. 

15 

16 Args: 

17 name (str): Name of spinner (run python -m rich.spinner). 

18 text (RenderableType, optional): A renderable to display at the right of the spinner (str or Text typically). Defaults to "". 

19 style (StyleType, optional): Style for spinner animation. Defaults to None. 

20 speed (float, optional): Speed factor for animation. Defaults to 1.0. 

21 

22 Raises: 

23 KeyError: If name isn't one of the supported spinner animations. 

24 """ 

25 

26 def __init__( 

27 self, 

28 name: str, 

29 text: "RenderableType" = "", 

30 *, 

31 style: Optional["StyleType"] = None, 

32 speed: float = 1.0, 

33 ) -> None: 

34 try: 

35 spinner = SPINNERS[name] 

36 except KeyError: 

37 raise KeyError(f"no spinner called {name!r}") 

38 self.text: "Union[RenderableType, Text]" = ( 

39 Text.from_markup(text) if isinstance(text, str) else text 

40 ) 

41 self.name = name 

42 self.frames = cast(List[str], spinner["frames"])[:] 

43 self.interval = cast(float, spinner["interval"]) 

44 self.start_time: Optional[float] = None 

45 self.style = style 

46 self.speed = speed 

47 self.frame_no_offset: float = 0.0 

48 self._update_speed = 0.0 

49 

50 def __rich_console__( 

51 self, console: "Console", options: "ConsoleOptions" 

52 ) -> "RenderResult": 

53 yield self.render(console.get_time()) 

54 

55 def __rich_measure__( 

56 self, console: "Console", options: "ConsoleOptions" 

57 ) -> Measurement: 

58 text = self.render(0) 

59 return Measurement.get(console, options, text) 

60 

61 def render(self, time: float) -> "RenderableType": 

62 """Render the spinner for a given time. 

63 

64 Args: 

65 time (float): Time in seconds. 

66 

67 Returns: 

68 RenderableType: A renderable containing animation frame. 

69 """ 

70 if self.start_time is None: 

71 self.start_time = time 

72 

73 frame_no = ((time - self.start_time) * self.speed) / ( 

74 self.interval / 1000.0 

75 ) + self.frame_no_offset 

76 frame = Text( 

77 self.frames[int(frame_no) % len(self.frames)], style=self.style or "" 

78 ) 

79 

80 if self._update_speed: 

81 self.frame_no_offset = frame_no 

82 self.start_time = time 

83 self.speed = self._update_speed 

84 self._update_speed = 0.0 

85 

86 if not self.text: 

87 return frame 

88 elif isinstance(self.text, (str, Text)): 

89 return Text.assemble(frame, " ", self.text) 

90 else: 

91 table = Table.grid(padding=1) 

92 table.add_row(frame, self.text) 

93 return table 

94 

95 def update( 

96 self, 

97 *, 

98 text: "RenderableType" = "", 

99 style: Optional["StyleType"] = None, 

100 speed: Optional[float] = None, 

101 ) -> None: 

102 """Updates attributes of a spinner after it has been started. 

103 

104 Args: 

105 text (RenderableType, optional): A renderable to display at the right of the spinner (str or Text typically). Defaults to "". 

106 style (StyleType, optional): Style for spinner animation. Defaults to None. 

107 speed (float, optional): Speed factor for animation. Defaults to None. 

108 """ 

109 if text: 

110 self.text = Text.from_markup(text) if isinstance(text, str) else text 

111 if style: 

112 self.style = style 

113 if speed: 

114 self._update_speed = speed 

115 

116 

117if __name__ == "__main__": # pragma: no cover 

118 from time import sleep 

119 

120 from .columns import Columns 

121 from .panel import Panel 

122 from .live import Live 

123 

124 all_spinners = Columns( 

125 [ 

126 Spinner(spinner_name, text=Text(repr(spinner_name), style="green")) 

127 for spinner_name in sorted(SPINNERS.keys()) 

128 ], 

129 column_first=True, 

130 expand=True, 

131 ) 

132 

133 with Live( 

134 Panel(all_spinners, title="Spinners", border_style="blue"), 

135 refresh_per_second=20, 

136 ) as live: 

137 while True: 

138 sleep(0.1)