Skip to content

Commit

Permalink
Fix formatting of lambda star arguments (#6257)
Browse files Browse the repository at this point in the history
## Summary
Previously, the ruff formatter was removing the star argument of
`lambda` expressions when formatting.

Given the following code snippet
```python
lambda *a: ()
lambda **b: ()
```
it would be formatted to
```python
lambda: ()
lambda: ()
```

We fix this by checking for the presence of `args`, `vararg` or `kwarg`
in the `lambda` expression, before we were only checking for the
presence of `args`.

Fixes #5894

## Test Plan

Add new tests cases.

---------

Co-authored-by: Charlie Marsh <[email protected]>
  • Loading branch information
LaBatata101 and charliermarsh authored Aug 2, 2023
1 parent c362ea7 commit 7c5791f
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 242 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,19 @@ def f(

# ...but we do preserve a trailing comma after the arguments
a = lambda b,: 0

lambda a,: 0
lambda *args,: 0
lambda **kwds,: 0
lambda a, *args,: 0
lambda a, **kwds,: 0
lambda *args, b,: 0
lambda *, b,: 0
lambda *args, **kwds,: 0
lambda a, *args, b,: 0
lambda a, *, b,: 0
lambda a, *args, **kwds,: 0
lambda *args, b, **kwds,: 0
lambda *, b, **kwds,: 0
lambda a, *args, b, **kwds,: 0
lambda a, *, b, **kwds,: 0
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,21 @@ def f42(
c,
):
pass


# Check trailing commas are permitted in funcdef argument list.
def f(a, ): pass
def f(*args, ): pass
def f(**kwds, ): pass
def f(a, *args, ): pass
def f(a, **kwds, ): pass
def f(*args, b, ): pass
def f(*, b, ): pass
def f(*args, **kwds, ): pass
def f(a, *args, b, ): pass
def f(a, *, b, ): pass
def f(a, *args, **kwds, ): pass
def f(*args, b, **kwds, ): pass
def f(*, b, **kwds, ): pass
def f(a, *args, b, **kwds, ): pass
def f(a, *, b, **kwds, ): pass
3 changes: 2 additions & 1 deletion crates/ruff_python_formatter/src/expression/expr_lambda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {

write!(f, [text("lambda")])?;

if !parameters.args.is_empty() {
if !parameters.args.is_empty() || parameters.vararg.is_some() || parameters.kwarg.is_some()
{
write!(
f,
[
Expand Down
21 changes: 14 additions & 7 deletions crates/ruff_python_formatter/src/other/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ pub(crate) struct ArgumentSeparator {
pub(crate) following_start: TextSize,
}

/// Finds slash and star in `f(a, /, b, *, c)`
/// Finds slash and star in `f(a, /, b, *, c)` or `lambda a, /, b, *, c: 1`.
///
/// Returns slash and star
/// Returns the location of the slash and star separators, if any.
pub(crate) fn find_argument_separators(
contents: &str,
parameters: &Parameters,
Expand Down Expand Up @@ -347,14 +347,21 @@ pub(crate) fn find_argument_separators(
} else {
let mut tokens = SimpleTokenizer::new(contents, parameters.range).skip_trivia();

let lparen = tokens
.next()
.expect("The function definition can't end here");
debug_assert!(lparen.kind() == SimpleTokenKind::LParen, "{lparen:?}");
let star = tokens
let lparen_or_star = tokens
.next()
.expect("The function definition can't end here");

// In a function definition, the first token should always be a `(`; in a lambda
// definition, it _can't_ be a `(`.
let star = if lparen_or_star.kind == SimpleTokenKind::LParen {
tokens
.next()
.expect("The function definition can't end here")
} else {
lparen_or_star
};
debug_assert!(star.kind() == SimpleTokenKind::Star, "{star:?}");

Some(ArgumentSeparator {
preceding_end: parameters.range.start(),
separator: star.range,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ def f(
# ...but we do preserve a trailing comma after the arguments
a = lambda b,: 0
lambda a,: 0
lambda *args,: 0
lambda **kwds,: 0
lambda a, *args,: 0
lambda a, **kwds,: 0
lambda *args, b,: 0
lambda *, b,: 0
lambda *args, **kwds,: 0
lambda a, *args, b,: 0
lambda a, *, b,: 0
lambda a, *args, **kwds,: 0
lambda *args, b, **kwds,: 0
lambda *, b, **kwds,: 0
lambda a, *args, b, **kwds,: 0
lambda a, *, b, **kwds,: 0
```

## Output
Expand Down Expand Up @@ -162,6 +178,22 @@ def f(
# ...but we do preserve a trailing comma after the arguments
a = lambda b,: 0
lambda a,: 0
lambda *args,: 0
lambda **kwds,: 0
lambda a, *args,: 0
lambda a, **kwds,: 0
lambda *args, b,: 0
lambda: 0
lambda *args, **kwds,: 0
lambda a, *args, b,: 0
lambda a, *, b,: 0
lambda a, *args, **kwds,: 0
lambda *args, b, **kwds,: 0
lambda *, b, **kwds,: 0
lambda a, *args, b, **kwds,: 0
lambda a, *, b, **kwds,: 0
```


Expand Down
Loading

0 comments on commit 7c5791f

Please sign in to comment.