Skip to content

Commit

Permalink
Format DictComp expression (#5771)
Browse files Browse the repository at this point in the history
## Summary

Format `DictComp` like `ListComp` from #5600. It's not 100%, but I
figured maybe it's worth starting to explore.

## Test Plan

Added ruff fixture based on `ListComp`'s.
  • Loading branch information
cnpryer authored and konstin committed Jul 19, 2023
1 parent 18ad339 commit e5c3481
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{i: i for i in []}

{i: i for i in [1,]}

{
a: a # a
for # for
c # c
in # in
e # e
}

{
# above a
a: a # a
# above for
for # for
# above c
c # c
# above in
in # in
# above e
e # e
# above if
if # if
# above f
f # f
# above if2
if # if2
# above g
g # g
}

{
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee]: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
for
ccccccccccccccccccccccccccccccccccccccc,
ddddddddddddddddddd, [eeeeeeeeeeeeeeeeeeeeee, fffffffffffffffffffffffff]
in
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd
if
fffffffffffffffffffffffffffffffffffffffffff < gggggggggggggggggggggggggggggggggggggggggggggg < hhhhhhhhhhhhhhhhhhhhhhhhhh
if
gggggggggggggggggggggggggggggggggggggggggggg
}
36 changes: 31 additions & 5 deletions crates/ruff_python_formatter/src/expression/expr_dict_comp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::context::PyFormatContext;
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
use crate::expression::parentheses::{parenthesized, NeedsParentheses, OptionalParentheses};
use crate::AsFormat;
use crate::{FormatNodeRule, FormattedIterExt, PyFormatter};
use ruff_formatter::prelude::{
format_args, format_with, group, soft_line_break_or_space, space, text,
};
use ruff_formatter::{write, Buffer, FormatResult};
use ruff_python_ast::node::AnyNodeRef;
use rustpython_parser::ast::ExprDictComp;
Expand All @@ -9,11 +13,33 @@ use rustpython_parser::ast::ExprDictComp;
pub struct FormatExprDictComp;

impl FormatNodeRule<ExprDictComp> for FormatExprDictComp {
fn fmt_fields(&self, _item: &ExprDictComp, f: &mut PyFormatter) -> FormatResult<()> {
fn fmt_fields(&self, item: &ExprDictComp, f: &mut PyFormatter) -> FormatResult<()> {
let ExprDictComp {
range: _,
key,
value,
generators,
} = item;

let joined = format_with(|f| {
f.join_with(soft_line_break_or_space())
.entries(generators.iter().formatted())
.finish()
});

write!(
f,
[not_yet_implemented_custom_text(
"{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}"
[parenthesized(
"{",
&format_args!(
group(&key.format()),
text(":"),
space(),
value.format(),
soft_line_break_or_space(),
group(&joined)
),
"}"
)]
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,27 +316,19 @@ last_call()
()
(1,)
(1, 2)
@@ -95,14 +98,11 @@
[(i**2) for i in (1, 2, 3)]
[(i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c"))]
[((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3)]
-{i: 0 for i in (1, 2, 3)}
-{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()}
-{
- k: v
@@ -101,7 +104,10 @@
{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
-}
+{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+ 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()
@@ -115,7 +115,7 @@
@@ -115,7 +121,7 @@
arg,
another,
kwarg="hey",
Expand All @@ -345,7 +337,7 @@ last_call()
) # note: no trailing comma pre-3.6
call(*gidgets[:2])
call(a, *gidgets[:2])
@@ -152,13 +152,13 @@
@@ -152,13 +158,13 @@
slice[0:1]
slice[0:1:2]
slice[:]
Expand All @@ -362,7 +354,7 @@ last_call()
numpy[0, :]
numpy[:, i]
numpy[0, :2]
@@ -172,7 +172,7 @@
@@ -172,7 +178,7 @@
numpy[1 : c + 1, c]
numpy[-(c + 1) :, d]
numpy[:, l[-2]]
Expand All @@ -371,7 +363,7 @@ last_call()
numpy[np.newaxis, :]
(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}
@@ -181,10 +181,10 @@
@@ -181,10 +187,10 @@
(SomeName)
SomeName
(Good, Bad, Ugly)
Expand All @@ -386,7 +378,7 @@ last_call()
(*starred,)
{
"id": "1",
@@ -208,24 +208,14 @@
@@ -208,24 +214,14 @@
what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
vars_to_remove
)
Expand Down Expand Up @@ -419,7 +411,7 @@ last_call()
Ø = set()
authorsukasz.say_thanks()
mapping = {
@@ -237,10 +227,10 @@
@@ -237,10 +233,10 @@
def gen():
Expand All @@ -434,22 +426,16 @@ last_call()
async def f():
@@ -248,8 +238,12 @@
@@ -249,7 +245,7 @@
print(*[] or [1])
-print(**{1: 3} if False else {x: x for x in range(3)})
print(**{1: 3} if False else {x: x for x in range(3)})
-print(*lambda x: x)
+print(
+ **{1: 3}
+ if False
+ else {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
+)
+print(*lambda NOT_YET_IMPLEMENTED_lambda: True)
assert not Test, "Short message"
assert this is ComplexTest and not requirements.fit_in_a_single_line(
force=False
@@ -259,7 +253,7 @@
@@ -259,7 +255,7 @@
...
for y in ():
...
Expand All @@ -458,7 +444,7 @@ last_call()
...
for i in call():
...
@@ -328,13 +322,18 @@
@@ -328,13 +324,18 @@
):
return True
if (
Expand All @@ -480,7 +466,7 @@ last_call()
^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n
):
return True
@@ -342,7 +341,8 @@
@@ -342,7 +343,8 @@
~aaaaaaaaaaaaaaaa.a
+ aaaaaaaaaaaaaaaa.b
- aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e
Expand Down Expand Up @@ -595,11 +581,17 @@ str or None if (1 if True else 2) else str or bytes or None
[(i**2) for i in (1, 2, 3)]
[(i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c"))]
[((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3)]
{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
{NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
{i: 0 for i in (1, 2, 3)}
{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()}
{
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()
Expand Down Expand Up @@ -735,11 +727,7 @@ async def f():
print(*[] or [1])
print(
**{1: 3}
if False
else {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
)
print(**{1: 3} if False else {x: x for x in range(3)})
print(*lambda NOT_YET_IMPLEMENTED_lambda: True)
assert not Test, "Short message"
assert this is ComplexTest and not requirements.fit_in_a_single_line(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,6 @@ return np.divide(
f = f() ** 5
g = a.b**c.d
h = 5 ** funcs.f()
@@ -26,7 +26,7 @@
m = [([2**63], [1, 2**63])]
n = count <= 10**5
o = settings(max_examples=10**6)
-p = {(k, k**2): v**2 for k, v in pairs}
+p = {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
q = [10**i for i in range(6)]
r = x**y
@@ -34,7 +34,7 @@
b = 5.0 ** f()
c = -(5.0**2.0)
Expand All @@ -102,15 +93,6 @@ return np.divide(
f = f() ** 5.0
g = a.b**c.d
h = 5.0 ** funcs.f()
@@ -45,7 +45,7 @@
m = [([2.0**63.0], [1.0, 2**63.0])]
n = count <= 10**5.0
o = settings(max_examples=10**6.0)
-p = {(k, k**2): v**2.0 for k, v in pairs}
+p = {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
q = [10.5**i for i in range(6)]
```

## Ruff Output
Expand Down Expand Up @@ -144,7 +126,7 @@ l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001)
m = [([2**63], [1, 2**63])]
n = count <= 10**5
o = settings(max_examples=10**6)
p = {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
p = {(k, k**2): v**2 for k, v in pairs}
q = [10**i for i in range(6)]
r = x**y
Expand All @@ -163,7 +145,7 @@ l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001)
m = [([2.0**63.0], [1.0, 2**63.0])]
n = count <= 10**5.0
o = settings(max_examples=10**6.0)
p = {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
p = {(k, k**2): v**2.0 for k, v in pairs}
q = [10.5**i for i in range(6)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,44 +96,6 @@ def example8():
def example4():
@@ -50,35 +44,11 @@
def example6():
- return {a: a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]}
+ return {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
def example7():
- return {
- a: a
- for a in [
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 20000000000000000000,
- ]
- }
+ return {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
def example8():
```

## Ruff Output
Expand Down Expand Up @@ -185,11 +147,35 @@ def example5():
def example6():
return {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
return {a: a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]}
def example7():
return {NOT_IMPLEMENTED_dict_key: NOT_IMPLEMENTED_dict_value for key, value in NOT_IMPLEMENTED_dict}
return {
a: a
for a in [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20000000000000000000,
]
}
def example8():
Expand Down
Loading

0 comments on commit e5c3481

Please sign in to comment.