Skip to content

Commit 83da9a0

Browse files
committed
format ExprJoinedStr
wip to check direction currently generates invalid python because it doesn't know to switch quote style when the nesting is inside a formatted value like in `f"MOAR {' '.join([])}"` so it makes the inner quotes double as well
1 parent e1d76b6 commit 83da9a0

File tree

4 files changed

+61
-23
lines changed

4 files changed

+61
-23
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ wsl = { version = "0.1.0" }
5252
# v1.0.1
5353
libcst = { git = "https://github.com/Instagram/LibCST.git", rev = "3cacca1a1029f05707e50703b49fe3dd860aa839", default-features = false }
5454

55-
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "db04fd415774032e1e2ceb03bcbf5305e0d22c8c" }
56-
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "db04fd415774032e1e2ceb03bcbf5305e0d22c8c" , default-features = false, features = ["num-bigint"]}
57-
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "db04fd415774032e1e2ceb03bcbf5305e0d22c8c", default-features = false, features = ["num-bigint"] }
58-
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "db04fd415774032e1e2ceb03bcbf5305e0d22c8c", default-features = false }
59-
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "db04fd415774032e1e2ceb03bcbf5305e0d22c8c" , default-features = false, features = ["full-lexer", "num-bigint"] }
55+
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "472f0d480650bb1c3c95596fcb910895b8d25ab5" }
56+
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "472f0d480650bb1c3c95596fcb910895b8d25ab5" , default-features = false, features = ["num-bigint"]}
57+
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "472f0d480650bb1c3c95596fcb910895b8d25ab5", default-features = false, features = ["num-bigint"] }
58+
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "472f0d480650bb1c3c95596fcb910895b8d25ab5", default-features = false }
59+
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "472f0d480650bb1c3c95596fcb910895b8d25ab5" , default-features = false, features = ["full-lexer", "num-bigint"] }
6060

6161
[profile.release]
6262
lto = "fat"

crates/ruff_python_formatter/src/expression/expr_formatted_value.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::context::PyFormatContext;
2+
use crate::expression::parentheses::Parentheses;
23
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
3-
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
4+
use crate::prelude::*;
5+
use crate::{FormatNodeRule, PyFormatter};
46
use ruff_formatter::{write, Buffer, FormatResult};
57
use ruff_python_ast::node::AnyNodeRef;
68
use rustpython_parser::ast::ExprFormattedValue;
@@ -10,7 +12,21 @@ pub struct FormatExprFormattedValue;
1012

1113
impl FormatNodeRule<ExprFormattedValue> for FormatExprFormattedValue {
1214
fn fmt_fields(&self, item: &ExprFormattedValue, f: &mut PyFormatter) -> FormatResult<()> {
13-
write!(f, [not_yet_implemented(item)])
15+
let ExprFormattedValue {
16+
range: _,
17+
value,
18+
// TODO
19+
conversion: _,
20+
format_spec: _,
21+
} = item;
22+
write!(
23+
f,
24+
[
25+
text("{"),
26+
value.format().with_options(Parentheses::Never),
27+
text("}")
28+
]
29+
)
1430
}
1531
}
1632

crates/ruff_python_formatter/src/expression/expr_joined_str.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,43 @@
11
use crate::context::PyFormatContext;
2-
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
3-
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
4-
use ruff_formatter::{write, Buffer, FormatResult};
2+
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
3+
use crate::expression::string::{StringPrefix, StringQuotes};
4+
use crate::expression::Expr;
5+
use crate::prelude::*;
6+
use crate::{verbatim_text, FormatNodeRule, PyFormatter};
7+
use ruff_formatter::{write, Buffer, FormatError, FormatResult};
58
use ruff_python_ast::node::AnyNodeRef;
69
use rustpython_parser::ast::ExprJoinedStr;
710

811
#[derive(Default)]
912
pub struct FormatExprJoinedStr;
1013

1114
impl FormatNodeRule<ExprJoinedStr> for FormatExprJoinedStr {
12-
fn fmt_fields(&self, _item: &ExprJoinedStr, f: &mut PyFormatter) -> FormatResult<()> {
13-
write!(
14-
f,
15-
[not_yet_implemented_custom_text(
16-
r#"f"NOT_YET_IMPLEMENTED_ExprJoinedStr""#
17-
)]
18-
)
15+
fn fmt_fields(&self, item: &ExprJoinedStr, f: &mut PyFormatter) -> FormatResult<()> {
16+
let ExprJoinedStr { range, values } = item;
17+
18+
// TODO: can we re-use instead of copy/paste?
19+
let string_content = f.context().locator().slice(*range);
20+
let prefix = StringPrefix::parse(string_content);
21+
let after_prefix = &string_content[usize::from(prefix.text_len())..];
22+
23+
let quotes = StringQuotes::parse(after_prefix).ok_or(FormatError::syntax_error(
24+
"Didn't find string quotes after prefix",
25+
))?;
26+
27+
prefix.fmt(f)?;
28+
quotes.fmt(f)?;
29+
// TODO: join_with empty? or some other join?
30+
for value in values {
31+
match value {
32+
// TODO: can we do better?
33+
Expr::Constant(_) => write!(f, [verbatim_text(value)])?,
34+
Expr::FormattedValue(_) => {
35+
write!(f, [value.format().with_options(Parentheses::Never)])?;
36+
}
37+
_ => unreachable!(),
38+
};
39+
}
40+
quotes.fmt(f)
1941
}
2042
}
2143

0 commit comments

Comments
 (0)