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

69 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:35 +0000

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

2 

3if TYPE_CHECKING: 

4 from .console import ( 

5 Console, 

6 ConsoleOptions, 

7 RenderableType, 

8 RenderResult, 

9 ) 

10from .jupyter import JupyterMixin 

11from .measure import Measurement 

12from .style import Style 

13from .segment import Segment 

14 

15 

16PaddingDimensions = Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int, int]] 

17 

18 

19class Padding(JupyterMixin): 

20 """Draw space around content. 

21 

22 Example: 

23 >>> print(Padding("Hello", (2, 4), style="on blue")) 

24 

25 Args: 

26 renderable (RenderableType): String or other renderable. 

27 pad (Union[int, Tuple[int]]): Padding for top, right, bottom, and left borders. 

28 May be specified with 1, 2, or 4 integers (CSS style). 

29 style (Union[str, Style], optional): Style for padding characters. Defaults to "none". 

30 expand (bool, optional): Expand padding to fit available width. Defaults to True. 

31 """ 

32 

33 def __init__( 

34 self, 

35 renderable: "RenderableType", 

36 pad: "PaddingDimensions" = (0, 0, 0, 0), 

37 *, 

38 style: Union[str, Style] = "none", 

39 expand: bool = True, 

40 ): 

41 self.renderable = renderable 

42 self.top, self.right, self.bottom, self.left = self.unpack(pad) 

43 self.style = style 

44 self.expand = expand 

45 

46 @classmethod 

47 def indent(cls, renderable: "RenderableType", level: int) -> "Padding": 

48 """Make padding instance to render an indent. 

49 

50 Args: 

51 renderable (RenderableType): String or other renderable. 

52 level (int): Number of characters to indent. 

53 

54 Returns: 

55 Padding: A Padding instance. 

56 """ 

57 

58 return Padding(renderable, pad=(0, 0, 0, level), expand=False) 

59 

60 @staticmethod 

61 def unpack(pad: "PaddingDimensions") -> Tuple[int, int, int, int]: 

62 """Unpack padding specified in CSS style.""" 

63 if isinstance(pad, int): 

64 return (pad, pad, pad, pad) 

65 if len(pad) == 1: 

66 _pad = pad[0] 

67 return (_pad, _pad, _pad, _pad) 

68 if len(pad) == 2: 

69 pad_top, pad_right = cast(Tuple[int, int], pad) 

70 return (pad_top, pad_right, pad_top, pad_right) 

71 if len(pad) == 4: 

72 top, right, bottom, left = cast(Tuple[int, int, int, int], pad) 

73 return (top, right, bottom, left) 

74 raise ValueError(f"1, 2 or 4 integers required for padding; {len(pad)} given") 

75 

76 def __repr__(self) -> str: 

77 return f"Padding({self.renderable!r}, ({self.top},{self.right},{self.bottom},{self.left}))" 

78 

79 def __rich_console__( 

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

81 ) -> "RenderResult": 

82 style = console.get_style(self.style) 

83 if self.expand: 

84 width = options.max_width 

85 else: 

86 width = min( 

87 Measurement.get(console, options, self.renderable).maximum 

88 + self.left 

89 + self.right, 

90 options.max_width, 

91 ) 

92 render_options = options.update_width(width - self.left - self.right) 

93 if render_options.height is not None: 

94 render_options = render_options.update_height( 

95 height=render_options.height - self.top - self.bottom 

96 ) 

97 lines = console.render_lines( 

98 self.renderable, render_options, style=style, pad=True 

99 ) 

100 _Segment = Segment 

101 

102 left = _Segment(" " * self.left, style) if self.left else None 

103 right = ( 

104 [_Segment(f'{" " * self.right}', style), _Segment.line()] 

105 if self.right 

106 else [_Segment.line()] 

107 ) 

108 blank_line: Optional[List[Segment]] = None 

109 if self.top: 

110 blank_line = [_Segment(f'{" " * width}\n', style)] 

111 yield from blank_line * self.top 

112 if left: 

113 for line in lines: 

114 yield left 

115 yield from line 

116 yield from right 

117 else: 

118 for line in lines: 

119 yield from line 

120 yield from right 

121 if self.bottom: 

122 blank_line = blank_line or [_Segment(f'{" " * width}\n', style)] 

123 yield from blank_line * self.bottom 

124 

125 def __rich_measure__( 

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

127 ) -> "Measurement": 

128 max_width = options.max_width 

129 extra_width = self.left + self.right 

130 if max_width - extra_width < 1: 

131 return Measurement(max_width, max_width) 

132 measure_min, measure_max = Measurement.get(console, options, self.renderable) 

133 measurement = Measurement(measure_min + extra_width, measure_max + extra_width) 

134 measurement = measurement.with_maximum(max_width) 

135 return measurement 

136 

137 

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

139 from rich import print 

140 

141 print(Padding("Hello, World", (2, 4), style="on blue"))