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:
konstin 2023-06-21 17:09:39 +02:00 committed by GitHub
parent 4634560c80
commit 6155fd647d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1065 additions and 430 deletions

View file

@ -0,0 +1,82 @@
# Handle comments both when lower and upper exist and when they don't
a1 = "a"[
# a
1 # b
: # c
2 # d
]
a2 = "a"[
# a
# b
: # c
# d
]
# Check all places where comments can exist
b1 = "b"[ # a
# b
1 # c
# d
: # e
# f
2 # g
# h
: # i
# j
3 # k
# l
]
# Handle the spacing from the colon correctly with upper leading comments
c1 = "c"[
1
: # e
# f
2
]
c2 = "c"[
1
: # e
2
]
c3 = "c"[
1
:
# f
2
]
c4 = "c"[
1
: # f
2
]
# End of line comments
d1 = "d"[ # comment
:
]
d2 = "d"[ # comment
1:
]
d3 = "d"[
1 # comment
:
]
# Spacing around the colon(s)
def a():
...
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 :]

View file

@ -1,16 +1,14 @@
use std::cmp::Ordering; use crate::comments::visitor::{CommentPlacement, DecoratedComment};
use crate::comments::CommentLinePosition;
use ruff_text_size::{TextRange, TextSize}; use crate::expression::expr_slice::{assign_comment_in_slice, ExprSliceCommentSection};
use rustpython_parser::ast::Ranged; use crate::trivia::{first_non_trivia_token_rev, SimpleTokenizer, Token, TokenKind};
use ruff_python_ast::node::{AnyNodeRef, AstNode};
use ruff_python_ast::node::AnyNodeRef;
use ruff_python_ast::source_code::Locator; use ruff_python_ast::source_code::Locator;
use ruff_python_ast::whitespace; use ruff_python_ast::whitespace;
use ruff_python_whitespace::{PythonWhitespace, UniversalNewlines}; use ruff_python_whitespace::{PythonWhitespace, UniversalNewlines};
use ruff_text_size::{TextRange, TextSize};
use crate::comments::visitor::{CommentPlacement, DecoratedComment}; use rustpython_parser::ast::{Expr, ExprSlice, Ranged};
use crate::comments::CommentLinePosition; use std::cmp::Ordering;
use crate::trivia::{SimpleTokenizer, Token, TokenKind};
/// Implements the custom comment placement logic. /// Implements the custom comment placement logic.
pub(super) fn place_comment<'a>( pub(super) fn place_comment<'a>(
@ -30,6 +28,7 @@ pub(super) fn place_comment<'a>(
handle_trailing_binary_expression_left_or_operator_comment, handle_trailing_binary_expression_left_or_operator_comment,
handle_leading_function_with_decorators_comment, handle_leading_function_with_decorators_comment,
handle_dict_unpacking_comment, handle_dict_unpacking_comment,
handle_slice_comments,
]; ];
for handler in HANDLERS { for handler in HANDLERS {
comment = match handler(comment, locator) { comment = match handler(comment, locator) {
@ -837,6 +836,87 @@ fn handle_module_level_own_line_comment_before_class_or_function_comment<'a>(
} }
} }
/// Handles the attaching comments left or right of the colon in a slice as trailing comment of the
/// preceding node or leading comment of the following node respectively.
/// ```python
/// a = "input"[
/// 1 # c
/// # d
/// :2
/// ]
/// ```
fn handle_slice_comments<'a>(
comment: DecoratedComment<'a>,
locator: &Locator,
) -> CommentPlacement<'a> {
let expr_slice = match comment.enclosing_node() {
AnyNodeRef::ExprSlice(expr_slice) => expr_slice,
AnyNodeRef::ExprSubscript(expr_subscript) => {
if expr_subscript.value.end() < expr_subscript.slice.start() {
if let Expr::Slice(expr_slice) = expr_subscript.slice.as_ref() {
expr_slice
} else {
return CommentPlacement::Default(comment);
}
} else {
return CommentPlacement::Default(comment);
}
}
_ => return CommentPlacement::Default(comment),
};
let ExprSlice {
range: _,
lower,
upper,
step,
} = expr_slice;
// Check for `foo[ # comment`, but only if they are on the same line
let after_lbracket = matches!(
first_non_trivia_token_rev(comment.slice().start(), locator.contents()),
Some(Token {
kind: TokenKind::LBracket,
..
})
);
if comment.line_position().is_end_of_line() && after_lbracket {
// Keep comments after the opening bracket there by formatting them outside the
// soft block indent
// ```python
// "a"[ # comment
// 1:
// ]
// ```
debug_assert!(
matches!(comment.enclosing_node(), AnyNodeRef::ExprSubscript(_)),
"{:?}",
comment.enclosing_node()
);
return CommentPlacement::dangling(comment.enclosing_node(), comment);
}
let assignment =
assign_comment_in_slice(comment.slice().range(), locator.contents(), expr_slice);
let node = match assignment {
ExprSliceCommentSection::Lower => lower,
ExprSliceCommentSection::Upper => upper,
ExprSliceCommentSection::Step => step,
};
if let Some(node) = node {
if comment.slice().start() < node.start() {
CommentPlacement::leading(node.as_ref().into(), comment)
} else {
// If a trailing comment is an end of line comment that's fine because we have a node
// ahead of it
CommentPlacement::trailing(node.as_ref().into(), comment)
}
} else {
CommentPlacement::dangling(expr_slice.as_any_node_ref(), comment)
}
}
/// Finds the offset of the `/` that separates the positional only and arguments from the other arguments. /// Finds the offset of the `/` that separates the positional only and arguments from the other arguments.
/// Returns `None` if the positional only separator `/` isn't present in the specified range. /// Returns `None` if the positional only separator `/` isn't present in the specified range.
fn find_pos_only_slash_offset( fn find_pos_only_slash_offset(

View file

@ -1,26 +1,264 @@
use crate::comments::{dangling_comments, Comments, SourceComment};
use crate::expression::parentheses::{ use crate::expression::parentheses::{
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize, default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
}; };
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter}; use crate::trivia::Token;
use crate::trivia::{first_non_trivia_token, TokenKind};
use crate::comments::Comments; use crate::{AsFormat, FormatNodeRule, PyFormatter};
use ruff_formatter::{write, Buffer, FormatResult}; use ruff_formatter::prelude::{hard_line_break, line_suffix_boundary, space, text};
use ruff_formatter::{write, Buffer, Format, FormatError, FormatResult};
use ruff_python_ast::node::AstNode;
use ruff_python_ast::prelude::{Expr, Ranged};
use ruff_text_size::TextRange;
use rustpython_parser::ast::ExprSlice; use rustpython_parser::ast::ExprSlice;
#[derive(Default)] #[derive(Default)]
pub struct FormatExprSlice; pub struct FormatExprSlice;
impl FormatNodeRule<ExprSlice> for FormatExprSlice { impl FormatNodeRule<ExprSlice> for FormatExprSlice {
fn fmt_fields(&self, _item: &ExprSlice, f: &mut PyFormatter) -> FormatResult<()> { /// This implementation deviates from black in that comments are attached to the section of the
write!( /// slice they originate in
f, fn fmt_fields(&self, item: &ExprSlice, f: &mut PyFormatter) -> FormatResult<()> {
[not_yet_implemented_custom_text( // `[lower:upper:step]`
"NOT_IMPLEMENTED_start:NOT_IMPLEMENTED_end" let ExprSlice {
)] range,
) lower,
upper,
step,
} = item;
let (first_colon, second_colon) =
find_colons(f.context().contents(), *range, lower, upper)?;
// Handle comment placement
// In placements.rs, we marked comment for None nodes a dangling and associated all others
// as leading or dangling wrt to a node. That means we either format a node and only have
// to handle newlines and spacing, or the node is None and we insert the corresponding
// slice of dangling comments
let comments = f.context().comments().clone();
let slice_dangling_comments = comments.dangling_comments(item.as_any_node_ref());
// Put the dangling comments (where the nodes are missing) into buckets
let first_colon_partition_index = slice_dangling_comments
.partition_point(|x| x.slice().start() < first_colon.range.start());
let (dangling_lower_comments, dangling_upper_step_comments) =
slice_dangling_comments.split_at(first_colon_partition_index);
let (dangling_upper_comments, dangling_step_comments) =
if let Some(second_colon) = &second_colon {
let second_colon_partition_index = dangling_upper_step_comments
.partition_point(|x| x.slice().start() < second_colon.range.start());
dangling_upper_step_comments.split_at(second_colon_partition_index)
} else {
// Without a second colon they remaining dangling comments belong between the first
// colon and the closing parentheses
(dangling_upper_step_comments, [].as_slice())
};
// Ensure there a no dangling comments for a node if the node is present
debug_assert!(lower.is_none() || dangling_lower_comments.is_empty());
debug_assert!(upper.is_none() || dangling_upper_comments.is_empty());
debug_assert!(step.is_none() || dangling_step_comments.is_empty());
// Handle spacing around the colon(s)
// https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices
let lower_simple = lower.as_ref().map_or(true, |expr| is_simple_expr(expr));
let upper_simple = upper.as_ref().map_or(true, |expr| is_simple_expr(expr));
let step_simple = step.as_ref().map_or(true, |expr| is_simple_expr(expr));
let all_simple = lower_simple && upper_simple && step_simple;
// lower
if let Some(lower) = lower {
write!(f, [lower.format(), line_suffix_boundary()])?;
} else {
dangling_comments(dangling_lower_comments).fmt(f)?;
}
// First colon
// The spacing after the colon depends on both the lhs and the rhs:
// ```
// e00 = x[:]
// e01 = x[:1]
// e02 = x[: a()]
// e10 = x[1:]
// e11 = x[1:1]
// e12 = x[1 : a()]
// e20 = x[a() :]
// e21 = x[a() : 1]
// e22 = x[a() : a()]
// e200 = "e"[a() : :]
// e201 = "e"[a() :: 1]
// e202 = "e"[a() :: a()]
// ```
if !all_simple {
space().fmt(f)?;
}
text(":").fmt(f)?;
// No upper node, no need for a space, e.g. `x[a() :]`
if !all_simple && upper.is_some() {
space().fmt(f)?;
}
// Upper
if let Some(upper) = upper {
let upper_leading_comments = comments.leading_comments(upper.as_ref());
leading_comments_spacing(f, upper_leading_comments)?;
write!(f, [upper.format(), line_suffix_boundary()])?;
} else {
if let Some(first) = dangling_upper_comments.first() {
// Here the spacing for end-of-line comments works but own line comments need
// explicit spacing
if first.line_position().is_own_line() {
hard_line_break().fmt(f)?;
}
}
dangling_comments(dangling_upper_comments).fmt(f)?;
}
// (optionally) step
if second_colon.is_some() {
// Same spacing rules as for the first colon, except for the strange case when the
// second colon exists, but neither upper nor step
// ```
// e200 = "e"[a() : :]
// e201 = "e"[a() :: 1]
// e202 = "e"[a() :: a()]
// ```
if !all_simple && (upper.is_some() || step.is_none()) {
space().fmt(f)?;
}
text(":").fmt(f)?;
// No step node, no need for a space
if !all_simple && step.is_some() {
space().fmt(f)?;
}
if let Some(step) = step {
let step_leading_comments = comments.leading_comments(step.as_ref());
leading_comments_spacing(f, step_leading_comments)?;
step.format().fmt(f)?;
} else {
if !dangling_step_comments.is_empty() {
// Put the colon and comments on their own lines
write!(
f,
[hard_line_break(), dangling_comments(dangling_step_comments)]
)?;
}
}
} else {
debug_assert!(step.is_none(), "step can't exist without a second colon");
}
Ok(())
} }
} }
/// We're in a slice, so we know there's a first colon, but with have to look into the source
/// to find out whether there is a second one, too, e.g. `[1:2]` and `[1:10:2]`.
///
/// Returns the first and optionally the second colon.
pub(crate) fn find_colons(
contents: &str,
range: TextRange,
lower: &Option<Box<Expr>>,
upper: &Option<Box<Expr>>,
) -> FormatResult<(Token, Option<Token>)> {
let after_lower = lower
.as_ref()
.map_or(range.start(), |lower| lower.range().end());
let first_colon =
first_non_trivia_token(after_lower, contents).ok_or(FormatError::SyntaxError)?;
if first_colon.kind != TokenKind::Colon {
return Err(FormatError::SyntaxError);
}
let after_upper = upper
.as_ref()
.map_or(first_colon.end(), |upper| upper.range().end());
// At least the closing bracket must exist, so there must be a token there
let next_token =
first_non_trivia_token(after_upper, contents).ok_or(FormatError::SyntaxError)?;
let second_colon = if next_token.kind == TokenKind::Colon {
debug_assert!(
next_token.range.start() < range.end(),
"The next token in a slice must either be a colon or the closing bracket"
);
Some(next_token)
} else {
None
};
Ok((first_colon, second_colon))
}
/// Determines whether this expression needs a space around the colon
/// <https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices>
fn is_simple_expr(expr: &Expr) -> bool {
matches!(expr, Expr::Constant(_) | Expr::Name(_))
}
pub(crate) enum ExprSliceCommentSection {
Lower,
Upper,
Step,
}
/// Assigns a comment to lower/upper/step in `[lower:upper:step]`.
///
/// ```python
/// "sliceable"[
/// # lower comment
/// :
/// # upper comment
/// :
/// # step comment
/// ]
/// ```
pub(crate) fn assign_comment_in_slice(
comment: TextRange,
contents: &str,
expr_slice: &ExprSlice,
) -> ExprSliceCommentSection {
let ExprSlice {
range,
lower,
upper,
step: _,
} = expr_slice;
let (first_colon, second_colon) = find_colons(contents, *range, lower, upper)
.expect("SyntaxError when trying to parse slice");
if comment.start() < first_colon.range.start() {
ExprSliceCommentSection::Lower
} else {
// We are to the right of the first colon
if let Some(second_colon) = second_colon {
if comment.start() < second_colon.range.start() {
ExprSliceCommentSection::Upper
} else {
ExprSliceCommentSection::Step
}
} else {
// No second colon means there is no step
ExprSliceCommentSection::Upper
}
}
}
/// Manual spacing for the leading comments of upper and step
fn leading_comments_spacing(
f: &mut PyFormatter,
leading_comments: &[SourceComment],
) -> FormatResult<()> {
if let Some(first) = leading_comments.first() {
if first.line_position().is_own_line() {
// Insert a newline after the colon so the comment ends up on its own line
hard_line_break().fmt(f)?;
} else {
// Insert the two spaces between the colon and the end-of-line comment after the colon
write!(f, [space(), space()])?;
}
}
Ok(())
}
impl NeedsParentheses for ExprSlice { impl NeedsParentheses for ExprSlice {
fn needs_parentheses( fn needs_parentheses(
&self, &self,

View file

@ -1,24 +1,52 @@
use crate::comments::{trailing_comments, Comments};
use crate::expression::parentheses::{ use crate::expression::parentheses::{
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize, default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
}; };
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter}; use crate::{AsFormat, FormatNodeRule, PyFormatter};
use ruff_formatter::prelude::{group, soft_block_indent, text};
use crate::comments::Comments; use ruff_formatter::{format_args, write, Buffer, FormatResult};
use ruff_formatter::{write, Buffer, FormatResult}; use ruff_python_ast::node::AstNode;
use rustpython_parser::ast::ExprSubscript; use rustpython_parser::ast::ExprSubscript;
#[derive(Default)] #[derive(Default)]
pub struct FormatExprSubscript; pub struct FormatExprSubscript;
impl FormatNodeRule<ExprSubscript> for 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!( write!(
f, f,
[not_yet_implemented_custom_text( [group(&format_args![
"NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]" 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 { impl NeedsParentheses for ExprSubscript {
@ -28,6 +56,9 @@ impl NeedsParentheses for ExprSubscript {
source: &str, source: &str,
comments: &Comments, comments: &Comments,
) -> Parentheses { ) -> 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,
}
} }
} }

View file

@ -2,10 +2,10 @@ use crate::comments::{trailing_comments, Comments};
use crate::expression::parentheses::{ use crate::expression::parentheses::{
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize, default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
}; };
use crate::prelude::*;
use crate::trivia::{SimpleTokenizer, TokenKind}; use crate::trivia::{SimpleTokenizer, TokenKind};
use crate::FormatNodeRule; use crate::{AsFormat, FormatNodeRule, PyFormatter};
use ruff_formatter::FormatContext; use ruff_formatter::prelude::{hard_line_break, space, text};
use ruff_formatter::{Format, FormatContext, FormatResult};
use ruff_python_ast::prelude::UnaryOp; use ruff_python_ast::prelude::UnaryOp;
use ruff_text_size::{TextLen, TextRange}; use ruff_text_size::{TextLen, TextRange};
use rustpython_parser::ast::{ExprUnaryOp, Ranged}; use rustpython_parser::ast::{ExprUnaryOp, Ranged};

View file

@ -273,36 +273,7 @@ if True:
let formatted_code = printed.as_code(); let formatted_code = printed.as_code();
let reformatted = match format_module(formatted_code) { ensure_stability_when_formatting_twice(formatted_code);
Ok(reformatted) => reformatted,
Err(err) => {
panic!(
"Expected formatted code to be valid syntax: {err}:\
\n---\n{formatted_code}---\n",
);
}
};
if reformatted.as_code() != formatted_code {
let diff = TextDiff::from_lines(formatted_code, reformatted.as_code())
.unified_diff()
.header("Formatted once", "Formatted twice")
.to_string();
panic!(
r#"Reformatting the formatted code a second time resulted in formatting changes.
---
{diff}---
Formatted once:
---
{formatted_code}---
Formatted twice:
---
{}---"#,
reformatted.as_code()
);
}
if formatted_code == expected_output { if formatted_code == expected_output {
// Black and Ruff formatting matches. Delete any existing snapshot files because the Black output // Black and Ruff formatting matches. Delete any existing snapshot files because the Black output
@ -374,6 +345,8 @@ Formatted twice:
let reformatted = let reformatted =
format_module(formatted_code).unwrap_or_else(|err| panic!("Expected formatted code to be valid syntax but it contains syntax errors: {err}\n{formatted_code}")); format_module(formatted_code).unwrap_or_else(|err| panic!("Expected formatted code to be valid syntax but it contains syntax errors: {err}\n{formatted_code}"));
ensure_stability_when_formatting_twice(formatted_code);
if reformatted.as_code() != formatted_code { if reformatted.as_code() != formatted_code {
let diff = TextDiff::from_lines(formatted_code, reformatted.as_code()) let diff = TextDiff::from_lines(formatted_code, reformatted.as_code())
.unified_diff() .unified_diff()
@ -406,6 +379,40 @@ Formatted twice:
Ok(()) Ok(())
} }
/// Format another time and make sure that there are no changes anymore
fn ensure_stability_when_formatting_twice(formatted_code: &str) {
let reformatted = match format_module(formatted_code) {
Ok(reformatted) => reformatted,
Err(err) => {
panic!(
"Expected formatted code to be valid syntax: {err}:\
\n---\n{formatted_code}---\n",
);
}
};
if reformatted.as_code() != formatted_code {
let diff = TextDiff::from_lines(formatted_code, reformatted.as_code())
.unified_diff()
.header("Formatted once", "Formatted twice")
.to_string();
panic!(
r#"Reformatting the formatted code a second time resulted in formatting changes.
---
{diff}---
Formatted once:
---
{formatted_code}---
Formatted twice:
---
{}---"#,
reformatted.as_code()
);
}
}
/// Use this test to debug the formatting of some snipped /// Use this test to debug the formatting of some snipped
#[ignore] #[ignore]
#[test] #[test]

View file

@ -73,9 +73,8 @@ y = 100(no)
+if 10 .NOT_IMPLEMENTED_attr: +if 10 .NOT_IMPLEMENTED_attr:
... ...
-y = 100[no] y = 100[no]
-y = 100(no) -y = 100(no)
+y = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+y = NOT_IMPLEMENTED_call() +y = NOT_IMPLEMENTED_call()
``` ```
@ -102,7 +101,7 @@ x = -100.0000J
if 10 .NOT_IMPLEMENTED_attr: if 10 .NOT_IMPLEMENTED_attr:
... ...
y = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] y = 100[no]
y = NOT_IMPLEMENTED_call() y = NOT_IMPLEMENTED_call()
``` ```

View file

@ -264,32 +264,30 @@ instruction()#comment with bad spacing
if typedargslist: if typedargslist:
- parameters.children = [children[0], body, children[-1]] # (1 # )1 - parameters.children = [children[0], body, children[-1]] # (1 # )1
- parameters.children = [ - parameters.children = [
- children[0],
+ parameters.NOT_IMPLEMENTED_attr = [ + parameters.NOT_IMPLEMENTED_attr = [
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # (1 + children[0], # (1
body, + body,
- children[-1], # type: ignore + children[-1], # )1
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # )1
+ ] + ]
+ parameters.NOT_IMPLEMENTED_attr = [ + parameters.NOT_IMPLEMENTED_attr = [
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], children[0],
+ body, body,
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # type: ignore children[-1], # type: ignore
] ]
else: else:
- parameters.children = [ - parameters.children = [
- parameters.children[0], # (2 what if this was actually long - parameters.children[0], # (2 what if this was actually long
+ parameters.NOT_IMPLEMENTED_attr = [ + parameters.NOT_IMPLEMENTED_attr = [
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # (2 what if this was actually long + parameters.NOT_IMPLEMENTED_attr[0], # (2 what if this was actually long
body, body,
- parameters.children[-1], # )2 - parameters.children[-1], # )2
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # )2 + parameters.NOT_IMPLEMENTED_attr[-1], # )2
] ]
- parameters.children = [parameters.what_if_this_was_actually_long.children[0], body, parameters.children[-1]] # type: ignore - parameters.children = [parameters.what_if_this_was_actually_long.children[0], body, parameters.children[-1]] # type: ignore
+ parameters.NOT_IMPLEMENTED_attr = [ + parameters.NOT_IMPLEMENTED_attr = [
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], + parameters.NOT_IMPLEMENTED_attr.NOT_IMPLEMENTED_attr[0],
+ body, + body,
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], + parameters.NOT_IMPLEMENTED_attr[-1],
+ ] # type: ignore + ] # type: ignore
if ( if (
- self._proc is not None - self._proc is not None
@ -460,25 +458,25 @@ else:
def inline_comments_in_brackets_ruin_everything(): def inline_comments_in_brackets_ruin_everything():
if typedargslist: if typedargslist:
parameters.NOT_IMPLEMENTED_attr = [ parameters.NOT_IMPLEMENTED_attr = [
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # (1 children[0], # (1
body, body,
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # )1 children[-1], # )1
] ]
parameters.NOT_IMPLEMENTED_attr = [ parameters.NOT_IMPLEMENTED_attr = [
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], children[0],
body, body,
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # type: ignore children[-1], # type: ignore
] ]
else: else:
parameters.NOT_IMPLEMENTED_attr = [ parameters.NOT_IMPLEMENTED_attr = [
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # (2 what if this was actually long parameters.NOT_IMPLEMENTED_attr[0], # (2 what if this was actually long
body, body,
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # )2 parameters.NOT_IMPLEMENTED_attr[-1], # )2
] ]
parameters.NOT_IMPLEMENTED_attr = [ parameters.NOT_IMPLEMENTED_attr = [
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], parameters.NOT_IMPLEMENTED_attr.NOT_IMPLEMENTED_attr[0],
body, body,
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], parameters.NOT_IMPLEMENTED_attr[-1],
] # type: ignore ] # type: ignore
if ( if (
NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right

View file

@ -153,12 +153,9 @@ aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*ite
tup = ( tup = (
another_element, another_element,
@@ -84,35 +85,22 @@ @@ -86,33 +87,20 @@
def func( def func(
- a=some_list[0], # type: int a=some_list[0], # type: int
+ a=NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # type: int
): # type: () -> int ): # type: () -> int
- c = call( - c = call(
- 0.0123, - 0.0123,
@ -293,7 +290,7 @@ def f(
def func( def func(
a=NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], # type: int a=some_list[0], # type: int
): # type: () -> int ): # type: () -> int
c = NOT_IMPLEMENTED_call() c = NOT_IMPLEMENTED_call()

View file

@ -276,7 +276,7 @@ last_call()
Name Name
None None
True True
@@ -30,203 +31,178 @@ @@ -30,134 +31,120 @@
-1 -1
~int and not v1 ^ 123 + v2 | True ~int and not v1 ^ 123 + v2 | True
(~int) and (not ((v1 ^ (123 + v2)) | True)) (~int) and (not ((v1 ^ (123 + v2)) | True))
@ -297,13 +297,6 @@ last_call()
-(str or None) if True else (str or bytes or None) -(str or None) if True else (str or bytes or None)
-str or None if (1 if True else 2) else str or bytes or None -str or None if (1 if True else 2) else str or bytes or None
-(str or None) if (1 if True else 2) else (str or bytes or None) -(str or None) if (1 if True else 2) else (str or bytes or None)
-(
- (super_long_variable_name or None)
- if (1 if super_long_test_name else 2)
- else (str or bytes or None)
-)
-{"2.7": dead, "3.7": (long_live or die_hard)}
-{"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}}
++really ** -confusing ** ~operator**-precedence ++really ** -confusing ** ~operator**-precedence
+flags & ~select.NOT_IMPLEMENTED_attr and NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right +flags & ~select.NOT_IMPLEMENTED_attr and NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right
+lambda x: True +lambda x: True
@ -328,9 +321,7 @@ last_call()
+ "NOT_YET_IMPLEMENTED_STRING": (long_live or die_hard), + "NOT_YET_IMPLEMENTED_STRING": (long_live or die_hard),
+ **{"NOT_YET_IMPLEMENTED_STRING": verygood}, + **{"NOT_YET_IMPLEMENTED_STRING": verygood},
+} +}
{**a, **b, **c} +{**a, **b, **c}
-{"2.7", "3.6", "3.7", "3.8", "3.9", ("4.0" if gilectomy else "3.10")}
-({"a": "b"}, (True or False), (+value), "string", b"bytes") or None
+{ +{
+ "NOT_YET_IMPLEMENTED_STRING", + "NOT_YET_IMPLEMENTED_STRING",
+ "NOT_YET_IMPLEMENTED_STRING", + "NOT_YET_IMPLEMENTED_STRING",
@ -339,7 +330,16 @@ last_call()
+ "NOT_YET_IMPLEMENTED_STRING", + "NOT_YET_IMPLEMENTED_STRING",
+ (NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false), + (NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false),
+} +}
+( (
- (super_long_variable_name or None)
- if (1 if super_long_test_name else 2)
- else (str or bytes or None)
-)
-{"2.7": dead, "3.7": (long_live or die_hard)}
-{"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}}
-{**a, **b, **c}
-{"2.7", "3.6", "3.7", "3.8", "3.9", ("4.0" if gilectomy else "3.10")}
-({"a": "b"}, (True or False), (+value), "string", b"bytes") or None
+ {"NOT_YET_IMPLEMENTED_STRING": "NOT_YET_IMPLEMENTED_STRING"}, + {"NOT_YET_IMPLEMENTED_STRING": "NOT_YET_IMPLEMENTED_STRING"},
+ (True or False), + (True or False),
+ (+value), + (+value),
@ -352,7 +352,12 @@ last_call()
(1, 2, 3) (1, 2, 3)
[] []
[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)] [1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]
-[ +[1, 2, 3]
+[NOT_YET_IMPLEMENTED_ExprStarred]
+[NOT_YET_IMPLEMENTED_ExprStarred]
+[NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
+[4, NOT_YET_IMPLEMENTED_ExprStarred, 5]
[
- 1, - 1,
- 2, - 2,
- 3, - 3,
@ -369,12 +374,7 @@ last_call()
- *a, - *a,
- 5, - 5,
-] -]
+[1, 2, 3] -[
+[NOT_YET_IMPLEMENTED_ExprStarred]
+[NOT_YET_IMPLEMENTED_ExprStarred]
+[NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
+[4, NOT_YET_IMPLEMENTED_ExprStarred, 5]
[
this_is_a_very_long_variable_which_will_force_a_delimiter_split, this_is_a_very_long_variable_which_will_force_a_delimiter_split,
element, element,
another, another,
@ -393,6 +393,33 @@ last_call()
-{i: j for i, j in ((1, "a"), (2, "b"), (3, "c"))} -{i: j for i, j in ((1, "a"), (2, "b"), (3, "c"))}
-{a: b * 2 for a, b in dictionary.items()} -{a: b * 2 for a, b in dictionary.items()}
-{a: b * -2 for a, b in dictionary.items()} -{a: b * -2 for a, b in dictionary.items()}
-{
- k: v
- for k, v in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension
-}
-Python3 > Python2 > COBOL
-Life is Life
-call()
-call(arg)
-call(kwarg="hey")
-call(arg, kwarg="hey")
-call(arg, another, kwarg="hey", **kwargs)
-call(
- this_is_a_very_long_variable_which_will_force_a_delimiter_split,
- arg,
- another,
- kwarg="hey",
- **kwargs,
-) # note: no trailing comma pre-3.6
-call(*gidgets[:2])
-call(a, *gidgets[:2])
-call(**self.screen_kwargs)
-call(b, **self.screen_kwargs)
-lukasz.langa.pl
-call.me(maybe)
-(1).real
-(1.0).real
-....__class__
+NOT_YET_IMPLEMENTED_ExprSetComp +NOT_YET_IMPLEMENTED_ExprSetComp
+NOT_YET_IMPLEMENTED_ExprSetComp +NOT_YET_IMPLEMENTED_ExprSetComp
+NOT_YET_IMPLEMENTED_ExprSetComp +NOT_YET_IMPLEMENTED_ExprSetComp
@ -423,81 +450,22 @@ last_call()
+1 .NOT_IMPLEMENTED_attr +1 .NOT_IMPLEMENTED_attr
+1.0 .NOT_IMPLEMENTED_attr +1.0 .NOT_IMPLEMENTED_attr
+....NOT_IMPLEMENTED_attr +....NOT_IMPLEMENTED_attr
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] list[str]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] dict[str, int]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] tuple[str, ...]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] tuple[str, int, float, dict[str, int]]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] tuple[
+NOT_YET_IMPLEMENTED_StmtAnnAssign
+NOT_YET_IMPLEMENTED_StmtAnnAssign
+NOT_YET_IMPLEMENTED_StmtAnnAssign
+NOT_YET_IMPLEMENTED_StmtAnnAssign # type: ignore
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
{
- k: v
- for k, v in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension
+ "NOT_YET_IMPLEMENTED_STRING": dead,
+ "NOT_YET_IMPLEMENTED_STRING": long_live or die_hard,
}
-Python3 > Python2 > COBOL
-Life is Life
-call()
-call(arg)
-call(kwarg="hey")
-call(arg, kwarg="hey")
-call(arg, another, kwarg="hey", **kwargs)
-call(
- this_is_a_very_long_variable_which_will_force_a_delimiter_split,
- arg,
- another,
- kwarg="hey",
- **kwargs,
-) # note: no trailing comma pre-3.6
-call(*gidgets[:2])
-call(a, *gidgets[:2])
-call(**self.screen_kwargs)
-call(b, **self.screen_kwargs)
-lukasz.langa.pl
-call.me(maybe)
-(1).real
-(1.0).real
-....__class__
-list[str]
-dict[str, int]
-tuple[str, ...]
-tuple[str, int, float, dict[str, int]]
-tuple[
- str, - str,
- int, - int,
- float, - float,
- dict[str, int], - dict[str, int],
-] + (
+ str,
+ int,
+ float,
+ dict[str, int],
+ )
]
-very_long_variable_name_filters: t.List[ -very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]], - t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
-] -]
@ -510,35 +478,43 @@ last_call()
-xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( -xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod(
- sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__) - sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
-) # type: ignore -) # type: ignore
-slice[0] +NOT_YET_IMPLEMENTED_StmtAnnAssign
-slice[0:1] +NOT_YET_IMPLEMENTED_StmtAnnAssign
-slice[0:1:2] +NOT_YET_IMPLEMENTED_StmtAnnAssign
-slice[:] +NOT_YET_IMPLEMENTED_StmtAnnAssign # type: ignore
slice[0]
slice[0:1]
slice[0:1:2]
slice[:]
-slice[:-1] -slice[:-1]
-slice[1:] +slice[ : -1]
slice[1:]
-slice[::-1] -slice[::-1]
-slice[d :: d + 1] +slice[ :: -1]
-slice[:c, c - 1] slice[d :: d + 1]
-numpy[:, 0:1] slice[:c, c - 1]
numpy[:, 0:1]
-numpy[:, :-1] -numpy[:, :-1]
-numpy[0, :] +numpy[:, : -1]
-numpy[:, i] numpy[0, :]
-numpy[0, :2] numpy[:, i]
-numpy[:N, 0] numpy[0, :2]
-numpy[:2, :4] @@ -171,62 +158,58 @@
-numpy[2:4, 1:5] numpy[1 : c + 1, c]
-numpy[4:, 2:] numpy[-(c + 1) :, d]
-numpy[:, (0, 1, 2, 5)] numpy[:, l[-2]]
-numpy[0, [0]]
-numpy[:, [i]]
-numpy[1 : c + 1, c]
-numpy[-(c + 1) :, d]
-numpy[:, l[-2]]
-numpy[:, ::-1] -numpy[:, ::-1]
-numpy[np.newaxis, :] -numpy[np.newaxis, :]
-(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None) -(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None)
-{"2.7": dead, "3.7": long_live or die_hard} -{"2.7": dead, "3.7": long_live or die_hard}
-{"2.7", "3.6", "3.7", "3.8", "3.9", "4.0" if gilectomy else "3.10"} -{"2.7", "3.6", "3.7", "3.8", "3.9", "4.0" if gilectomy else "3.10"}
+numpy[:, :: -1]
+numpy[np.NOT_IMPLEMENTED_attr, :]
+NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
+{
+ "NOT_YET_IMPLEMENTED_STRING": dead,
+ "NOT_YET_IMPLEMENTED_STRING": long_live or die_hard,
+}
+{ +{
+ "NOT_YET_IMPLEMENTED_STRING", + "NOT_YET_IMPLEMENTED_STRING",
+ "NOT_YET_IMPLEMENTED_STRING", + "NOT_YET_IMPLEMENTED_STRING",
@ -585,7 +561,13 @@ last_call()
-g = 1, *"ten" -g = 1, *"ten"
-what_is_up_with_those_new_coord_names = (coord_names + set(vars_to_create)) + set( -what_is_up_with_those_new_coord_names = (coord_names + set(vars_to_create)) + set(
- vars_to_remove - vars_to_remove
-) +e = NOT_IMPLEMENTED_call()
+f = 1, NOT_YET_IMPLEMENTED_ExprStarred
+g = 1, NOT_YET_IMPLEMENTED_ExprStarred
+what_is_up_with_those_new_coord_names = (
+ (coord_names + NOT_IMPLEMENTED_call())
+ + NOT_IMPLEMENTED_call()
)
-what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set( -what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
- vars_to_remove - vars_to_remove
-) -)
@ -596,13 +578,7 @@ last_call()
- ) - )
- .order_by(models.Customer.id.asc()) - .order_by(models.Customer.id.asc())
- .all() - .all()
+e = NOT_IMPLEMENTED_call() -)
+f = 1, NOT_YET_IMPLEMENTED_ExprStarred
+g = 1, NOT_YET_IMPLEMENTED_ExprStarred
+what_is_up_with_those_new_coord_names = (
+ (coord_names + NOT_IMPLEMENTED_call())
+ + NOT_IMPLEMENTED_call()
)
-result = ( -result = (
- session.query(models.Customer.id) - session.query(models.Customer.id)
- .filter( - .filter(
@ -625,7 +601,7 @@ last_call()
mapping = { mapping = {
A: 0.25 * (10.0 / 12), A: 0.25 * (10.0 / 12),
B: 0.1 * (10.0 / 12), B: 0.1 * (10.0 / 12),
@@ -236,64 +212,38 @@ @@ -236,64 +219,38 @@
def gen(): def gen():
@ -714,7 +690,7 @@ last_call()
): ):
return True return True
if ( if (
@@ -327,24 +277,44 @@ @@ -327,24 +284,44 @@
): ):
return True return True
if ( if (
@ -771,7 +747,7 @@ last_call()
): ):
return True return True
( (
@@ -363,8 +333,9 @@ @@ -363,8 +340,9 @@
bbbb >> bbbb * bbbb bbbb >> bbbb * bbbb
( (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@ -908,41 +884,48 @@ NOT_IMPLEMENTED_call()
1 .NOT_IMPLEMENTED_attr 1 .NOT_IMPLEMENTED_attr
1.0 .NOT_IMPLEMENTED_attr 1.0 .NOT_IMPLEMENTED_attr
....NOT_IMPLEMENTED_attr ....NOT_IMPLEMENTED_attr
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] list[str]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] dict[str, int]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] tuple[str, ...]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] tuple[str, int, float, dict[str, int]]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] tuple[
(
str,
int,
float,
dict[str, int],
)
]
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
NOT_YET_IMPLEMENTED_StmtAnnAssign # type: ignore NOT_YET_IMPLEMENTED_StmtAnnAssign # type: ignore
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[0]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[0:1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[0:1:2]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[:]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ : -1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[1:]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ :: -1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[d :: d + 1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[:c, c - 1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, 0:1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, : -1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[0, :]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, i]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[0, :2]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:N, 0]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:2, :4]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[2:4, 1:5]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[4:, 2:]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, (0, 1, 2, 5)]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[0, [0]]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, [i]]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[1 : c + 1, c]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[-(c + 1) :, d]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, l[-2]]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[:, :: -1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] numpy[np.NOT_IMPLEMENTED_attr, :]
NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
{ {
"NOT_YET_IMPLEMENTED_STRING": dead, "NOT_YET_IMPLEMENTED_STRING": dead,

View file

@ -273,7 +273,7 @@ d={'a':1,
+ debug: bool = False, + debug: bool = False,
+ **kwargs, + **kwargs,
+) -> str: +) -> str:
+ return NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + return text[number : -1]
+ +
+ +
# fmt: on # fmt: on
@ -296,7 +296,7 @@ d={'a':1,
def spaces_types( def spaces_types(
@@ -51,76 +70,61 @@ @@ -51,76 +70,71 @@
d: dict = {}, d: dict = {},
e: bool = True, e: bool = True,
f: int = -1, f: int = -1,
@ -323,15 +323,22 @@ d={'a':1,
def subscriptlist(): def subscriptlist():
- atom[ atom[
- # fmt: off # fmt: off
- 'some big and', - 'some big and',
- 'complex subscript', - 'complex subscript',
- # fmt: on - # fmt: on
- goes + here, - goes + here,
- andhere, - andhere,
- ] + (
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + "NOT_YET_IMPLEMENTED_STRING",
+ "NOT_YET_IMPLEMENTED_STRING",
+ # fmt: on
+ goes
+ + here,
+ andhere,
+ )
]
def import_as_names(): def import_as_names():
@ -390,7 +397,7 @@ d={'a':1,
# fmt: off # fmt: off
# hey, that won't work # hey, that won't work
@@ -130,13 +134,15 @@ @@ -130,13 +144,15 @@
def on_and_off_broken(): def on_and_off_broken():
@ -411,7 +418,7 @@ d={'a':1,
# fmt: on # fmt: on
# fmt: off # fmt: off
# ...but comments still get reformatted even though they should not be # ...but comments still get reformatted even though they should not be
@@ -145,80 +151,21 @@ @@ -145,80 +161,21 @@
def long_lines(): def long_lines():
if True: if True:
@ -551,7 +558,7 @@ def function_signature_stress_test(
debug: bool = False, debug: bool = False,
**kwargs, **kwargs,
) -> str: ) -> str:
return NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] return text[number : -1]
# fmt: on # fmt: on
@ -595,7 +602,17 @@ something = {
def subscriptlist(): def subscriptlist():
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] atom[
# fmt: off
(
"NOT_YET_IMPLEMENTED_STRING",
"NOT_YET_IMPLEMENTED_STRING",
# fmt: on
goes
+ here,
andhere,
)
]
def import_as_names(): def import_as_names():

View file

@ -167,7 +167,7 @@ def __await__(): return (yield)
**kwargs, **kwargs,
) -> str: ) -> str:
- return text[number:-1] - return text[number:-1]
+ return NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + return text[number : -1]
-def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""): -def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""):
@ -330,7 +330,7 @@ def function_signature_stress_test(
debug: bool = False, debug: bool = False,
**kwargs, **kwargs,
) -> str: ) -> str:
return NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] return text[number : -1]
def spaces( def spaces(

View file

@ -94,7 +94,7 @@ some_module.some_function(
} }
tup = ( tup = (
1, 1,
@@ -24,45 +24,18 @@ @@ -24,45 +24,23 @@
def f( def f(
a: int = 1, a: int = 1,
): ):
@ -106,7 +106,9 @@ some_module.some_function(
- call2( - call2(
- arg=[1, 2, 3], - arg=[1, 2, 3],
- ) - )
- x = { + NOT_IMPLEMENTED_call()
+ NOT_IMPLEMENTED_call()
x = {
- "a": 1, - "a": 1,
- "b": 2, - "b": 2,
- }["a"] - }["a"]
@ -123,9 +125,11 @@ some_module.some_function(
- "h": 8, - "h": 8,
- }["a"] - }["a"]
- ): - ):
+ NOT_IMPLEMENTED_call() + "NOT_YET_IMPLEMENTED_STRING": 1,
+ NOT_IMPLEMENTED_call() + "NOT_YET_IMPLEMENTED_STRING": 2,
+ x = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + }[
+ "NOT_YET_IMPLEMENTED_STRING"
+ ]
+ if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right: + if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:
pass pass
@ -133,7 +137,7 @@ some_module.some_function(
-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( -def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
- Set["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] - Set["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"]
-): -):
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: +def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set["NOT_YET_IMPLEMENTED_STRING"]:
json = { json = {
- "k": { - "k": {
- "k2": { - "k2": {
@ -148,7 +152,7 @@ some_module.some_function(
} }
@@ -80,35 +53,16 @@ @@ -80,35 +58,16 @@
pass pass
@ -221,12 +225,17 @@ def f(
): ):
NOT_IMPLEMENTED_call() NOT_IMPLEMENTED_call()
NOT_IMPLEMENTED_call() NOT_IMPLEMENTED_call()
x = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] x = {
"NOT_YET_IMPLEMENTED_STRING": 1,
"NOT_YET_IMPLEMENTED_STRING": 2,
}[
"NOT_YET_IMPLEMENTED_STRING"
]
if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right: if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:
pass pass
def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set["NOT_YET_IMPLEMENTED_STRING"]:
json = { json = {
"NOT_YET_IMPLEMENTED_STRING": { "NOT_YET_IMPLEMENTED_STRING": {
"NOT_YET_IMPLEMENTED_STRING": {"NOT_YET_IMPLEMENTED_STRING": [1]}, "NOT_YET_IMPLEMENTED_STRING": {"NOT_YET_IMPLEMENTED_STRING": [1]},

View file

@ -25,25 +25,28 @@ list_of_types = [tuple[int,],]
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -1,22 +1,12 @@ @@ -1,22 +1,17 @@
# We should not treat the trailing comma # We should not treat the trailing comma
# in a single-element subscript. # in a single-element subscript.
-a: tuple[int,] -a: tuple[int,]
-b = tuple[int,] -b = tuple[int,]
+NOT_YET_IMPLEMENTED_StmtAnnAssign +NOT_YET_IMPLEMENTED_StmtAnnAssign
+b = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +b = tuple[(int,)]
# The magic comma still applies to multi-element subscripts. # The magic comma still applies to multi-element subscripts.
-c: tuple[ -c: tuple[
- int, - int,
- int, - int,
-] -]
-d = tuple[
- int,
- int,
-]
+NOT_YET_IMPLEMENTED_StmtAnnAssign +NOT_YET_IMPLEMENTED_StmtAnnAssign
+d = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] d = tuple[
- int,
- int,
+ (
+ int,
+ int,
+ )
]
# Magic commas still work as expected for non-subscripts. # Magic commas still work as expected for non-subscripts.
-small_list = [ -small_list = [
@ -53,7 +56,7 @@ list_of_types = [tuple[int,],]
- tuple[int,], - tuple[int,],
-] -]
+small_list = [1] +small_list = [1]
+list_of_types = [NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]] +list_of_types = [tuple[(int,)]]
``` ```
## Ruff Output ## Ruff Output
@ -62,15 +65,20 @@ list_of_types = [tuple[int,],]
# We should not treat the trailing comma # We should not treat the trailing comma
# in a single-element subscript. # in a single-element subscript.
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
b = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] b = tuple[(int,)]
# The magic comma still applies to multi-element subscripts. # The magic comma still applies to multi-element subscripts.
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
d = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] d = tuple[
(
int,
int,
)
]
# Magic commas still work as expected for non-subscripts. # Magic commas still work as expected for non-subscripts.
small_list = [1] small_list = [1]
list_of_types = [NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]] list_of_types = [tuple[(int,)]]
``` ```
## Black Output ## Black Output

View file

@ -92,7 +92,7 @@ return np.divide(
-j = super().name ** 5 -j = super().name ** 5
-k = [(2**idx, value) for idx, value in pairs] -k = [(2**idx, value) for idx, value in pairs]
-l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001) -l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001)
+d = 5 ** NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +d = 5 ** f["NOT_YET_IMPLEMENTED_STRING"]
+e = NOT_IMPLEMENTED_call() +e = NOT_IMPLEMENTED_call()
+f = NOT_IMPLEMENTED_call() ** 5 +f = NOT_IMPLEMENTED_call() ** 5
+g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr +g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr
@ -125,7 +125,7 @@ return np.divide(
-j = super().name ** 5.0 -j = super().name ** 5.0
-k = [(2.0**idx, value) for idx, value in pairs] -k = [(2.0**idx, value) for idx, value in pairs]
-l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001) -l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001)
+d = 5.0 ** NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +d = 5.0 ** f["NOT_YET_IMPLEMENTED_STRING"]
+e = NOT_IMPLEMENTED_call() +e = NOT_IMPLEMENTED_call()
+f = NOT_IMPLEMENTED_call() ** 5.0 +f = NOT_IMPLEMENTED_call() ** 5.0
+g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr +g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr
@ -181,7 +181,7 @@ def function_dont_replace_spaces():
a = 5**~4 a = 5**~4
b = 5 ** NOT_IMPLEMENTED_call() b = 5 ** NOT_IMPLEMENTED_call()
c = -(5**2) c = -(5**2)
d = 5 ** NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] d = 5 ** f["NOT_YET_IMPLEMENTED_STRING"]
e = NOT_IMPLEMENTED_call() e = NOT_IMPLEMENTED_call()
f = NOT_IMPLEMENTED_call() ** 5 f = NOT_IMPLEMENTED_call() ** 5
g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr
@ -200,7 +200,7 @@ r = x**y
a = 5.0**~4.0 a = 5.0**~4.0
b = 5.0 ** NOT_IMPLEMENTED_call() b = 5.0 ** NOT_IMPLEMENTED_call()
c = -(5.0**2.0) c = -(5.0**2.0)
d = 5.0 ** NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] d = 5.0 ** f["NOT_YET_IMPLEMENTED_STRING"]
e = NOT_IMPLEMENTED_call() e = NOT_IMPLEMENTED_call()
f = NOT_IMPLEMENTED_call() ** 5.0 f = NOT_IMPLEMENTED_call() ** 5.0
g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr g = a.NOT_IMPLEMENTED_attr**c.NOT_IMPLEMENTED_attr

View file

@ -40,7 +40,7 @@ xxxxxxxxx_yyy_zzzzzzzz[xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxx
-xxxxxxxxx_yyy_zzzzzzzz[ -xxxxxxxxx_yyy_zzzzzzzz[
- xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1) - xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1)
-] = 1 -] = 1
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] = 1 +xxxxxxxxx_yyy_zzzzzzzz[NOT_IMPLEMENTED_call(), NOT_IMPLEMENTED_call()] = 1
``` ```
## Ruff Output ## Ruff Output
@ -61,7 +61,7 @@ xxxxxxxxx_yyy_zzzzzzzz[xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxx
# Make when when the left side of assignment plus the opening paren "... = (" is # Make when when the left side of assignment plus the opening paren "... = (" is
# exactly line length limit + 1, it won't be split like that. # exactly line length limit + 1, it won't be split like that.
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] = 1 xxxxxxxxx_yyy_zzzzzzzz[NOT_IMPLEMENTED_call(), NOT_IMPLEMENTED_call()] = 1
``` ```
## Black Output ## Black Output

View file

@ -123,35 +123,36 @@ def foo() -> tuple[int, int, int,]:
return 2 return 2
@@ -95,26 +99,14 @@ @@ -99,22 +103,22 @@
# Return type with commas
-def foo() -> tuple[int, int, int]:
+def foo() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]:
return 2 return 2
-def foo() -> ( -def foo() -> (
- tuple[ - tuple[
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, +def foo() -> tuple[
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + (
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
- ] - ]
-): -):
+def foo() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: + )
+]:
return 2 return 2
# Magic trailing comma example # Magic trailing comma example
-def foo() -> ( -def foo() -> (
- tuple[ - tuple[
- int, +def foo() -> tuple[
- int, + (
- int, int,
int,
int,
- ] - ]
-): -):
+def foo() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: + )
+]:
return 2 return 2
``` ```
@ -259,16 +260,28 @@ def foo() -> (
# Return type with commas # Return type with commas
def foo() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: def foo() -> tuple[int, int, int]:
return 2 return 2
def foo() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: def foo() -> tuple[
(
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
)
]:
return 2 return 2
# Magic trailing comma example # Magic trailing comma example
def foo() -> NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]: def foo() -> tuple[
(
int,
int,
int,
)
]:
return 2 return 2
``` ```

View file

@ -60,26 +60,31 @@ func(
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -1,25 +1,30 @@ @@ -1,25 +1,35 @@
# We should not remove the trailing comma in a single-element subscript. # We should not remove the trailing comma in a single-element subscript.
-a: tuple[int,] -a: tuple[int,]
-b = tuple[int,] -b = tuple[int,]
+NOT_YET_IMPLEMENTED_StmtAnnAssign +NOT_YET_IMPLEMENTED_StmtAnnAssign
+b = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +b = tuple[(int,)]
# But commas in multiple element subscripts should be removed. # But commas in multiple element subscripts should be removed.
-c: tuple[int, int] -c: tuple[int, int]
-d = tuple[int, int] -d = tuple[int, int]
+NOT_YET_IMPLEMENTED_StmtAnnAssign +NOT_YET_IMPLEMENTED_StmtAnnAssign
+d = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +d = tuple[
+ (
+ int,
+ int,
+ )
+]
# Remove commas for non-subscripts. # Remove commas for non-subscripts.
small_list = [1] small_list = [1]
-list_of_types = [tuple[int,]] -list_of_types = [tuple[int,]]
+list_of_types = [NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]] +list_of_types = [tuple[(int,)]]
small_set = {1} small_set = {1}
-set_of_types = {tuple[int,]} -set_of_types = {tuple[int,]}
+set_of_types = {NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]} +set_of_types = {tuple[(int,)]}
# Except single element tuples # Except single element tuples
small_tuple = (1,) small_tuple = (1,)
@ -108,17 +113,22 @@ func(
```py ```py
# We should not remove the trailing comma in a single-element subscript. # We should not remove the trailing comma in a single-element subscript.
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
b = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] b = tuple[(int,)]
# But commas in multiple element subscripts should be removed. # But commas in multiple element subscripts should be removed.
NOT_YET_IMPLEMENTED_StmtAnnAssign NOT_YET_IMPLEMENTED_StmtAnnAssign
d = NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] d = tuple[
(
int,
int,
)
]
# Remove commas for non-subscripts. # Remove commas for non-subscripts.
small_list = [1] small_list = [1]
list_of_types = [NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]] list_of_types = [tuple[(int,)]]
small_set = {1} small_set = {1}
set_of_types = {NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]} set_of_types = {tuple[(int,)]}
# Except single element tuples # Except single element tuples
small_tuple = (1,) small_tuple = (1,)

View file

@ -76,158 +76,137 @@ x[
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -1,59 +1,48 @@ @@ -1,33 +1,33 @@
-slice[a.b : c.d] -slice[a.b : c.d]
-slice[d :: d + 1] +slice[a.NOT_IMPLEMENTED_attr : c.NOT_IMPLEMENTED_attr]
-slice[d + 1 :: d] slice[d :: d + 1]
-slice[d::d] slice[d + 1 :: d]
-slice[0] slice[d::d]
-slice[-1] slice[0]
slice[-1]
-slice[:-1] -slice[:-1]
-slice[::-1] -slice[::-1]
-slice[:c, c - 1] +slice[ : -1]
-slice[c, c + 1, d::] +slice[ :: -1]
-slice[ham[c::d] :: 1] slice[:c, c - 1]
-slice[ham[cheese**2 : -1] : 1 : 1, ham[1:2]] slice[c, c + 1, d::]
slice[ham[c::d] :: 1]
slice[ham[cheese**2 : -1] : 1 : 1, ham[1:2]]
-slice[:-1:] -slice[:-1:]
-slice[lambda: None : lambda: None] -slice[lambda: None : lambda: None]
-slice[lambda x, y, *args, really=2, **kwargs: None :, None::] -slice[lambda x, y, *args, really=2, **kwargs: None :, None::]
-slice[1 or 2 : True and False] +slice[ : -1 :]
+slice[lambda x: True : lambda x: True]
+slice[lambda x: True :, None::]
slice[1 or 2 : True and False]
-slice[not so_simple : 1 < val <= 10] -slice[not so_simple : 1 < val <= 10]
-slice[(1 for i in range(42)) : x] -slice[(1 for i in range(42)) : x]
-slice[:: [i for i in range(42)]] -slice[:: [i for i in range(42)]]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +slice[not so_simple : NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +slice[(i for i in []) : x]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +slice[ :: [i for i in []]]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
async def f(): async def f():
- slice[await x : [i async for i in arange(42)] : 42] - slice[await x : [i async for i in arange(42)] : 42]
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + slice[await x : [i for i in []] : 42]
# These are from PEP-8: # These are from PEP-8:
-ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:] ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
-ham[lower:upper], ham[lower:upper:], ham[lower::step] ham[lower:upper], ham[lower:upper:], ham[lower::step]
+(
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+)
+(
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+ NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
+)
# ham[lower+offset : upper+offset] # ham[lower+offset : upper+offset]
-ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)] -ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
-ham[lower + offset : upper + offset] +ham[ : NOT_IMPLEMENTED_call() : NOT_IMPLEMENTED_call()], ham[ :: NOT_IMPLEMENTED_call()]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] ham[lower + offset : upper + offset]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
-slice[::, ::] slice[::, ::]
-slice[ @@ -50,10 +50,14 @@
- # A slice[
- : # A
- # B 1
- :
- # C
-]
-slice[
- # A
- 1:
- # B
- 2:
- # C
- 3
-]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key]
-slice[
- # A
- 1
- + 2 : - + 2 :
- # B + + 2 :
# B
- 3 : - 3 :
- # C + 3 :
- 4 # C
-] 4
]
-x[1:2:3] # A # B # C -x[1:2:3] # A # B # C
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] +x[
+NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + 1: # A
+ 2: # B
+ 3 # C
+]
``` ```
## Ruff Output ## Ruff Output
```py ```py
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[a.NOT_IMPLEMENTED_attr : c.NOT_IMPLEMENTED_attr]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[d :: d + 1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[d + 1 :: d]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[d::d]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[0]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[-1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ : -1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ :: -1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[:c, c - 1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[c, c + 1, d::]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ham[c::d] :: 1]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ham[cheese**2 : -1] : 1 : 1, ham[1:2]]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ : -1 :]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[lambda x: True : lambda x: True]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[lambda x: True :, None::]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[1 or 2 : True and False]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[not so_simple : NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[(i for i in []) : x]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[ :: [i for i in []]]
async def f(): async def f():
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[await x : [i for i in []] : 42]
# These are from PEP-8: # These are from PEP-8:
( ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], ham[lower:upper], ham[lower:upper:], ham[lower::step]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
)
(
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key],
)
# ham[lower+offset : upper+offset] # ham[lower+offset : upper+offset]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key], NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] ham[ : NOT_IMPLEMENTED_call() : NOT_IMPLEMENTED_call()], ham[ :: NOT_IMPLEMENTED_call()]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] ham[lower + offset : upper + offset]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[::, ::]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] # A
:
# B
:
# C
]
slice[
# A
1:
# B
2:
# C
3
]
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] slice[
NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] # A
1
+ 2 :
# B
3 :
# C
4
]
x[
1: # A
2: # B
3 # C
]
``` ```
## Black Output ## Black Output

View file

@ -46,7 +46,7 @@ assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -1,50 +1,26 @@ @@ -1,50 +1,30 @@
-zero( -zero(
- one, - one,
-).two( -).two(
@ -86,7 +86,11 @@ assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
- }, - },
- api_key=api_key, - api_key=api_key,
- )["extensions"]["sdk"]["token"] - )["extensions"]["sdk"]["token"]
+ return NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] + return NOT_IMPLEMENTED_call()["NOT_YET_IMPLEMENTED_STRING"][
+ "NOT_YET_IMPLEMENTED_STRING"
+ ][
+ "NOT_YET_IMPLEMENTED_STRING"
+ ]
# Edge case where a bug in a working-in-progress version of # Edge case where a bug in a working-in-progress version of
@ -126,7 +130,11 @@ NOT_IMPLEMENTED_call()
# Example from https://github.com/psf/black/issues/3229 # Example from https://github.com/psf/black/issues/3229
def refresh_token(self, device_family, refresh_token, api_key): def refresh_token(self, device_family, refresh_token, api_key):
return NOT_IMPLEMENTED_value[NOT_IMPLEMENTED_key] return NOT_IMPLEMENTED_call()["NOT_YET_IMPLEMENTED_STRING"][
"NOT_YET_IMPLEMENTED_STRING"
][
"NOT_YET_IMPLEMENTED_STRING"
]
# Edge case where a bug in a working-in-progress version of # Edge case where a bug in a working-in-progress version of

View file

@ -0,0 +1,177 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
---
## Input
```py
# Handle comments both when lower and upper exist and when they don't
a1 = "a"[
# a
1 # b
: # c
2 # d
]
a2 = "a"[
# a
# b
: # c
# d
]
# Check all places where comments can exist
b1 = "b"[ # a
# b
1 # c
# d
: # e
# f
2 # g
# h
: # i
# j
3 # k
# l
]
# Handle the spacing from the colon correctly with upper leading comments
c1 = "c"[
1
: # e
# f
2
]
c2 = "c"[
1
: # e
2
]
c3 = "c"[
1
:
# f
2
]
c4 = "c"[
1
: # f
2
]
# End of line comments
d1 = "d"[ # comment
:
]
d2 = "d"[ # comment
1:
]
d3 = "d"[
1 # comment
:
]
# Spacing around the colon(s)
def a():
...
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 :]
```
## Output
```py
# Handle comments both when lower and upper exist and when they don't
a1 = "NOT_YET_IMPLEMENTED_STRING"[
# a
1 # b
: # c
2 # d
]
a2 = "NOT_YET_IMPLEMENTED_STRING"[
# a
# b
: # c
# d
]
# Check all places where comments can exist
b1 = "NOT_YET_IMPLEMENTED_STRING"[ # a
# b
1 # c
# d
: # e
# f
2 # g
# h
: # i
# j
3 # k
# l
]
# Handle the spacing from the colon correctly with upper leading comments
c1 = "NOT_YET_IMPLEMENTED_STRING"[
1: # e
# f
2
]
c2 = "NOT_YET_IMPLEMENTED_STRING"[
1: # e
2
]
c3 = "NOT_YET_IMPLEMENTED_STRING"[
1:
# f
2
]
c4 = "NOT_YET_IMPLEMENTED_STRING"[
1: # f
2
]
# End of line comments
d1 = "NOT_YET_IMPLEMENTED_STRING"[ # comment
:
]
d2 = "NOT_YET_IMPLEMENTED_STRING"[ # comment
1:
]
d3 = "NOT_YET_IMPLEMENTED_STRING"[
1 # comment
:
]
# Spacing around the colon(s)
def a():
...
e00 = "NOT_YET_IMPLEMENTED_STRING"[:]
e01 = "NOT_YET_IMPLEMENTED_STRING"[:1]
e02 = "NOT_YET_IMPLEMENTED_STRING"[ : NOT_IMPLEMENTED_call()]
e10 = "NOT_YET_IMPLEMENTED_STRING"[1:]
e11 = "NOT_YET_IMPLEMENTED_STRING"[1:1]
e12 = "NOT_YET_IMPLEMENTED_STRING"[1 : NOT_IMPLEMENTED_call()]
e20 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() :]
e21 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() : 1]
e22 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() : NOT_IMPLEMENTED_call()]
e200 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() : :]
e201 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() :: 1]
e202 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() :: NOT_IMPLEMENTED_call()]
e210 = "NOT_YET_IMPLEMENTED_STRING"[NOT_IMPLEMENTED_call() : 1 :]
```

View file

@ -112,9 +112,8 @@ impl Token {
self.range.start() self.range.start()
} }
#[allow(unused)]
pub(crate) const fn end(&self) -> TextSize { pub(crate) const fn end(&self) -> TextSize {
self.range.start() self.range.end()
} }
} }