Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/prompt_toolkit/styles/base.py: 81%

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  

1""" 

2The base classes for the styling. 

3""" 

4 

5from __future__ import annotations 

6 

7from abc import ABCMeta, abstractmethod 

8from collections.abc import Callable, Hashable 

9from typing import NamedTuple 

10 

11__all__ = [ 

12 "Attrs", 

13 "DEFAULT_ATTRS", 

14 "ANSI_COLOR_NAMES", 

15 "ANSI_COLOR_NAMES_ALIASES", 

16 "BaseStyle", 

17 "DummyStyle", 

18 "DynamicStyle", 

19] 

20 

21 

22#: Style attributes. 

23class Attrs(NamedTuple): 

24 color: str | None 

25 bgcolor: str | None 

26 bold: bool | None 

27 underline: bool | None 

28 strike: bool | None 

29 italic: bool | None 

30 blink: bool | None 

31 reverse: bool | None 

32 hidden: bool | None 

33 dim: bool | None 

34 

35 

36""" 

37:param color: Hexadecimal string. E.g. '000000' or Ansi color name: e.g. 'ansiblue' 

38:param bgcolor: Hexadecimal string. E.g. 'ffffff' or Ansi color name: e.g. 'ansired' 

39:param bold: Boolean 

40:param underline: Boolean 

41:param strike: Boolean 

42:param italic: Boolean 

43:param blink: Boolean 

44:param reverse: Boolean 

45:param hidden: Boolean 

46:param dim: Boolean 

47""" 

48 

49#: The default `Attrs`. 

50DEFAULT_ATTRS = Attrs( 

51 color="", 

52 bgcolor="", 

53 bold=False, 

54 underline=False, 

55 strike=False, 

56 italic=False, 

57 blink=False, 

58 reverse=False, 

59 hidden=False, 

60 dim=False, 

61) 

62 

63 

64#: ``Attrs.bgcolor/fgcolor`` can be in either 'ffffff' format, or can be any of 

65#: the following in case we want to take colors from the 8/16 color palette. 

66#: Usually, in that case, the terminal application allows to configure the RGB 

67#: values for these names. 

68#: ISO 6429 colors 

69ANSI_COLOR_NAMES = [ 

70 "ansidefault", 

71 # Low intensity, dark. (One or two components 0x80, the other 0x00.) 

72 "ansiblack", 

73 "ansired", 

74 "ansigreen", 

75 "ansiyellow", 

76 "ansiblue", 

77 "ansimagenta", 

78 "ansicyan", 

79 "ansigray", 

80 # High intensity, bright. (One or two components 0xff, the other 0x00. Not supported everywhere.) 

81 "ansibrightblack", 

82 "ansibrightred", 

83 "ansibrightgreen", 

84 "ansibrightyellow", 

85 "ansibrightblue", 

86 "ansibrightmagenta", 

87 "ansibrightcyan", 

88 "ansiwhite", 

89] 

90 

91 

92# People don't use the same ANSI color names everywhere. In prompt_toolkit 1.0 

93# we used some unconventional names (which were contributed like that to 

94# Pygments). This is fixed now, but we still support the old names. 

95 

96# The table below maps the old aliases to the current names. 

97ANSI_COLOR_NAMES_ALIASES: dict[str, str] = { 

98 "ansidarkgray": "ansibrightblack", 

99 "ansiteal": "ansicyan", 

100 "ansiturquoise": "ansibrightcyan", 

101 "ansibrown": "ansiyellow", 

102 "ansipurple": "ansimagenta", 

103 "ansifuchsia": "ansibrightmagenta", 

104 "ansilightgray": "ansigray", 

105 "ansidarkred": "ansired", 

106 "ansidarkgreen": "ansigreen", 

107 "ansidarkblue": "ansiblue", 

108} 

109assert set(ANSI_COLOR_NAMES_ALIASES.values()).issubset(set(ANSI_COLOR_NAMES)) 

110assert not (set(ANSI_COLOR_NAMES_ALIASES.keys()) & set(ANSI_COLOR_NAMES)) 

111 

112 

113class BaseStyle(metaclass=ABCMeta): 

114 """ 

115 Abstract base class for prompt_toolkit styles. 

116 """ 

117 

118 @abstractmethod 

119 def get_attrs_for_style_str( 

120 self, style_str: str, default: Attrs = DEFAULT_ATTRS 

121 ) -> Attrs: 

122 """ 

123 Return :class:`.Attrs` for the given style string. 

124 

125 :param style_str: The style string. This can contain inline styling as 

126 well as classnames (e.g. "class:title"). 

127 :param default: `Attrs` to be used if no styling was defined. 

128 """ 

129 

130 @property 

131 @abstractmethod 

132 def style_rules(self) -> list[tuple[str, str]]: 

133 """ 

134 The list of style rules, used to create this style. 

135 (Required for `DynamicStyle` and `_MergedStyle` to work.) 

136 """ 

137 return [] 

138 

139 @abstractmethod 

140 def invalidation_hash(self) -> Hashable: 

141 """ 

142 Invalidation hash for the style. When this changes over time, the 

143 renderer knows that something in the style changed, and that everything 

144 has to be redrawn. 

145 """ 

146 

147 

148class DummyStyle(BaseStyle): 

149 """ 

150 A style that doesn't style anything. 

151 """ 

152 

153 def get_attrs_for_style_str( 

154 self, style_str: str, default: Attrs = DEFAULT_ATTRS 

155 ) -> Attrs: 

156 return default 

157 

158 def invalidation_hash(self) -> Hashable: 

159 return 1 # Always the same value. 

160 

161 @property 

162 def style_rules(self) -> list[tuple[str, str]]: 

163 return [] 

164 

165 

166class DynamicStyle(BaseStyle): 

167 """ 

168 Style class that can dynamically returns an other Style. 

169 

170 :param get_style: Callable that returns a :class:`.Style` instance. 

171 """ 

172 

173 def __init__(self, get_style: Callable[[], BaseStyle | None]): 

174 self.get_style = get_style 

175 self._dummy = DummyStyle() 

176 

177 def get_attrs_for_style_str( 

178 self, style_str: str, default: Attrs = DEFAULT_ATTRS 

179 ) -> Attrs: 

180 style = self.get_style() or self._dummy 

181 

182 return style.get_attrs_for_style_str(style_str, default) 

183 

184 def invalidation_hash(self) -> Hashable: 

185 return (self.get_style() or self._dummy).invalidation_hash() 

186 

187 @property 

188 def style_rules(self) -> list[tuple[str, str]]: 

189 return (self.get_style() or self._dummy).style_rules