Skip to content

Commit

Permalink
Indent lambda parameters if parameters wrap
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Nov 3, 2023
1 parent e7fb0ac commit 70968de
Show file tree
Hide file tree
Showing 10 changed files with 625 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"preview": "disabled"
},
{
"preview": "enabled"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,71 @@ def f(
z
)


# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing


# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z
] # Trailing
# Trailing

lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: d

# Regression tests for https://github.com/astral-sh/ruff/issues/8179
Expand Down
12 changes: 0 additions & 12 deletions crates/ruff_python_formatter/src/comments/placement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1805,18 +1805,6 @@ fn handle_lambda_comment<'a>(
locator: &Locator,
) -> CommentPlacement<'a> {
if let Some(parameters) = lambda.parameters.as_deref() {
// Comments between the `lambda` and the parameters are dangling on the lambda:
// ```python
// (
// lambda # comment
// x:
// y
// )
// ```
if comment.start() < parameters.start() {
return CommentPlacement::dangling(comment.enclosing_node(), comment);
}

// Comments between the parameters and the body are dangling on the lambda:
// ```python
// (
Expand Down
8 changes: 8 additions & 0 deletions crates/ruff_python_formatter/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ impl<'a> PyFormatContext<'a> {
pub(crate) fn comments(&self) -> &Comments<'a> {
&self.comments
}

pub(crate) const fn is_preview(&self) -> bool {
self.options.preview().is_enabled()
}

pub(crate) const fn is_stable(&self) -> bool {
!self.is_preview()
}
}

impl FormatContext for PyFormatContext<'_> {
Expand Down
46 changes: 31 additions & 15 deletions crates/ruff_python_formatter/src/expression/expr_lambda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use ruff_python_ast::ExprLambda;
use ruff_text_size::Ranged;

use crate::comments::{dangling_comments, SourceComment};
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parenthesize};
use crate::expression::{has_own_parentheses, maybe_parenthesize_expression};
use crate::other::parameters::ParametersParentheses;
use crate::prelude::*;

Expand All @@ -25,7 +26,7 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
write!(f, [token("lambda")])?;

if let Some(parameters) = parameters {
// In this context, a dangling comment can either be a comment between the `lambda` the
// In this context, a dangling comment can either be a comment between the `lambda` and the
// parameters, or a comment between the parameters and the body.
let (dangling_before_parameters, dangling_after_parameters) = dangling
.split_at(dangling.partition_point(|comment| comment.end() < parameters.start()));
Expand All @@ -36,20 +37,30 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
write!(f, [dangling_comments(dangling_before_parameters)])?;
}

write!(
f,
[parameters
.format()
.with_options(ParametersParentheses::Never)]
)?;
group(&format_with(|f: &mut PyFormatter| {
if f.context().node_level().is_parenthesized() {
soft_block_indent(
&parameters
.format()
.with_options(ParametersParentheses::Never),
)
.fmt(f)
} else {
parameters
.format()
.with_options(ParametersParentheses::Never)
.fmt(f)
}?;

write!(f, [token(":")])?;
token(":").fmt(f)?;

if dangling_after_parameters.is_empty() {
write!(f, [space()])?;
} else {
write!(f, [dangling_comments(dangling_after_parameters)])?;
}
if dangling_after_parameters.is_empty() {
space().fmt(f)
} else {
dangling_comments(dangling_after_parameters).fmt(f)
}
}))
.fmt(f)?;
} else {
write!(f, [token(":")])?;

Expand All @@ -61,7 +72,12 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
}
}

write!(f, [body.format()])
// Avoid parenthesizing lists, dictionaries, etc.
if f.context().is_stable() || has_own_parentheses(body, f.context()).is_some() {
body.format().fmt(f)
} else {
maybe_parenthesize_expression(body, item, Parenthesize::IfBreaksOrIfRequired).fmt(f)
}
}

fn fmt_dangling_comments(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ impl NeedsParentheses for ExprNamedExpr {
|| parent.is_stmt_delete()
|| parent.is_stmt_for()
|| parent.is_stmt_function_def()
|| parent.is_expr_lambda()
{
OptionalParentheses::Always
} else {
Expand Down
9 changes: 1 addition & 8 deletions crates/ruff_python_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,7 @@ if True:
#[test]
fn quick_test() {
let source = r#"
def main() -> None:
if True:
some_very_long_variable_name_abcdefghijk = Foo()
some_very_long_variable_name_abcdefghijk = some_very_long_variable_name_abcdefghijk[
some_very_long_variable_name_abcdefghijk.some_very_long_attribute_name
== "This is a very long string abcdefghijk"
]
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: d
"#;
let source_type = PySourceType::Python;
let (tokens, comment_ranges) = tokens_and_ranges(source, source_type).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_python_formatter/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl PyFormatOptions {
self.line_ending
}

pub fn preview(&self) -> PreviewMode {
pub const fn preview(&self) -> PreviewMode {
self.preview
}

Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_python_formatter/src/other/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl FormatNodeRule<Parameters> for FormatParameters {
+ usize::from(kwarg.is_some());

if self.parentheses == ParametersParentheses::Never {
write!(f, [group(&format_inner), dangling_comments(dangling)])
write!(f, [format_inner, dangling_comments(dangling)])
} else if num_parameters == 0 {
let mut f = WithNodeLevel::new(NodeLevel::ParenthesizedExpression, f);
// No parameters, format any dangling comments between `()`
Expand Down
Loading

0 comments on commit 70968de

Please sign in to comment.