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
9 from dataclasses import dataclass, field
11 from operator import attrgetter
12 from typing import Dict, Set
14 if sys.version_info < (3, 8):
15 from typing_extensions import Final
17 from typing import Final
19 from black.const import DEFAULT_LINE_LENGTH
22 class TargetVersion(Enum):
35 NUMERIC_UNDERSCORES = 3
36 TRAILING_COMMA_IN_CALL = 4
37 TRAILING_COMMA_IN_DEF = 5
38 # The following two feature-flags are mutually exclusive, and exactly one should be
39 # set for every version of python.
42 ASSIGNMENT_EXPRESSIONS = 8
43 POS_ONLY_ARGUMENTS = 9
44 RELAXED_DECORATORS = 10
46 UNPACKING_ON_FLOW = 12
47 ANN_ASSIGN_EXTENDED_RHS = 13
48 FORCE_OPTIONAL_PARENTHESES = 50
51 FUTURE_ANNOTATIONS = 51
54 FUTURE_FLAG_TO_FEATURE: Final = {
55 "annotations": Feature.FUTURE_ANNOTATIONS,
59 VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
60 TargetVersion.PY33: {Feature.ASYNC_IDENTIFIERS},
61 TargetVersion.PY34: {Feature.ASYNC_IDENTIFIERS},
62 TargetVersion.PY35: {Feature.TRAILING_COMMA_IN_CALL, Feature.ASYNC_IDENTIFIERS},
65 Feature.NUMERIC_UNDERSCORES,
66 Feature.TRAILING_COMMA_IN_CALL,
67 Feature.TRAILING_COMMA_IN_DEF,
68 Feature.ASYNC_IDENTIFIERS,
72 Feature.NUMERIC_UNDERSCORES,
73 Feature.TRAILING_COMMA_IN_CALL,
74 Feature.TRAILING_COMMA_IN_DEF,
75 Feature.ASYNC_KEYWORDS,
76 Feature.FUTURE_ANNOTATIONS,
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 Feature.ASSIGNMENT_EXPRESSIONS,
86 Feature.POS_ONLY_ARGUMENTS,
87 Feature.UNPACKING_ON_FLOW,
88 Feature.ANN_ASSIGN_EXTENDED_RHS,
92 Feature.NUMERIC_UNDERSCORES,
93 Feature.TRAILING_COMMA_IN_CALL,
94 Feature.TRAILING_COMMA_IN_DEF,
95 Feature.ASYNC_KEYWORDS,
96 Feature.FUTURE_ANNOTATIONS,
97 Feature.ASSIGNMENT_EXPRESSIONS,
98 Feature.RELAXED_DECORATORS,
99 Feature.POS_ONLY_ARGUMENTS,
100 Feature.UNPACKING_ON_FLOW,
101 Feature.ANN_ASSIGN_EXTENDED_RHS,
103 TargetVersion.PY310: {
105 Feature.NUMERIC_UNDERSCORES,
106 Feature.TRAILING_COMMA_IN_CALL,
107 Feature.TRAILING_COMMA_IN_DEF,
108 Feature.ASYNC_KEYWORDS,
109 Feature.FUTURE_ANNOTATIONS,
110 Feature.ASSIGNMENT_EXPRESSIONS,
111 Feature.RELAXED_DECORATORS,
112 Feature.POS_ONLY_ARGUMENTS,
113 Feature.UNPACKING_ON_FLOW,
114 Feature.ANN_ASSIGN_EXTENDED_RHS,
115 Feature.PATTERN_MATCHING,
120 def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> bool:
121 return all(feature in VERSION_TO_FEATURES[version] for version in target_versions)
126 target_versions: Set[TargetVersion] = field(default_factory=set)
127 line_length: int = DEFAULT_LINE_LENGTH
128 string_normalization: bool = True
130 is_ipynb: bool = False
131 magic_trailing_comma: bool = True
132 experimental_string_processing: bool = False
134 def get_cache_key(self) -> str:
135 if self.target_versions:
136 version_str = ",".join(
138 for version in sorted(self.target_versions, key=attrgetter("value"))
144 str(self.line_length),
145 str(int(self.string_normalization)),
146 str(int(self.is_pyi)),
147 str(int(self.is_ipynb)),
148 str(int(self.magic_trailing_comma)),
149 str(int(self.experimental_string_processing)),
151 return ".".join(parts)