From a961f75e134a17f1c2306de593bf727a265decfd Mon Sep 17 00:00:00 2001 From: Chris Pryer <14341145+cnpryer@users.noreply.github.com> Date: Fri, 14 Jul 2023 03:01:33 -0400 Subject: [PATCH] Format `assert` statement (#5168) --- .../test/fixtures/ruff/statement/assert.py | 30 +++ .../src/statement/stmt_assert.rs | 33 ++- ...aneous__long_strings_flag_disabled.py.snap | 44 ++-- ...tibility@simple_cases__collections.py.snap | 17 +- ...tibility@simple_cases__composition.py.snap | 234 ++++++++---------- ...ses__composition_no_trailing_comma.py.snap | 234 ++++++++---------- ...tibility@simple_cases__empty_lines.py.snap | 8 +- ...atibility@simple_cases__expression.py.snap | 34 ++- ...mpatibility@simple_cases__fmtonoff.py.snap | 4 +- ...patibility@simple_cases__fmtonoff2.py.snap | 13 +- ...mpatibility@simple_cases__function.py.snap | 12 +- ...ompatibility@simple_cases__torture.py.snap | 46 ++-- ...__trailing_commas_in_leading_parts.py.snap | 26 +- .../format@statement__assert.py.snap | 77 ++++++ 14 files changed, 442 insertions(+), 370 deletions(-) create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assert.py create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@statement__assert.py.snap diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assert.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assert.py new file mode 100644 index 0000000000000..8f12d268b0e5a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assert.py @@ -0,0 +1,30 @@ +assert True # Trailing same-line +assert True is True # Trailing same-line +assert 1, "Some string" # Trailing same-line +assert aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # Trailing same-line + +assert ( # Dangle1 + # Dangle2 +) + +# TODO: https://github.com/astral-sh/ruff/pull/5168#issuecomment-1630767421 +# Leading assert +assert ( + # Leading test value + True # Trailing test value same-line + # Trailing test value own-line +), "Some string" # Trailing msg same-line +# Trailing assert + +# Random dangler + +# TODO: https://github.com/astral-sh/ruff/pull/5168#issuecomment-1630767421 +# Leading assert +assert ( + # Leading test value + True # Trailing test value same-line + # Trailing test value own-line + + # Test dangler +), "Some string" # Trailing msg same-line +# Trailing assert diff --git a/crates/ruff_python_formatter/src/statement/stmt_assert.rs b/crates/ruff_python_formatter/src/statement/stmt_assert.rs index 1631051c4ee7e..ab09b8053d3fb 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_assert.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_assert.rs @@ -1,4 +1,7 @@ -use crate::{not_yet_implemented, FormatNodeRule, PyFormatter}; +use crate::expression::maybe_parenthesize_expression; +use crate::expression::parentheses::Parenthesize; +use crate::{FormatNodeRule, PyFormatter}; +use ruff_formatter::prelude::{space, text}; use ruff_formatter::{write, Buffer, FormatResult}; use rustpython_parser::ast::StmtAssert; @@ -7,6 +10,32 @@ pub struct FormatStmtAssert; impl FormatNodeRule for FormatStmtAssert { fn fmt_fields(&self, item: &StmtAssert, f: &mut PyFormatter) -> FormatResult<()> { - write!(f, [not_yet_implemented(item)]) + let StmtAssert { + range: _, + test, + msg, + } = item; + + write!( + f, + [ + text("assert"), + space(), + maybe_parenthesize_expression(test, item, Parenthesize::IfBreaks) + ] + )?; + + if let Some(msg) = msg { + write!( + f, + [ + text(","), + space(), + maybe_parenthesize_expression(msg, item, Parenthesize::IfBreaks), + ] + )?; + } + + Ok(()) } } diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap index fe648573cc0af..f65f0a835bb3a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap @@ -316,37 +316,23 @@ long_unmergable_string_with_pragma = ( comment_string = "Long lines with inline comments should have their comments appended to the reformatted string's enclosing right parentheses." # This comment gets thrown to the top. -@@ -165,25 +165,13 @@ +@@ -165,13 +165,9 @@ triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" -assert ( - some_type_of_boolean_expression -), "Followed by a really really really long string that is used to provide context to the AssertionError exception." -+NOT_YET_IMPLEMENTED_StmtAssert ++assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception." -assert ( - some_type_of_boolean_expression -), "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format( -- "formatting" --) -+NOT_YET_IMPLEMENTED_StmtAssert - --assert some_type_of_boolean_expression, ( -- "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s." -- % "formatting" --) -+NOT_YET_IMPLEMENTED_StmtAssert - --assert some_type_of_boolean_expression, ( -- "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s." -- % ("string", "formatting") --) -+NOT_YET_IMPLEMENTED_StmtAssert ++assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format( + "formatting" + ) - some_function_call( - "With a reallly generic name and with a really really long string that is, at some point down the line, " -@@ -221,8 +209,8 @@ +@@ -221,8 +217,8 @@ func_with_bad_comma( ( "This is a really long string argument to a function that has a trailing comma" @@ -357,7 +343,7 @@ long_unmergable_string_with_pragma = ( ) func_with_bad_parens_that_wont_fit_in_one_line( -@@ -271,10 +259,10 @@ +@@ -271,10 +267,10 @@ def foo(): @@ -542,13 +528,21 @@ pragma_comment_string2 = "Lines which end with an inline pragma comment of the f triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" -NOT_YET_IMPLEMENTED_StmtAssert +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception." -NOT_YET_IMPLEMENTED_StmtAssert +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format( + "formatting" +) -NOT_YET_IMPLEMENTED_StmtAssert +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s." + % "formatting" +) -NOT_YET_IMPLEMENTED_StmtAssert +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s." + % ("string", "formatting") +) some_function_call( "With a reallly generic name and with a really really long string that is, at some point down the line, " diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__collections.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__collections.py.snap index cf6666738208c..9850888f4ea60 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__collections.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__collections.py.snap @@ -110,18 +110,6 @@ if True: nested_no_trailing_comma = {(1, 2, 3), (4, 5, 6)} nested_long_lines = [ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -@@ -52,10 +41,7 @@ - y = { - "oneple": (1,), - } --assert False, ( -- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa wraps %s" -- % bar --) -+NOT_YET_IMPLEMENTED_StmtAssert - - # looping over a 1-tuple should also not get wrapped - for x in (1,): ``` ## Ruff Output @@ -170,7 +158,10 @@ x = {"oneple": (1,)} y = { "oneple": (1,), } -NOT_YET_IMPLEMENTED_StmtAssert +assert False, ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa wraps %s" + % bar +) # looping over a 1-tuple should also not get wrapped for x in (1,): diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap index 71b76f27cd760..c1e0f895db355 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap @@ -203,110 +203,20 @@ class C: print(i) xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy( push_manager=context.request.resource_manager, -@@ -59,101 +59,23 @@ - ) - - def easy_asserts(self) -> None: -- assert { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } == expected, "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert expected == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- }, "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert expected == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } -+ NOT_YET_IMPLEMENTED_StmtAssert - - def tricky_asserts(self) -> None: -- assert { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } == expected( -- value, is_going_to_be="too long to fit in a single line", srsly=True -- ), "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, +@@ -120,9 +120,7 @@ + key7: value7, + key8: value8, + key9: value9, - } == expected, ( - "Not what we expected and the message is too long to fit in one line" - ) -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert expected( -- value, is_going_to_be="too long to fit in a single line", srsly=True -- ) == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- }, "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert ++ } == expected, "Not what we expected and the message is too long to fit in one line" -- assert expected == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- }, ( -- "Not what we expected and the message is too long to fit in one line" -- " because it's too long" -- ) -+ NOT_YET_IMPLEMENTED_StmtAssert + assert expected( + value, is_going_to_be="too long to fit in a single line", srsly=True +@@ -153,7 +151,8 @@ + " because it's too long" + ) - dis_c_instance_method = """\ + dis_c_instance_method = ( @@ -314,7 +224,7 @@ class C: %3d 0 LOAD_FAST 1 (x) 2 LOAD_CONST 1 (1) 4 COMPARE_OP 2 (==) -@@ -161,21 +83,8 @@ +@@ -161,8 +160,8 @@ 8 STORE_ATTR 0 (x) 10 LOAD_CONST 0 (None) 12 RETURN_VALUE @@ -324,21 +234,7 @@ class C: + % (_C.__init__.__code__.co_firstlineno + 1,) ) -- assert ( -- expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect -- == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } -- ) -+ NOT_YET_IMPLEMENTED_StmtAssert + assert ( ``` ## Ruff Output @@ -405,20 +301,97 @@ class C: ) def easy_asserts(self) -> None: - NOT_YET_IMPLEMENTED_StmtAssert + assert { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } == expected, "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + }, "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } def tricky_asserts(self) -> None: - NOT_YET_IMPLEMENTED_StmtAssert + assert { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } == expected( + value, is_going_to_be="too long to fit in a single line", srsly=True + ), "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } == expected, "Not what we expected and the message is too long to fit in one line" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected( + value, is_going_to_be="too long to fit in a single line", srsly=True + ) == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + }, "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + }, ( + "Not what we expected and the message is too long to fit in one line" + " because it's too long" + ) dis_c_instance_method = ( """\ @@ -433,7 +406,20 @@ class C: % (_C.__init__.__code__.co_firstlineno + 1,) ) - NOT_YET_IMPLEMENTED_StmtAssert + assert ( + expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect + == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } + ) ``` ## Black Output diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap index 975059e7a0062..3374be58a3682 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap @@ -203,110 +203,20 @@ class C: print(i) xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy( push_manager=context.request.resource_manager, -@@ -59,101 +59,23 @@ - ) - - def easy_asserts(self) -> None: -- assert { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } == expected, "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert expected == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- }, "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert expected == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } -+ NOT_YET_IMPLEMENTED_StmtAssert - - def tricky_asserts(self) -> None: -- assert { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } == expected( -- value, is_going_to_be="too long to fit in a single line", srsly=True -- ), "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, +@@ -120,9 +120,7 @@ + key7: value7, + key8: value8, + key9: value9, - } == expected, ( - "Not what we expected and the message is too long to fit in one line" - ) -+ NOT_YET_IMPLEMENTED_StmtAssert - -- assert expected( -- value, is_going_to_be="too long to fit in a single line", srsly=True -- ) == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- }, "Not what we expected" -+ NOT_YET_IMPLEMENTED_StmtAssert ++ } == expected, "Not what we expected and the message is too long to fit in one line" -- assert expected == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- }, ( -- "Not what we expected and the message is too long to fit in one line" -- " because it's too long" -- ) -+ NOT_YET_IMPLEMENTED_StmtAssert + assert expected( + value, is_going_to_be="too long to fit in a single line", srsly=True +@@ -153,7 +151,8 @@ + " because it's too long" + ) - dis_c_instance_method = """\ + dis_c_instance_method = ( @@ -314,7 +224,7 @@ class C: %3d 0 LOAD_FAST 1 (x) 2 LOAD_CONST 1 (1) 4 COMPARE_OP 2 (==) -@@ -161,21 +83,8 @@ +@@ -161,8 +160,8 @@ 8 STORE_ATTR 0 (x) 10 LOAD_CONST 0 (None) 12 RETURN_VALUE @@ -324,21 +234,7 @@ class C: + % (_C.__init__.__code__.co_firstlineno + 1,) ) -- assert ( -- expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect -- == { -- key1: value1, -- key2: value2, -- key3: value3, -- key4: value4, -- key5: value5, -- key6: value6, -- key7: value7, -- key8: value8, -- key9: value9, -- } -- ) -+ NOT_YET_IMPLEMENTED_StmtAssert + assert ( ``` ## Ruff Output @@ -405,20 +301,97 @@ class C: ) def easy_asserts(self) -> None: - NOT_YET_IMPLEMENTED_StmtAssert + assert { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } == expected, "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + }, "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } def tricky_asserts(self) -> None: - NOT_YET_IMPLEMENTED_StmtAssert + assert { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } == expected( + value, is_going_to_be="too long to fit in a single line", srsly=True + ), "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } == expected, "Not what we expected and the message is too long to fit in one line" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected( + value, is_going_to_be="too long to fit in a single line", srsly=True + ) == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + }, "Not what we expected" - NOT_YET_IMPLEMENTED_StmtAssert + assert expected == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + }, ( + "Not what we expected and the message is too long to fit in one line" + " because it's too long" + ) dis_c_instance_method = ( """\ @@ -433,7 +406,20 @@ class C: % (_C.__init__.__code__.co_firstlineno + 1,) ) - NOT_YET_IMPLEMENTED_StmtAssert + assert ( + expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect + == { + key1: value1, + key2: value2, + key3: value3, + key4: value4, + key5: value5, + key6: value6, + key7: value7, + key8: value8, + key9: value9, + } + ) ``` ## Black Output diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__empty_lines.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__empty_lines.py.snap index 4cfde0d1a6179..10d5e1ee87270 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__empty_lines.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__empty_lines.py.snap @@ -109,7 +109,7 @@ def g(): return DOUBLESPACE - assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}" -+ NOT_YET_IMPLEMENTED_StmtAssert ++ assert p is not None, f"NOT_YET_IMPLEMENTED_ExprJoinedStr" prev = leaf.prev_sibling if not prev: @@ -126,7 +126,7 @@ def g(): # Another comment because more comments - assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}" -+ NOT_YET_IMPLEMENTED_StmtAssert ++ assert p is not None, f"NOT_YET_IMPLEMENTED_ExprJoinedStr" prev = leaf.prev_sibling if not prev: @@ -153,7 +153,7 @@ def f(): if t == token.COMMENT: # another trailing comment return DOUBLESPACE - NOT_YET_IMPLEMENTED_StmtAssert + assert p is not None, f"NOT_YET_IMPLEMENTED_ExprJoinedStr" prev = leaf.prev_sibling if not prev: @@ -203,7 +203,7 @@ def g(): return DOUBLESPACE # Another comment because more comments - NOT_YET_IMPLEMENTED_StmtAssert + assert p is not None, f"NOT_YET_IMPLEMENTED_ExprJoinedStr" prev = leaf.prev_sibling if not prev: diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap index ad164bd6c6c05..758568c021325 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap @@ -398,11 +398,10 @@ last_call() (*starred,) { "id": "1", -@@ -207,25 +207,15 @@ - ) +@@ -208,24 +208,14 @@ what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set( vars_to_remove --) + ) -result = ( - session.query(models.Customer.id) - .filter( @@ -410,7 +409,7 @@ last_call() - ) - .order_by(models.Customer.id.asc()) - .all() - ) +-) -result = ( - session.query(models.Customer.id) - .filter( @@ -447,27 +446,22 @@ last_call() async def f(): -@@ -248,18 +238,20 @@ +@@ -248,8 +238,12 @@ print(*[] or [1]) -print(**{1: 3} if False else {x: x for x in range(3)}) -print(*lambda x: x) --assert not Test, "Short message" --assert this is ComplexTest and not requirements.fit_in_a_single_line( -- force=False --), "Short message" --assert parens is TooMany +print( + **{1: 3} + if False + else {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict} +) +print(*lambda NOT_YET_IMPLEMENTED_lambda: True) -+NOT_YET_IMPLEMENTED_StmtAssert -+NOT_YET_IMPLEMENTED_StmtAssert -+NOT_YET_IMPLEMENTED_StmtAssert - for (x,) in (1,), (2,), (3,): + assert not Test, "Short message" + assert this is ComplexTest and not requirements.fit_in_a_single_line( + force=False +@@ -259,7 +253,7 @@ ... for y in (): ... @@ -476,7 +470,7 @@ last_call() ... for i in call(): ... -@@ -328,13 +320,18 @@ +@@ -328,13 +322,18 @@ ): return True if ( @@ -498,7 +492,7 @@ last_call() ^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n ): return True -@@ -342,7 +339,8 @@ +@@ -342,7 +341,8 @@ ~aaaaaaaaaaaaaaaa.a + aaaaaaaaaaaaaaaa.b - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e @@ -759,9 +753,11 @@ print( else {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict} ) print(*lambda NOT_YET_IMPLEMENTED_lambda: True) -NOT_YET_IMPLEMENTED_StmtAssert -NOT_YET_IMPLEMENTED_StmtAssert -NOT_YET_IMPLEMENTED_StmtAssert +assert not Test, "Short message" +assert this is ComplexTest and not requirements.fit_in_a_single_line( + force=False +), "Short message" +assert parens is TooMany for (x,) in (1,), (2,), (3,): ... for y in (): diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap index 2aa1ef102dc99..0afead70b9afb 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap @@ -272,7 +272,7 @@ d={'a':1, - offset = attr.ib(default=attr.Factory(lambda: _r.uniform(1, 2))) - assert task._cancel_stack[: len(old_stack)] == old_stack + offset = attr.ib(default=attr.Factory(lambda NOT_YET_IMPLEMENTED_lambda: True)) -+ NOT_YET_IMPLEMENTED_StmtAssert ++ assert task._cancel_stack[ : len(old_stack)] == old_stack def spaces_types( @@ -452,7 +452,7 @@ def function_signature_stress_test( # fmt: on def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""): offset = attr.ib(default=attr.Factory(lambda NOT_YET_IMPLEMENTED_lambda: True)) - NOT_YET_IMPLEMENTED_StmtAssert + assert task._cancel_stack[ : len(old_stack)] == old_stack def spaces_types( diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff2.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff2.py.snap index abdfcb6d563f9..012dd71335b64 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff2.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff2.py.snap @@ -77,10 +77,10 @@ def test_calculate_fades(): + def check_fader(test): -+ pass - -- pass +- + pass ++ def verify_fader(test): - # misaligned comment + # misaligned comment @@ -89,10 +89,9 @@ def test_calculate_fades(): + def verify_fader(test): """Hey, ho.""" -- assert test.passed() -+ NOT_YET_IMPLEMENTED_StmtAssert -+ + assert test.passed() ++ def test_calculate_fades(): calcs = [ # one is zero/none @@ -141,7 +140,7 @@ def verify_fader(test): def verify_fader(test): """Hey, ho.""" - NOT_YET_IMPLEMENTED_StmtAssert + assert test.passed() def test_calculate_fades(): diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap index 219714a500d0f..a362d715fde68 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap @@ -129,16 +129,14 @@ def __await__(): return (yield) - offset = attr.ib(default=attr.Factory(lambda: _r.uniform(10000, 200000))) - assert task._cancel_stack[: len(old_stack)] == old_stack + offset = attr.ib(default=attr.Factory(lambda NOT_YET_IMPLEMENTED_lambda: True)) -+ NOT_YET_IMPLEMENTED_StmtAssert ++ assert task._cancel_stack[ : len(old_stack)] == old_stack def spaces_types( -@@ -64,19 +63,15 @@ - +@@ -65,18 +64,14 @@ def spaces2(result=_core.Value(None)): -- assert fut is self._read_fut, (fut, self._read_fut) -+ NOT_YET_IMPLEMENTED_StmtAssert + assert fut is self._read_fut, (fut, self._read_fut) + # EMPTY LINE WITH WHITESPACE (this comment will be removed) @@ -228,7 +226,7 @@ def function_signature_stress_test( def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""): offset = attr.ib(default=attr.Factory(lambda NOT_YET_IMPLEMENTED_lambda: True)) - NOT_YET_IMPLEMENTED_StmtAssert + assert task._cancel_stack[ : len(old_stack)] == old_stack def spaces_types( @@ -246,7 +244,7 @@ def spaces_types( def spaces2(result=_core.Value(None)): - NOT_YET_IMPLEMENTED_StmtAssert + assert fut is self._read_fut, (fut, self._read_fut) # EMPTY LINE WITH WHITESPACE (this comment will be removed) diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap index 058819773d264..69341cf62750c 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap @@ -41,7 +41,7 @@ assert ( ```diff --- Black +++ Ruff -@@ -2,20 +2,10 @@ +@@ -2,7 +2,7 @@ ( () << 0 @@ -49,22 +49,8 @@ assert ( + **101234234242352525425252352352525234890264906820496920680926538059059209922523523525 ) # --assert sort_by_dependency( -- { -- "1": {"2", "3"}, -- "2": {"2a", "2b"}, -- "3": {"3a", "3b"}, -- "2a": set(), -- "2b": set(), -- "3a": set(), -- "3b": set(), -- } --) == ["2a", "2b", "2", "3a", "3b", "3", "1"] -+NOT_YET_IMPLEMENTED_StmtAssert - - importA - 0 -@@ -25,9 +15,7 @@ + assert sort_by_dependency( +@@ -25,9 +25,7 @@ class A: def foo(self): for _ in range(10): @@ -75,15 +61,6 @@ assert ( def test(self, othr): -@@ -52,7 +40,4 @@ - ) - - --assert a_function( -- very_long_arguments_that_surpass_the_limit, -- which_is_eighty_eight_in_this_case_plus_a_bit_more, --) == {"x": "this need to pass the line limit as well", "b": "but only by a little bit"} -+NOT_YET_IMPLEMENTED_StmtAssert ``` ## Ruff Output @@ -96,7 +73,17 @@ importA **101234234242352525425252352352525234890264906820496920680926538059059209922523523525 ) # -NOT_YET_IMPLEMENTED_StmtAssert +assert sort_by_dependency( + { + "1": {"2", "3"}, + "2": {"2a", "2b"}, + "3": {"3a", "3b"}, + "2a": set(), + "2b": set(), + "3a": set(), + "3b": set(), + } +) == ["2a", "2b", "2", "3a", "3b", "3", "1"] importA 0 @@ -131,7 +118,10 @@ def test(self, othr): ) -NOT_YET_IMPLEMENTED_StmtAssert +assert a_function( + very_long_arguments_that_surpass_the_limit, + which_is_eighty_eight_in_this_case_plus_a_bit_more, +) == {"x": "this need to pass the line limit as well", "b": "but only by a little bit"} ``` ## Black Output diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap index 5084e5caa424c..6a978187fcc96 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap @@ -56,23 +56,14 @@ assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx( # Example from https://github.com/psf/black/issues/3229 -@@ -37,14 +35,7 @@ - - # Edge case where a bug in a working-in-progress version of - # https://github.com/psf/black/pull/3370 causes an infinite recursion. --assert ( -- long_module.long_class.long_func().another_func() -- == long_module.long_class.long_func()["some_key"].another_func(arg1) --) -+NOT_YET_IMPLEMENTED_StmtAssert - +@@ -45,6 +43,4 @@ # Regression test for https://github.com/psf/black/issues/3414. --assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx( -- xxxxxxxxx + assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx( + xxxxxxxxx -).xxxxxxxxxxxxxxxxxx(), ( - "xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -) -+NOT_YET_IMPLEMENTED_StmtAssert ++).xxxxxxxxxxxxxxxxxx(), "xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` ## Ruff Output @@ -115,10 +106,15 @@ def refresh_token(self, device_family, refresh_token, api_key): # Edge case where a bug in a working-in-progress version of # https://github.com/psf/black/pull/3370 causes an infinite recursion. -NOT_YET_IMPLEMENTED_StmtAssert +assert ( + long_module.long_class.long_func().another_func() + == long_module.long_class.long_func()["some_key"].another_func(arg1) +) # Regression test for https://github.com/psf/black/issues/3414. -NOT_YET_IMPLEMENTED_StmtAssert +assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx( + xxxxxxxxx +).xxxxxxxxxxxxxxxxxx(), "xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` ## Black Output diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__assert.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__assert.py.snap new file mode 100644 index 0000000000000..089244c385f89 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__assert.py.snap @@ -0,0 +1,77 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assert.py +--- +## Input +```py +assert True # Trailing same-line +assert True is True # Trailing same-line +assert 1, "Some string" # Trailing same-line +assert aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # Trailing same-line + +assert ( # Dangle1 + # Dangle2 +) + +# TODO: https://github.com/astral-sh/ruff/pull/5168#issuecomment-1630767421 +# Leading assert +assert ( + # Leading test value + True # Trailing test value same-line + # Trailing test value own-line +), "Some string" # Trailing msg same-line +# Trailing assert + +# Random dangler + +# TODO: https://github.com/astral-sh/ruff/pull/5168#issuecomment-1630767421 +# Leading assert +assert ( + # Leading test value + True # Trailing test value same-line + # Trailing test value own-line + + # Test dangler +), "Some string" # Trailing msg same-line +# Trailing assert +``` + +## Output +```py +assert True # Trailing same-line +assert True is True # Trailing same-line +assert 1, "Some string" # Trailing same-line +assert aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # Trailing same-line + +assert ( # Dangle1 + # Dangle2 +) + +# TODO: https://github.com/astral-sh/ruff/pull/5168#issuecomment-1630767421 +# Leading assert +assert ( + # Leading test value + True # Trailing test value same-line +), ( + # Trailing test value own-line + "Some string" +) # Trailing msg same-line +# Trailing assert + +# Random dangler + +# TODO: https://github.com/astral-sh/ruff/pull/5168#issuecomment-1630767421 +# Leading assert +assert ( + # Leading test value + True # Trailing test value same-line +), ( + # Trailing test value own-line + # Test dangler + "Some string" +) # Trailing msg same-line +# Trailing assert +``` + + +