mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 12:55:05 +00:00
Fix formatting of single with-item with trailing comment (#14005)
This commit is contained in:
parent
20b8a43017
commit
cf0f5e1318
5 changed files with 276 additions and 14 deletions
|
@ -6,9 +6,11 @@ use crate::expression::parentheses::{
|
|||
is_expression_parenthesized, parenthesized, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::preview::is_with_single_item_pre_39_enabled;
|
||||
use crate::preview::{
|
||||
is_with_single_item_pre_39_enabled, is_with_single_target_parentheses_enabled,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum WithItemLayout {
|
||||
/// A with item that is the `with`s only context manager and its context expression is parenthesized.
|
||||
///
|
||||
|
@ -69,8 +71,7 @@ pub enum WithItemLayout {
|
|||
/// a
|
||||
// ): ...
|
||||
/// ```
|
||||
#[default]
|
||||
ParenthesizedContextManagers,
|
||||
ParenthesizedContextManagers { single: bool },
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -78,6 +79,12 @@ pub struct FormatWithItem {
|
|||
layout: WithItemLayout,
|
||||
}
|
||||
|
||||
impl Default for WithItemLayout {
|
||||
fn default() -> Self {
|
||||
WithItemLayout::ParenthesizedContextManagers { single: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl FormatRuleWithOptions<WithItem, PyFormatContext<'_>> for FormatWithItem {
|
||||
type Options = WithItemLayout;
|
||||
|
||||
|
@ -97,6 +104,10 @@ impl FormatNodeRule<WithItem> for FormatWithItem {
|
|||
let comments = f.context().comments().clone();
|
||||
let trailing_as_comments = comments.dangling(item);
|
||||
|
||||
// WARNING: The `is_parenthesized` returns false-positives
|
||||
// if the `with` has a single item without a target.
|
||||
// E.g., it returns `true` for `with (a)` even though the parentheses
|
||||
// belong to the with statement and not the expression but it can't determine that.
|
||||
let is_parenthesized = is_expression_parenthesized(
|
||||
context_expr.into(),
|
||||
f.context().comments().ranges(),
|
||||
|
@ -105,10 +116,17 @@ impl FormatNodeRule<WithItem> for FormatWithItem {
|
|||
|
||||
match self.layout {
|
||||
// Remove the parentheses of the `with_items` if the with statement adds parentheses
|
||||
WithItemLayout::ParenthesizedContextManagers => {
|
||||
if is_parenthesized {
|
||||
// ...except if the with item is parenthesized, then use this with item as a preferred breaking point
|
||||
// or when it has comments, then parenthesize it to prevent comments from moving.
|
||||
WithItemLayout::ParenthesizedContextManagers { single } => {
|
||||
// ...except if the with item is parenthesized and it's not the only with item or it has a target.
|
||||
// Then use the context expression as a preferred breaking point.
|
||||
let prefer_breaking_context_expression =
|
||||
if is_with_single_target_parentheses_enabled(f.context()) {
|
||||
(optional_vars.is_some() || !single) && is_parenthesized
|
||||
} else {
|
||||
is_parenthesized
|
||||
};
|
||||
|
||||
if prefer_breaking_context_expression {
|
||||
maybe_parenthesize_expression(
|
||||
context_expr,
|
||||
item,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue