diff --git a/CHANGES.md b/CHANGES.md index f29834a3f7f..0e2974d706e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,22 +6,54 @@ +This release introduces the new 2024 stable style (#4106), stabilizing the following +changes: + +- Add parentheses around `if`-`else` expressions (#2278) +- Dummy class and function implementations consisting only of `...` are formatted more + compactly (#3796) +- If an assignment statement is too long, we now prefer splitting on the right-hand side + (#3368) +- Hex codes in Unicode escape sequences are now standardized to lowercase (#2916) +- Allow empty first lines at the beginning of most blocks (#3967, #4061) +- Add parentheses around long type annotations (#3899) +- Standardize on a single newline after module docstrings (#3932) +- Fix incorrect magic trailing comma handling in return types (#3916) +- Remove blank lines before class docstrings (#3692) +- Wrap multiple context managers in parentheses if combined in a single `with` statement + (#3489) +- Fix bug in line length calculations for power operations (#3942) +- Add trailing commas to collection literals even if there's a comment after the last + entry (#3393) +- When using `--skip-magic-trailing-comma` or `-C`, trailing commas are stripped from + subscript expressions with more than 1 element (#3209) +- Add extra blank lines in stubs in a few cases (#3564, #3862) +- Accept raw strings as docstrings (#3947) +- Split long lines in case blocks (#4024) +- Stop removing spaces from walrus operators within subscripts (#3823) +- Fix incorrect formatting of certain async statements (#3609) +- Allow combining `# fmt: skip` with other comments (#3959) + ### Stable style -### Preview style - - +Several bug fixes were made in features that are moved to the stable style in this +release: - Fix comment handling when parenthesising conditional expressions (#4134) -- Format module docstrings the same as class and function docstrings (#4095) - Fix bug where spaces were not added around parenthesized walruses in subscripts, unlike other binary operators (#4109) - Remove empty lines before docstrings in async functions (#4132) - Address a missing case in the change to allow empty lines at the beginning of all blocks, except immediately before a docstring (#4130) - For stubs, fix logic to enforce empty line after nested classes with bodies (#4141) + +### Preview style + + + +- Format module docstrings the same as class and function docstrings (#4095) - Fix crash when using a walrus in a dictionary (#4155) - Fix unnecessary parentheses when wrapping long dicts (#4135) diff --git a/src/black/comments.py b/src/black/comments.py index 52bb024a799..910e1b760f0 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -3,7 +3,7 @@ from functools import lru_cache from typing import Collection, Final, Iterator, List, Optional, Tuple, Union -from black.mode import Mode, Preview +from black.mode import Mode from black.nodes import ( CLOSING_BRACKETS, STANDALONE_COMMENT, @@ -390,22 +390,18 @@ def _contains_fmt_skip_comment(comment_line: str, mode: Mode) -> bool: # noqa:XXX # fmt:skip # a nice line <-- multiple comments (Preview) # pylint:XXX; fmt:skip <-- list of comments (; separated, Preview) """ - semantic_comment_blocks = ( - [ - comment_line, - *[ - _COMMENT_PREFIX + comment.strip() - for comment in comment_line.split(_COMMENT_PREFIX)[1:] - ], - *[ - _COMMENT_PREFIX + comment.strip() - for comment in comment_line.strip(_COMMENT_PREFIX).split( - _COMMENT_LIST_SEPARATOR - ) - ], - ] - if Preview.single_line_format_skip_with_multiple_comments in mode - else [comment_line] - ) + semantic_comment_blocks = [ + comment_line, + *[ + _COMMENT_PREFIX + comment.strip() + for comment in comment_line.split(_COMMENT_PREFIX)[1:] + ], + *[ + _COMMENT_PREFIX + comment.strip() + for comment in comment_line.strip(_COMMENT_PREFIX).split( + _COMMENT_LIST_SEPARATOR + ) + ], + ] return any(comment in FMT_SKIP for comment in semantic_comment_blocks) diff --git a/src/black/linegen.py b/src/black/linegen.py index dd296eb801d..a276805f2fe 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -115,10 +115,8 @@ def line(self, indent: int = 0) -> Iterator[Line]: self.current_line.depth += indent return # Line is empty, don't emit. Creating a new one unnecessary. - if ( - Preview.improved_async_statements_handling in self.mode - and len(self.current_line.leaves) == 1 - and is_async_stmt_or_funcdef(self.current_line.leaves[0]) + if len(self.current_line.leaves) == 1 and is_async_stmt_or_funcdef( + self.current_line.leaves[0] ): # Special case for async def/for/with statements. `visit_async_stmt` # adds an `ASYNC` leaf then visits the child def/for/with statement @@ -164,20 +162,19 @@ def visit_default(self, node: LN) -> Iterator[Line]: def visit_test(self, node: Node) -> Iterator[Line]: """Visit an `x if y else z` test""" - if Preview.parenthesize_conditional_expressions in self.mode: - already_parenthesized = ( - node.prev_sibling and node.prev_sibling.type == token.LPAR - ) + already_parenthesized = ( + node.prev_sibling and node.prev_sibling.type == token.LPAR + ) - if not already_parenthesized: - # Similar to logic in wrap_in_parentheses - lpar = Leaf(token.LPAR, "") - rpar = Leaf(token.RPAR, "") - prefix = node.prefix - node.prefix = "" - lpar.prefix = prefix - node.insert_child(0, lpar) - node.append_child(rpar) + if not already_parenthesized: + # Similar to logic in wrap_in_parentheses + lpar = Leaf(token.LPAR, "") + rpar = Leaf(token.RPAR, "") + prefix = node.prefix + node.prefix = "" + lpar.prefix = prefix + node.insert_child(0, lpar) + node.append_child(rpar) yield from self.visit_default(node) @@ -292,9 +289,7 @@ def visit_match_case(self, node: Node) -> Iterator[Line]: def visit_suite(self, node: Node) -> Iterator[Line]: """Visit a suite.""" - if ( - self.mode.is_pyi or Preview.dummy_implementations in self.mode - ) and is_stub_suite(node, self.mode): + if is_stub_suite(node): yield from self.visit(node.children[2]) else: yield from self.visit_default(node) @@ -308,11 +303,7 @@ def visit_simple_stmt(self, node: Node) -> Iterator[Line]: prev_type = child.type if node.parent and node.parent.type in STATEMENT: - if Preview.dummy_implementations in self.mode: - condition = is_parent_function_or_class(node) - else: - condition = self.mode.is_pyi - if condition and is_stub_body(node): + if is_parent_function_or_class(node) and is_stub_body(node): yield from self.visit_default(node) else: yield from self.line(+1) @@ -320,11 +311,7 @@ def visit_simple_stmt(self, node: Node) -> Iterator[Line]: yield from self.line(-1) else: - if ( - not (self.mode.is_pyi or Preview.dummy_implementations in self.mode) - or not node.parent - or not is_stub_suite(node.parent, self.mode) - ): + if not node.parent or not is_stub_suite(node.parent): yield from self.line() yield from self.visit_default(node) @@ -342,11 +329,7 @@ def visit_async_stmt(self, node: Node) -> Iterator[Line]: break internal_stmt = next(children) - if Preview.improved_async_statements_handling in self.mode: - yield from self.visit(internal_stmt) - else: - for child in internal_stmt.children: - yield from self.visit(child) + yield from self.visit(internal_stmt) def visit_decorators(self, node: Node) -> Iterator[Line]: """Visit decorators.""" @@ -420,10 +403,9 @@ def foo(a: int, b: float = 7): ... def foo(a: (int), b: (float) = 7): ... """ - if Preview.parenthesize_long_type_hints in self.mode: - assert len(node.children) == 3 - if maybe_make_parens_invisible_in_atom(node.children[2], parent=node): - wrap_in_parentheses(node, node.children[2], visible=False) + assert len(node.children) == 3 + if maybe_make_parens_invisible_in_atom(node.children[2], parent=node): + wrap_in_parentheses(node, node.children[2], visible=False) yield from self.visit_default(node) @@ -529,13 +511,7 @@ def __post_init__(self) -> None: self.visit_with_stmt = partial(v, keywords={"with"}, parens={"with"}) self.visit_classdef = partial(v, keywords={"class"}, parens=Ø) - # When this is moved out of preview, add ":" directly to ASSIGNMENTS in nodes.py - if Preview.parenthesize_long_type_hints in self.mode: - assignments = ASSIGNMENTS | {":"} - else: - assignments = ASSIGNMENTS - self.visit_expr_stmt = partial(v, keywords=Ø, parens=assignments) - + self.visit_expr_stmt = partial(v, keywords=Ø, parens=ASSIGNMENTS) self.visit_return_stmt = partial(v, keywords={"return"}, parens={"return"}) self.visit_import_from = partial(v, keywords=Ø, parens={"import"}) self.visit_del_stmt = partial(v, keywords=Ø, parens={"del"}) @@ -576,9 +552,7 @@ def transform_line( # We need the line string when power operators are hugging to determine if we should # split the line. Default to line_str, if no power operator are present on the line. line_str_hugging_power_ops = ( - (_hugging_power_ops_line_to_string(line, features, mode) or line_str) - if Preview.fix_power_op_line_length in mode - else line_str + _hugging_power_ops_line_to_string(line, features, mode) or line_str ) ll = mode.line_length @@ -688,9 +662,6 @@ def should_split_funcdef_with_rhs(line: Line, mode: Mode) -> bool: """If a funcdef has a magic trailing comma in the return type, then we should first split the line with rhs to respect the comma. """ - if Preview.respect_magic_trailing_comma_in_return_type not in mode: - return False - return_type_leaves: List[Leaf] = [] in_return_type = False @@ -919,9 +890,6 @@ def _maybe_split_omitting_optional_parens( try: # The RHSResult Omitting Optional Parens. rhs_oop = _first_right_hand_split(line, omit=omit) - prefer_splitting_rhs_mode = ( - Preview.prefer_splitting_right_hand_side_of_assignments in line.mode - ) is_split_right_after_equal = ( len(rhs.head.leaves) >= 2 and rhs.head.leaves[-2].type == token.EQUAL ) @@ -937,8 +905,7 @@ def _maybe_split_omitting_optional_parens( ) if ( not ( - prefer_splitting_rhs_mode - and is_split_right_after_equal + is_split_right_after_equal and rhs_head_contains_brackets and rhs_head_short_enough and rhs_head_explode_blocked_by_magic_trailing_comma @@ -1224,11 +1191,7 @@ def append_to_line(leaf: Leaf) -> Iterator[Line]: trailing_comma_safe and Feature.TRAILING_COMMA_IN_CALL in features ) - if ( - Preview.add_trailing_comma_consistently in mode - and last_leaf.type == STANDALONE_COMMENT - and leaf_idx == last_non_comment_leaf - ): + if last_leaf.type == STANDALONE_COMMENT and leaf_idx == last_non_comment_leaf: current_line = _safe_add_trailing_comma( trailing_comma_safe, delimiter_priority, current_line ) @@ -1315,11 +1278,7 @@ def normalize_invisible_parens( # noqa: C901 # Fixes a bug where invisible parens are not properly wrapped around # case blocks. - if ( - isinstance(child, Node) - and child.type == syms.case_block - and Preview.long_case_block_line_splitting in mode - ): + if isinstance(child, Node) and child.type == syms.case_block: normalize_invisible_parens( child, parens_after={"case"}, mode=mode, features=features ) @@ -1374,7 +1333,6 @@ def normalize_invisible_parens( # noqa: C901 and child.next_sibling is not None and child.next_sibling.type == token.COLON and child.value == "case" - and Preview.long_case_block_line_splitting in mode ): # A special patch for "case case:" scenario, the second occurrence # of case will be not parsed as a Python keyword. @@ -1448,7 +1406,6 @@ def _maybe_wrap_cms_in_parens( """ if ( Feature.PARENTHESIZED_CONTEXT_MANAGERS not in features - or Preview.wrap_multiple_context_managers_in_parens not in mode or len(node.children) <= 2 # If it's an atom, it's already wrapped in parens. or node.children[1].type == syms.atom diff --git a/src/black/lines.py b/src/black/lines.py index 9eb5785da57..29f87137614 100644 --- a/src/black/lines.py +++ b/src/black/lines.py @@ -202,9 +202,7 @@ def _is_triple_quoted_string(self) -> bool: value = self.leaves[0].value if value.startswith(('"""', "'''")): return True - if Preview.accept_raw_docstrings in self.mode and value.startswith( - ("r'''", 'r"""', "R'''", 'R"""') - ): + if value.startswith(("r'''", 'r"""', "R'''", 'R"""')): return True return False @@ -450,14 +448,8 @@ def is_complex_subscript(self, leaf: Leaf) -> bool: if subscript_start.type == syms.subscriptlist: subscript_start = child_towards(subscript_start, leaf) - # When this is moved out of preview, add syms.namedexpr_test directly to - # TEST_DESCENDANTS in nodes.py - if Preview.walrus_subscript in self.mode: - test_decendants = TEST_DESCENDANTS | {syms.namedexpr_test} - else: - test_decendants = TEST_DESCENDANTS return subscript_start is not None and any( - n.type in test_decendants for n in subscript_start.pre_order() + n.type in TEST_DESCENDANTS for n in subscript_start.pre_order() ) def enumerate_with_length( @@ -567,8 +559,7 @@ def maybe_empty_lines(self, current_line: Line) -> LinesBlock: lines (two on module-level). """ form_feed = ( - Preview.allow_form_feeds in self.mode - and current_line.depth == 0 + current_line.depth == 0 and bool(current_line.leaves) and "\f\n" in current_line.leaves[0].prefix ) @@ -582,8 +573,7 @@ def maybe_empty_lines(self, current_line: Line) -> LinesBlock: else before - previous_after ) if ( - Preview.module_docstring_newlines in current_line.mode - and self.previous_block + self.previous_block and self.previous_block.previous_block is None and len(self.previous_block.original_line.leaves) == 1 and self.previous_block.original_line.is_docstring @@ -640,11 +630,7 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: if previous_def is not None: assert self.previous_line is not None if self.mode.is_pyi: - if ( - Preview.blank_line_after_nested_stub_class in self.mode - and previous_def.is_class - and not previous_def.is_stub_class - ): + if previous_def.is_class and not previous_def.is_stub_class: before = 1 elif depth and not current_line.is_def and self.previous_line.is_def: # Empty lines between attributes and methods should be preserved. @@ -695,18 +681,12 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: and self.previous_line.is_class and current_line.is_docstring ): - if Preview.no_blank_line_before_class_docstring in current_line.mode: - return 0, 1 - return before, 1 + return 0, 1 # In preview mode, always allow blank lines, except right before a function # docstring - is_empty_first_line_ok = ( - Preview.allow_empty_first_line_in_block in current_line.mode - and ( - not current_line.is_docstring - or (self.previous_line and not self.previous_line.is_def) - ) + is_empty_first_line_ok = not current_line.is_docstring or ( + self.previous_line and not self.previous_line.is_def ) if ( @@ -736,7 +716,7 @@ def _maybe_empty_lines_for_class_or_def( # noqa: C901 if self.previous_line.depth < current_line.depth and ( self.previous_line.is_class or self.previous_line.is_def ): - if self.mode.is_pyi or not Preview.allow_empty_first_line_in_block: + if self.mode.is_pyi: return 0, 0 else: return 1 if user_had_newline else 0, 0 @@ -776,10 +756,7 @@ def _maybe_empty_lines_for_class_or_def( # noqa: C901 # Don't inspect the previous line if it's part of the body of the previous # statement in the same level, we always want a blank line if there's # something with a body preceding. - elif ( - Preview.blank_line_between_nested_and_def_stub_file in current_line.mode - and self.previous_line.depth > current_line.depth - ): + elif self.previous_line.depth > current_line.depth: newlines = 1 elif ( current_line.is_def or current_line.is_decorator @@ -800,11 +777,7 @@ def _maybe_empty_lines_for_class_or_def( # noqa: C901 newlines = 1 if current_line.depth else 2 # If a user has left no space after a dummy implementation, don't insert # new lines. This is useful for instance for @overload or Protocols. - if ( - Preview.dummy_implementations in self.mode - and self.previous_line.is_stub_def - and not user_had_newline - ): + if self.previous_line.is_stub_def and not user_had_newline: newlines = 0 if comment_to_add_newlines is not None: previous_block = comment_to_add_newlines.previous_block @@ -859,11 +832,9 @@ def is_line_short_enough( # noqa: C901 if not line_str: line_str = line_to_string(line) - width = str_width if Preview.respect_east_asian_width in mode else len - if Preview.multiline_string_handling not in mode: return ( - width(line_str) <= mode.line_length + str_width(line_str) <= mode.line_length and "\n" not in line_str # multiline strings and not line.contains_standalone_comments() ) @@ -872,10 +843,10 @@ def is_line_short_enough( # noqa: C901 return False if "\n" not in line_str: # No multiline strings (MLS) present - return width(line_str) <= mode.line_length + return str_width(line_str) <= mode.line_length first, *_, last = line_str.split("\n") - if width(first) > mode.line_length or width(last) > mode.line_length: + if str_width(first) > mode.line_length or str_width(last) > mode.line_length: return False # Traverse the AST to examine the context of the multiline string (MLS), @@ -1015,11 +986,7 @@ def can_omit_invisible_parens( return False if delimiter_count == 1: - if ( - Preview.wrap_multiple_context_managers_in_parens in line.mode - and max_priority == COMMA_PRIORITY - and rhs.head.is_with_or_async_with_stmt - ): + if max_priority == COMMA_PRIORITY and rhs.head.is_with_or_async_with_stmt: # For two context manager with statements, the optional parentheses read # better. In this case, `rhs.body` is the context managers part of # the with statement. `rhs.head` is the `with (` part on the previous diff --git a/src/black/mode.py b/src/black/mode.py index 466b78228fc..1b97f3508ee 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -168,35 +168,14 @@ def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> b class Preview(Enum): """Individual preview style features.""" - add_trailing_comma_consistently = auto() - blank_line_after_nested_stub_class = auto() - blank_line_between_nested_and_def_stub_file = 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() - parenthesize_long_type_hints = auto() - respect_magic_trailing_comma_in_return_type = auto() - skip_magic_trailing_comma_in_subscript = auto() - wrap_long_dict_values_in_parens = auto() - wrap_multiple_context_managers_in_parens = auto() - dummy_implementations = auto() - walrus_subscript = auto() - module_docstring_newlines = auto() - accept_raw_docstrings = auto() - fix_power_op_line_length = auto() hug_parens_with_braces_and_square_brackets = auto() - allow_empty_first_line_in_block = auto() - single_line_format_skip_with_multiple_comments = auto() - long_case_block_line_splitting = auto() - allow_form_feeds = auto() unify_docstring_detection = auto() - respect_east_asian_width = auto() + wrap_long_dict_values_in_parens = auto() + multiline_string_handling = auto() class Deprecated(UserWarning): diff --git a/src/black/nodes.py b/src/black/nodes.py index 7ee2df2e061..a8869cba234 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -104,6 +104,7 @@ syms.trailer, syms.term, syms.power, + syms.namedexpr_test, } TYPED_NAMES: Final = {syms.tname, syms.tname_star} ASSIGNMENTS: Final = { @@ -121,6 +122,7 @@ ">>=", "**=", "//=", + ":", } IMPLICIT_TUPLE: Final = {syms.testlist, syms.testlist_star_expr, syms.exprlist} @@ -346,9 +348,7 @@ def whitespace(leaf: Leaf, *, complex_subscript: bool, mode: Mode) -> str: # no return NO - elif Preview.walrus_subscript in mode and ( - t == token.COLONEQUAL or prev.type == token.COLONEQUAL - ): + elif t == token.COLONEQUAL or prev.type == token.COLONEQUAL: return SPACE elif not complex_subscript: @@ -753,13 +753,9 @@ def is_function_or_class(node: Node) -> bool: return node.type in {syms.funcdef, syms.classdef, syms.async_funcdef} -def is_stub_suite(node: Node, mode: Mode) -> bool: +def is_stub_suite(node: Node) -> bool: """Return True if `node` is a suite with a stub body.""" - if ( - node.parent is not None - and Preview.dummy_implementations in mode - and not is_parent_function_or_class(node) - ): + if node.parent is not None and not is_parent_function_or_class(node): return False # If there is a comment, we want to keep it. diff --git a/tests/data/cases/preview_allow_empty_first_line.py b/tests/data/cases/allow_empty_first_line.py similarity index 98% rename from tests/data/cases/preview_allow_empty_first_line.py rename to tests/data/cases/allow_empty_first_line.py index 4269987305d..32a170a97d0 100644 --- a/tests/data/cases/preview_allow_empty_first_line.py +++ b/tests/data/cases/allow_empty_first_line.py @@ -1,4 +1,3 @@ -# flags: --preview def foo(): """ Docstring diff --git a/tests/data/cases/preview_async_stmts.py b/tests/data/cases/async_stmts.py similarity index 93% rename from tests/data/cases/preview_async_stmts.py rename to tests/data/cases/async_stmts.py index 0a7671be5a6..fe9594b2164 100644 --- a/tests/data/cases/preview_async_stmts.py +++ b/tests/data/cases/async_stmts.py @@ -1,4 +1,3 @@ -# flags: --preview async def func() -> (int): return 0 diff --git a/tests/data/cases/comments5.py b/tests/data/cases/comments5.py index bda40619f62..4270d3a09a2 100644 --- a/tests/data/cases/comments5.py +++ b/tests/data/cases/comments5.py @@ -45,8 +45,7 @@ def wat(): @deco2(with_args=True) # leading 3 @deco3 -def decorated1(): - ... +def decorated1(): ... # leading 1 @@ -54,8 +53,7 @@ def decorated1(): # leading 2 @deco2(with_args=True) # leading function comment -def decorated1(): - ... +def decorated1(): ... # Note: this is fixed in @@ -65,8 +63,7 @@ def decorated1(): # This comment should be split from `some_instruction` by two lines but isn't. -def g(): - ... +def g(): ... if __name__ == "__main__": diff --git a/tests/data/cases/conditional_expression.py b/tests/data/cases/conditional_expression.py index 76251bd9318..f65d6fb00e7 100644 --- a/tests/data/cases/conditional_expression.py +++ b/tests/data/cases/conditional_expression.py @@ -1,4 +1,3 @@ -# flags: --preview long_kwargs_single_line = my_function( foo="test, this is a sample value", bar=some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz, @@ -197,7 +196,9 @@ def foo(wait: bool = True): time.sleep(1) if wait else None -a = "".join(( - "", # comment - "" if True else "", -)) +a = "".join( + ( + "", # comment + "" if True else "", + ) +) diff --git a/tests/data/cases/preview_context_managers_38.py b/tests/data/cases/context_managers_38.py similarity index 96% rename from tests/data/cases/preview_context_managers_38.py rename to tests/data/cases/context_managers_38.py index 719d94fdcc5..54fb97c708b 100644 --- a/tests/data/cases/preview_context_managers_38.py +++ b/tests/data/cases/context_managers_38.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.8 +# flags: --minimum-version=3.8 with \ make_context_manager1() as cm1, \ make_context_manager2() as cm2, \ diff --git a/tests/data/cases/preview_context_managers_39.py b/tests/data/cases/context_managers_39.py similarity index 98% rename from tests/data/cases/preview_context_managers_39.py rename to tests/data/cases/context_managers_39.py index 589e00ad187..60fd1a56409 100644 --- a/tests/data/cases/preview_context_managers_39.py +++ b/tests/data/cases/context_managers_39.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.9 +# flags: --minimum-version=3.9 with \ make_context_manager1() as cm1, \ make_context_manager2() as cm2, \ diff --git a/tests/data/cases/preview_context_managers_autodetect_310.py b/tests/data/cases/context_managers_autodetect_310.py similarity index 93% rename from tests/data/cases/preview_context_managers_autodetect_310.py rename to tests/data/cases/context_managers_autodetect_310.py index a9e31076f03..80f211032e5 100644 --- a/tests/data/cases/preview_context_managers_autodetect_310.py +++ b/tests/data/cases/context_managers_autodetect_310.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.10 +# flags: --minimum-version=3.10 # This file uses pattern matching introduced in Python 3.10. diff --git a/tests/data/cases/preview_context_managers_autodetect_311.py b/tests/data/cases/context_managers_autodetect_311.py similarity index 92% rename from tests/data/cases/preview_context_managers_autodetect_311.py rename to tests/data/cases/context_managers_autodetect_311.py index af1e83fe74c..020c4cea967 100644 --- a/tests/data/cases/preview_context_managers_autodetect_311.py +++ b/tests/data/cases/context_managers_autodetect_311.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.11 +# flags: --minimum-version=3.11 # This file uses except* clause in Python 3.11. diff --git a/tests/data/cases/preview_context_managers_autodetect_38.py b/tests/data/cases/context_managers_autodetect_38.py similarity index 98% rename from tests/data/cases/preview_context_managers_autodetect_38.py rename to tests/data/cases/context_managers_autodetect_38.py index 25217a40604..79e438b995e 100644 --- a/tests/data/cases/preview_context_managers_autodetect_38.py +++ b/tests/data/cases/context_managers_autodetect_38.py @@ -1,4 +1,3 @@ -# flags: --preview # This file doesn't use any Python 3.9+ only grammars. diff --git a/tests/data/cases/preview_context_managers_autodetect_39.py b/tests/data/cases/context_managers_autodetect_39.py similarity index 93% rename from tests/data/cases/preview_context_managers_autodetect_39.py rename to tests/data/cases/context_managers_autodetect_39.py index 3f72e48db9d..98e674b2f9d 100644 --- a/tests/data/cases/preview_context_managers_autodetect_39.py +++ b/tests/data/cases/context_managers_autodetect_39.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.9 +# flags: --minimum-version=3.9 # This file uses parenthesized context managers introduced in Python 3.9. diff --git a/tests/data/cases/preview_dummy_implementations.py b/tests/data/cases/dummy_implementations.py similarity index 99% rename from tests/data/cases/preview_dummy_implementations.py rename to tests/data/cases/dummy_implementations.py index 3cd392c9587..0a52c081bcc 100644 --- a/tests/data/cases/preview_dummy_implementations.py +++ b/tests/data/cases/dummy_implementations.py @@ -1,4 +1,3 @@ -# flags: --preview from typing import NoReturn, Protocol, Union, overload class Empty: diff --git a/tests/data/cases/empty_lines.py b/tests/data/cases/empty_lines.py index 4fd47b93dca..4c03e432383 100644 --- a/tests/data/cases/empty_lines.py +++ b/tests/data/cases/empty_lines.py @@ -119,6 +119,7 @@ def f(): if not prev: prevp = preceding_leaf(p) if not prevp or prevp.type in OPENING_BRACKETS: + return NO if prevp.type == token.EQUAL: diff --git a/tests/data/cases/fmtonoff.py b/tests/data/cases/fmtonoff.py index d1f15cd5c8b..8af94563af8 100644 --- a/tests/data/cases/fmtonoff.py +++ b/tests/data/cases/fmtonoff.py @@ -243,12 +243,8 @@ def spaces_types( g: int = 1 if False else 2, h: str = "", i: str = r"", -): - ... - - -def spaces2(result=_core.Value(None)): - ... +): ... +def spaces2(result=_core.Value(None)): ... something = { diff --git a/tests/data/cases/fmtonoff5.py b/tests/data/cases/fmtonoff5.py index 181151b6bd6..4c134a9eea3 100644 --- a/tests/data/cases/fmtonoff5.py +++ b/tests/data/cases/fmtonoff5.py @@ -161,8 +161,7 @@ def this_wont_be_formatted ( self ) -> str: ... class Factory(t.Protocol): - def this_will_be_formatted(self, **kwargs) -> Named: - ... + def this_will_be_formatted(self, **kwargs) -> Named: ... # fmt: on diff --git a/tests/data/cases/preview_form_feeds.py b/tests/data/cases/form_feeds.py similarity index 99% rename from tests/data/cases/preview_form_feeds.py rename to tests/data/cases/form_feeds.py index dc3bd6cfe2e..48ffc98106b 100644 --- a/tests/data/cases/preview_form_feeds.py +++ b/tests/data/cases/form_feeds.py @@ -1,4 +1,3 @@ -# flags: --preview # Warning! This file contains form feeds (ASCII 0x0C, often represented by \f or ^L). diff --git a/tests/data/cases/function.py b/tests/data/cases/function.py index 2d642c8731b..4e3f91fd8b1 100644 --- a/tests/data/cases/function.py +++ b/tests/data/cases/function.py @@ -158,10 +158,7 @@ def spaces_types( g: int = 1 if False else 2, h: str = "", i: str = r"", -): - ... - - +): ... def spaces2(result=_core.Value(None)): assert fut is self._read_fut, (fut, self._read_fut) diff --git a/tests/data/cases/remove_newline_after_match.py b/tests/data/cases/keep_newline_after_match.py similarity index 98% rename from tests/data/cases/remove_newline_after_match.py rename to tests/data/cases/keep_newline_after_match.py index fe6592b664d..dbeccce6264 100644 --- a/tests/data/cases/remove_newline_after_match.py +++ b/tests/data/cases/keep_newline_after_match.py @@ -21,15 +21,21 @@ def http_status(status): # output def http_status(status): + match status: + case 400: + return "Bad request" case 401: + return "Unauthorized" case 403: + return "Forbidden" case 404: + return "Not found" \ No newline at end of file diff --git a/tests/data/cases/long_strings_flag_disabled.py b/tests/data/cases/long_strings_flag_disabled.py index db3954e3abd..d81c331cab2 100644 --- a/tests/data/cases/long_strings_flag_disabled.py +++ b/tests/data/cases/long_strings_flag_disabled.py @@ -43,8 +43,10 @@ % ( "formatted", "string", - ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)." - % ("soooo", 2), + ): ( + "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)." + % ("soooo", 2) + ), } func_with_keywords( @@ -254,10 +256,12 @@ + CONCATENATED + "using the '+' operator." ) -annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." -annotated_variable: Literal[ - "fakse_literal" -] = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +annotated_variable: Final = ( + "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +) +annotated_variable: Literal["fakse_literal"] = ( + "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +) backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\" backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\\\" diff --git a/tests/data/cases/module_docstring_1.py b/tests/data/cases/module_docstring_1.py index d5897b4db60..5751154f7f0 100644 --- a/tests/data/cases/module_docstring_1.py +++ b/tests/data/cases/module_docstring_1.py @@ -1,4 +1,3 @@ -# flags: --preview """Single line module-level docstring should be followed by single newline.""" diff --git a/tests/data/cases/module_docstring_2.py b/tests/data/cases/module_docstring_2.py index 1cc9aea9aea..ac486096c02 100644 --- a/tests/data/cases/module_docstring_2.py +++ b/tests/data/cases/module_docstring_2.py @@ -1,7 +1,7 @@ # flags: --preview """I am a very helpful module docstring. -With trailing spaces: +With trailing spaces (only removed with unify_docstring_detection on): Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, @@ -39,7 +39,7 @@ # output """I am a very helpful module docstring. -With trailing spaces: +With trailing spaces (only removed with unify_docstring_detection on): Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, diff --git a/tests/data/cases/module_docstring_3.py b/tests/data/cases/module_docstring_3.py index 0631e136a3d..3d0058dd554 100644 --- a/tests/data/cases/module_docstring_3.py +++ b/tests/data/cases/module_docstring_3.py @@ -1,4 +1,3 @@ -# flags: --preview """Single line module-level docstring should be followed by single newline.""" a = 1 diff --git a/tests/data/cases/module_docstring_4.py b/tests/data/cases/module_docstring_4.py index 515174dcc04..b1720078f71 100644 --- a/tests/data/cases/module_docstring_4.py +++ b/tests/data/cases/module_docstring_4.py @@ -1,4 +1,3 @@ -# flags: --preview """Single line module-level docstring should be followed by single newline.""" a = 1 diff --git a/tests/data/cases/module_docstring_followed_by_class.py b/tests/data/cases/module_docstring_followed_by_class.py index 6fdbfc8c240..c291e61b960 100644 --- a/tests/data/cases/module_docstring_followed_by_class.py +++ b/tests/data/cases/module_docstring_followed_by_class.py @@ -1,4 +1,3 @@ -# flags: --preview """Two blank lines between module docstring and a class.""" class MyClass: pass diff --git a/tests/data/cases/module_docstring_followed_by_function.py b/tests/data/cases/module_docstring_followed_by_function.py index 5913a59e1fe..fd29b98da8e 100644 --- a/tests/data/cases/module_docstring_followed_by_function.py +++ b/tests/data/cases/module_docstring_followed_by_function.py @@ -1,4 +1,3 @@ -# flags: --preview """Two blank lines between module docstring and a function def.""" def function(): pass diff --git a/tests/data/cases/nested_stub.py b/tests/data/cases/nested_stub.py index ef13c588ce6..40ca11e9330 100644 --- a/tests/data/cases/nested_stub.py +++ b/tests/data/cases/nested_stub.py @@ -1,4 +1,4 @@ -# flags: --pyi --preview +# flags: --pyi import sys class Outer: diff --git a/tests/data/cases/preview_no_blank_line_before_docstring.py b/tests/data/cases/no_blank_line_before_docstring.py similarity index 98% rename from tests/data/cases/preview_no_blank_line_before_docstring.py rename to tests/data/cases/no_blank_line_before_docstring.py index faeaa1e46e4..ced125fef78 100644 --- a/tests/data/cases/preview_no_blank_line_before_docstring.py +++ b/tests/data/cases/no_blank_line_before_docstring.py @@ -1,4 +1,3 @@ -# flags: --preview def line_before_docstring(): """Please move me up""" @@ -63,4 +62,5 @@ class MultilineDocstringsAsWell: class SingleQuotedDocstring: + "I'm a docstring but I don't even get triple quotes." diff --git a/tests/data/cases/preview_pattern_matching_long.py b/tests/data/cases/pattern_matching_long.py similarity index 94% rename from tests/data/cases/preview_pattern_matching_long.py rename to tests/data/cases/pattern_matching_long.py index df849fdc4f2..9a944c9d0c9 100644 --- a/tests/data/cases/preview_pattern_matching_long.py +++ b/tests/data/cases/pattern_matching_long.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.10 +# flags: --minimum-version=3.10 match x: case "abcd" | "abcd" | "abcd" : pass diff --git a/tests/data/cases/preview_pattern_matching_trailing_comma.py b/tests/data/cases/pattern_matching_trailing_comma.py similarity index 92% rename from tests/data/cases/preview_pattern_matching_trailing_comma.py rename to tests/data/cases/pattern_matching_trailing_comma.py index e6c0d88bb80..5660b0f6a14 100644 --- a/tests/data/cases/preview_pattern_matching_trailing_comma.py +++ b/tests/data/cases/pattern_matching_trailing_comma.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.10 +# flags: --minimum-version=3.10 match maybe, multiple: case perhaps, 5: pass diff --git a/tests/data/cases/pep604_union_types_line_breaks.py b/tests/data/cases/pep604_union_types_line_breaks.py index fee2b840494..745bc9e8b02 100644 --- a/tests/data/cases/pep604_union_types_line_breaks.py +++ b/tests/data/cases/pep604_union_types_line_breaks.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.10 +# flags: --minimum-version=3.10 # This has always worked z= Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong diff --git a/tests/data/cases/pep_572_py310.py b/tests/data/cases/pep_572_py310.py index 9f999deeb89..ba488d4741c 100644 --- a/tests/data/cases/pep_572_py310.py +++ b/tests/data/cases/pep_572_py310.py @@ -1,8 +1,8 @@ # flags: --minimum-version=3.10 # Unparenthesized walruses are now allowed in indices since Python 3.10. -x[a:=0] -x[a:=0, b:=1] -x[5, b:=0] +x[a := 0] +x[a := 0, b := 1] +x[5, b := 0] # Walruses are allowed inside generator expressions on function calls since 3.10. if any(match := pattern_error.match(s) for s in buffer): diff --git a/tests/data/cases/pep_572_remove_parens.py b/tests/data/cases/pep_572_remove_parens.py index 24f1ac29168..f0026ceb032 100644 --- a/tests/data/cases/pep_572_remove_parens.py +++ b/tests/data/cases/pep_572_remove_parens.py @@ -96,18 +96,16 @@ async def await_the_walrus(): foo(x=(y := f(x))) -def foo(answer=(p := 42)): - ... +def foo(answer=(p := 42)): ... -def foo2(answer: (p := 42) = 5): - ... +def foo2(answer: (p := 42) = 5): ... lambda: (x := 1) a[(x := 12)] -a[:(x := 13)] +a[: (x := 13)] # we don't touch expressions in f-strings but if we do one day, don't break 'em f"{(x:=10)}" diff --git a/tests/data/cases/preview_pep_572.py b/tests/data/cases/pep_572_slices.py similarity index 75% rename from tests/data/cases/preview_pep_572.py rename to tests/data/cases/pep_572_slices.py index 75ad0cc4176..aa772b1f1f5 100644 --- a/tests/data/cases/preview_pep_572.py +++ b/tests/data/cases/pep_572_slices.py @@ -1,4 +1,3 @@ -# flags: --preview x[(a:=0):] x[:(a:=0)] diff --git a/tests/data/cases/preview_percent_precedence.py b/tests/data/cases/percent_precedence.py similarity index 91% rename from tests/data/cases/preview_percent_precedence.py rename to tests/data/cases/percent_precedence.py index aeaf450ff5e..7822e42c69d 100644 --- a/tests/data/cases/preview_percent_precedence.py +++ b/tests/data/cases/percent_precedence.py @@ -1,4 +1,3 @@ -# flags: --preview ("" % a) ** 2 ("" % a)[0] ("" % a)() @@ -31,9 +30,9 @@ 2 // ("" % a) 2 % ("" % a) +("" % a) -b + "" % a +b + ("" % a) -("" % a) -b - "" % a +b - ("" % a) b + -("" % a) ~("" % a) 2 ** ("" % a) diff --git a/tests/data/cases/preview_power_op_spacing.py b/tests/data/cases/power_op_spacing_long.py similarity index 99% rename from tests/data/cases/preview_power_op_spacing.py rename to tests/data/cases/power_op_spacing_long.py index 650c6fecb20..30e6eb788b3 100644 --- a/tests/data/cases/preview_power_op_spacing.py +++ b/tests/data/cases/power_op_spacing_long.py @@ -1,4 +1,3 @@ -# flags: --preview a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 b = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 c = 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 diff --git a/tests/data/cases/preview_prefer_rhs_split.py b/tests/data/cases/prefer_rhs_split.py similarity index 99% rename from tests/data/cases/preview_prefer_rhs_split.py rename to tests/data/cases/prefer_rhs_split.py index 28d89c368c0..f3d9fd67251 100644 --- a/tests/data/cases/preview_prefer_rhs_split.py +++ b/tests/data/cases/prefer_rhs_split.py @@ -1,4 +1,3 @@ -# flags: --preview first_item, second_item = ( some_looooooooong_module.some_looooooooooooooong_function_name( first_argument, second_argument, third_argument diff --git a/tests/data/cases/py310_pep572.py b/tests/data/cases/py310_pep572.py index 172be3898d6..73fbe44d42c 100644 --- a/tests/data/cases/py310_pep572.py +++ b/tests/data/cases/py310_pep572.py @@ -1,4 +1,4 @@ -# flags: --preview --minimum-version=3.10 +# flags: --minimum-version=3.10 x[a:=0] x[a := 0] x[a := 0, b := 1] diff --git a/tests/data/cases/python39.py b/tests/data/cases/python39.py index 1b9536c1529..85eddc38e00 100644 --- a/tests/data/cases/python39.py +++ b/tests/data/cases/python39.py @@ -15,19 +15,16 @@ def f(): # output @relaxed_decorator[0] -def f(): - ... +def f(): ... @relaxed_decorator[ extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length ] -def f(): - ... +def f(): ... @extremely_long_variable_name_that_doesnt_fit := complex.expression( with_long="arguments_value_that_wont_fit_at_the_end_of_the_line" ) -def f(): - ... \ No newline at end of file +def f(): ... \ No newline at end of file diff --git a/tests/data/cases/raw_docstring.py b/tests/data/cases/raw_docstring.py index 751fd3201df..7f88bb2de86 100644 --- a/tests/data/cases/raw_docstring.py +++ b/tests/data/cases/raw_docstring.py @@ -1,4 +1,4 @@ -# flags: --preview --skip-string-normalization +# flags: --skip-string-normalization class C: r"""Raw""" diff --git a/tests/data/cases/preview_docstring_no_string_normalization.py b/tests/data/cases/raw_docstring_no_string_normalization.py similarity index 88% rename from tests/data/cases/preview_docstring_no_string_normalization.py rename to tests/data/cases/raw_docstring_no_string_normalization.py index 712c7364f51..a201c1e8fae 100644 --- a/tests/data/cases/preview_docstring_no_string_normalization.py +++ b/tests/data/cases/raw_docstring_no_string_normalization.py @@ -1,4 +1,4 @@ -# flags: --preview --skip-string-normalization +# flags: --skip-string-normalization def do_not_touch_this_prefix(): R"""There was a bug where docstring prefixes would be normalized even with -S.""" diff --git a/tests/data/cases/remove_newline_after_code_block_open.py b/tests/data/cases/remove_newline_after_code_block_open.py index ef2e5c2f6f5..6622e8afb7d 100644 --- a/tests/data/cases/remove_newline_after_code_block_open.py +++ b/tests/data/cases/remove_newline_after_code_block_open.py @@ -3,14 +3,14 @@ def foo1(): - print("The newline above me should be deleted!") + print("The newline above me should be kept!") def foo2(): - print("All the newlines above me should be deleted!") + print("All the newlines above me should be kept!") def foo3(): @@ -30,31 +30,31 @@ def foo4(): class Foo: def bar(self): - print("The newline above me should be deleted!") + print("The newline above me should be kept!") for i in range(5): - print(f"{i}) The line above me should be removed!") + print(f"{i}) The line above me should be kept!") for i in range(5): - print(f"{i}) The lines above me should be removed!") + print(f"{i}) The lines above me should be kept!") for i in range(5): for j in range(7): - print(f"{i}) The lines above me should be removed!") + print(f"{i}) The lines above me should be kept!") if random.randint(0, 3) == 0: - print("The new line above me is about to be removed!") + print("The new line above me will be kept!") if random.randint(0, 3) == 0: @@ -62,43 +62,45 @@ def bar(self): - print("The new lines above me is about to be removed!") + print("The new lines above me will be kept!") if random.randint(0, 3) == 0: + if random.uniform(0, 1) > 0.5: - print("Two lines above me are about to be removed!") + + print("Two lines above me will be kept!") while True: - print("The newline above me should be deleted!") + print("The newline above me should be kept!") while True: - print("The newlines above me should be deleted!") + print("The newlines above me should be kept!") while True: while False: - print("The newlines above me should be deleted!") + print("The newlines above me should be kept!") with open("/path/to/file.txt", mode="w") as file: - file.write("The new line above me is about to be removed!") + file.write("The new line above me will be kept!") with open("/path/to/file.txt", mode="w") as file: - file.write("The new lines above me is about to be removed!") + file.write("The new lines above me will be kept!") with open("/path/to/file.txt", mode="r") as read_file: @@ -113,20 +115,24 @@ def bar(self): def foo1(): - print("The newline above me should be deleted!") + + print("The newline above me should be kept!") def foo2(): - print("All the newlines above me should be deleted!") + + print("All the newlines above me should be kept!") def foo3(): + print("No newline above me!") print("There is a newline above me, and that's OK!") def foo4(): + # There is a comment here print("The newline above me should not be deleted!") @@ -134,56 +140,73 @@ def foo4(): class Foo: def bar(self): - print("The newline above me should be deleted!") + + print("The newline above me should be kept!") for i in range(5): - print(f"{i}) The line above me should be removed!") + + print(f"{i}) The line above me should be kept!") for i in range(5): - print(f"{i}) The lines above me should be removed!") + + print(f"{i}) The lines above me should be kept!") for i in range(5): + for j in range(7): - print(f"{i}) The lines above me should be removed!") + + print(f"{i}) The lines above me should be kept!") if random.randint(0, 3) == 0: - print("The new line above me is about to be removed!") + + print("The new line above me will be kept!") if random.randint(0, 3) == 0: - print("The new lines above me is about to be removed!") + + print("The new lines above me will be kept!") if random.randint(0, 3) == 0: + if random.uniform(0, 1) > 0.5: - print("Two lines above me are about to be removed!") + + print("Two lines above me will be kept!") while True: - print("The newline above me should be deleted!") + + print("The newline above me should be kept!") while True: - print("The newlines above me should be deleted!") + + print("The newlines above me should be kept!") while True: + while False: - print("The newlines above me should be deleted!") + + print("The newlines above me should be kept!") with open("/path/to/file.txt", mode="w") as file: - file.write("The new line above me is about to be removed!") + + file.write("The new line above me will be kept!") with open("/path/to/file.txt", mode="w") as file: - file.write("The new lines above me is about to be removed!") + + file.write("The new lines above me will be kept!") with open("/path/to/file.txt", mode="r") as read_file: + with open("/path/to/output_file.txt", mode="w") as write_file: + write_file.writelines(read_file.readlines()) diff --git a/tests/data/cases/return_annotation_brackets.py b/tests/data/cases/return_annotation_brackets.py index 8509ecdb92c..ed05bed61f4 100644 --- a/tests/data/cases/return_annotation_brackets.py +++ b/tests/data/cases/return_annotation_brackets.py @@ -88,7 +88,6 @@ def foo() -> tuple[int, int, int,]: return 2 # Magic trailing comma example, with params -# this is broken - the trailing comma is transferred to the param list. Fixed in preview def foo(a,b) -> tuple[int, int, int,]: return 2 @@ -194,30 +193,27 @@ def foo() -> tuple[int, int, int]: return 2 -def foo() -> ( - tuple[ - loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, - loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, - loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, - ] -): +def foo() -> tuple[ + loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, +]: return 2 # Magic trailing comma example -def foo() -> ( - tuple[ - int, - int, - int, - ] -): +def foo() -> tuple[ + int, + int, + int, +]: return 2 # Magic trailing comma example, with params -# this is broken - the trailing comma is transferred to the param list. Fixed in preview -def foo( - a, b -) -> tuple[int, int, int,]: +def foo(a, b) -> tuple[ + int, + int, + int, +]: return 2 diff --git a/tests/data/cases/preview_single_line_format_skip_with_multiple_comments.py b/tests/data/cases/single_line_format_skip_with_multiple_comments.py similarity index 97% rename from tests/data/cases/preview_single_line_format_skip_with_multiple_comments.py rename to tests/data/cases/single_line_format_skip_with_multiple_comments.py index efde662baa8..7212740fc42 100644 --- a/tests/data/cases/preview_single_line_format_skip_with_multiple_comments.py +++ b/tests/data/cases/single_line_format_skip_with_multiple_comments.py @@ -1,4 +1,3 @@ -# flags: --preview foo = 123 # fmt: skip # noqa: E501 # pylint bar = ( 123 , diff --git a/tests/data/cases/preview_trailing_comma.py b/tests/data/cases/trailing_comma.py similarity index 97% rename from tests/data/cases/preview_trailing_comma.py rename to tests/data/cases/trailing_comma.py index bba7e7ad16d..5b09c664606 100644 --- a/tests/data/cases/preview_trailing_comma.py +++ b/tests/data/cases/trailing_comma.py @@ -1,4 +1,3 @@ -# flags: --preview e = { "a": fun(msg, "ts"), "longggggggggggggggid": ..., diff --git a/tests/data/cases/walrus_in_dict.py b/tests/data/cases/walrus_in_dict.py index c33eecd84a6..c91ad9e8611 100644 --- a/tests/data/cases/walrus_in_dict.py +++ b/tests/data/cases/walrus_in_dict.py @@ -1,7 +1,9 @@ # flags: --preview +# This is testing an issue that is specific to the preview style { "is_update": (up := commit.hash in update_hashes) } # output +# This is testing an issue that is specific to the preview style {"is_update": (up := commit.hash in update_hashes)}