Remove f-string UnclosedLbrace error checking from the lexer (#10372)
This error check is already handled by the new parser. Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
This commit is contained in:
committed by
Dhruv Manilawala
parent
156f7994a7
commit
d41ecfe351
@@ -0,0 +1,8 @@
|
||||
# TODO(dhruvmanila): Remove the dummy test case and uncomment the others when this is fixed. See PR #10372
|
||||
x +
|
||||
|
||||
# f'{'
|
||||
# f'{foo!r'
|
||||
# f'{foo='
|
||||
# f"{"
|
||||
# f"""{"""
|
||||
@@ -723,19 +723,6 @@ impl<'source> Lexer<'source> {
|
||||
let Some(index) = memchr::memchr(quote_byte, self.cursor.rest().as_bytes()) else {
|
||||
self.cursor.skip_to_end();
|
||||
|
||||
if let Some(fstring) = self.fstrings.current() {
|
||||
// When we are in an f-string, check whether the initial quote
|
||||
// matches with f-strings quotes and if it is, then this must be a
|
||||
// missing '}' token so raise the proper error.
|
||||
if fstring.quote_char() == quote
|
||||
&& fstring.is_triple_quoted() == kind.is_triple_quoted()
|
||||
{
|
||||
return Err(LexicalError::new(
|
||||
LexicalErrorType::FStringError(FStringErrorType::UnclosedLbrace),
|
||||
self.token_range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
return Err(LexicalError::new(
|
||||
LexicalErrorType::UnclosedStringError,
|
||||
self.token_range(),
|
||||
@@ -772,19 +759,6 @@ impl<'source> Lexer<'source> {
|
||||
else {
|
||||
self.cursor.skip_to_end();
|
||||
|
||||
if let Some(fstring) = self.fstrings.current() {
|
||||
// When we are in an f-string, check whether the initial quote
|
||||
// matches with f-strings quotes and if it is, then this must be a
|
||||
// missing '}' token so raise the proper error.
|
||||
if fstring.quote_char() == quote
|
||||
&& fstring.is_triple_quoted() == kind.is_triple_quoted()
|
||||
{
|
||||
return Err(LexicalError::new(
|
||||
LexicalErrorType::FStringError(FStringErrorType::UnclosedLbrace),
|
||||
self.token_range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
return Err(LexicalError::new(
|
||||
LexicalErrorType::StringError,
|
||||
self.token_range(),
|
||||
@@ -813,19 +787,6 @@ impl<'source> Lexer<'source> {
|
||||
|
||||
match ch {
|
||||
Some('\r' | '\n') => {
|
||||
if let Some(fstring) = self.fstrings.current() {
|
||||
// When we are in an f-string, check whether the initial quote
|
||||
// matches with f-strings quotes and if it is, then this must be a
|
||||
// missing '}' token so raise the proper error.
|
||||
if fstring.quote_char() == quote && !fstring.is_triple_quoted() {
|
||||
return Err(LexicalError::new(
|
||||
LexicalErrorType::FStringError(
|
||||
FStringErrorType::UnclosedLbrace,
|
||||
),
|
||||
self.token_range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
return Err(LexicalError::new(
|
||||
LexicalErrorType::UnclosedStringError,
|
||||
self.token_range(),
|
||||
@@ -2319,9 +2280,7 @@ f"{(lambda x:{x})}"
|
||||
|
||||
#[test]
|
||||
fn test_fstring_error() {
|
||||
use FStringErrorType::{
|
||||
SingleRbrace, UnclosedLbrace, UnterminatedString, UnterminatedTripleQuotedString,
|
||||
};
|
||||
use FStringErrorType::{SingleRbrace, UnterminatedString, UnterminatedTripleQuotedString};
|
||||
|
||||
assert_eq!(lex_fstring_error("f'}'"), SingleRbrace);
|
||||
assert_eq!(lex_fstring_error("f'{{}'"), SingleRbrace);
|
||||
@@ -2331,17 +2290,6 @@ f"{(lambda x:{x})}"
|
||||
assert_eq!(lex_fstring_error("f'{a:b}}'"), SingleRbrace);
|
||||
assert_eq!(lex_fstring_error("f'{3:}}>10}'"), SingleRbrace);
|
||||
assert_eq!(lex_fstring_error(r"f'\{foo}\}'"), SingleRbrace);
|
||||
assert_eq!(lex_fstring_error("f'{'"), UnclosedLbrace);
|
||||
assert_eq!(lex_fstring_error("f'{foo!r'"), UnclosedLbrace);
|
||||
assert_eq!(lex_fstring_error("f'{foo='"), UnclosedLbrace);
|
||||
assert_eq!(
|
||||
lex_fstring_error(
|
||||
r#"f"{"
|
||||
"#
|
||||
),
|
||||
UnclosedLbrace
|
||||
);
|
||||
assert_eq!(lex_fstring_error(r#"f"""{""""#), UnclosedLbrace);
|
||||
|
||||
assert_eq!(lex_fstring_error(r#"f""#), UnterminatedString);
|
||||
assert_eq!(lex_fstring_error(r"f'"), UnterminatedString);
|
||||
@@ -2357,25 +2305,4 @@ f"{(lambda x:{x})}"
|
||||
UnterminatedTripleQuotedString
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fstring_error_location() {
|
||||
assert_debug_snapshot!(lex_error("f'{'"), @r###"
|
||||
LexicalError {
|
||||
error: FStringError(
|
||||
UnclosedLbrace,
|
||||
),
|
||||
location: 3..4,
|
||||
}
|
||||
"###);
|
||||
|
||||
assert_debug_snapshot!(lex_error("f'{'α"), @r###"
|
||||
LexicalError {
|
||||
error: FStringError(
|
||||
UnclosedLbrace,
|
||||
),
|
||||
location: 3..6,
|
||||
}
|
||||
"###);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_parser/resources/invalid/expressions/unclosed_fstring_lbrace.py
|
||||
---
|
||||
## AST
|
||||
|
||||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..160,
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 107..110,
|
||||
value: BinOp(
|
||||
ExprBinOp {
|
||||
range: 107..110,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 107..108,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
op: Add,
|
||||
right: Name(
|
||||
ExprName {
|
||||
range: 110..110,
|
||||
id: "",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
```
|
||||
## Errors
|
||||
|
||||
|
|
||||
1 | # TODO(dhruvmanila): Remove the dummy test case and uncomment the others when this is fixed. See PR #10372
|
||||
2 | x +
|
||||
| ^ Syntax Error: Expression expected.
|
||||
3 |
|
||||
4 | # f'{'
|
||||
5 | # f'{foo!r'
|
||||
|
|
||||
Reference in New Issue
Block a user