@@ -16,6 +16,8 @@ use rustpython_ast::{
1616use rustpython_ast:: { Constant , ConversionFlag , Int } ;
1717use std:: ops:: Deref ;
1818
19+ use crate :: utils:: replace_first_and_last;
20+
1921enum Precedence {
2022 NamedExpr = 1 ,
2123 Tuple = 2 ,
@@ -986,6 +988,8 @@ impl Unparser {
986988 self . write_str ( "f" ) ;
987989 }
988990 let mut expr_source = String :: new ( ) ;
991+
992+ let mut formatted_values_sources: Vec < String > = Vec :: new ( ) ;
989993 for expr in node. values . iter ( ) {
990994 let mut inner_unparser = Unparser :: new ( ) ;
991995 match expr {
@@ -996,22 +1000,50 @@ impl Unparser {
9961000 } else {
9971001 unreachable ! ( )
9981002 }
1003+ expr_source += inner_unparser. source . as_str ( ) ;
1004+ }
1005+ Expr :: FormattedValue ( formatted) => {
1006+ expr_source += & ( "{" . to_owned ( )
1007+ + formatted_values_sources. len ( ) . to_string ( ) . as_str ( )
1008+ + "}" ) ;
1009+ inner_unparser. unparse_expr_formatted_value ( formatted) ;
1010+ formatted_values_sources. push ( inner_unparser. source ) ;
9991011 }
10001012 _ => {
10011013 inner_unparser. unparse_expr ( expr) ;
1014+ expr_source += inner_unparser. source . as_str ( ) ;
10021015 }
10031016 }
1004-
1005- expr_source += inner_unparser. source . as_str ( ) ;
10061017 }
10071018
10081019 if is_spec {
1020+ for ( i, formatted) in formatted_values_sources. iter ( ) . enumerate ( ) {
1021+ let to_replace = "{" . to_owned ( ) + i. to_string ( ) . as_str ( ) + "}" ;
1022+ expr_source = expr_source. replace ( & to_replace, formatted)
1023+ }
10091024 self . write_str ( & expr_source) ;
10101025 } else {
1011- let escaped_source = rustpython_literal:: escape:: UnicodeEscape :: new_repr ( & expr_source)
1012- . str_repr ( )
1013- . to_string ( )
1014- . unwrap ( ) ;
1026+ let mut escaped_source =
1027+ rustpython_literal:: escape:: UnicodeEscape :: new_repr ( & expr_source)
1028+ . str_repr ( )
1029+ . to_string ( )
1030+ . unwrap ( ) ;
1031+ for ( i, formatted) in formatted_values_sources. iter ( ) . enumerate ( ) {
1032+ let to_replace = "{" . to_owned ( ) + i. to_string ( ) . as_str ( ) + "}" ;
1033+ escaped_source = escaped_source. replace ( & to_replace, formatted)
1034+ }
1035+
1036+ let has_single = escaped_source. contains ( "'" ) ;
1037+ let has_double = escaped_source. contains ( "\" " ) ;
1038+ let has_single_doc = escaped_source. contains ( "'''" ) ;
1039+ if has_single && has_double && has_single_doc {
1040+ escaped_source = replace_first_and_last ( & escaped_source, "\" \" \" " )
1041+ } else if has_single && has_double {
1042+ escaped_source = replace_first_and_last ( & escaped_source, "'''" )
1043+ } else if has_single {
1044+ escaped_source = replace_first_and_last ( & escaped_source, "\" " )
1045+ }
1046+
10151047 self . write_str ( & escaped_source) ;
10161048 }
10171049 }
0 commit comments