Break global and nonlocal statements over continuation lines (#6172)

## Summary

Builds on #6170 to break `global` and `nonlocal` statements, such that
we get:

```python
def f():
    global \
        analyze_featuremap_layer, \
        analyze_featuremapcompression_layer, \
        analyze_latencies_post, \
        analyze_motions_layer, \
        analyze_size_model
```

Instead of:

```python
def f():
    global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
```

Notably, we avoid applying this formatting if the statement ends in a
comment. Otherwise, the comment would _need_ to be placed after the last
item, like:

```python
def f():
    global \
        analyze_featuremap_layer, \
        analyze_featuremapcompression_layer, \
        analyze_latencies_post, \
        analyze_motions_layer, \
        analyze_size_model  # noqa
```

To me, this seems wrong (and would break the `# noqa` comment). Ideally,
the items would be parenthesized, and the comment would be on the inner
parenthesis, like:

```python
def f():
    global (  # noqa
        analyze_featuremap_layer,
        analyze_featuremapcompression_layer,
        analyze_latencies_post,
        analyze_motions_layer,
        analyze_size_model
    )
```

But that's not valid syntax.
This commit is contained in:
Charlie Marsh 2023-08-02 15:55:00 -04:00 committed by GitHub
parent 9f38dbd06e
commit 9425ed72a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 10 deletions

View file

@ -10,3 +10,7 @@ def f():
def f():
global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
def f():
global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model # end-of-line comment

View file

@ -10,3 +10,7 @@ def f():
def f():
nonlocal analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
def f():
nonlocal analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model # end-of-line comment

View file

@ -1,4 +1,5 @@
use ruff_formatter::{format_args, write};
use ruff_python_ast::node::AstNode;
use ruff_python_ast::StmtGlobal;
use crate::prelude::*;
@ -9,10 +10,44 @@ pub struct FormatStmtGlobal;
impl FormatNodeRule<StmtGlobal> for FormatStmtGlobal {
fn fmt_fields(&self, item: &StmtGlobal, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [text("global"), space()])?;
// Join the `global` names, breaking across continuation lines if necessary, unless the
// `global` statement has a trailing comment, in which case, breaking the names would
// move the comment "off" of the `global` statement.
if f.context()
.comments()
.has_trailing_comments(item.as_any_node_ref())
{
let joined = format_with(|f| {
f.join_with(format_args![text(","), space()])
.entries(item.names.iter().formatted())
.finish()
});
f.join_with(format_args![text(","), space()])
.entries(item.names.iter().formatted())
.finish()
write!(f, [text("global"), space(), &joined])
} else {
let joined = format_with(|f| {
f.join_with(&format_args![
text(","),
space(),
if_group_breaks(&text("\\")),
soft_line_break(),
])
.entries(item.names.iter().formatted())
.finish()
});
write!(
f,
[
text("global"),
space(),
&group(&format_args!(
if_group_breaks(&text("\\")),
soft_line_break(),
&soft_block_indent(&joined)
))
]
)
}
}
}

View file

@ -1,4 +1,5 @@
use ruff_formatter::{format_args, write};
use ruff_python_ast::node::AstNode;
use ruff_python_ast::StmtNonlocal;
use crate::prelude::*;
@ -9,10 +10,44 @@ pub struct FormatStmtNonlocal;
impl FormatNodeRule<StmtNonlocal> for FormatStmtNonlocal {
fn fmt_fields(&self, item: &StmtNonlocal, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [text("nonlocal"), space()])?;
// Join the `nonlocal` names, breaking across continuation lines if necessary, unless the
// `nonlocal` statement has a trailing comment, in which case, breaking the names would
// move the comment "off" of the `nonlocal` statement.
if f.context()
.comments()
.has_trailing_comments(item.as_any_node_ref())
{
let joined = format_with(|f| {
f.join_with(format_args![text(","), space()])
.entries(item.names.iter().formatted())
.finish()
});
f.join_with(format_args![text(","), space()])
.entries(item.names.iter().formatted())
.finish()
write!(f, [text("nonlocal"), space(), &joined])
} else {
let joined = format_with(|f| {
f.join_with(&format_args![
text(","),
space(),
if_group_breaks(&text("\\")),
soft_line_break(),
])
.entries(item.names.iter().formatted())
.finish()
});
write!(
f,
[
text("nonlocal"),
space(),
&group(&format_args!(
if_group_breaks(&text("\\")),
soft_line_break(),
&soft_block_indent(&joined)
))
]
)
}
}
}

View file

@ -16,6 +16,10 @@ def f():
def f():
global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
def f():
global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model # end-of-line comment
```
## Output
@ -31,7 +35,16 @@ def f():
def f():
global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
global \
analyze_featuremap_layer, \
analyze_featuremapcompression_layer, \
analyze_latencies_post, \
analyze_motions_layer, \
analyze_size_model
def f():
global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model # end-of-line comment
```

View file

@ -16,6 +16,10 @@ def f():
def f():
nonlocal analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
def f():
nonlocal analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model # end-of-line comment
```
## Output
@ -31,7 +35,16 @@ def f():
def f():
nonlocal analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model
nonlocal \
analyze_featuremap_layer, \
analyze_featuremapcompression_layer, \
analyze_latencies_post, \
analyze_motions_layer, \
analyze_size_model
def f():
nonlocal analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model # end-of-line comment
```