All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 """Data structures configuring Black behavior.
3 Mostly around Python language feature support per version and Black configuration
7 from dataclasses import dataclass, field
9 from operator import attrgetter
10 from typing import Dict, Set
12 from black.const import DEFAULT_LINE_LENGTH
15 class TargetVersion(Enum):
26 def is_python2(self) -> bool:
27 return self is TargetVersion.PY27
31 # All string literals are unicode
34 NUMERIC_UNDERSCORES = 3
35 TRAILING_COMMA_IN_CALL = 4
36 TRAILING_COMMA_IN_DEF = 5
37 # The following two feature-flags are mutually exclusive, and exactly one should be
38 # set for every version of python.
41 ASSIGNMENT_EXPRESSIONS = 8
42 POS_ONLY_ARGUMENTS = 9
43 RELAXED_DECORATORS = 10
45 FORCE_OPTIONAL_PARENTHESES = 50
47 # temporary for Python 2 deprecation
50 AUTOMATIC_PARAMETER_UNPACKING = 202
51 COMMA_STYLE_EXCEPT = 203
52 COMMA_STYLE_RAISE = 204
53 LONG_INT_LITERAL = 205
54 OCTAL_INT_LITERAL = 206
58 VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
60 Feature.ASYNC_IDENTIFIERS,
63 Feature.AUTOMATIC_PARAMETER_UNPACKING,
64 Feature.COMMA_STYLE_EXCEPT,
65 Feature.COMMA_STYLE_RAISE,
66 Feature.LONG_INT_LITERAL,
67 Feature.OCTAL_INT_LITERAL,
68 Feature.BACKQUOTE_REPR,
70 TargetVersion.PY33: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
71 TargetVersion.PY34: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
73 Feature.UNICODE_LITERALS,
74 Feature.TRAILING_COMMA_IN_CALL,
75 Feature.ASYNC_IDENTIFIERS,
78 Feature.UNICODE_LITERALS,
80 Feature.NUMERIC_UNDERSCORES,
81 Feature.TRAILING_COMMA_IN_CALL,
82 Feature.TRAILING_COMMA_IN_DEF,
83 Feature.ASYNC_IDENTIFIERS,
86 Feature.UNICODE_LITERALS,
88 Feature.NUMERIC_UNDERSCORES,
89 Feature.TRAILING_COMMA_IN_CALL,
90 Feature.TRAILING_COMMA_IN_DEF,
91 Feature.ASYNC_KEYWORDS,
94 Feature.UNICODE_LITERALS,
96 Feature.NUMERIC_UNDERSCORES,
97 Feature.TRAILING_COMMA_IN_CALL,
98 Feature.TRAILING_COMMA_IN_DEF,
99 Feature.ASYNC_KEYWORDS,
100 Feature.ASSIGNMENT_EXPRESSIONS,
101 Feature.POS_ONLY_ARGUMENTS,
103 TargetVersion.PY39: {
104 Feature.UNICODE_LITERALS,
106 Feature.NUMERIC_UNDERSCORES,
107 Feature.TRAILING_COMMA_IN_CALL,
108 Feature.TRAILING_COMMA_IN_DEF,
109 Feature.ASYNC_KEYWORDS,
110 Feature.ASSIGNMENT_EXPRESSIONS,
111 Feature.RELAXED_DECORATORS,
112 Feature.POS_ONLY_ARGUMENTS,
114 TargetVersion.PY310: {
115 Feature.UNICODE_LITERALS,
117 Feature.NUMERIC_UNDERSCORES,
118 Feature.TRAILING_COMMA_IN_CALL,
119 Feature.TRAILING_COMMA_IN_DEF,
120 Feature.ASYNC_KEYWORDS,
121 Feature.ASSIGNMENT_EXPRESSIONS,
122 Feature.RELAXED_DECORATORS,
123 Feature.POS_ONLY_ARGUMENTS,
124 Feature.PATTERN_MATCHING,
129 def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> bool:
130 return all(feature in VERSION_TO_FEATURES[version] for version in target_versions)
135 target_versions: Set[TargetVersion] = field(default_factory=set)
136 line_length: int = DEFAULT_LINE_LENGTH
137 string_normalization: bool = True
139 is_ipynb: bool = False
140 magic_trailing_comma: bool = True
141 experimental_string_processing: bool = False
143 def get_cache_key(self) -> str:
144 if self.target_versions:
145 version_str = ",".join(
147 for version in sorted(self.target_versions, key=attrgetter("value"))
153 str(self.line_length),
154 str(int(self.string_normalization)),
155 str(int(self.is_pyi)),
156 str(int(self.is_ipynb)),
157 str(int(self.magic_trailing_comma)),
158 str(int(self.experimental_string_processing)),
160 return ".".join(parts)