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
 
   8 from dataclasses import dataclass, field
 
   9 from enum import Enum, auto
 
  10 from hashlib import sha256
 
  11 from operator import attrgetter
 
  12 from typing import Dict, Set
 
  13 from warnings import warn
 
  15 if sys.version_info < (3, 8):
 
  16     from typing_extensions import Final
 
  18     from typing import Final
 
  20 from black.const import DEFAULT_LINE_LENGTH
 
  23 class TargetVersion(Enum):
 
  37     NUMERIC_UNDERSCORES = 3
 
  38     TRAILING_COMMA_IN_CALL = 4
 
  39     TRAILING_COMMA_IN_DEF = 5
 
  40     # The following two feature-flags are mutually exclusive, and exactly one should be
 
  41     # set for every version of python.
 
  44     ASSIGNMENT_EXPRESSIONS = 8
 
  45     POS_ONLY_ARGUMENTS = 9
 
  46     RELAXED_DECORATORS = 10
 
  48     UNPACKING_ON_FLOW = 12
 
  49     ANN_ASSIGN_EXTENDED_RHS = 13
 
  51     VARIADIC_GENERICS = 15
 
  53     FORCE_OPTIONAL_PARENTHESES = 50
 
  56     FUTURE_ANNOTATIONS = 51
 
  59 FUTURE_FLAG_TO_FEATURE: Final = {
 
  60     "annotations": Feature.FUTURE_ANNOTATIONS,
 
  64 VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
 
  65     TargetVersion.PY33: {Feature.ASYNC_IDENTIFIERS},
 
  66     TargetVersion.PY34: {Feature.ASYNC_IDENTIFIERS},
 
  67     TargetVersion.PY35: {Feature.TRAILING_COMMA_IN_CALL, Feature.ASYNC_IDENTIFIERS},
 
  70         Feature.NUMERIC_UNDERSCORES,
 
  71         Feature.TRAILING_COMMA_IN_CALL,
 
  72         Feature.TRAILING_COMMA_IN_DEF,
 
  73         Feature.ASYNC_IDENTIFIERS,
 
  77         Feature.NUMERIC_UNDERSCORES,
 
  78         Feature.TRAILING_COMMA_IN_CALL,
 
  79         Feature.TRAILING_COMMA_IN_DEF,
 
  80         Feature.ASYNC_KEYWORDS,
 
  81         Feature.FUTURE_ANNOTATIONS,
 
  85         Feature.DEBUG_F_STRINGS,
 
  86         Feature.NUMERIC_UNDERSCORES,
 
  87         Feature.TRAILING_COMMA_IN_CALL,
 
  88         Feature.TRAILING_COMMA_IN_DEF,
 
  89         Feature.ASYNC_KEYWORDS,
 
  90         Feature.FUTURE_ANNOTATIONS,
 
  91         Feature.ASSIGNMENT_EXPRESSIONS,
 
  92         Feature.POS_ONLY_ARGUMENTS,
 
  93         Feature.UNPACKING_ON_FLOW,
 
  94         Feature.ANN_ASSIGN_EXTENDED_RHS,
 
  98         Feature.DEBUG_F_STRINGS,
 
  99         Feature.NUMERIC_UNDERSCORES,
 
 100         Feature.TRAILING_COMMA_IN_CALL,
 
 101         Feature.TRAILING_COMMA_IN_DEF,
 
 102         Feature.ASYNC_KEYWORDS,
 
 103         Feature.FUTURE_ANNOTATIONS,
 
 104         Feature.ASSIGNMENT_EXPRESSIONS,
 
 105         Feature.RELAXED_DECORATORS,
 
 106         Feature.POS_ONLY_ARGUMENTS,
 
 107         Feature.UNPACKING_ON_FLOW,
 
 108         Feature.ANN_ASSIGN_EXTENDED_RHS,
 
 110     TargetVersion.PY310: {
 
 112         Feature.DEBUG_F_STRINGS,
 
 113         Feature.NUMERIC_UNDERSCORES,
 
 114         Feature.TRAILING_COMMA_IN_CALL,
 
 115         Feature.TRAILING_COMMA_IN_DEF,
 
 116         Feature.ASYNC_KEYWORDS,
 
 117         Feature.FUTURE_ANNOTATIONS,
 
 118         Feature.ASSIGNMENT_EXPRESSIONS,
 
 119         Feature.RELAXED_DECORATORS,
 
 120         Feature.POS_ONLY_ARGUMENTS,
 
 121         Feature.UNPACKING_ON_FLOW,
 
 122         Feature.ANN_ASSIGN_EXTENDED_RHS,
 
 123         Feature.PATTERN_MATCHING,
 
 125     TargetVersion.PY311: {
 
 127         Feature.DEBUG_F_STRINGS,
 
 128         Feature.NUMERIC_UNDERSCORES,
 
 129         Feature.TRAILING_COMMA_IN_CALL,
 
 130         Feature.TRAILING_COMMA_IN_DEF,
 
 131         Feature.ASYNC_KEYWORDS,
 
 132         Feature.FUTURE_ANNOTATIONS,
 
 133         Feature.ASSIGNMENT_EXPRESSIONS,
 
 134         Feature.RELAXED_DECORATORS,
 
 135         Feature.POS_ONLY_ARGUMENTS,
 
 136         Feature.UNPACKING_ON_FLOW,
 
 137         Feature.ANN_ASSIGN_EXTENDED_RHS,
 
 138         Feature.PATTERN_MATCHING,
 
 140         Feature.VARIADIC_GENERICS,
 
 145 def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> bool:
 
 146     return all(feature in VERSION_TO_FEATURES[version] for version in target_versions)
 
 150     """Individual preview style features."""
 
 152     annotation_parens = auto()
 
 153     empty_lines_before_class_or_def_with_leading_comments = auto()
 
 154     handle_trailing_commas_in_head = auto()
 
 155     long_docstring_quotes_on_newline = auto()
 
 156     normalize_docstring_quotes_and_prefixes_properly = auto()
 
 157     one_element_subscript = auto()
 
 158     prefer_splitting_right_hand_side_of_assignments = auto()
 
 159     remove_block_trailing_newline = auto()
 
 160     remove_redundant_parens = auto()
 
 161     # NOTE: string_processing requires wrap_long_dict_values_in_parens
 
 162     # for https://github.com/psf/black/issues/3117 to be fixed.
 
 163     string_processing = auto()
 
 164     skip_magic_trailing_comma_in_subscript = auto()
 
 165     wrap_long_dict_values_in_parens = auto()
 
 168 class Deprecated(UserWarning):
 
 169     """Visible deprecation warning."""
 
 174     target_versions: Set[TargetVersion] = field(default_factory=set)
 
 175     line_length: int = DEFAULT_LINE_LENGTH
 
 176     string_normalization: bool = True
 
 178     is_ipynb: bool = False
 
 179     skip_source_first_line: bool = False
 
 180     magic_trailing_comma: bool = True
 
 181     experimental_string_processing: bool = False
 
 182     python_cell_magics: Set[str] = field(default_factory=set)
 
 183     preview: bool = False
 
 185     def __post_init__(self) -> None:
 
 186         if self.experimental_string_processing:
 
 189                     "`experimental string processing` has been included in `preview`"
 
 190                     " and deprecated. Use `preview` instead."
 
 195     def __contains__(self, feature: Preview) -> bool:
 
 197         Provide `Preview.FEATURE in Mode` syntax that mirrors the ``preview`` flag.
 
 199         The argument is not checked and features are not differentiated.
 
 200         They only exist to make development easier by clarifying intent.
 
 202         if feature is Preview.string_processing:
 
 203             return self.preview or self.experimental_string_processing
 
 206     def get_cache_key(self) -> str:
 
 207         if self.target_versions:
 
 208             version_str = ",".join(
 
 210                 for version in sorted(self.target_versions, key=attrgetter("value"))
 
 216             str(self.line_length),
 
 217             str(int(self.string_normalization)),
 
 218             str(int(self.is_pyi)),
 
 219             str(int(self.is_ipynb)),
 
 220             str(int(self.skip_source_first_line)),
 
 221             str(int(self.magic_trailing_comma)),
 
 222             str(int(self.experimental_string_processing)),
 
 223             str(int(self.preview)),
 
 224             sha256((",".join(sorted(self.python_cell_magics))).encode()).hexdigest(),
 
 226         return ".".join(parts)