X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/dc90d4951f66ac665582159537b902017d9a0361..257d392217974a76231e306133288748c7b70786:/src/black/mode.py diff --git a/src/black/mode.py b/src/black/mode.py index b28dcd8..4d979af 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -4,23 +4,17 @@ Mostly around Python language feature support per version and Black configuratio chosen by the user. """ -import sys - from dataclasses import dataclass, field -from enum import Enum +from enum import Enum, auto +from hashlib import sha256 from operator import attrgetter -from typing import Dict, Set - -if sys.version_info < (3, 8): - from typing_extensions import Final -else: - from typing import Final +from typing import Dict, Final, Set +from warnings import warn from black.const import DEFAULT_LINE_LENGTH class TargetVersion(Enum): - PY27 = 2 PY33 = 3 PY34 = 4 PY35 = 5 @@ -29,14 +23,11 @@ class TargetVersion(Enum): PY38 = 8 PY39 = 9 PY310 = 10 - - def is_python2(self) -> bool: - return self is TargetVersion.PY27 + PY311 = 11 + PY312 = 12 class Feature(Enum): - # All string literals are unicode - UNICODE_LITERALS = 1 F_STRINGS = 2 NUMERIC_UNDERSCORES = 3 TRAILING_COMMA_IN_CALL = 4 @@ -50,21 +41,17 @@ class Feature(Enum): RELAXED_DECORATORS = 10 PATTERN_MATCHING = 11 UNPACKING_ON_FLOW = 12 + ANN_ASSIGN_EXTENDED_RHS = 13 + EXCEPT_STAR = 14 + VARIADIC_GENERICS = 15 + DEBUG_F_STRINGS = 16 + PARENTHESIZED_CONTEXT_MANAGERS = 17 + TYPE_PARAMS = 18 FORCE_OPTIONAL_PARENTHESES = 50 # __future__ flags FUTURE_ANNOTATIONS = 51 - # temporary for Python 2 deprecation - PRINT_STMT = 200 - EXEC_STMT = 201 - AUTOMATIC_PARAMETER_UNPACKING = 202 - COMMA_STYLE_EXCEPT = 203 - COMMA_STYLE_RAISE = 204 - LONG_INT_LITERAL = 205 - OCTAL_INT_LITERAL = 206 - BACKQUOTE_REPR = 207 - FUTURE_FLAG_TO_FEATURE: Final = { "annotations": Feature.FUTURE_ANNOTATIONS, @@ -72,26 +59,10 @@ FUTURE_FLAG_TO_FEATURE: Final = { VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { - TargetVersion.PY27: { - Feature.ASYNC_IDENTIFIERS, - Feature.PRINT_STMT, - Feature.EXEC_STMT, - Feature.AUTOMATIC_PARAMETER_UNPACKING, - Feature.COMMA_STYLE_EXCEPT, - Feature.COMMA_STYLE_RAISE, - Feature.LONG_INT_LITERAL, - Feature.OCTAL_INT_LITERAL, - Feature.BACKQUOTE_REPR, - }, - TargetVersion.PY33: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS}, - TargetVersion.PY34: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS}, - TargetVersion.PY35: { - Feature.UNICODE_LITERALS, - Feature.TRAILING_COMMA_IN_CALL, - Feature.ASYNC_IDENTIFIERS, - }, + TargetVersion.PY33: {Feature.ASYNC_IDENTIFIERS}, + TargetVersion.PY34: {Feature.ASYNC_IDENTIFIERS}, + TargetVersion.PY35: {Feature.TRAILING_COMMA_IN_CALL, Feature.ASYNC_IDENTIFIERS}, TargetVersion.PY36: { - Feature.UNICODE_LITERALS, Feature.F_STRINGS, Feature.NUMERIC_UNDERSCORES, Feature.TRAILING_COMMA_IN_CALL, @@ -99,7 +70,6 @@ VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { Feature.ASYNC_IDENTIFIERS, }, TargetVersion.PY37: { - Feature.UNICODE_LITERALS, Feature.F_STRINGS, Feature.NUMERIC_UNDERSCORES, Feature.TRAILING_COMMA_IN_CALL, @@ -108,8 +78,8 @@ VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { Feature.FUTURE_ANNOTATIONS, }, TargetVersion.PY38: { - Feature.UNICODE_LITERALS, Feature.F_STRINGS, + Feature.DEBUG_F_STRINGS, Feature.NUMERIC_UNDERSCORES, Feature.TRAILING_COMMA_IN_CALL, Feature.TRAILING_COMMA_IN_DEF, @@ -118,10 +88,11 @@ VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { Feature.ASSIGNMENT_EXPRESSIONS, Feature.POS_ONLY_ARGUMENTS, Feature.UNPACKING_ON_FLOW, + Feature.ANN_ASSIGN_EXTENDED_RHS, }, TargetVersion.PY39: { - Feature.UNICODE_LITERALS, Feature.F_STRINGS, + Feature.DEBUG_F_STRINGS, Feature.NUMERIC_UNDERSCORES, Feature.TRAILING_COMMA_IN_CALL, Feature.TRAILING_COMMA_IN_DEF, @@ -131,10 +102,28 @@ VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { Feature.RELAXED_DECORATORS, Feature.POS_ONLY_ARGUMENTS, Feature.UNPACKING_ON_FLOW, + Feature.ANN_ASSIGN_EXTENDED_RHS, + Feature.PARENTHESIZED_CONTEXT_MANAGERS, }, TargetVersion.PY310: { - Feature.UNICODE_LITERALS, Feature.F_STRINGS, + Feature.DEBUG_F_STRINGS, + Feature.NUMERIC_UNDERSCORES, + Feature.TRAILING_COMMA_IN_CALL, + Feature.TRAILING_COMMA_IN_DEF, + Feature.ASYNC_KEYWORDS, + Feature.FUTURE_ANNOTATIONS, + Feature.ASSIGNMENT_EXPRESSIONS, + Feature.RELAXED_DECORATORS, + Feature.POS_ONLY_ARGUMENTS, + Feature.UNPACKING_ON_FLOW, + Feature.ANN_ASSIGN_EXTENDED_RHS, + Feature.PARENTHESIZED_CONTEXT_MANAGERS, + Feature.PATTERN_MATCHING, + }, + TargetVersion.PY311: { + Feature.F_STRINGS, + Feature.DEBUG_F_STRINGS, Feature.NUMERIC_UNDERSCORES, Feature.TRAILING_COMMA_IN_CALL, Feature.TRAILING_COMMA_IN_DEF, @@ -144,7 +133,30 @@ VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = { Feature.RELAXED_DECORATORS, Feature.POS_ONLY_ARGUMENTS, Feature.UNPACKING_ON_FLOW, + Feature.ANN_ASSIGN_EXTENDED_RHS, + Feature.PARENTHESIZED_CONTEXT_MANAGERS, Feature.PATTERN_MATCHING, + Feature.EXCEPT_STAR, + Feature.VARIADIC_GENERICS, + }, + TargetVersion.PY312: { + Feature.F_STRINGS, + Feature.DEBUG_F_STRINGS, + Feature.NUMERIC_UNDERSCORES, + Feature.TRAILING_COMMA_IN_CALL, + Feature.TRAILING_COMMA_IN_DEF, + Feature.ASYNC_KEYWORDS, + Feature.FUTURE_ANNOTATIONS, + Feature.ASSIGNMENT_EXPRESSIONS, + Feature.RELAXED_DECORATORS, + Feature.POS_ONLY_ARGUMENTS, + Feature.UNPACKING_ON_FLOW, + Feature.ANN_ASSIGN_EXTENDED_RHS, + Feature.PARENTHESIZED_CONTEXT_MANAGERS, + Feature.PATTERN_MATCHING, + Feature.EXCEPT_STAR, + Feature.VARIADIC_GENERICS, + Feature.TYPE_PARAMS, }, } @@ -153,6 +165,29 @@ def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> b return all(feature in VERSION_TO_FEATURES[version] for version in target_versions) +class Preview(Enum): + """Individual preview style features.""" + + add_trailing_comma_consistently = auto() + blank_line_after_nested_stub_class = auto() + hex_codes_in_unicode_sequences = auto() + improved_async_statements_handling = auto() + multiline_string_handling = auto() + no_blank_line_before_class_docstring = auto() + prefer_splitting_right_hand_side_of_assignments = auto() + # NOTE: string_processing requires wrap_long_dict_values_in_parens + # for https://github.com/psf/black/issues/3117 to be fixed. + string_processing = auto() + parenthesize_conditional_expressions = auto() + skip_magic_trailing_comma_in_subscript = auto() + wrap_long_dict_values_in_parens = auto() + wrap_multiple_context_managers_in_parens = auto() + + +class Deprecated(UserWarning): + """Visible deprecation warning.""" + + @dataclass class Mode: target_versions: Set[TargetVersion] = field(default_factory=set) @@ -160,8 +195,30 @@ class Mode: string_normalization: bool = True is_pyi: bool = False is_ipynb: bool = False + skip_source_first_line: bool = False magic_trailing_comma: bool = True experimental_string_processing: bool = False + python_cell_magics: Set[str] = field(default_factory=set) + preview: bool = False + + def __post_init__(self) -> None: + if self.experimental_string_processing: + warn( + "`experimental string processing` has been included in `preview`" + " and deprecated. Use `preview` instead.", + Deprecated, + ) + + def __contains__(self, feature: Preview) -> bool: + """ + Provide `Preview.FEATURE in Mode` syntax that mirrors the ``preview`` flag. + + The argument is not checked and features are not differentiated. + They only exist to make development easier by clarifying intent. + """ + if feature is Preview.string_processing: + return self.preview or self.experimental_string_processing + return self.preview def get_cache_key(self) -> str: if self.target_versions: @@ -177,7 +234,10 @@ class Mode: str(int(self.string_normalization)), str(int(self.is_pyi)), str(int(self.is_ipynb)), + str(int(self.skip_source_first_line)), str(int(self.magic_trailing_comma)), str(int(self.experimental_string_processing)), + str(int(self.preview)), + sha256((",".join(sorted(self.python_cell_magics))).encode()).hexdigest(), ] return ".".join(parts)