Skip to main content

rustpython_unparser/
unparser.rs

1use rustpython_ast::{
2    Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, ExceptHandler, ExceptHandlerExceptHandler,
3    Expr, ExprAttribute, ExprAwait, ExprBinOp, ExprBoolOp, ExprCall, ExprCompare, ExprConstant,
4    ExprDict, ExprDictComp, ExprFormattedValue, ExprGeneratorExp, ExprIfExp, ExprJoinedStr,
5    ExprLambda, ExprList, ExprListComp, ExprName, ExprNamedExpr, ExprSet, ExprSetComp, ExprSlice,
6    ExprStarred, ExprSubscript, ExprTuple, ExprUnaryOp, ExprYield, ExprYieldFrom, Keyword,
7    MatchCase, Operator, Pattern, PatternMatchAs, PatternMatchClass, PatternMatchMapping,
8    PatternMatchOr, PatternMatchSequence, PatternMatchSingleton, PatternMatchStar,
9    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, text_size::TextRange,
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 = rustpython_literal::escape::UnicodeEscape::new_repr(
1034                rustpython_wtf8::Wtf8::new(expr_source.as_str()),
1035            )
1036            .str_repr()
1037            .to_string()
1038            .unwrap();
1039            for (i, formatted) in formatted_values_sources.iter().enumerate() {
1040                let to_replace = "{".to_owned() + i.to_string().as_str() + "}";
1041                escaped_source = escaped_source.replace(&to_replace, formatted)
1042            }
1043
1044            let has_single = escaped_source.contains("'");
1045            let has_double = escaped_source.contains("\"");
1046
1047            if has_single
1048                && has_double
1049                && escaped_source.starts_with("\"")
1050                && escaped_source.ends_with("\"")
1051            {
1052                escaped_source = replace_first_and_last(&escaped_source, "\"\"\"")
1053            } else if has_single
1054                && has_double
1055                && escaped_source.starts_with("'")
1056                && escaped_source.ends_with("'")
1057            {
1058                escaped_source = replace_first_and_last(&escaped_source, "'''")
1059            } else if has_single {
1060                escaped_source = replace_first_and_last(&escaped_source, "\"")
1061            }
1062
1063            self.write_str(&escaped_source);
1064        }
1065    }
1066
1067    fn _unparse_constant(&mut self, constant: &Constant) {
1068        let inf_str = "1e309";
1069        return match constant {
1070            Constant::Tuple(values) => {
1071                self.write_str("(");
1072                let mut values_iter = values.iter().peekable();
1073                while let Some(value) = values_iter.next() {
1074                    self._unparse_constant(value);
1075                    if values_iter.peek().is_some() || values.len() == 1 {
1076                        self.write_str(", ");
1077                    }
1078                }
1079                self.write_str(")");
1080            }
1081            Constant::Ellipsis => self.write_str("..."),
1082            Constant::Bool(value) => {
1083                if *value {
1084                    self.write_str("True")
1085                } else {
1086                    self.write_str("False")
1087                }
1088            }
1089            Constant::Bytes(value) => {
1090                let escaped = rustpython_literal::escape::AsciiEscape::new_repr(value)
1091                    .bytes_repr()
1092                    .to_string()
1093                    .unwrap();
1094                self.write_str(&escaped);
1095            }
1096            Constant::Int(value) => self.write_str(&value.to_string()),
1097            Constant::Str(value) => {
1098                let escaped = rustpython_literal::escape::UnicodeEscape::new_repr(
1099                    rustpython_wtf8::Wtf8::new(value.as_str()),
1100                )
1101                .str_repr()
1102                .to_string()
1103                .unwrap();
1104
1105                self.write_str(&escaped);
1106            }
1107            Constant::None => self.write_str("None"),
1108            Constant::Complex { real, imag } => {
1109                if real.is_infinite() || imag.is_infinite() {
1110                    self.write_str(&constant.to_string().replace("inf", &inf_str));
1111                } else {
1112                    self.write_str(&constant.to_string());
1113                }
1114            }
1115            Constant::Float(value) => {
1116                if value.is_infinite() {
1117                    self.write_str(inf_str);
1118                } else {
1119                    let mut str_value = value.to_string();
1120                    if value.fract() == 0.0 {
1121                        let mut trailing_zeroes = 0;
1122                        while str_value.ends_with("0") {
1123                            str_value.pop();
1124                            trailing_zeroes += 1;
1125                        }
1126                        str_value = format!("{}e{}", str_value, trailing_zeroes);
1127                    } else if str_value.starts_with(&format!("0.{}", "0".repeat(5))) {
1128                        let mut trimmed = str_value[2..].to_owned();
1129                        let mut factor = 1;
1130                        while trimmed.starts_with("0") {
1131                            trimmed = trimmed[1..].to_owned();
1132                            factor += 1;
1133                        }
1134                        str_value = format!("{}e-{}", trimmed, factor);
1135                    }
1136                    self.write_str(&str_value);
1137                }
1138            }
1139        };
1140    }
1141
1142    fn unparse_expr_constant(&mut self, node: &ExprConstant<TextRange>) {
1143        if node.kind.as_deref().is_some_and(|kind| kind == "u") {
1144            self.write_str("u");
1145        }
1146        self._unparse_constant(&node.value)
1147    }
1148
1149    fn unparse_expr_attribute(&mut self, node: &ExprAttribute<TextRange>) {
1150        self.unparse_expr(&node.value);
1151        self.write_str(".");
1152        self.write_str(&node.attr);
1153    }
1154    fn unparse_expr_subscript(&mut self, node: &ExprSubscript<TextRange>) {
1155        self.with_precedence(Precedence::Atom, |prec_self| {
1156            prec_self.unparse_expr(&node.value);
1157        });
1158        self.write_str("[");
1159        self.unparse_expr(&node.slice);
1160        self.write_str("]");
1161    }
1162    fn unparse_expr_starred(&mut self, node: &ExprStarred<TextRange>) {
1163        self.write_str("*");
1164        self.with_precedence_num(EXPR_PRECEDENCE, |prec_self| {
1165            prec_self.unparse_expr(&node.value);
1166        });
1167    }
1168
1169    fn unparse_expr_name(&mut self, node: &ExprName<TextRange>) {
1170        self.write_str(&node.id.as_str())
1171    }
1172    fn unparse_expr_list(&mut self, node: &ExprList<TextRange>) {
1173        let mut elts_iter = node.elts.iter().peekable();
1174        self.write_str("[");
1175        while let Some(expr) = elts_iter.next() {
1176            self.unparse_expr(expr);
1177            if elts_iter.peek().is_some() {
1178                self.write_str(", ");
1179            }
1180        }
1181        self.write_str("]");
1182    }
1183
1184    fn unparse_expr_tuple(&mut self, node: &ExprTuple<TextRange>) {
1185        let mut elts_iter = node.elts.iter().peekable();
1186        let should_delimit =
1187            node.elts.len() == 0 || self.precedence_level > Precedence::Tuple.value();
1188        if should_delimit {
1189            self.write_str("(");
1190        }
1191
1192        while let Some(expr) = elts_iter.next() {
1193            self.unparse_expr(expr);
1194            if elts_iter.peek().is_some() || node.elts.len() == 1 {
1195                self.write_str(", ");
1196            }
1197        }
1198        if should_delimit {
1199            self.write_str(")");
1200        }
1201    }
1202
1203    fn unparse_expr_slice(&mut self, node: &ExprSlice<TextRange>) {
1204        if let Some(lower) = &node.lower {
1205            self.unparse_expr(lower);
1206        }
1207        self.write_str(":");
1208        if let Some(upper) = &node.upper {
1209            self.unparse_expr(upper);
1210        }
1211        if let Some(step) = &node.step {
1212            self.write_str(":");
1213            self.unparse_expr(step);
1214        }
1215    }
1216
1217    fn unparse_operator(&mut self, node: &Operator) {
1218        self.write_str(match node {
1219            Operator::Add => "+",
1220            Operator::Sub => "-",
1221            Operator::BitOr => "|",
1222            Operator::BitAnd => "&",
1223            Operator::BitXor => "^",
1224            Operator::Div => "/",
1225            Operator::FloorDiv => "//",
1226            Operator::LShift => "<<",
1227            Operator::MatMult => "@",
1228            Operator::Mod => "%",
1229            Operator::Pow => "**",
1230            Operator::RShift => ">>",
1231            Operator::Mult => "*",
1232        })
1233    }
1234
1235    fn unparse_comprehension(&mut self, node: &Comprehension<TextRange>) {
1236        if node.is_async {
1237            self.write_str(" async for ");
1238        } else {
1239            self.write_str(" for ");
1240        }
1241        self.with_precedence(Precedence::Tuple, |prec_self| {
1242            prec_self.unparse_expr(&node.target);
1243        });
1244
1245        self.write_str(" in ");
1246
1247        self.with_precedence_num(Precedence::Test.value() + 1, |prec_self| {
1248            prec_self.unparse_expr(&node.iter);
1249            for if_ in &node.ifs {
1250                prec_self.write_str(" if ");
1251                prec_self.unparse_expr(if_);
1252            }
1253        });
1254    }
1255
1256    fn unparse_excepthandler(&mut self, node: &ExceptHandler<TextRange>) {
1257        match node {
1258            ExceptHandler::ExceptHandler(data) => self.unparse_excepthandler_except_handler(data),
1259        }
1260    }
1261
1262    fn unparse_excepthandler_except_handler(
1263        &mut self,
1264        node: &ExceptHandlerExceptHandler<TextRange>,
1265    ) {
1266        self.fill("except");
1267        if self.in_try_star {
1268            self.write_str("*")
1269        }
1270
1271        if let Some(type_) = &node.type_ {
1272            self.write_str(" ");
1273            self.unparse_expr(type_);
1274        }
1275        if let Some(name) = &node.name {
1276            self.write_str(" as ");
1277            self.write_str(name);
1278        }
1279
1280        self.write_str(":");
1281        self.block(|block_self| {
1282            for stmt in &node.body {
1283                block_self.unparse_stmt(stmt);
1284            }
1285        });
1286    }
1287
1288    fn unparse_arguments(&mut self, node: &Arguments<TextRange>) {
1289        let mut posonly_iter = node.posonlyargs.iter().peekable();
1290        let mut args_iter = node.args.iter().peekable();
1291        let mut kw_iter = node.kwonlyargs.iter().peekable();
1292        while let Some(posonly) = posonly_iter.next() {
1293            self.unparse_arg(posonly.as_arg());
1294            if let Some(default) = &posonly.default {
1295                self.write_str("=");
1296                self.unparse_expr(default);
1297            }
1298
1299            if posonly_iter.peek().is_some() {
1300                self.write_str(", ");
1301            }
1302        }
1303
1304        if node.posonlyargs.len() > 0 {
1305            self.write_str(", /,");
1306        }
1307
1308        while let Some(arg) = args_iter.next() {
1309            self.unparse_arg(arg.as_arg());
1310            if let Some(default) = &arg.default {
1311                self.write_str("=");
1312                self.unparse_expr(default);
1313            }
1314            if args_iter.peek().is_some()
1315                || node.vararg.is_some()
1316                || kw_iter.peek().is_some()
1317                || node.kwarg.is_some()
1318            {
1319                self.write_str(", ");
1320            }
1321        }
1322
1323        if let Some(vararg) = &node.vararg {
1324            self.write_str("*");
1325            self.write_str(&vararg.arg);
1326
1327            if let Some(annotation) = &vararg.annotation {
1328                self.write_str(": ");
1329                self.unparse_expr(annotation);
1330            }
1331            if kw_iter.peek().is_some() || node.kwarg.is_some() {
1332                self.write_str(", ");
1333            }
1334        } else if node.kwonlyargs.len() > 0 {
1335            self.write_str("*, ");
1336        }
1337
1338        while let Some(kw) = kw_iter.next() {
1339            self.unparse_arg(kw.as_arg());
1340            if let Some(default) = &kw.default {
1341                self.write_str("=");
1342                self.unparse_expr(default);
1343            }
1344            if kw_iter.peek().is_some() || node.kwarg.is_some() {
1345                self.write_str(", ");
1346            }
1347        }
1348
1349        if let Some(kwarg) = &node.kwarg {
1350            self.write_str("**");
1351            self.write_str(&kwarg.arg);
1352            if let Some(annotation) = &kwarg.annotation {
1353                self.write_str(": ");
1354                self.unparse_expr(&annotation);
1355            }
1356        }
1357    }
1358
1359    fn unparse_arg(&mut self, node: &Arg<TextRange>) {
1360        self.write_str(node.arg.as_str());
1361        if let Some(annotation) = &node.annotation {
1362            self.write_str(": ");
1363            self.unparse_expr(annotation);
1364        }
1365    }
1366
1367    fn unparse_keyword(&mut self, node: &Keyword<TextRange>) {
1368        if let Some(arg) = &node.arg {
1369            self.write_str(arg.as_str());
1370            self.write_str("=");
1371        } else {
1372            self.write_str("**");
1373        }
1374
1375        self.unparse_expr(&node.value);
1376    }
1377
1378    fn unparse_alias(&mut self, node: &Alias<TextRange>) {
1379        self.write_str(node.name.as_str());
1380        if node.asname.is_some() {
1381            self.write_str(&format!(" as {}", node.asname.as_ref().unwrap()));
1382        }
1383    }
1384
1385    fn unparse_withitem(&mut self, node: &WithItem<TextRange>) {
1386        self.unparse_expr(&node.context_expr);
1387        if let Some(var) = &node.optional_vars {
1388            self.write_str(" as ");
1389            self.unparse_expr(var);
1390        }
1391    }
1392
1393    fn unparse_match_case(&mut self, node: &MatchCase<TextRange>) {
1394        self.fill("case ");
1395        self.unparse_pattern(&node.pattern);
1396        if let Some(guard) = &node.guard {
1397            self.write_str(" if ");
1398            self.unparse_expr(&guard);
1399        }
1400        self.write_str(":");
1401        self.block(|block_self| {
1402            for stmt in &node.body {
1403                block_self.unparse_stmt(stmt);
1404            }
1405        });
1406    }
1407
1408    fn unparse_pattern(&mut self, node: &Pattern<TextRange>) {
1409        match node {
1410            Pattern::MatchValue(data) => self.unparse_pattern_match_value(data),
1411            Pattern::MatchSingleton(data) => self.unparse_pattern_match_singleton(data),
1412            Pattern::MatchSequence(data) => self.unparse_pattern_match_sequence(data),
1413            Pattern::MatchMapping(data) => self.unparse_pattern_match_mapping(data),
1414            Pattern::MatchClass(data) => self.unparse_pattern_match_class(data),
1415            Pattern::MatchStar(data) => self.unparse_pattern_match_star(data),
1416            Pattern::MatchAs(data) => self.unparse_pattern_match_as(data),
1417            Pattern::MatchOr(data) => self.unparse_pattern_match_or(data),
1418        }
1419    }
1420
1421    fn unparse_pattern_match_value(&mut self, node: &PatternMatchValue<TextRange>) {
1422        self.unparse_expr(&node.value)
1423    }
1424
1425    fn unparse_pattern_match_singleton(&mut self, node: &PatternMatchSingleton<TextRange>) {
1426        self._unparse_constant(&node.value);
1427    }
1428
1429    fn unparse_pattern_match_sequence(&mut self, node: &PatternMatchSequence<TextRange>) {
1430        let mut patterns_iter = node.patterns.iter().peekable();
1431        self.write_str("[");
1432        while let Some(pattern) = patterns_iter.next() {
1433            self.unparse_pattern(pattern);
1434            if patterns_iter.peek().is_some() {
1435                self.write_str(" , ");
1436            }
1437        }
1438        self.write_str("]");
1439    }
1440
1441    fn unparse_pattern_match_mapping(&mut self, node: &PatternMatchMapping<TextRange>) {
1442        let mut pairs_iter = node.keys.iter().zip(node.patterns.iter()).peekable();
1443        self.write_str("{");
1444        while let Some((key, pattern)) = pairs_iter.next() {
1445            self.unparse_expr(key);
1446            self.write_str(": ");
1447            self.unparse_pattern(pattern);
1448            if pairs_iter.peek().is_some() {
1449                self.write_str(", ");
1450            }
1451        }
1452        if let Some(rest) = &node.rest {
1453            if node.keys.len() > 0 {
1454                self.write_str(", ");
1455            }
1456            self.write_str("**");
1457            self.write_str(rest.as_str());
1458        }
1459
1460        self.write_str("}");
1461    }
1462
1463    fn unparse_pattern_match_class(&mut self, node: &PatternMatchClass<TextRange>) {
1464        let mut patterns_iter = node.patterns.iter().peekable();
1465        let mut kwd_iter = node
1466            .kwd_attrs
1467            .iter()
1468            .zip(node.kwd_patterns.iter())
1469            .peekable();
1470        self.unparse_expr(&node.cls);
1471        self.write_str("(");
1472        while let Some(pattern) = patterns_iter.next() {
1473            self.unparse_pattern(pattern);
1474            if patterns_iter.peek().is_some() || kwd_iter.peek().is_some() {
1475                self.write_str(", ");
1476            }
1477        }
1478        while let Some((attr, pattern)) = kwd_iter.next() {
1479            self.write_str(attr.as_str());
1480            self.write_str("=");
1481            self.unparse_pattern(pattern);
1482            if kwd_iter.peek().is_some() {
1483                self.write_str(", ");
1484            }
1485        }
1486
1487        self.write_str(")");
1488    }
1489
1490    fn unparse_pattern_match_star(&mut self, node: &PatternMatchStar<TextRange>) {
1491        let name = match &node.name {
1492            Some(name) => name.as_str(),
1493            None => "_",
1494        };
1495        self.write_str("*");
1496        self.write_str(name);
1497    }
1498
1499    fn unparse_pattern_match_as(&mut self, node: &PatternMatchAs<TextRange>) {
1500        match &node.name {
1501            Some(name) => match &node.pattern {
1502                Some(pattern) => {
1503                    let with_parens = self.precedence_level > Precedence::Test.value();
1504                    if with_parens {
1505                        self.write_str("(");
1506                    }
1507                    self.with_precedence(Precedence::Bor, |prec_self| {
1508                        prec_self.unparse_pattern(pattern);
1509                    });
1510                    self.write_str(" as ");
1511                    self.write_str(name);
1512
1513                    if with_parens {
1514                        self.write_str(")");
1515                    }
1516                }
1517                None => {
1518                    self.write_str(name);
1519                }
1520            },
1521            None => {
1522                self.write_str("_");
1523            }
1524        };
1525    }
1526
1527    fn unparse_pattern_match_or(&mut self, node: &PatternMatchOr<TextRange>) {
1528        let mut patterns_iter = node.patterns.iter().peekable();
1529        while let Some(pattern) = patterns_iter.next() {
1530            self.unparse_pattern(pattern);
1531            if patterns_iter.peek().is_some() {
1532                self.write_str(" | ");
1533            }
1534        }
1535    }
1536
1537    fn unparse_type_param(&mut self, node: &TypeParam<TextRange>) {
1538        match node {
1539            TypeParam::TypeVar(data) => self.unparse_type_param_type_var(data),
1540            TypeParam::ParamSpec(data) => self.unparse_type_param_param_spec(data),
1541            TypeParam::TypeVarTuple(data) => self.unparse_type_param_type_var_tuple(data),
1542        }
1543    }
1544
1545    fn unparse_type_param_type_var(&mut self, node: &TypeParamTypeVar<TextRange>) {
1546        self.write_str(&node.name);
1547        if let Some(bound) = &node.bound {
1548            self.write_str(": ");
1549            self.unparse_expr(bound);
1550        }
1551    }
1552
1553    fn unparse_type_param_param_spec(&mut self, node: &TypeParamParamSpec<TextRange>) {
1554        self.write_str("**");
1555        self.write_str(&node.name);
1556    }
1557
1558    fn unparse_type_param_type_var_tuple(&mut self, node: &TypeParamTypeVarTuple<TextRange>) {
1559        self.write_str("*");
1560        self.write_str(&node.name);
1561    }
1562}