Skip to content

Commit

Permalink
Implement module formatting using JoinNodesBuilder
Browse files Browse the repository at this point in the history
This uses JoinNodesBuilder to implement module formatting for #4800

See the snapshots for the changed behaviour. See one PR up for a CLI that i used to verify the trailing new line behaviour
  • Loading branch information
konstin committed Jun 2, 2023
1 parent f5521f0 commit bf700af
Show file tree
Hide file tree
Showing 41 changed files with 704 additions and 1,241 deletions.
13 changes: 7 additions & 6 deletions crates/ruff_python_formatter/src/module/mod_module.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use crate::AsFormat;
use crate::builders::PyFormatterExtensions;
use crate::context::NodeLevel;
use crate::{FormatNodeRule, PyFormatter};
use ruff_formatter::prelude::hard_line_break;
use ruff_formatter::{write, Buffer, FormatResult};

use ruff_formatter::{Format, FormatResult};
use rustpython_parser::ast::ModModule;

#[derive(Default)]
pub struct FormatModModule;

impl FormatNodeRule<ModModule> for FormatModModule {
fn fmt_fields(&self, item: &ModModule, f: &mut PyFormatter) -> FormatResult<()> {
for stmt in &item.body {
write!(f, [stmt.format(), hard_line_break()])?;
}
f.join_nodes(NodeLevel::TopLevel)
.nodes(&item.body)
.finish()?;
hard_line_break().fmt(f)?;
Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ y = 100(no)
```diff
--- Black
+++ Ruff
@@ -1,22 +1,20 @@
@@ -1,21 +1,21 @@
-x = (123456789).bit_count()
+x = 123456789 .bit_count()
x = (123456).__abs__()
Expand All @@ -53,8 +53,6 @@ y = 100(no)
-x = 0o777.real
-x = (0.000000006).hex()
-x = -100.0000j
-
-if (10).real:
+x = .1.is_integer()
+x = 1. .imag
+x = 1E+1.imag
Expand All @@ -69,11 +67,12 @@ y = 100(no)
+x = 0O777 .real
+x = 0.000000006 .hex()
+x = -100.0000J
-if (10).real:
+if 10 .real:
...
-
y = 100[no]
y = 100(no)
```

## Ruff Output
Expand All @@ -95,8 +94,10 @@ x = 0B1011 .conjugate()
x = 0O777 .real
x = 0.000000006 .hex()
x = -100.0000J
if 10 .real:
...
y = 100[no]
y = 100(no)
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class NormalClass (
```diff
--- Black
+++ Ruff
@@ -1,30 +1,21 @@
@@ -1,30 +1,23 @@
-class SimpleClassWithBlankParentheses:
+class SimpleClassWithBlankParentheses():
pass
Expand All @@ -50,13 +50,13 @@ class NormalClass (
def test_func(self):
return None
-
-
class ClassWithEmptyFunc(object):
+
+class ClassWithEmptyFunc(object):
-class ClassWithEmptyFunc(object):
def func_with_blank_parentheses():
return 5
-
-
def public_func_with_blank_parentheses():
return None
-
Expand Down Expand Up @@ -89,6 +89,8 @@ class ClassWithEmptyFunc(object):
def func_with_blank_parentheses():
return 5
def public_func_with_blank_parentheses():
return None
def class_under_the_func_with_blank_parentheses():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ if True:
```diff
--- Black
+++ Ruff
@@ -1,99 +1,61 @@
@@ -1,75 +1,49 @@
import core, time, a
-
from . import A, B, C
-
# keeps existing trailing comma
Expand All @@ -104,7 +104,7 @@ if True:
from foo import (
xyzzy as magic,
)
-
-a = {
- 1,
- 2,
Expand Down Expand Up @@ -162,24 +162,22 @@ if True:
pass
for (x,) in (1,), (2,), (3,):
pass
-
-[
- 1,
- 2,
- 3,
-]
-
-division_result_tuple = (6 / 2,)
+[1, 2, 3,]
-division_result_tuple = (6 / 2,)
+division_result_tuple = (6/2,)
print("foo %r", (foo.bar,))
-
if True:
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
Config.IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING
| {pylons.controllers.WSGIController}
@@ -79,21 +53,15 @@
)
-
if True:
- ec2client.get_waiter("instance_stopped").wait(
+ ec2client.get_waiter('instance_stopped').wait(
Expand Down Expand Up @@ -210,6 +208,7 @@ if True:

```py
import core, time, a
from . import A, B, C
# keeps existing trailing comma
from foo import (
Expand All @@ -224,6 +223,7 @@ from foo import (
from foo import (
xyzzy as magic,
)
a = {1,2,3,}
b = {
1,2,
Expand All @@ -249,14 +249,18 @@ for x in (1,):
pass
for (x,) in (1,), (2,), (3,):
pass
[1, 2, 3,]
division_result_tuple = (6/2,)
print("foo %r", (foo.bar,))
if True:
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
Config.IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING
| {pylons.controllers.WSGIController}
)
if True:
ec2client.get_waiter('instance_stopped').wait(
InstanceIds=[instance.id],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ def bobtwo(): \
```diff
--- Black
+++ Ruff
@@ -1,6 +1,7 @@
@@ -1,6 +1,9 @@
-def bob(): # pylint: disable=W9016
+def bob(): \
+ # pylint: disable=W9016
pass
-
-
-def bobtwo(): # some comment here
+def bobtwo(): \
+ \
Expand All @@ -42,6 +42,8 @@ def bobtwo(): \
def bob(): \
# pylint: disable=W9016
pass
def bobtwo(): \
\
# some comment here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ instruction()#comment with bad spacing
```diff
--- Black
+++ Ruff
@@ -1,39 +1,38 @@
@@ -1,39 +1,40 @@
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
- MyLovelyCompanyTeamProjectComponent, # NOT DRY
+ MyLovelyCompanyTeamProjectComponent # NOT DRY
Expand All @@ -187,7 +187,7 @@ instruction()#comment with bad spacing
- MyLovelyCompanyTeamProjectComponent as component, # DRY
+ MyLovelyCompanyTeamProjectComponent as component # DRY
)
-
# Please keep __all__ alphabetized within each category.
__all__ = [
Expand Down Expand Up @@ -227,7 +227,7 @@ instruction()#comment with bad spacing
+ 'NamedTuple', # Not really a type.
+ 'Generator',
]
-
not_shareables = [
# singletons
True,
Expand All @@ -238,11 +238,10 @@ instruction()#comment with bad spacing
# builtin types and objects
type,
object,
@@ -47,21 +46,21 @@
Cheese("Wensleydale"),
@@ -48,20 +49,21 @@
SubBytes(b"spam"),
]
-
-if "PYTHON" in os.environ:
+if 'PYTHON' in os.environ:
add_compiler(compiler_from_env())
Expand All @@ -267,7 +266,7 @@ instruction()#comment with bad spacing
children[0],
body,
children[-1], # type: ignore
@@ -73,49 +72,42 @@
@@ -73,49 +75,42 @@
parameters.children[-1], # )2
]
parameters.children = [parameters.what_if_this_was_actually_long.children[0], body, parameters.children[-1]] # type: ignore
Expand Down Expand Up @@ -340,7 +339,7 @@ instruction()#comment with bad spacing
]
lcomp2 = [
# hello
@@ -127,7 +119,7 @@
@@ -127,7 +122,7 @@
]
lcomp3 = [
# This one is actually too long to fit in a single line.
Expand All @@ -349,7 +348,7 @@ instruction()#comment with bad spacing
# yup
for element in collection.select_elements()
# right
@@ -140,28 +132,20 @@
@@ -140,25 +135,21 @@
# and round and round we go
# and round and round we go
Expand All @@ -363,7 +362,7 @@ instruction()#comment with bad spacing
+ Leaf(token.NEWLINE, '\n') # FIXME: \r\n?
+ ],
)
-
-
-CONFIG_FILES = (
- [
Expand All @@ -373,19 +372,16 @@ instruction()#comment with bad spacing
- + USER_CONFIG_FILES
-) # type: Final
-
-
+CONFIG_FILES = [CONFIG_FILE, ] + SHARED_CONFIG_FILES + USER_CONFIG_FILES # type: Final
class Test:
def _init_host(self, parsed) -> None:
- if parsed.hostname is None or not parsed.hostname.strip(): # type: ignore
+ if (parsed.hostname is None or # type: ignore
+ not parsed.hostname.strip()):
pass
-
-
#######################
### SECTION COMMENT ###
#######################
```

## Ruff Output
Expand All @@ -397,6 +393,7 @@ from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
MyLovelyCompanyTeamProjectComponent as component # DRY
)
# Please keep __all__ alphabetized within each category.
__all__ = [
Expand All @@ -421,6 +418,7 @@ __all__ = [
'NamedTuple', # Not really a type.
'Generator',
]
not_shareables = [
# singletons
True,
Expand All @@ -439,6 +437,7 @@ not_shareables = [
Cheese("Wensleydale"),
SubBytes(b"spam"),
]
if 'PYTHON' in os.environ:
add_compiler(compiler_from_env())
else:
Expand Down Expand Up @@ -533,12 +532,16 @@ short
Leaf(token.NEWLINE, '\n') # FIXME: \r\n?
],
)
CONFIG_FILES = [CONFIG_FILE, ] + SHARED_CONFIG_FILES + USER_CONFIG_FILES # type: Final
class Test:
def _init_host(self, parsed) -> None:
if (parsed.hostname is None or # type: ignore
not parsed.hostname.strip()):
pass
#######################
### SECTION COMMENT ###
#######################
Expand Down
Loading

0 comments on commit bf700af

Please sign in to comment.