Parenthesize match..case if guards (#13513)

This commit is contained in:
Micha Reiser 2024-09-26 08:44:33 +02:00 committed by GitHub
parent 8012707348
commit 9442cd8fae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 155 additions and 88 deletions

View file

@ -59,6 +59,10 @@ pub(crate) enum Parenthesize {
/// Same as [`Self::IfBreaks`] except that it uses [`parenthesize_if_expands`] for expressions
/// with the layout [`NeedsParentheses::BestFit`] which is used by non-splittable
/// expressions like literals, name, and strings.
///
/// Use this layout over `IfBreaks` when there's a sequence of `maybe_parenthesize_expression`
/// in a single logical-line and you want to break from right-to-left. Use `IfBreaks` for the
/// first expression and `IfBreaksParenthesized` for the rest.
IfBreaksParenthesized,
/// Same as [`Self::IfBreaksParenthesized`] but uses [`parenthesize_if_expands`] for nested

View file

@ -3,7 +3,10 @@ use ruff_python_ast::AstNode;
use ruff_python_ast::MatchCase;
use crate::builders::parenthesize_if_expands;
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::{
NeedsParentheses, OptionalParentheses, Parentheses, Parenthesize,
};
use crate::pattern::maybe_parenthesize_pattern;
use crate::prelude::*;
use crate::preview::is_match_case_parentheses_enabled;
@ -62,6 +65,19 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
}
});
let format_guard = guard.as_deref().map(|guard| {
format_with(|f| {
write!(f, [space(), token("if"), space()])?;
if is_match_case_parentheses_enabled(f.context()) {
maybe_parenthesize_expression(guard, item, Parenthesize::IfBreaksParenthesized)
.fmt(f)
} else {
guard.format().fmt(f)
}
})
});
write!(
f,
[
@ -69,13 +85,7 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
ClauseHeader::MatchCase(item),
dangling_item_comments,
&format_with(|f| {
write!(f, [token("case"), space(), format_pattern])?;
if let Some(guard) = guard {
write!(f, [space(), token("if"), space(), guard.format()])?;
}
Ok(())
write!(f, [token("case"), space(), format_pattern, format_guard])
}),
),
clause_body(

View file

@ -39,6 +39,8 @@ pub(crate) fn is_empty_parameters_no_unnecessary_parentheses_around_return_value
/// See [#6933](https://github.com/astral-sh/ruff/issues/6933).
/// This style also covers the black preview styles `remove_redundant_guard_parens` and `parens_for_long_if_clauses_in_case_block `.
/// WARNING: This preview style depends on `is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled`
/// because it relies on the new semantic of `IfBreaksParenthesized`.
pub(crate) fn is_match_case_parentheses_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}