mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
Format Slice Expressions (#5047)
This formats slice expressions and subscript expressions. Spaces around the colons follows the same rules as black (https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices): ```python e00 = "e"[:] e01 = "e"[:1] e02 = "e"[: a()] e10 = "e"[1:] e11 = "e"[1:1] e12 = "e"[1 : a()] e20 = "e"[a() :] e21 = "e"[a() : 1] e22 = "e"[a() : a()] e200 = "e"[a() : :] e201 = "e"[a() :: 1] e202 = "e"[a() :: a()] e210 = "e"[a() : 1 :] ``` Comment placement is different due to our very different infrastructure. If we have explicit bounds (e.g. `x[1:2]`) all comments get assigned as leading or trailing to the bound expression. If a bound is missing `[:]`, comments get marked as dangling and placed in the same section as they were originally in: ```python x = "x"[ # a # b : # c # d ] ``` to ```python x = "x"[ # a # b : # c # d ] ``` Except for the potential trailing end-of-line comments, all comments get formatted on their own line. This can be improved by keeping end-of-line comments after the opening bracket or after a colon as such but the changes were already complex enough. I added tests for comment placement and spaces.
This commit is contained in:
parent
4634560c80
commit
6155fd647d
22 changed files with 1065 additions and 430 deletions
|
@ -1,24 +1,52 @@
|
|||
use crate::comments::{trailing_comments, Comments};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
use crate::comments::Comments;
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{group, soft_block_indent, text};
|
||||
use ruff_formatter::{format_args, write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use rustpython_parser::ast::ExprSubscript;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatExprSubscript;
|
||||
|
||||
impl FormatNodeRule<ExprSubscript> for FormatExprSubscript {
|
||||
fn fmt_fields(&self, _item: &ExprSubscript, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
fn fmt_fields(&self, item: &ExprSubscript, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let ExprSubscript {
|
||||
range: _,
|
||||
value,
|
||||
slice,
|
||||
ctx: _,
|
||||
} = item;
|
||||
|
||||
let comments = f.context().comments().clone();
|
||||
let dangling_comments = comments.dangling_comments(item.as_any_node_ref());
|
||||
debug_assert!(
|
||||
dangling_comments.len() <= 1,
|
||||
"The subscript expression must have at most a single comment, the one after the bracket"
|
||||
);
|
||||
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]"
|
||||
)]
|
||||
[group(&format_args![
|
||||
value.format(),
|
||||
text("["),
|
||||
trailing_comments(dangling_comments),
|
||||
soft_block_indent(&slice.format()),
|
||||
text("]")
|
||||
])]
|
||||
)
|
||||
}
|
||||
|
||||
fn fmt_dangling_comments(
|
||||
&self,
|
||||
_node: &ExprSubscript,
|
||||
_f: &mut PyFormatter,
|
||||
) -> FormatResult<()> {
|
||||
// Handled inside of `fmt_fields`
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl NeedsParentheses for ExprSubscript {
|
||||
|
@ -28,6 +56,9 @@ impl NeedsParentheses for ExprSubscript {
|
|||
source: &str,
|
||||
comments: &Comments,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, source, comments)
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue