Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format assert statement #5168

Merged
merged 23 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
assert (
# Asserted
)

# Some assert
assert (
# Let's go inside
True # Go around this
# Below that
), "Some string" # Outside this way
# Passed all that

# Dangle this here

# Some assert
assert (
# Let's go inside
True # Go around this
# Below that

# Dangle that there
), "Some string" # Outside this way
# Passed all that
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
---
## Input
```py
assert (
# Asserted
)

# Some assert
assert (
# Let's go inside
True # Go around this
# Below that
), "Some string" # Outside this way
# Passed all that

# Dangle this here

# Some assert
assert (
# Let's go inside
True # Go around this
# Below that

# Dangle that there
), "Some string" # Outside this way
# Passed all that
```



## Output
```py
assert (
# Asserted
)

# Some assert
assert (
# Let's go inside
True # Go around this
# Below that
), "Some string" # Outside this way
# Passed all that

# Dangle this here

# Some assert
assert (
# Let's go inside
True # Go around this
# Below that
# Dangle that there
), "Some string" # Outside this way
# Passed all that
```


32 changes: 30 additions & 2 deletions crates/ruff_python_formatter/src/statement/stmt_assert.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
use crate::expression::parentheses::Parenthesize;
use crate::{AsFormat, FormatNodeRule, PyFormatter};
use ruff_formatter::prelude::{space, text};
use ruff_formatter::{write, Buffer, FormatResult};
use rustpython_parser::ast::StmtAssert;

Expand All @@ -7,6 +9,32 @@ pub struct FormatStmtAssert;

impl FormatNodeRule<StmtAssert> for FormatStmtAssert {
fn fmt_fields(&self, item: &StmtAssert, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [not_yet_implemented(item)])
let StmtAssert {
range: _,
test,
msg,
} = item;
if let Some(msg) = msg {
write!(
f,
[
text("assert"),
space(),
test.format().with_options(Parenthesize::IfBreaks),
text(","),
space(),
msg.format().with_options(Parenthesize::IfBreaks)
]
)
} else {
write!(
f,
[
text("assert"),
space(),
test.format().with_options(Parenthesize::IfBreaks)
]
)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I prefer to keep the shared logic outside of the if..else branches. It avoids that the reader has to parse both branches of the if statement to identify what's difference between them

Suggested change
if let Some(msg) = msg {
write!(
f,
[
text("assert"),
space(),
test.format().with_options(Parenthesize::IfBreaks),
text(","),
space(),
msg.format().with_options(Parenthesize::IfBreaks)
]
)
} else {
write!(
f,
[
text("assert"),
space(),
test.format().with_options(Parenthesize::IfBreaks)
]
)
}
write!(f, [
text("assert"),
space(),
test.format().with_options(Parenthesize::IfBreaks),
])?;
if let Some(msg) = msg {
write!(
f,
[
text(","),
space(),
msg.format().with_options(Parenthesize::IfBreaks)
]
)
}
Ok(())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh I don't even see this as a nit lol.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up adding a group, so I've deviated from your suggestion. I'm still finding my feet with some of this stuff, so feel free to tell me to stop over-implementing this.

I'd want to format this next

# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
    xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
    "xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)

And then finally figure out comment placement, but I can rip out the fixture I've added for that and follow up after this is merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 709c4a7

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Yeah, it can sometimes be very subtle.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -358,37 +358,7 @@ 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 +163,13 @@

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, 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

some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
@@ -212,29 +198,25 @@
@@ -212,29 +210,25 @@
)

func_with_bad_comma(
Expand Down Expand Up @@ -425,7 +395,7 @@ long_unmergable_string_with_pragma = (
x,
y,
z,
@@ -243,21 +225,13 @@
@@ -243,21 +237,13 @@
func_with_bad_parens(
x,
y,
Expand All @@ -451,7 +421,7 @@ long_unmergable_string_with_pragma = (

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 \\\\"
@@ -271,10 +245,10 @@
@@ -271,10 +257,10 @@


def foo():
Expand Down Expand Up @@ -634,13 +604,25 @@ 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, "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, NOT_YET_IMPLEMENTED_ExprJoinedStr

prev = leaf.prev_sibling
if not prev:
Expand Down Expand Up @@ -172,7 +172,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, NOT_YET_IMPLEMENTED_ExprJoinedStr

prev = leaf.prev_sibling
if not prev:
Expand Down Expand Up @@ -222,7 +222,7 @@ def f():
if t == token.COMMENT: # another trailing comment
return DOUBLESPACE

NOT_YET_IMPLEMENTED_StmtAssert
assert p is not None, NOT_YET_IMPLEMENTED_ExprJoinedStr

prev = leaf.prev_sibling
if not prev:
Expand Down Expand Up @@ -280,7 +280,7 @@ def g():
return DOUBLESPACE

# Another comment because more comments
NOT_YET_IMPLEMENTED_StmtAssert
assert p is not None, NOT_YET_IMPLEMENTED_ExprJoinedStr

prev = leaf.prev_sibling
if not prev:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,16 +397,16 @@ last_call()
- int,
- float,
- dict[str, int],
-]
-very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
+ (
+ str,
+ int,
+ float,
+ dict[str, int],
+ )
]
-very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
-]
-xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
- sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
-)
Expand Down Expand Up @@ -506,7 +506,7 @@ last_call()
Ø = set()
authors.łukasz.say_thanks()
mapping = {
@@ -237,29 +221,33 @@
@@ -237,19 +221,23 @@


def gen():
Expand All @@ -527,22 +527,17 @@ last_call()
-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(*NOT_YET_IMPLEMENTED_ExprStarred)
+print(
+ **{1: 3}
+ if False
+ else {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+)
+print(*NOT_YET_IMPLEMENTED_ExprStarred)
+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 +247,9 @@
...
for y in ():
...
Expand All @@ -553,7 +548,7 @@ last_call()
...
for i in call():
...
@@ -328,13 +316,18 @@
@@ -328,13 +318,18 @@
):
return True
if (
Expand All @@ -575,7 +570,7 @@ last_call()
^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n
):
return True
@@ -342,7 +335,8 @@
@@ -342,7 +337,8 @@
~aaaaaaaaaaaaaaaa.a
+ aaaaaaaaaaaaaaaa.b
- aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e
Expand Down Expand Up @@ -830,9 +825,11 @@ print(
else {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
)
print(*NOT_YET_IMPLEMENTED_ExprStarred)
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 ():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 x: True))
+ NOT_YET_IMPLEMENTED_StmtAssert
+ assert task._cancel_stack[ : len(old_stack)] == old_stack


def spaces_types(
Expand Down Expand Up @@ -458,7 +458,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 x: True))
NOT_YET_IMPLEMENTED_StmtAssert
assert task._cancel_stack[ : len(old_stack)] == old_stack


def spaces_types(
Expand Down
Loading