Skip to content

Commit 3e9f4ee

Browse files
authored
fix(unparser): correct precedences for comprehensions and generators (#17)
1 parent 7898e37 commit 3e9f4ee

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

src/unparser.rs

+34-14
Original file line numberDiff line numberDiff line change
@@ -789,11 +789,15 @@ impl Unparser {
789789
fn unparse_expr_if_exp(&mut self, node: &ExprIfExp<TextRange>) {
790790
let enum_member = Expr::IfExp(node.to_owned());
791791
self.delimit_precedence(&enum_member, |block_self| {
792-
block_self.unparse_expr(&node.body);
793-
block_self.write_str(" if ");
794-
block_self.unparse_expr(&node.test);
795-
block_self.write_str(" else ");
796-
block_self.unparse_expr(&node.orelse);
792+
block_self.with_precedence_num(Precedence::Test.value() + 1, |prec_self| {
793+
prec_self.unparse_expr(&node.body);
794+
prec_self.write_str(" if ");
795+
prec_self.unparse_expr(&node.test);
796+
});
797+
block_self.with_precedence(Precedence::Test, |prec_self| {
798+
prec_self.write_str(" else ");
799+
prec_self.unparse_expr(&node.orelse);
800+
});
797801
})
798802
}
799803

@@ -811,7 +815,10 @@ impl Unparser {
811815
self.write_str("**");
812816
}
813817
}
814-
self.unparse_expr(value);
818+
self.with_precedence_num(EXPR_PRECEDENCE, |prec_self| {
819+
prec_self.unparse_expr(value);
820+
});
821+
815822
if zipped.peek().is_some() {
816823
self.write_str(", ");
817824
}
@@ -1173,14 +1180,21 @@ impl Unparser {
11731180

11741181
fn unparse_expr_tuple(&mut self, node: &ExprTuple<TextRange>) {
11751182
let mut elts_iter = node.elts.iter().peekable();
1176-
self.write_str("(");
1183+
let should_delimit =
1184+
node.elts.len() == 0 || self.precedence_level > Precedence::Tuple.value();
1185+
if should_delimit {
1186+
self.write_str("(");
1187+
}
1188+
11771189
while let Some(expr) = elts_iter.next() {
11781190
self.unparse_expr(expr);
11791191
if elts_iter.peek().is_some() || node.elts.len() == 1 {
11801192
self.write_str(", ");
11811193
}
11821194
}
1183-
self.write_str(")");
1195+
if should_delimit {
1196+
self.write_str(")");
1197+
}
11841198
}
11851199

11861200
fn unparse_expr_slice(&mut self, node: &ExprSlice<TextRange>) {
@@ -1221,13 +1235,19 @@ impl Unparser {
12211235
} else {
12221236
self.write_str(" for ");
12231237
}
1224-
self.unparse_expr(&node.target);
1238+
self.with_precedence(Precedence::Tuple, |prec_self| {
1239+
prec_self.unparse_expr(&node.target);
1240+
});
1241+
12251242
self.write_str(" in ");
1226-
self.unparse_expr(&node.iter);
1227-
for if_ in &node.ifs {
1228-
self.write_str(" if ");
1229-
self.unparse_expr(if_);
1230-
}
1243+
1244+
self.with_precedence_num(Precedence::Test.value() + 1, |prec_self| {
1245+
prec_self.unparse_expr(&node.iter);
1246+
for if_ in &node.ifs {
1247+
prec_self.write_str(" if ");
1248+
prec_self.unparse_expr(if_);
1249+
}
1250+
});
12311251
}
12321252

12331253
fn unparse_excepthandler(&mut self, node: &ExceptHandler<TextRange>) {

test_files/precedence.py

+18
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
1+
import dataclasses
2+
13
reduce = "abcdefhijklmnopqrstuvwxyz"
24
reduce_list = (list(reduce) + [None] * 5)[:5]
5+
6+
7+
@dataclasses.dataclass
8+
class MyDataclass:
9+
name: str
10+
11+
12+
# from pydantic._internal._fields
13+
dataclass_fields = {
14+
field.name
15+
for field in (
16+
dataclasses.fields(MyDataclass) if dataclasses.is_dataclass(MyDataclass) else ()
17+
)
18+
}
19+
20+
a, b, c = "a", "b", "c"

0 commit comments

Comments
 (0)