rustpython_unparser/
unparser.rs

1use rustpython_ast::{
2    text_size::TextRange, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, ExceptHandler,
3    ExceptHandlerExceptHandler, Expr, ExprAttribute, ExprAwait, ExprBinOp, ExprBoolOp, ExprCall,
4    ExprCompare, ExprConstant, ExprDict, ExprDictComp, ExprFormattedValue, ExprGeneratorExp,
5    ExprIfExp, ExprJoinedStr, ExprLambda, ExprList, ExprListComp, ExprName, ExprNamedExpr, ExprSet,
6    ExprSetComp, ExprSlice, ExprStarred, ExprSubscript, ExprTuple, ExprUnaryOp, ExprYield,
7    ExprYieldFrom, Keyword, MatchCase, Operator, Pattern, PatternMatchAs, PatternMatchClass,
8    PatternMatchMapping, PatternMatchOr, PatternMatchSequence, PatternMatchSingleton,
9    PatternMatchStar, PatternMatchValue, Stmt, StmtAnnAssign, StmtAssert, StmtAssign, StmtAsyncFor,
10    StmtAsyncFunctionDef, StmtAsyncWith, StmtAugAssign, StmtBreak, StmtClassDef, StmtContinue,
11    StmtDelete, StmtExpr, StmtFor, StmtFunctionDef, StmtGlobal, StmtIf, StmtImport, StmtImportFrom,
12    StmtMatch, StmtNonlocal, StmtPass, StmtRaise, StmtReturn, StmtTry, StmtTryStar, StmtTypeAlias,
13    StmtWhile, StmtWith, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple,
14    UnaryOp, WithItem,
15};
16use rustpython_ast::{Constant, ConversionFlag, Int};
17use std::ops::Deref;
18
19use crate::utils::replace_first_and_last;
20
21enum Precedence {
22    NamedExpr = 1,
23    Tuple = 2,
24    Yield = 3,
25    Test = 4,
26    Or = 5,
27    And = 6,
28    Not = 7,
29    Cmp = 8,
30
31    Bor = 9,
32    Bxor = 10,
33    Band = 11,
34    Shift = 12,
35    Arith = 13,
36    Term = 14,
37    Factor = 15,
38    Power = 16,
39    Await = 17,
40    Atom = 18,
41}
42
43impl Precedence {
44    fn value(self) -> usize {
45        self as usize
46    }
47}
48
49const EXPR_PRECEDENCE: usize = 9;
50
51fn get_precedence(node: &Expr<TextRange>) -> usize {
52    match node {
53        Expr::NamedExpr(_) => Precedence::NamedExpr.value(),
54        Expr::Tuple(_) => Precedence::Tuple.value(),
55        Expr::Yield(_) => Precedence::Yield.value(),
56        Expr::YieldFrom(_) => Precedence::Yield.value(),
57        Expr::IfExp(_) => Precedence::Test.value(),
58        Expr::Lambda(_) => Precedence::Test.value(),
59        Expr::BoolOp(data) => match data.op {
60            BoolOp::Or => Precedence::Or.value(),
61            BoolOp::And => Precedence::And.value(),
62        },
63        Expr::UnaryOp(data) => match data.op {
64            UnaryOp::Not => Precedence::Not.value(),
65            UnaryOp::UAdd => Precedence::Factor.value(),
66            UnaryOp::USub => Precedence::Factor.value(),
67            UnaryOp::Invert => Precedence::Factor.value(),
68        },
69        Expr::Compare(_) => Precedence::Cmp.value(),
70        Expr::BinOp(data) => match data.op {
71            Operator::BitOr => Precedence::Bor.value(),
72            Operator::BitXor => Precedence::Bxor.value(),
73            Operator::BitAnd => Precedence::Band.value(),
74            Operator::LShift => Precedence::Shift.value(),
75            Operator::RShift => Precedence::Shift.value(),
76            Operator::Add => Precedence::Arith.value(),
77            Operator::Sub => Precedence::Arith.value(),
78            Operator::Div => Precedence::Term.value(),
79            Operator::FloorDiv => Precedence::Term.value(),
80            Operator::Mult => Precedence::Term.value(),
81            Operator::MatMult => Precedence::Term.value(),
82            Operator::Mod => Precedence::Term.value(),
83            Operator::Pow => Precedence::Power.value(),
84        },
85        Expr::Await(_) => Precedence::Await.value(),
86        _ => Precedence::Test.value(),
87    }
88}
89
90pub struct Unparser {
91    pub source: String,
92    indent: usize,
93    in_try_star: bool,
94    precedence_level: usize,
95}
96
97impl Unparser {
98    pub fn new() -> Self {
99        Unparser {
100            in_try_star: false,
101            indent: 0,
102            precedence_level: Precedence::Test.value(),
103            source: String::new(),
104        }
105    }
106
107    fn fill(&mut self, str_: &str) {
108        if self.source.len() > 0 {
109            self.write_str(&("\n".to_owned() + &" ".repeat(self.indent * 4) + str_))
110        } else {
111            self.write_str(str_);
112        }
113    }
114
115    fn write_str(&mut self, str_: &str) {
116        self.source += str_
117    }
118
119    fn write_type_comment(&mut self, type_comment: &Option<String>) {
120        if let Some(str_) = type_comment {
121            self.write_str("  # type: ignore");
122            self.write_str(str_);
123        }
124    }
125
126    fn block<F>(&mut self, f: F)
127    where
128        F: FnOnce(&mut Self),
129    {
130        self.indent += 1;
131        f(self);
132        self.indent -= 1;
133    }
134
135    fn delimit_precedence<F>(&mut self, node: &Expr<TextRange>, f: F)
136    where
137        F: FnOnce(&mut Self),
138    {
139        let should_delimit = self.precedence_level > get_precedence(node);
140        if should_delimit {
141            self.write_str("(");
142        }
143        f(self);
144        if should_delimit {
145            self.write_str(")");
146        }
147    }
148
149    fn with_precedence<F>(&mut self, prec: Precedence, f: F)
150    where
151        F: FnOnce(&mut Self),
152    {
153        let prev_prec = self.precedence_level;
154        self.precedence_level = prec.value();
155        f(self);
156        self.precedence_level = prev_prec;
157    }
158
159    fn with_precedence_num<F>(&mut self, prec: usize, f: F)
160    where
161        F: FnOnce(&mut Self),
162    {
163        let prev_prec = self.precedence_level;
164        self.precedence_level = prec;
165        f(self);
166        self.precedence_level = prev_prec;
167    }
168
169    pub fn unparse_stmt(&mut self, node: &Stmt<TextRange>) {
170        match node {
171            Stmt::FunctionDef(data) => self.unparse_stmt_function_def(data),
172            Stmt::AsyncFunctionDef(data) => self.unparse_stmt_async_function_def(data),
173            Stmt::ClassDef(data) => self.unparse_stmt_class_def(data),
174            Stmt::Return(data) => self.unparse_stmt_return(data),
175            Stmt::Delete(data) => self.unparse_stmt_delete(data),
176            Stmt::Assign(data) => self.unparse_stmt_assign(data),
177            Stmt::TypeAlias(data) => self.unparse_stmt_type_alias(data),
178            Stmt::AugAssign(data) => self.unparse_stmt_aug_assign(data),
179            Stmt::AnnAssign(data) => self.unparse_stmt_ann_assign(data),
180            Stmt::For(data) => self.unparse_stmt_for(data),
181            Stmt::AsyncFor(data) => self.unparse_stmt_async_for(data),
182            Stmt::While(data) => self.unparse_stmt_while(data),
183            Stmt::If(data) => self.unparse_stmt_if(data, false),
184            Stmt::With(data) => self.unparse_stmt_with(data),
185            Stmt::AsyncWith(data) => self.unparse_stmt_async_with(data),
186            Stmt::Match(data) => self.unparse_stmt_match(data),
187            Stmt::Raise(data) => self.unparse_stmt_raise(data),
188            Stmt::Try(data) => self.unparse_stmt_try(data),
189            Stmt::TryStar(data) => self.unparse_stmt_try_star(data),
190            Stmt::Assert(data) => self.unparse_stmt_assert(data),
191            Stmt::Import(data) => self.unparse_stmt_import(data),
192            Stmt::ImportFrom(data) => self.unparse_stmt_import_from(data),
193            Stmt::Global(data) => self.unparse_stmt_global(data),
194            Stmt::Nonlocal(data) => self.unparse_stmt_nonlocal(data),
195            Stmt::Expr(data) => self.unparse_stmt_expr(data),
196            Stmt::Pass(data) => self.unparse_stmt_pass(data),
197            Stmt::Break(data) => self.unparse_stmt_break(data),
198            Stmt::Continue(data) => self.unparse_stmt_continue(data),
199        }
200    }
201
202    fn unparse_stmt_pass(&mut self, _node: &StmtPass<TextRange>) {
203        self.fill("pass")
204    }
205
206    fn unparse_stmt_break(&mut self, _node: &StmtBreak<TextRange>) {
207        self.fill("break")
208    }
209
210    fn unparse_stmt_continue(&mut self, _node: &StmtContinue<TextRange>) {
211        self.fill("continue")
212    }
213
214    fn unparse_stmt_function_def(&mut self, node: &StmtFunctionDef<TextRange>) {
215        for decorator in &node.decorator_list {
216            self.fill("@");
217            self.unparse_expr(&decorator);
218        }
219        self.fill("def ");
220        self.write_str(&node.name);
221
222        if node.type_params.len() > 0 {
223            self.write_str("[");
224            let mut type_params_iter = node.type_params.iter().peekable();
225            while let Some(type_param) = type_params_iter.next() {
226                self.unparse_type_param(type_param);
227                if type_params_iter.peek().is_some() {
228                    self.write_str(", ");
229                }
230            }
231            self.write_str("]");
232        }
233        self.write_str("(");
234
235        self.unparse_arguments(&node.args);
236
237        self.write_str(")");
238        if let Some(returns) = &node.returns {
239            self.write_str(" -> ");
240            self.unparse_expr(&returns);
241        }
242        self.write_str(":");
243        self.write_type_comment(&node.type_comment);
244        self.block(|block_self| {
245            for value in &node.body {
246                block_self.unparse_stmt(&value);
247            }
248        });
249    }
250
251    fn unparse_stmt_async_function_def(&mut self, node: &StmtAsyncFunctionDef<TextRange>) {
252        for decorator in &node.decorator_list {
253            self.fill("@");
254            self.unparse_expr(&decorator);
255        }
256        self.fill("async def ");
257        self.write_str(&node.name);
258        if node.type_params.len() > 0 {
259            self.write_str("[");
260            let mut type_params_iter = node.type_params.iter().peekable();
261            while let Some(type_param) = type_params_iter.next() {
262                self.unparse_type_param(type_param);
263                if type_params_iter.peek().is_some() {
264                    self.write_str(", ");
265                }
266            }
267            self.write_str("]");
268        }
269        self.write_str("(");
270
271        self.unparse_arguments(&node.args);
272
273        self.write_str(")");
274        if let Some(returns) = &node.returns {
275            self.write_str(" -> ");
276            self.unparse_expr(&returns);
277        }
278        self.write_str(":");
279        self.write_type_comment(&node.type_comment);
280        self.block(|block_self| {
281            for value in &node.body {
282                block_self.unparse_stmt(&value);
283            }
284        });
285    }
286
287    fn unparse_stmt_class_def(&mut self, node: &StmtClassDef<TextRange>) {
288        for decorator in &node.decorator_list {
289            self.fill("@");
290            self.unparse_expr(decorator);
291        }
292
293        self.fill("class ");
294        self.write_str(&node.name);
295
296        if node.type_params.len() > 0 {
297            self.write_str("[");
298            let mut type_params_iter = node.type_params.iter().peekable();
299            while let Some(type_param) = type_params_iter.next() {
300                self.unparse_type_param(type_param);
301                if type_params_iter.peek().is_some() {
302                    self.write_str(", ");
303                }
304            }
305            self.write_str("]");
306        }
307
308        let mut bases_iter = node.bases.iter().peekable();
309        let mut keywords_iter = node.keywords.iter().peekable();
310        let has_parens = bases_iter.peek().is_some() || keywords_iter.peek().is_some();
311        if has_parens {
312            self.write_str("(");
313        }
314
315        while let Some(base) = bases_iter.next() {
316            self.unparse_expr(base);
317            if bases_iter.peek().is_some() || keywords_iter.peek().is_some() {
318                self.write_str(", ");
319            }
320        }
321        while let Some(keyword) = keywords_iter.next() {
322            self.unparse_keyword(keyword);
323            if keywords_iter.peek().is_some() {
324                self.write_str(", ");
325            }
326        }
327        if has_parens {
328            self.write_str(")");
329        }
330        self.write_str(":");
331
332        self.block(|block_self| {
333            for value in &node.body {
334                block_self.unparse_stmt(&value);
335            }
336        });
337    }
338
339    fn unparse_stmt_return(&mut self, node: &StmtReturn<TextRange>) {
340        self.fill("return ");
341        if let Some(value) = &node.value {
342            self.unparse_expr(&value);
343        }
344    }
345    fn unparse_stmt_delete(&mut self, node: &StmtDelete<TextRange>) {
346        self.fill("del ");
347        let mut targets_iter = node.targets.iter().peekable();
348
349        while let Some(target) = targets_iter.next() {
350            self.unparse_expr(target);
351            if targets_iter.peek().is_some() {
352                self.write_str(", ");
353            }
354        }
355    }
356
357    fn unparse_stmt_assign(&mut self, node: &StmtAssign<TextRange>) {
358        let mut targets_iter = node.targets.iter().peekable();
359        self.fill("");
360        while let Some(target) = targets_iter.next() {
361            self.with_precedence(Precedence::Tuple, |prec_self| {
362                prec_self.unparse_expr(target);
363            });
364
365            if targets_iter.peek().is_some() {
366                self.write_str(" = ");
367            }
368        }
369        self.write_str(" = ");
370        self.unparse_expr(&node.value);
371        self.write_type_comment(&node.type_comment);
372    }
373
374    fn unparse_stmt_type_alias(&mut self, node: &StmtTypeAlias<TextRange>) {
375        self.fill("type ");
376        self.unparse_expr(&node.name);
377        if node.type_params.len() > 0 {
378            self.write_str("[");
379            let mut type_params_iter = node.type_params.iter().peekable();
380            while let Some(type_param) = type_params_iter.next() {
381                self.unparse_type_param(type_param);
382                if type_params_iter.peek().is_some() {
383                    self.write_str(", ");
384                }
385            }
386            self.write_str("]");
387        }
388        self.write_str(" = ");
389        self.unparse_expr(&node.value);
390    }
391
392    fn unparse_stmt_aug_assign(&mut self, node: &StmtAugAssign<TextRange>) {
393        self.fill("");
394        self.unparse_expr(&node.target);
395        self.write_str(" ");
396        self.unparse_operator(&node.op);
397        self.write_str("= ");
398        self.unparse_expr(&node.value);
399    }
400
401    fn unparse_stmt_ann_assign(&mut self, node: &StmtAnnAssign<TextRange>) {
402        self.fill("");
403        self.unparse_expr(&node.target);
404        self.write_str(": ");
405        self.unparse_expr(&node.annotation);
406        if let Some(value) = &node.value {
407            self.write_str(" = ");
408            self.unparse_expr(value);
409        }
410    }
411
412    fn unparse_stmt_for(&mut self, node: &StmtFor<TextRange>) {
413        self.fill("for ");
414        self.unparse_expr(&node.target);
415        self.write_str(" in ");
416        self.unparse_expr(&node.iter);
417        self.write_str(":");
418        self.write_type_comment(&node.type_comment);
419        self.block(|block_self| {
420            for value in &node.body {
421                block_self.unparse_stmt(value);
422            }
423        });
424        if node.orelse.len() > 0 {
425            self.fill("else:");
426            self.block(|block_self| {
427                for stmt in &node.orelse {
428                    block_self.unparse_stmt(stmt);
429                }
430            });
431        }
432    }
433    fn unparse_stmt_async_for(&mut self, node: &StmtAsyncFor<TextRange>) {
434        self.fill("async for ");
435        self.unparse_expr(&node.target);
436        self.write_str(" in ");
437        self.unparse_expr(&node.iter);
438        self.write_str(":");
439        self.write_type_comment(&node.type_comment);
440        self.block(|block_self| {
441            for value in &node.body {
442                block_self.unparse_stmt(value);
443            }
444        });
445        if node.orelse.len() > 0 {
446            self.fill("else:");
447            self.block(|block_self| {
448                for stmt in &node.orelse {
449                    block_self.unparse_stmt(stmt);
450                }
451            });
452        }
453    }
454    fn unparse_stmt_while(&mut self, node: &StmtWhile<TextRange>) {
455        self.fill("while ");
456        self.unparse_expr(&node.test);
457        self.write_str(":");
458        self.block(|block_self| {
459            for stmt in &node.body {
460                block_self.unparse_stmt(stmt);
461            }
462        });
463
464        if node.orelse.len() > 0 {
465            self.fill("else:");
466            self.block(|block_self| {
467                for stmt in &node.orelse {
468                    block_self.unparse_stmt(stmt);
469                }
470            });
471        }
472    }
473
474    fn unparse_stmt_if(&mut self, node: &StmtIf<TextRange>, inner_if: bool) {
475        if inner_if {
476            self.fill("elif ");
477        } else {
478            self.fill("if ");
479        }
480
481        self.unparse_expr(&node.test);
482        self.write_str(":");
483        self.block(|block_self| {
484            for stmt in &node.body {
485                block_self.unparse_stmt(stmt);
486            }
487        });
488        match node.orelse.as_slice() {
489            [Stmt::If(inner_if)] => {
490                self.unparse_stmt_if(inner_if, true);
491            }
492            [] => {}
493            _ => {
494                self.fill("else:");
495                self.block(|block_self| {
496                    for stmt in &node.orelse {
497                        block_self.unparse_stmt(stmt);
498                    }
499                });
500            }
501        }
502    }
503
504    fn unparse_stmt_with(&mut self, node: &StmtWith<TextRange>) {
505        self.fill("with ");
506        let mut items_iter = node.items.iter().peekable();
507        while let Some(item) = items_iter.next() {
508            self.unparse_withitem(item);
509            if items_iter.peek().is_some() {
510                self.write_str(", ");
511            }
512        }
513        self.write_str(":");
514        self.block(|block_self| {
515            for stmt in &node.body {
516                block_self.unparse_stmt(stmt);
517            }
518        });
519    }
520    fn unparse_stmt_async_with(&mut self, node: &StmtAsyncWith<TextRange>) {
521        self.fill("async with ");
522        let mut items_iter = node.items.iter().peekable();
523        while let Some(item) = items_iter.next() {
524            self.unparse_withitem(item);
525            if items_iter.peek().is_some() {
526                self.write_str(", ");
527            }
528        }
529        self.write_str(":");
530        self.block(|block_self| {
531            for stmt in &node.body {
532                block_self.unparse_stmt(stmt);
533            }
534        });
535    }
536
537    fn unparse_stmt_match(&mut self, node: &StmtMatch<TextRange>) {
538        self.fill("match ");
539        self.unparse_expr(&node.subject);
540        self.write_str(":");
541        self.block(|block_self| {
542            for case in &node.cases {
543                block_self.unparse_match_case(case);
544            }
545        });
546    }
547
548    fn unparse_stmt_raise(&mut self, node: &StmtRaise<TextRange>) {
549        self.fill("raise ");
550        if let Some(exc) = &node.exc {
551            self.unparse_expr(exc);
552        }
553        if let Some(cause) = &node.cause {
554            self.write_str(" from ");
555            self.unparse_expr(cause);
556        }
557    }
558
559    fn unparse_stmt_try(&mut self, node: &StmtTry<TextRange>) {
560        let prev_try_star = self.in_try_star;
561        self.in_try_star = false;
562        self.fill("try:");
563        self.block(|block_self| {
564            for stmt in &node.body {
565                block_self.unparse_stmt(stmt);
566            }
567        });
568
569        for handler in &node.handlers {
570            self.unparse_excepthandler(handler);
571        }
572
573        if node.orelse.len() > 0 {
574            self.fill("else:");
575            self.block(|block_self| {
576                for stmt in &node.orelse {
577                    block_self.unparse_stmt(stmt);
578                }
579            });
580        }
581
582        if node.finalbody.len() > 0 {
583            self.fill("finally:");
584            self.block(|block_self| {
585                for stmt in &node.finalbody {
586                    block_self.unparse_stmt(stmt);
587                }
588            });
589        }
590        self.in_try_star = prev_try_star;
591    }
592    fn unparse_stmt_try_star(&mut self, node: &StmtTryStar<TextRange>) {
593        let prev_try_star = self.in_try_star;
594        self.in_try_star = true;
595        self.fill("try:");
596        self.block(|block_self| {
597            for stmt in &node.body {
598                block_self.unparse_stmt(stmt);
599            }
600        });
601
602        for handler in &node.handlers {
603            self.unparse_excepthandler(handler);
604        }
605
606        if node.orelse.len() > 0 {
607            self.fill("else:");
608            self.block(|block_self| {
609                for stmt in &node.orelse {
610                    block_self.unparse_stmt(stmt);
611                }
612            });
613        }
614
615        if node.finalbody.len() > 0 {
616            self.fill("finally:");
617            self.block(|block_self| {
618                for stmt in &node.finalbody {
619                    block_self.unparse_stmt(stmt);
620                }
621            });
622        }
623        self.in_try_star = prev_try_star;
624    }
625    fn unparse_stmt_assert(&mut self, node: &StmtAssert<TextRange>) {
626        self.fill("assert ");
627        self.unparse_expr(&node.test);
628        if let Some(msg) = &node.msg {
629            self.write_str(", ");
630            self.unparse_expr(msg);
631        }
632    }
633
634    fn unparse_stmt_import(&mut self, node: &StmtImport<TextRange>) {
635        self.fill("import ");
636        let mut iter = node.names.iter().peekable();
637        while let Some(name) = iter.next() {
638            self.unparse_alias(name);
639            if iter.peek().is_some() {
640                self.write_str(", ");
641            }
642        }
643    }
644    fn unparse_stmt_import_from(&mut self, node: &StmtImportFrom<TextRange>) {
645        self.fill("from ");
646        let level = node.level.unwrap_or(Int::new(0));
647        self.write_str(&".".repeat(level.to_usize()));
648        let module = match &node.module {
649            Some(name) => name.to_string(),
650            None => "".to_string(),
651        };
652        self.write_str(&(module + " import "));
653        let mut iter = node.names.iter().peekable();
654        while let Some(name) = iter.next() {
655            self.unparse_alias(name);
656            if iter.peek().is_some() {
657                self.write_str(", ");
658            }
659        }
660    }
661    fn unparse_stmt_global(&mut self, node: &StmtGlobal<TextRange>) {
662        self.fill("global ");
663        let mut iter = node.names.iter().peekable();
664        while let Some(name) = iter.next() {
665            self.write_str(name);
666            if iter.peek().is_some() {
667                self.write_str(", ");
668            }
669        }
670    }
671    fn unparse_stmt_nonlocal(&mut self, node: &StmtNonlocal<TextRange>) {
672        self.fill("nonlocal ");
673        let mut iter = node.names.iter().peekable();
674        while let Some(name) = iter.next() {
675            self.write_str(name);
676            if iter.peek().is_some() {
677                self.write_str(", ");
678            }
679        }
680    }
681    fn unparse_stmt_expr(&mut self, node: &StmtExpr<TextRange>) {
682        self.fill("");
683        self.with_precedence(Precedence::Yield, |block_self| {
684            block_self.unparse_expr(&node.value);
685        });
686    }
687
688    pub fn unparse_expr(&mut self, node: &Expr<TextRange>) {
689        match node {
690            Expr::BoolOp(data) => self.unparse_expr_bool_op(data),
691            Expr::NamedExpr(data) => self.unparse_expr_named_expr(data),
692            Expr::BinOp(data) => self.unparse_expr_bin_op(data),
693            Expr::UnaryOp(data) => self.unparse_expr_unary_op(data),
694            Expr::Lambda(data) => self.unparse_expr_lambda(data),
695            Expr::IfExp(data) => self.unparse_expr_if_exp(data),
696            Expr::Dict(data) => self.unparse_expr_dict(data),
697            Expr::Set(data) => self.unparse_expr_set(data),
698            Expr::ListComp(data) => self.unparse_expr_list_comp(data),
699            Expr::SetComp(data) => self.unparse_expr_set_comp(data),
700            Expr::DictComp(data) => self.unparse_expr_dict_comp(data),
701            Expr::GeneratorExp(data) => self.unparse_expr_generator_exp(data),
702            Expr::Await(data) => self.unparse_expr_await(data),
703            Expr::Yield(data) => self.unparse_expr_yield(data),
704            Expr::YieldFrom(data) => self.unparse_expr_yield_from(data),
705            Expr::Compare(data) => self.unparse_expr_compare(data),
706            Expr::Call(data) => self.unparse_expr_call(data),
707            Expr::FormattedValue(data) => self.unparse_expr_formatted_value(data),
708            Expr::JoinedStr(data) => self.unparse_expr_joined_str(data, false),
709            Expr::Constant(data) => self.unparse_expr_constant(data),
710            Expr::Attribute(data) => self.unparse_expr_attribute(data),
711            Expr::Subscript(data) => self.unparse_expr_subscript(data),
712            Expr::Starred(data) => self.unparse_expr_starred(data),
713            Expr::Name(data) => self.unparse_expr_name(data),
714            Expr::List(data) => self.unparse_expr_list(data),
715            Expr::Tuple(data) => self.unparse_expr_tuple(data),
716            Expr::Slice(data) => self.unparse_expr_slice(data),
717        }
718    }
719
720    fn unparse_expr_bool_op(&mut self, node: &ExprBoolOp<TextRange>) {
721        let enum_member = Expr::BoolOp(node.to_owned());
722        let mut operator_precedence = get_precedence(&enum_member);
723        let operator = match node.op {
724            BoolOp::And => " and ",
725            BoolOp::Or => " or ",
726        };
727
728        let mut values_iter = node.values.iter().peekable();
729        self.delimit_precedence(&enum_member, |block_self| {
730            while let Some(expr) = values_iter.next() {
731                operator_precedence += 1;
732                block_self.with_precedence_num(operator_precedence, |prec_self| {
733                    prec_self.unparse_expr(expr);
734                });
735                if values_iter.peek().is_some() {
736                    block_self.write_str(operator);
737                }
738            }
739        });
740    }
741
742    fn unparse_expr_named_expr(&mut self, node: &ExprNamedExpr<TextRange>) {
743        let enum_member = Expr::NamedExpr(node.to_owned());
744        self.delimit_precedence(&enum_member, |block_self| {
745            block_self.with_precedence(Precedence::Atom, |prec_self| {
746                prec_self.unparse_expr(&node.target);
747                prec_self.write_str(" := ");
748                prec_self.unparse_expr(&node.value);
749            });
750        })
751    }
752
753    fn unparse_expr_bin_op(&mut self, node: &ExprBinOp<TextRange>) {
754        let enum_member = Expr::BinOp(node.to_owned());
755
756        self.delimit_precedence(&enum_member, |block_self| {
757            block_self.unparse_expr(&node.left);
758            block_self.write_str(" ");
759            block_self.unparse_operator(&node.op);
760            block_self.write_str(" ");
761            block_self.unparse_expr(&node.right);
762        })
763    }
764
765    fn unparse_expr_unary_op(&mut self, node: &ExprUnaryOp<TextRange>) {
766        let enum_member = Expr::UnaryOp(node.to_owned());
767        let operator = match node.op {
768            UnaryOp::Invert => "~",
769            UnaryOp::Not => "not ",
770            UnaryOp::UAdd => "+",
771            UnaryOp::USub => "-",
772        };
773
774        self.delimit_precedence(&enum_member, |block_self| {
775            block_self.write_str(&operator);
776            block_self.unparse_expr(&node.operand)
777        })
778    }
779    fn unparse_expr_lambda(&mut self, node: &ExprLambda<TextRange>) {
780        let enum_member = Expr::Lambda(node.to_owned());
781
782        self.delimit_precedence(&enum_member, |block_self| {
783            block_self.write_str("lambda ");
784            block_self.unparse_arguments(&node.args);
785            block_self.write_str(": ");
786            block_self.unparse_expr(&node.body);
787        })
788    }
789    fn unparse_expr_if_exp(&mut self, node: &ExprIfExp<TextRange>) {
790        let enum_member = Expr::IfExp(node.to_owned());
791        self.delimit_precedence(&enum_member, |block_self| {
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            });
801        })
802    }
803
804    fn unparse_expr_dict(&mut self, node: &ExprDict<TextRange>) {
805        let mut zipped = node.keys.iter().zip(node.values.iter()).peekable();
806
807        self.write_str("{");
808        while let Some((key, value)) = zipped.next() {
809            match key {
810                Some(key_value) => {
811                    self.unparse_expr(key_value);
812                    self.write_str(": ");
813                }
814                None => {
815                    self.write_str("**");
816                }
817            }
818            self.with_precedence_num(EXPR_PRECEDENCE, |prec_self| {
819                prec_self.unparse_expr(value);
820            });
821
822            if zipped.peek().is_some() {
823                self.write_str(", ");
824            }
825        }
826        self.write_str("}");
827    }
828
829    fn unparse_expr_set(&mut self, node: &ExprSet<TextRange>) {
830        if node.elts.len() > 0 {
831            self.write_str("{");
832            let mut elts_iter = node.elts.iter().peekable();
833            while let Some(expr) = elts_iter.next() {
834                self.unparse_expr(expr);
835                if elts_iter.peek().is_some() {
836                    self.write_str(", ");
837                }
838            }
839            self.write_str("}");
840        } else {
841            self.write_str("{*()}");
842        }
843    }
844
845    fn unparse_expr_list_comp(&mut self, node: &ExprListComp<TextRange>) {
846        self.write_str("[");
847        self.unparse_expr(&node.elt);
848        for generator in &node.generators {
849            self.unparse_comprehension(generator);
850        }
851        self.write_str("]");
852    }
853
854    fn unparse_expr_set_comp(&mut self, node: &ExprSetComp<TextRange>) {
855        self.write_str("{");
856        self.unparse_expr(&node.elt);
857
858        for generator in &node.generators {
859            self.unparse_comprehension(generator);
860        }
861        self.write_str("}");
862    }
863
864    fn unparse_expr_dict_comp(&mut self, node: &ExprDictComp<TextRange>) {
865        self.write_str("{");
866        self.unparse_expr(&node.key);
867        self.write_str(": ");
868        self.unparse_expr(&node.value);
869
870        for generator in &node.generators {
871            self.unparse_comprehension(generator);
872        }
873        self.write_str("}");
874    }
875
876    fn unparse_expr_generator_exp(&mut self, node: &ExprGeneratorExp<TextRange>) {
877        self.write_str("(");
878        self.unparse_expr(&node.elt);
879
880        for generator in &node.generators {
881            self.unparse_comprehension(generator);
882        }
883        self.write_str(")");
884    }
885
886    fn unparse_expr_await(&mut self, node: &ExprAwait<TextRange>) {
887        let enum_member = Expr::Await(node.to_owned());
888        self.delimit_precedence(&enum_member, |block_self| {
889            block_self.write_str("await ");
890            block_self.with_precedence(Precedence::Atom, |prec_self| {
891                prec_self.unparse_expr(&node.value);
892            });
893        })
894    }
895
896    fn unparse_expr_yield(&mut self, node: &ExprYield<TextRange>) {
897        let enum_member = Expr::Yield(node.to_owned());
898        self.delimit_precedence(&enum_member, |block_self| {
899            block_self.write_str("yield");
900            if let Some(expr) = &node.value {
901                block_self.write_str(" ");
902                block_self.with_precedence(Precedence::Atom, |prec_self| {
903                    prec_self.unparse_expr(expr);
904                });
905            }
906        })
907    }
908
909    fn unparse_expr_yield_from(&mut self, node: &ExprYieldFrom<TextRange>) {
910        let enum_member = Expr::YieldFrom(node.to_owned());
911        self.delimit_precedence(&enum_member, |block_self| {
912            block_self.write_str("yield from ");
913
914            block_self.with_precedence(Precedence::Atom, |prec_self| {
915                prec_self.unparse_expr(&node.value);
916            });
917        })
918    }
919
920    fn unparse_expr_compare(&mut self, node: &ExprCompare<TextRange>) {
921        let enum_member = Expr::Compare(node.to_owned());
922        let zipped = node.ops.iter().zip(node.comparators.iter());
923        self.delimit_precedence(&enum_member, |block_self| {
924            block_self.unparse_expr(&node.left);
925            for (op, comp) in zipped {
926                let operator = match op {
927                    CmpOp::Eq => " == ",
928                    CmpOp::Gt => " > ",
929                    CmpOp::GtE => " >= ",
930                    CmpOp::In => " in ",
931                    CmpOp::Is => " is ",
932                    CmpOp::IsNot => " is not ",
933                    CmpOp::Lt => " < ",
934                    CmpOp::LtE => " <= ",
935                    CmpOp::NotEq => " != ",
936                    CmpOp::NotIn => " not in ",
937                };
938                block_self.write_str(&operator);
939                block_self.unparse_expr(comp);
940            }
941        })
942    }
943
944    fn unparse_expr_call(&mut self, node: &ExprCall<TextRange>) {
945        self.unparse_expr(&node.func);
946        let mut args_iter = node.args.iter().peekable();
947        let mut keywords_iter = node.keywords.iter().peekable();
948        self.write_str("(");
949        while let Some(arg) = args_iter.next() {
950            self.unparse_expr(arg);
951            if args_iter.peek().is_some() || keywords_iter.peek().is_some() {
952                self.write_str(", ");
953            }
954        }
955        while let Some(keyword) = keywords_iter.next() {
956            self.unparse_keyword(keyword);
957            if keywords_iter.peek().is_some() {
958                self.write_str(", ");
959            }
960        }
961        self.write_str(")");
962    }
963
964    fn unparse_expr_formatted_value(&mut self, node: &ExprFormattedValue<TextRange>) {
965        self.write_str("{");
966        let mut inner_unparser = Unparser::new();
967        inner_unparser.unparse_expr(&node.value);
968        let inner_expr = inner_unparser.source.as_str();
969        if inner_expr.starts_with("{") {
970            self.write_str(" ");
971        }
972        self.write_str(inner_expr);
973        if node.conversion != ConversionFlag::None {
974            self.write_str("!");
975            let buf = &[node.conversion as u8];
976            let c = std::str::from_utf8(buf).unwrap();
977            self.write_str(c);
978        }
979        if let Some(format_spec) = &node.format_spec {
980            self.write_str(":");
981            match format_spec.deref() {
982                Expr::JoinedStr(joined_str) => {
983                    if joined_str.values.len() > 0 {
984                        self.unparse_expr_joined_str(joined_str, true);
985                    }
986                }
987                _ => self.unparse_expr(&format_spec),
988            };
989        }
990        self.write_str("}");
991    }
992
993    fn unparse_expr_joined_str(&mut self, node: &ExprJoinedStr<TextRange>, is_spec: bool) {
994        if !is_spec {
995            self.write_str("f");
996        }
997        let mut expr_source = String::new();
998
999        let mut formatted_values_sources: Vec<String> = Vec::new();
1000        for expr in node.values.iter() {
1001            let mut inner_unparser = Unparser::new();
1002            match expr {
1003                Expr::Constant(ExprConstant { value, .. }) => {
1004                    if let Constant::Str(str_) = value {
1005                        let escaped = str_.replace('{', "{{").replace('}', "}}");
1006                        inner_unparser.write_str(&escaped);
1007                    } else {
1008                        unreachable!()
1009                    }
1010                    expr_source += inner_unparser.source.as_str();
1011                }
1012                Expr::FormattedValue(formatted) => {
1013                    expr_source += &("{".to_owned()
1014                        + formatted_values_sources.len().to_string().as_str()
1015                        + "}");
1016                    inner_unparser.unparse_expr_formatted_value(formatted);
1017                    formatted_values_sources.push(inner_unparser.source);
1018                }
1019                _ => {
1020                    inner_unparser.unparse_expr(expr);
1021                    expr_source += inner_unparser.source.as_str();
1022                }
1023            }
1024        }
1025
1026        if is_spec {
1027            for (i, formatted) in formatted_values_sources.iter().enumerate() {
1028                let to_replace = "{".to_owned() + i.to_string().as_str() + "}";
1029                expr_source = expr_source.replace(&to_replace, formatted)
1030            }
1031            self.write_str(&expr_source);
1032        } else {
1033            let mut escaped_source =
1034                rustpython_literal::escape::UnicodeEscape::new_repr(&expr_source)
1035                    .str_repr()
1036                    .to_string()
1037                    .unwrap();
1038            for (i, formatted) in formatted_values_sources.iter().enumerate() {
1039                let to_replace = "{".to_owned() + i.to_string().as_str() + "}";
1040                escaped_source = escaped_source.replace(&to_replace, formatted)
1041            }
1042
1043            let has_single = escaped_source.contains("'");
1044            let has_double = escaped_source.contains("\"");
1045
1046            if has_single
1047                && has_double
1048                && escaped_source.starts_with("\"")
1049                && escaped_source.ends_with("\"")
1050            {
1051                escaped_source = replace_first_and_last(&escaped_source, "\"\"\"")
1052            } else if has_single
1053                && has_double
1054                && escaped_source.starts_with("'")
1055                && escaped_source.ends_with("'")
1056            {
1057                escaped_source = replace_first_and_last(&escaped_source, "'''")
1058            } else if has_single {
1059                escaped_source = replace_first_and_last(&escaped_source, "\"")
1060            }
1061
1062            self.write_str(&escaped_source);
1063        }
1064    }
1065
1066    fn _unparse_constant(&mut self, constant: &Constant) {
1067        let inf_str = "1e309";
1068        return match constant {
1069            Constant::Tuple(values) => {
1070                self.write_str("(");
1071                let mut values_iter = values.iter().peekable();
1072                while let Some(value) = values_iter.next() {
1073                    self._unparse_constant(value);
1074                    if values_iter.peek().is_some() || values.len() == 1 {
1075                        self.write_str(", ");
1076                    }
1077                }
1078                self.write_str(")");
1079            }
1080            Constant::Ellipsis => self.write_str("..."),
1081            Constant::Bool(value) => {
1082                if *value {
1083                    self.write_str("True")
1084                } else {
1085                    self.write_str("False")
1086                }
1087            }
1088            Constant::Bytes(value) => {
1089                let escaped = rustpython_literal::escape::AsciiEscape::new_repr(value)
1090                    .bytes_repr()
1091                    .to_string()
1092                    .unwrap();
1093                self.write_str(&escaped);
1094            }
1095            Constant::Int(value) => self.write_str(&value.to_string()),
1096            Constant::Str(value) => {
1097                let escaped = rustpython_literal::escape::UnicodeEscape::new_repr(value)
1098                    .str_repr()
1099                    .to_string()
1100                    .unwrap();
1101
1102                self.write_str(&escaped);
1103            }
1104            Constant::None => self.write_str("None"),
1105            Constant::Complex { real, imag } => {
1106                if real.is_infinite() || imag.is_infinite() {
1107                    self.write_str(&constant.to_string().replace("inf", &inf_str));
1108                } else {
1109                    self.write_str(&constant.to_string());
1110                }
1111            }
1112            Constant::Float(value) => {
1113                if value.is_infinite() {
1114                    self.write_str(inf_str);
1115                } else {
1116                    let mut str_value = value.to_string();
1117                    if value.fract() == 0.0 {
1118                        let mut trailing_zeroes = 0;
1119                        while str_value.ends_with("0") {
1120                            str_value.pop();
1121                            trailing_zeroes += 1;
1122                        }
1123                        str_value = format!("{}e{}", str_value, trailing_zeroes);
1124                    } else if str_value.starts_with(&format!("0.{}", "0".repeat(5))) {
1125                        let mut trimmed = str_value[2..].to_owned();
1126                        let mut factor = 1;
1127                        while trimmed.starts_with("0") {
1128                            trimmed = trimmed[1..].to_owned();
1129                            factor += 1;
1130                        }
1131                        str_value = format!("{}e-{}", trimmed, factor);
1132                    }
1133                    self.write_str(&str_value);
1134                }
1135            }
1136        };
1137    }
1138
1139    fn unparse_expr_constant(&mut self, node: &ExprConstant<TextRange>) {
1140        if node.kind.as_deref().is_some_and(|kind| kind == "u") {
1141            self.write_str("u");
1142        }
1143        self._unparse_constant(&node.value)
1144    }
1145
1146    fn unparse_expr_attribute(&mut self, node: &ExprAttribute<TextRange>) {
1147        self.unparse_expr(&node.value);
1148        self.write_str(".");
1149        self.write_str(&node.attr);
1150    }
1151    fn unparse_expr_subscript(&mut self, node: &ExprSubscript<TextRange>) {
1152        self.with_precedence(Precedence::Atom, |prec_self| {
1153            prec_self.unparse_expr(&node.value);
1154        });
1155        self.write_str("[");
1156        self.unparse_expr(&node.slice);
1157        self.write_str("]");
1158    }
1159    fn unparse_expr_starred(&mut self, node: &ExprStarred<TextRange>) {
1160        self.write_str("*");
1161        self.with_precedence_num(EXPR_PRECEDENCE, |prec_self| {
1162            prec_self.unparse_expr(&node.value);
1163        });
1164    }
1165
1166    fn unparse_expr_name(&mut self, node: &ExprName<TextRange>) {
1167        self.write_str(&node.id.as_str())
1168    }
1169    fn unparse_expr_list(&mut self, node: &ExprList<TextRange>) {
1170        let mut elts_iter = node.elts.iter().peekable();
1171        self.write_str("[");
1172        while let Some(expr) = elts_iter.next() {
1173            self.unparse_expr(expr);
1174            if elts_iter.peek().is_some() {
1175                self.write_str(", ");
1176            }
1177        }
1178        self.write_str("]");
1179    }
1180
1181    fn unparse_expr_tuple(&mut self, node: &ExprTuple<TextRange>) {
1182        let mut elts_iter = node.elts.iter().peekable();
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
1189        while let Some(expr) = elts_iter.next() {
1190            self.unparse_expr(expr);
1191            if elts_iter.peek().is_some() || node.elts.len() == 1 {
1192                self.write_str(", ");
1193            }
1194        }
1195        if should_delimit {
1196            self.write_str(")");
1197        }
1198    }
1199
1200    fn unparse_expr_slice(&mut self, node: &ExprSlice<TextRange>) {
1201        if let Some(lower) = &node.lower {
1202            self.unparse_expr(lower);
1203        }
1204        self.write_str(":");
1205        if let Some(upper) = &node.upper {
1206            self.unparse_expr(upper);
1207        }
1208        if let Some(step) = &node.step {
1209            self.write_str(":");
1210            self.unparse_expr(step);
1211        }
1212    }
1213
1214    fn unparse_operator(&mut self, node: &Operator) {
1215        self.write_str(match node {
1216            Operator::Add => "+",
1217            Operator::Sub => "-",
1218            Operator::BitOr => "|",
1219            Operator::BitAnd => "&",
1220            Operator::BitXor => "^",
1221            Operator::Div => "/",
1222            Operator::FloorDiv => "//",
1223            Operator::LShift => "<<",
1224            Operator::MatMult => "@",
1225            Operator::Mod => "%",
1226            Operator::Pow => "**",
1227            Operator::RShift => ">>",
1228            Operator::Mult => "*",
1229        })
1230    }
1231
1232    fn unparse_comprehension(&mut self, node: &Comprehension<TextRange>) {
1233        if node.is_async {
1234            self.write_str(" async for ");
1235        } else {
1236            self.write_str(" for ");
1237        }
1238        self.with_precedence(Precedence::Tuple, |prec_self| {
1239            prec_self.unparse_expr(&node.target);
1240        });
1241
1242        self.write_str(" in ");
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        });
1251    }
1252
1253    fn unparse_excepthandler(&mut self, node: &ExceptHandler<TextRange>) {
1254        match node {
1255            ExceptHandler::ExceptHandler(data) => self.unparse_excepthandler_except_handler(data),
1256        }
1257    }
1258
1259    fn unparse_excepthandler_except_handler(
1260        &mut self,
1261        node: &ExceptHandlerExceptHandler<TextRange>,
1262    ) {
1263        self.fill("except");
1264        if self.in_try_star {
1265            self.write_str("*")
1266        }
1267
1268        if let Some(type_) = &node.type_ {
1269            self.write_str(" ");
1270            self.unparse_expr(type_);
1271        }
1272        if let Some(name) = &node.name {
1273            self.write_str(" as ");
1274            self.write_str(name);
1275        }
1276
1277        self.write_str(":");
1278        self.block(|block_self| {
1279            for stmt in &node.body {
1280                block_self.unparse_stmt(stmt);
1281            }
1282        });
1283    }
1284
1285    fn unparse_arguments(&mut self, node: &Arguments<TextRange>) {
1286        let mut posonly_iter = node.posonlyargs.iter().peekable();
1287        let mut args_iter = node.args.iter().peekable();
1288        let mut kw_iter = node.kwonlyargs.iter().peekable();
1289        while let Some(posonly) = posonly_iter.next() {
1290            self.unparse_arg(posonly.as_arg());
1291            if let Some(default) = &posonly.default {
1292                self.write_str("=");
1293                self.unparse_expr(default);
1294            }
1295
1296            if posonly_iter.peek().is_some() {
1297                self.write_str(", ");
1298            }
1299        }
1300
1301        if node.posonlyargs.len() > 0 {
1302            self.write_str(", /,");
1303        }
1304
1305        while let Some(arg) = args_iter.next() {
1306            self.unparse_arg(arg.as_arg());
1307            if let Some(default) = &arg.default {
1308                self.write_str("=");
1309                self.unparse_expr(default);
1310            }
1311            if args_iter.peek().is_some()
1312                || node.vararg.is_some()
1313                || kw_iter.peek().is_some()
1314                || node.kwarg.is_some()
1315            {
1316                self.write_str(", ");
1317            }
1318        }
1319
1320        if let Some(vararg) = &node.vararg {
1321            self.write_str("*");
1322            self.write_str(&vararg.arg);
1323
1324            if let Some(annotation) = &vararg.annotation {
1325                self.write_str(": ");
1326                self.unparse_expr(annotation);
1327            }
1328            if kw_iter.peek().is_some() || node.kwarg.is_some() {
1329                self.write_str(", ");
1330            }
1331        } else if node.kwonlyargs.len() > 0 {
1332            self.write_str("*, ");
1333        }
1334
1335        while let Some(kw) = kw_iter.next() {
1336            self.unparse_arg(kw.as_arg());
1337            if let Some(default) = &kw.default {
1338                self.write_str("=");
1339                self.unparse_expr(default);
1340            }
1341            if kw_iter.peek().is_some() || node.kwarg.is_some() {
1342                self.write_str(", ");
1343            }
1344        }
1345
1346        if let Some(kwarg) = &node.kwarg {
1347            self.write_str("**");
1348            self.write_str(&kwarg.arg);
1349            if let Some(annotation) = &kwarg.annotation {
1350                self.write_str(": ");
1351                self.unparse_expr(&annotation);
1352            }
1353        }
1354    }
1355
1356    fn unparse_arg(&mut self, node: &Arg<TextRange>) {
1357        self.write_str(node.arg.as_str());
1358        if let Some(annotation) = &node.annotation {
1359            self.write_str(": ");
1360            self.unparse_expr(annotation);
1361        }
1362    }
1363
1364    fn unparse_keyword(&mut self, node: &Keyword<TextRange>) {
1365        if let Some(arg) = &node.arg {
1366            self.write_str(arg.as_str());
1367            self.write_str("=");
1368        } else {
1369            self.write_str("**");
1370        }
1371
1372        self.unparse_expr(&node.value);
1373    }
1374
1375    fn unparse_alias(&mut self, node: &Alias<TextRange>) {
1376        self.write_str(node.name.as_str());
1377        if node.asname.is_some() {
1378            self.write_str(&format!(" as {}", node.asname.as_ref().unwrap()));
1379        }
1380    }
1381
1382    fn unparse_withitem(&mut self, node: &WithItem<TextRange>) {
1383        self.unparse_expr(&node.context_expr);
1384        if let Some(var) = &node.optional_vars {
1385            self.write_str(" as ");
1386            self.unparse_expr(var);
1387        }
1388    }
1389
1390    fn unparse_match_case(&mut self, node: &MatchCase<TextRange>) {
1391        self.fill("case ");
1392        self.unparse_pattern(&node.pattern);
1393        if let Some(guard) = &node.guard {
1394            self.write_str(" if ");
1395            self.unparse_expr(&guard);
1396        }
1397        self.write_str(":");
1398        self.block(|block_self| {
1399            for stmt in &node.body {
1400                block_self.unparse_stmt(stmt);
1401            }
1402        });
1403    }
1404
1405    fn unparse_pattern(&mut self, node: &Pattern<TextRange>) {
1406        match node {
1407            Pattern::MatchValue(data) => self.unparse_pattern_match_value(data),
1408            Pattern::MatchSingleton(data) => self.unparse_pattern_match_singleton(data),
1409            Pattern::MatchSequence(data) => self.unparse_pattern_match_sequence(data),
1410            Pattern::MatchMapping(data) => self.unparse_pattern_match_mapping(data),
1411            Pattern::MatchClass(data) => self.unparse_pattern_match_class(data),
1412            Pattern::MatchStar(data) => self.unparse_pattern_match_star(data),
1413            Pattern::MatchAs(data) => self.unparse_pattern_match_as(data),
1414            Pattern::MatchOr(data) => self.unparse_pattern_match_or(data),
1415        }
1416    }
1417
1418    fn unparse_pattern_match_value(&mut self, node: &PatternMatchValue<TextRange>) {
1419        self.unparse_expr(&node.value)
1420    }
1421
1422    fn unparse_pattern_match_singleton(&mut self, node: &PatternMatchSingleton<TextRange>) {
1423        self._unparse_constant(&node.value);
1424    }
1425
1426    fn unparse_pattern_match_sequence(&mut self, node: &PatternMatchSequence<TextRange>) {
1427        let mut patterns_iter = node.patterns.iter().peekable();
1428        self.write_str("[");
1429        while let Some(pattern) = patterns_iter.next() {
1430            self.unparse_pattern(pattern);
1431            if patterns_iter.peek().is_some() {
1432                self.write_str(" , ");
1433            }
1434        }
1435        self.write_str("]");
1436    }
1437
1438    fn unparse_pattern_match_mapping(&mut self, node: &PatternMatchMapping<TextRange>) {
1439        let mut pairs_iter = node.keys.iter().zip(node.patterns.iter()).peekable();
1440        self.write_str("{");
1441        while let Some((key, pattern)) = pairs_iter.next() {
1442            self.unparse_expr(key);
1443            self.write_str(": ");
1444            self.unparse_pattern(pattern);
1445            if pairs_iter.peek().is_some() {
1446                self.write_str(", ");
1447            }
1448        }
1449        if let Some(rest) = &node.rest {
1450            if node.keys.len() > 0 {
1451                self.write_str(", ");
1452            }
1453            self.write_str("**");
1454            self.write_str(rest.as_str());
1455        }
1456
1457        self.write_str("}");
1458    }
1459
1460    fn unparse_pattern_match_class(&mut self, node: &PatternMatchClass<TextRange>) {
1461        let mut patterns_iter = node.patterns.iter().peekable();
1462        let mut kwd_iter = node
1463            .kwd_attrs
1464            .iter()
1465            .zip(node.kwd_patterns.iter())
1466            .peekable();
1467        self.unparse_expr(&node.cls);
1468        self.write_str("(");
1469        while let Some(pattern) = patterns_iter.next() {
1470            self.unparse_pattern(pattern);
1471            if patterns_iter.peek().is_some() || kwd_iter.peek().is_some() {
1472                self.write_str(", ");
1473            }
1474        }
1475        while let Some((attr, pattern)) = kwd_iter.next() {
1476            self.write_str(attr.as_str());
1477            self.write_str("=");
1478            self.unparse_pattern(pattern);
1479            if kwd_iter.peek().is_some() {
1480                self.write_str(", ");
1481            }
1482        }
1483
1484        self.write_str(")");
1485    }
1486
1487    fn unparse_pattern_match_star(&mut self, node: &PatternMatchStar<TextRange>) {
1488        let name = match &node.name {
1489            Some(name) => name.as_str(),
1490            None => "_",
1491        };
1492        self.write_str("*");
1493        self.write_str(name);
1494    }
1495
1496    fn unparse_pattern_match_as(&mut self, node: &PatternMatchAs<TextRange>) {
1497        match &node.name {
1498            Some(name) => match &node.pattern {
1499                Some(pattern) => {
1500                    let with_parens = self.precedence_level > Precedence::Test.value();
1501                    if with_parens {
1502                        self.write_str("(");
1503                    }
1504                    self.with_precedence(Precedence::Bor, |prec_self| {
1505                        prec_self.unparse_pattern(pattern);
1506                    });
1507                    self.write_str(" as ");
1508                    self.write_str(name);
1509
1510                    if with_parens {
1511                        self.write_str(")");
1512                    }
1513                }
1514                None => {
1515                    self.write_str(name);
1516                }
1517            },
1518            None => {
1519                self.write_str("_");
1520            }
1521        };
1522    }
1523
1524    fn unparse_pattern_match_or(&mut self, node: &PatternMatchOr<TextRange>) {
1525        let mut patterns_iter = node.patterns.iter().peekable();
1526        while let Some(pattern) = patterns_iter.next() {
1527            self.unparse_pattern(pattern);
1528            if patterns_iter.peek().is_some() {
1529                self.write_str(" | ");
1530            }
1531        }
1532    }
1533
1534    fn unparse_type_param(&mut self, node: &TypeParam<TextRange>) {
1535        match node {
1536            TypeParam::TypeVar(data) => self.unparse_type_param_type_var(data),
1537            TypeParam::ParamSpec(data) => self.unparse_type_param_param_spec(data),
1538            TypeParam::TypeVarTuple(data) => self.unparse_type_param_type_var_tuple(data),
1539        }
1540    }
1541
1542    fn unparse_type_param_type_var(&mut self, node: &TypeParamTypeVar<TextRange>) {
1543        self.write_str(&node.name);
1544        if let Some(bound) = &node.bound {
1545            self.write_str(": ");
1546            self.unparse_expr(bound);
1547        }
1548    }
1549
1550    fn unparse_type_param_param_spec(&mut self, node: &TypeParamParamSpec<TextRange>) {
1551        self.write_str("**");
1552        self.write_str(&node.name);
1553    }
1554
1555    fn unparse_type_param_type_var_tuple(&mut self, node: &TypeParamTypeVarTuple<TextRange>) {
1556        self.write_str("*");
1557        self.write_str(&node.name);
1558    }
1559}