Skip to content

Commit

Permalink
Align formatting of patterns in match-cases with expression formattin…
Browse files Browse the repository at this point in the history
…g in clause headers (#13510)
  • Loading branch information
MichaReiser committed Sep 26, 2024
1 parent d7ffe46 commit 8012707
Show file tree
Hide file tree
Showing 12 changed files with 1,608 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
# Patterns that use BestFit should be parenthesized if they exceed the configured line width
# but fit within parentheses.
match x:
case (
"averyLongStringThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsPar"
):
pass


match x:
case (
b"averyLongStringThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsPa"
):
pass

match x:
case (
f"averyLongStringThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsPa"
):
pass


match x:
case (
5444444444444444444444444444444444444444444444444444444444444444444444444444444j
):
pass


match x:
case (
5444444444444444444444444444444444444444444444444444444444444444444444444444444
):
pass


match x:
case (
5.44444444444444444444444444444444444444444444444444444444444444444444444444444
):
pass


match x:
case (
averyLongIdentThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsParenth
):
pass


# But they aren't parenthesized when they exceed the line length even parenthesized
match x:
case "averyLongStringThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsParenthesized":
pass


match x:
case b"averyLongStringThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsParenthesized":
pass

match x:
case f"averyLongStringThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsParenthesized":
pass


match x:
case 54444444444444444444444444444444444444444444444444444444444444444444444444444444444j:
pass


match x:
case 5444444444444444444444444444444444444444444444444444444444444444444444444444444444:
pass


match x:
case 5.444444444444444444444444444444444444444444444444444444444444444444444444444444444:
pass


match x:
case averyLongIdentifierThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsParenthesized:
pass


# It uses the Multiline layout when there's an alias.
match x:
case (
averyLongIdentifierThatGetsParenthesizedOnceItExceedsTheConfiguredLineWidthFitsParenthe as b
):
pass



match x:
case (
"an implicit concatenated" "string literal" "in a match case" "that goes over multiple lines"
):
pass


## Patterns ending with a sequence, mapping, class, or parenthesized pattern should break the parenthesized-like pattern first
match x:
case A | [
aaaaaa,
bbbbbbbbbbbbbbbb,
cccccccccccccccccc,
ddddddddddddddddddddddddddd,
]:
pass

match x:
case A | (
aaaaaa,
bbbbbbbbbbbbbbbb,
cccccccccccccccccc,
ddddddddddddddddddddddddddd,
):
pass


match x:
case A | {
"a": aaaaaa,
"b": bbbbbbbbbbbbbbbb,
"c": cccccccccccccccccc,
"d": ddddddddddddddddddddddddddd,
}:
pass


match x:
case A | Class(
aaaaaa,
bbbbbbbbbbbbbbbb,
cccccccccccccccccc,
ddddddddddddddddddddddddddd,
):
pass



match x:
case A | (
aaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc.ddddddddddddddddddddddd
):
pass


## Patterns starting with a sequence, mapping, class, or parenthesized pattern should break the parenthesized-like pattern first
match x:
case [
aaaaaa,
bbbbbbbbbbbbbbbb,
cccccccccccccccccc,
ddddddddddddddddddddddddddd,
] | A:
pass

match x:
case (
aaaaaa,
bbbbbbbbbbbbbbbb,
cccccccccccccccccc,
ddddddddddddddddddddddddddd,
) | A:
pass


match x:
case {
"a": aaaaaa,
"b": bbbbbbbbbbbbbbbb,
"c": cccccccccccccccccc,
"d": ddddddddddddddddddddddddddd,
} | A:
pass


match x:
case Class(
aaaaaa,
bbbbbbbbbbbbbbbb,
cccccccccccccccccc,
ddddddddddddddddddddddddddd,
):
pass


## Not for non-parenthesized sequence patterns
match x:
case (
(1) | aaaaaaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccccccccccccccc,
):
pass

## Parenthesize patterns that start with a token
match x:
case (
A(
aaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc.ddddddddddddddddddddddd
)
| B
):
pass


## Always use parentheses for implicitly concatenated strings
match x:
case (
"implicit"
"concatenated"
"string"
| [aaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccccc, ddddddddddddddddddddddddddd]
):
pass


match x:
case (
b"implicit"
b"concatenated"
b"string"
| [aaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccccc, ddddddddddddddddddddddddddd]
):
pass


match x:
case (
f"implicit"
"concatenated"
"string"
| [aaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccccc, ddddddddddddddddddddddddddd]
):
pass


## Complex number expressions and unary expressions

match x:
case 4 - 3j | [
aaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbb,
cccccccccccccccccccccccccccccccccccccccc,
]:
pass


match x:
case 4 + 3j | [
aaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbb,
cccccccccccccccccccccccccccccccccccccccc,
]:
pass


match x:
case -1 | [
aaaaaaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccccccccccccccc,
]:
pass



### Parenthesized patterns
match x:
case (1) | [
aaaaaaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccccccccccccccc,
]:
pass


match x:
case ( # comment
1
) | [
aaaaaaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccccccccccccccc,
]:
pass



55 changes: 29 additions & 26 deletions crates/ruff_python_formatter/src/other/match_case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use ruff_python_ast::MatchCase;

use crate::builders::parenthesize_if_expands;
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
use crate::pattern::maybe_parenthesize_pattern;
use crate::prelude::*;
use crate::preview::is_match_case_parentheses_enabled;
use crate::statement::clause::{clause_body, clause_header, ClauseHeader};
use crate::statement::suite::SuiteKind;

Expand Down Expand Up @@ -34,39 +36,40 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
let comments = f.context().comments().clone();
let dangling_item_comments = comments.dangling(item);

let format_pattern = format_with(|f| {
if is_match_case_parentheses_enabled(f.context()) {
maybe_parenthesize_pattern(pattern, item).fmt(f)
} else {
let has_comments =
comments.has_leading(pattern) || comments.has_trailing_own_line(pattern);

if has_comments {
pattern.format().with_options(Parentheses::Always).fmt(f)
} else {
match pattern.needs_parentheses(item.as_any_node_ref(), f.context()) {
OptionalParentheses::Multiline => parenthesize_if_expands(
&pattern.format().with_options(Parentheses::Never),
)
.fmt(f),
OptionalParentheses::Always => {
pattern.format().with_options(Parentheses::Always).fmt(f)
}
OptionalParentheses::Never | OptionalParentheses::BestFit => {
pattern.format().with_options(Parentheses::Never).fmt(f)
}
}
}
}
});

write!(
f,
[
clause_header(
ClauseHeader::MatchCase(item),
dangling_item_comments,
&format_with(|f| {
write!(f, [token("case"), space()])?;

let has_comments = comments.has_leading(pattern)
|| comments.has_trailing_own_line(pattern);

if has_comments {
pattern.format().with_options(Parentheses::Always).fmt(f)?;
} else {
match pattern.needs_parentheses(item.as_any_node_ref(), f.context()) {
OptionalParentheses::Multiline => {
parenthesize_if_expands(
&pattern.format().with_options(Parentheses::Never),
)
.fmt(f)?;
}
OptionalParentheses::Always => {
pattern.format().with_options(Parentheses::Always).fmt(f)?;
}
OptionalParentheses::Never => {
pattern.format().with_options(Parentheses::Never).fmt(f)?;
}
OptionalParentheses::BestFit => {
pattern.format().with_options(Parentheses::Never).fmt(f)?;
}
}
}
write!(f, [token("case"), space(), format_pattern])?;

if let Some(guard) = guard {
write!(f, [space(), token("if"), space(), guard.format()])?;
Expand Down
Loading

0 comments on commit 8012707

Please sign in to comment.