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

47 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-20 06:09 +0000

1""" 

2The base classes for the styling. 

3""" 

4from __future__ import annotations 

5 

6from abc import ABCMeta, abstractmethod, abstractproperty 

7from typing import Callable, Hashable, NamedTuple 

8 

9__all__ = [ 

10 "Attrs", 

11 "DEFAULT_ATTRS", 

12 "ANSI_COLOR_NAMES", 

13 "ANSI_COLOR_NAMES_ALIASES", 

14 "BaseStyle", 

15 "DummyStyle", 

16 "DynamicStyle", 

17] 

18 

19 

20#: Style attributes. 

21class Attrs(NamedTuple): 

22 color: str | None 

23 bgcolor: str | None 

24 bold: bool | None 

25 underline: bool | None 

26 strike: bool | None 

27 italic: bool | None 

28 blink: bool | None 

29 reverse: bool | None 

30 hidden: bool | None 

31 

32 

33""" 

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

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

36:param bold: Boolean 

37:param underline: Boolean 

38:param strike: Boolean 

39:param italic: Boolean 

40:param blink: Boolean 

41:param reverse: Boolean 

42:param hidden: Boolean 

43""" 

44 

45#: The default `Attrs`. 

46DEFAULT_ATTRS = Attrs( 

47 color="", 

48 bgcolor="", 

49 bold=False, 

50 underline=False, 

51 strike=False, 

52 italic=False, 

53 blink=False, 

54 reverse=False, 

55 hidden=False, 

56) 

57 

58 

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

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

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

62#: values for these names. 

63#: ISO 6429 colors 

64ANSI_COLOR_NAMES = [ 

65 "ansidefault", 

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

67 "ansiblack", 

68 "ansired", 

69 "ansigreen", 

70 "ansiyellow", 

71 "ansiblue", 

72 "ansimagenta", 

73 "ansicyan", 

74 "ansigray", 

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

76 "ansibrightblack", 

77 "ansibrightred", 

78 "ansibrightgreen", 

79 "ansibrightyellow", 

80 "ansibrightblue", 

81 "ansibrightmagenta", 

82 "ansibrightcyan", 

83 "ansiwhite", 

84] 

85 

86 

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

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

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

90 

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

92ANSI_COLOR_NAMES_ALIASES: dict[str, str] = { 

93 "ansidarkgray": "ansibrightblack", 

94 "ansiteal": "ansicyan", 

95 "ansiturquoise": "ansibrightcyan", 

96 "ansibrown": "ansiyellow", 

97 "ansipurple": "ansimagenta", 

98 "ansifuchsia": "ansibrightmagenta", 

99 "ansilightgray": "ansigray", 

100 "ansidarkred": "ansired", 

101 "ansidarkgreen": "ansigreen", 

102 "ansidarkblue": "ansiblue", 

103} 

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

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

106 

107 

108class BaseStyle(metaclass=ABCMeta): 

109 """ 

110 Abstract base class for prompt_toolkit styles. 

111 """ 

112 

113 @abstractmethod 

114 def get_attrs_for_style_str( 

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

116 ) -> Attrs: 

117 """ 

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

119 

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

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

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

123 """ 

124 

125 @abstractproperty 

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

127 """ 

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

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

130 """ 

131 return [] 

132 

133 @abstractmethod 

134 def invalidation_hash(self) -> Hashable: 

135 """ 

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

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

138 has to be redrawn. 

139 """ 

140 

141 

142class DummyStyle(BaseStyle): 

143 """ 

144 A style that doesn't style anything. 

145 """ 

146 

147 def get_attrs_for_style_str( 

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

149 ) -> Attrs: 

150 return default 

151 

152 def invalidation_hash(self) -> Hashable: 

153 return 1 # Always the same value. 

154 

155 @property 

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

157 return [] 

158 

159 

160class DynamicStyle(BaseStyle): 

161 """ 

162 Style class that can dynamically returns an other Style. 

163 

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

165 """ 

166 

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

168 self.get_style = get_style 

169 self._dummy = DummyStyle() 

170 

171 def get_attrs_for_style_str( 

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

173 ) -> Attrs: 

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

175 

176 return style.get_attrs_for_style_str(style_str, default) 

177 

178 def invalidation_hash(self) -> Hashable: 

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

180 

181 @property 

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

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