mirror of https://github.com/astral-sh/ruff
Add more test cases; check format types that occur after placeholders
This commit is contained in:
parent
5df9ba716f
commit
268be0cf8e
|
|
@ -17,7 +17,9 @@
|
||||||
"{:*^30s}".format("centered") # OK
|
"{:*^30s}".format("centered") # OK
|
||||||
"{:{s}}".format("hello", s="s") # OK (nested replacement value not checked)
|
"{:{s}}".format("hello", s="s") # OK (nested replacement value not checked)
|
||||||
"{:{s:y}}".format("hello", s="s") # [bad-format-character] (nested replacement format spec checked)
|
"{:{s:y}}".format("hello", s="s") # [bad-format-character] (nested replacement format spec checked)
|
||||||
"{0:.{prec}g}".format(1.23, prec=15) # OK (cannot validate after nested replacement)
|
"{0:.{prec}g}".format(1.23, prec=15) # OK
|
||||||
|
"{0:.{foo}x{bar}y{foobar}g}".format(...) # OK (all nested replacements are consumed without considering in between chars)
|
||||||
|
"{0:.{foo}{bar}{foobar}y}".format(...) # [bad-format-character] (check value after replacements)
|
||||||
|
|
||||||
## f-strings
|
## f-strings
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,18 @@ bad_string_format_character.py:19:1: PLE1300 Unsupported format character 'y'
|
||||||
18 | "{:{s}}".format("hello", s="s") # OK (nested replacement value not checked)
|
18 | "{:{s}}".format("hello", s="s") # OK (nested replacement value not checked)
|
||||||
19 | "{:{s:y}}".format("hello", s="s") # [bad-format-character] (nested replacement format spec checked)
|
19 | "{:{s:y}}".format("hello", s="s") # [bad-format-character] (nested replacement format spec checked)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLE1300
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLE1300
|
||||||
20 | "{0:.{prec}g}".format(1.23, prec=15) # OK (cannot validate after nested replacement)
|
20 | "{0:.{prec}g}".format(1.23, prec=15) # OK
|
||||||
|
21 | "{0:.{foo}x{bar}y{foobar}g}".format(...) # OK (all nested replacements are consumed without considering in between chars)
|
||||||
|
|
|
||||||
|
|
||||||
|
bad_string_format_character.py:22:1: PLE1300 Unsupported format character 'y'
|
||||||
|
|
|
||||||
|
20 | "{0:.{prec}g}".format(1.23, prec=15) # OK
|
||||||
|
21 | "{0:.{foo}x{bar}y{foobar}g}".format(...) # OK (all nested replacements are consumed without considering in between chars)
|
||||||
|
22 | "{0:.{foo}{bar}{foobar}y}".format(...) # [bad-format-character] (check value after replacements)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLE1300
|
||||||
|
23 |
|
||||||
|
24 | ## f-strings
|
||||||
|
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ fn parse_precision(text: &str) -> Result<(Option<usize>, &str), FormatSpecError>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a format part within a format spec
|
/// Parses a placeholder within a format spec
|
||||||
fn parse_nested_placeholder<'a>(
|
fn parse_nested_placeholder<'a>(
|
||||||
placeholders: &mut Vec<FormatPart>,
|
placeholders: &mut Vec<FormatPart>,
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
|
|
@ -334,17 +334,22 @@ fn parse_nested_placeholder<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse and consume all placeholders in a format spec
|
||||||
///
|
///
|
||||||
fn consume_remaining_placeholders<'a>(
|
/// This will also consume any intermediate characters such as `x` and `y` in
|
||||||
|
/// ```
|
||||||
|
/// "x{foo}y{bar}z"
|
||||||
|
/// ```
|
||||||
|
fn consume_all_placeholders<'a>(
|
||||||
placeholders: &mut Vec<FormatPart>,
|
placeholders: &mut Vec<FormatPart>,
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
) -> Result<&'a str, FormatSpecError> {
|
) -> Result<&'a str, FormatSpecError> {
|
||||||
let mut chars = text.chars();
|
let mut chars = text.chars();
|
||||||
|
let mut text = text;
|
||||||
let mut placeholder_count = placeholders.len();
|
let mut placeholder_count = placeholders.len();
|
||||||
|
|
||||||
while chars.clone().contains(&'{') {
|
while chars.clone().contains(&'{') {
|
||||||
dbg!(&chars, placeholder_count);
|
text = parse_nested_placeholder(placeholders, chars.as_str())?;
|
||||||
let text = parse_nested_placeholder(placeholders, chars.as_str())?;
|
|
||||||
chars = text.chars();
|
chars = text.chars();
|
||||||
// If we did not parse a placeholder, consume a character
|
// If we did not parse a placeholder, consume a character
|
||||||
if placeholder_count == placeholders.len() {
|
if placeholder_count == placeholders.len() {
|
||||||
|
|
@ -353,14 +358,11 @@ fn consume_remaining_placeholders<'a>(
|
||||||
placeholder_count = placeholders.len();
|
placeholder_count = placeholders.len();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(text)
|
||||||
Ok(chars.as_str())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatSpec {
|
impl FormatSpec {
|
||||||
pub fn parse(text: &str) -> Result<Self, FormatSpecError> {
|
pub fn parse(text: &str) -> Result<Self, FormatSpecError> {
|
||||||
println!();
|
|
||||||
dbg!(text);
|
|
||||||
let mut replacements = vec![];
|
let mut replacements = vec![];
|
||||||
let text = parse_nested_placeholder(&mut replacements, text)?;
|
let text = parse_nested_placeholder(&mut replacements, text)?;
|
||||||
let (conversion, text) = FormatConversion::parse(text);
|
let (conversion, text) = FormatConversion::parse(text);
|
||||||
|
|
@ -378,7 +380,7 @@ impl FormatSpec {
|
||||||
let (grouping_option, text) = FormatGrouping::parse(text);
|
let (grouping_option, text) = FormatGrouping::parse(text);
|
||||||
let text = parse_nested_placeholder(&mut replacements, text)?;
|
let text = parse_nested_placeholder(&mut replacements, text)?;
|
||||||
let (precision, text) = parse_precision(text)?;
|
let (precision, text) = parse_precision(text)?;
|
||||||
let text = consume_remaining_placeholders(&mut replacements, text)?;
|
let text = consume_all_placeholders(&mut replacements, text)?;
|
||||||
|
|
||||||
let (format_type, _text) = if text.is_empty() {
|
let (format_type, _text) = if text.is_empty() {
|
||||||
(None, text)
|
(None, text)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue