Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/black/mode.py: 92%

85 statements  

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

1"""Data structures configuring Black behavior. 

2 

3Mostly around Python language feature support per version and Black configuration 

4chosen by the user. 

5""" 

6 

7import sys 

8from dataclasses import dataclass, field 

9from enum import Enum, auto 

10from hashlib import sha256 

11from operator import attrgetter 

12from typing import Dict, Set 

13from warnings import warn 

14 

15if sys.version_info < (3, 8): 

16 from typing_extensions import Final 

17else: 

18 from typing import Final 

19 

20from black.const import DEFAULT_LINE_LENGTH 

21 

22 

23class TargetVersion(Enum): 

24 PY33 = 3 

25 PY34 = 4 

26 PY35 = 5 

27 PY36 = 6 

28 PY37 = 7 

29 PY38 = 8 

30 PY39 = 9 

31 PY310 = 10 

32 PY311 = 11 

33 PY312 = 12 

34 

35 

36class Feature(Enum): 

37 F_STRINGS = 2 

38 NUMERIC_UNDERSCORES = 3 

39 TRAILING_COMMA_IN_CALL = 4 

40 TRAILING_COMMA_IN_DEF = 5 

41 # The following two feature-flags are mutually exclusive, and exactly one should be 

42 # set for every version of python. 

43 ASYNC_IDENTIFIERS = 6 

44 ASYNC_KEYWORDS = 7 

45 ASSIGNMENT_EXPRESSIONS = 8 

46 POS_ONLY_ARGUMENTS = 9 

47 RELAXED_DECORATORS = 10 

48 PATTERN_MATCHING = 11 

49 UNPACKING_ON_FLOW = 12 

50 ANN_ASSIGN_EXTENDED_RHS = 13 

51 EXCEPT_STAR = 14 

52 VARIADIC_GENERICS = 15 

53 DEBUG_F_STRINGS = 16 

54 PARENTHESIZED_CONTEXT_MANAGERS = 17 

55 TYPE_PARAMS = 18 

56 FORCE_OPTIONAL_PARENTHESES = 50 

57 

58 # __future__ flags 

59 FUTURE_ANNOTATIONS = 51 

60 

61 

62FUTURE_FLAG_TO_FEATURE: Final = { 

63 "annotations": Feature.FUTURE_ANNOTATIONS, 

64} 

65 

66 

67VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { 

68 TargetVersion.PY33: {Feature.ASYNC_IDENTIFIERS}, 

69 TargetVersion.PY34: {Feature.ASYNC_IDENTIFIERS}, 

70 TargetVersion.PY35: {Feature.TRAILING_COMMA_IN_CALL, Feature.ASYNC_IDENTIFIERS}, 

71 TargetVersion.PY36: { 

72 Feature.F_STRINGS, 

73 Feature.NUMERIC_UNDERSCORES, 

74 Feature.TRAILING_COMMA_IN_CALL, 

75 Feature.TRAILING_COMMA_IN_DEF, 

76 Feature.ASYNC_IDENTIFIERS, 

77 }, 

78 TargetVersion.PY37: { 

79 Feature.F_STRINGS, 

80 Feature.NUMERIC_UNDERSCORES, 

81 Feature.TRAILING_COMMA_IN_CALL, 

82 Feature.TRAILING_COMMA_IN_DEF, 

83 Feature.ASYNC_KEYWORDS, 

84 Feature.FUTURE_ANNOTATIONS, 

85 }, 

86 TargetVersion.PY38: { 

87 Feature.F_STRINGS, 

88 Feature.DEBUG_F_STRINGS, 

89 Feature.NUMERIC_UNDERSCORES, 

90 Feature.TRAILING_COMMA_IN_CALL, 

91 Feature.TRAILING_COMMA_IN_DEF, 

92 Feature.ASYNC_KEYWORDS, 

93 Feature.FUTURE_ANNOTATIONS, 

94 Feature.ASSIGNMENT_EXPRESSIONS, 

95 Feature.POS_ONLY_ARGUMENTS, 

96 Feature.UNPACKING_ON_FLOW, 

97 Feature.ANN_ASSIGN_EXTENDED_RHS, 

98 }, 

99 TargetVersion.PY39: { 

100 Feature.F_STRINGS, 

101 Feature.DEBUG_F_STRINGS, 

102 Feature.NUMERIC_UNDERSCORES, 

103 Feature.TRAILING_COMMA_IN_CALL, 

104 Feature.TRAILING_COMMA_IN_DEF, 

105 Feature.ASYNC_KEYWORDS, 

106 Feature.FUTURE_ANNOTATIONS, 

107 Feature.ASSIGNMENT_EXPRESSIONS, 

108 Feature.RELAXED_DECORATORS, 

109 Feature.POS_ONLY_ARGUMENTS, 

110 Feature.UNPACKING_ON_FLOW, 

111 Feature.ANN_ASSIGN_EXTENDED_RHS, 

112 Feature.PARENTHESIZED_CONTEXT_MANAGERS, 

113 }, 

114 TargetVersion.PY310: { 

115 Feature.F_STRINGS, 

116 Feature.DEBUG_F_STRINGS, 

117 Feature.NUMERIC_UNDERSCORES, 

118 Feature.TRAILING_COMMA_IN_CALL, 

119 Feature.TRAILING_COMMA_IN_DEF, 

120 Feature.ASYNC_KEYWORDS, 

121 Feature.FUTURE_ANNOTATIONS, 

122 Feature.ASSIGNMENT_EXPRESSIONS, 

123 Feature.RELAXED_DECORATORS, 

124 Feature.POS_ONLY_ARGUMENTS, 

125 Feature.UNPACKING_ON_FLOW, 

126 Feature.ANN_ASSIGN_EXTENDED_RHS, 

127 Feature.PARENTHESIZED_CONTEXT_MANAGERS, 

128 Feature.PATTERN_MATCHING, 

129 }, 

130 TargetVersion.PY311: { 

131 Feature.F_STRINGS, 

132 Feature.DEBUG_F_STRINGS, 

133 Feature.NUMERIC_UNDERSCORES, 

134 Feature.TRAILING_COMMA_IN_CALL, 

135 Feature.TRAILING_COMMA_IN_DEF, 

136 Feature.ASYNC_KEYWORDS, 

137 Feature.FUTURE_ANNOTATIONS, 

138 Feature.ASSIGNMENT_EXPRESSIONS, 

139 Feature.RELAXED_DECORATORS, 

140 Feature.POS_ONLY_ARGUMENTS, 

141 Feature.UNPACKING_ON_FLOW, 

142 Feature.ANN_ASSIGN_EXTENDED_RHS, 

143 Feature.PARENTHESIZED_CONTEXT_MANAGERS, 

144 Feature.PATTERN_MATCHING, 

145 Feature.EXCEPT_STAR, 

146 Feature.VARIADIC_GENERICS, 

147 }, 

148 TargetVersion.PY312: { 

149 Feature.F_STRINGS, 

150 Feature.DEBUG_F_STRINGS, 

151 Feature.NUMERIC_UNDERSCORES, 

152 Feature.TRAILING_COMMA_IN_CALL, 

153 Feature.TRAILING_COMMA_IN_DEF, 

154 Feature.ASYNC_KEYWORDS, 

155 Feature.FUTURE_ANNOTATIONS, 

156 Feature.ASSIGNMENT_EXPRESSIONS, 

157 Feature.RELAXED_DECORATORS, 

158 Feature.POS_ONLY_ARGUMENTS, 

159 Feature.UNPACKING_ON_FLOW, 

160 Feature.ANN_ASSIGN_EXTENDED_RHS, 

161 Feature.PARENTHESIZED_CONTEXT_MANAGERS, 

162 Feature.PATTERN_MATCHING, 

163 Feature.EXCEPT_STAR, 

164 Feature.VARIADIC_GENERICS, 

165 Feature.TYPE_PARAMS, 

166 }, 

167} 

168 

169 

170def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> bool: 

171 return all(feature in VERSION_TO_FEATURES[version] for version in target_versions) 

172 

173 

174class Preview(Enum): 

175 """Individual preview style features.""" 

176 

177 add_trailing_comma_consistently = auto() 

178 blank_line_after_nested_stub_class = auto() 

179 hex_codes_in_unicode_sequences = auto() 

180 improved_async_statements_handling = auto() 

181 multiline_string_handling = auto() 

182 no_blank_line_before_class_docstring = auto() 

183 prefer_splitting_right_hand_side_of_assignments = auto() 

184 # NOTE: string_processing requires wrap_long_dict_values_in_parens 

185 # for https://github.com/psf/black/issues/3117 to be fixed. 

186 string_processing = auto() 

187 parenthesize_conditional_expressions = auto() 

188 skip_magic_trailing_comma_in_subscript = auto() 

189 wrap_long_dict_values_in_parens = auto() 

190 wrap_multiple_context_managers_in_parens = auto() 

191 

192 

193class Deprecated(UserWarning): 

194 """Visible deprecation warning.""" 

195 

196 

197@dataclass 

198class Mode: 

199 target_versions: Set[TargetVersion] = field(default_factory=set) 

200 line_length: int = DEFAULT_LINE_LENGTH 

201 string_normalization: bool = True 

202 is_pyi: bool = False 

203 is_ipynb: bool = False 

204 skip_source_first_line: bool = False 

205 magic_trailing_comma: bool = True 

206 experimental_string_processing: bool = False 

207 python_cell_magics: Set[str] = field(default_factory=set) 

208 preview: bool = False 

209 

210 def __post_init__(self) -> None: 

211 if self.experimental_string_processing: 

212 warn( 

213 "`experimental string processing` has been included in `preview`" 

214 " and deprecated. Use `preview` instead.", 

215 Deprecated, 

216 ) 

217 

218 def __contains__(self, feature: Preview) -> bool: 

219 """ 

220 Provide `Preview.FEATURE in Mode` syntax that mirrors the ``preview`` flag. 

221 

222 The argument is not checked and features are not differentiated. 

223 They only exist to make development easier by clarifying intent. 

224 """ 

225 if feature is Preview.string_processing: 

226 return self.preview or self.experimental_string_processing 

227 return self.preview 

228 

229 def get_cache_key(self) -> str: 

230 if self.target_versions: 

231 version_str = ",".join( 

232 str(version.value) 

233 for version in sorted(self.target_versions, key=attrgetter("value")) 

234 ) 

235 else: 

236 version_str = "-" 

237 parts = [ 

238 version_str, 

239 str(self.line_length), 

240 str(int(self.string_normalization)), 

241 str(int(self.is_pyi)), 

242 str(int(self.is_ipynb)), 

243 str(int(self.skip_source_first_line)), 

244 str(int(self.magic_trailing_comma)), 

245 str(int(self.experimental_string_processing)), 

246 str(int(self.preview)), 

247 sha256((",".join(sorted(self.python_cell_magics))).encode()).hexdigest(), 

248 ] 

249 return ".".join(parts)