Skip to content

Commit a844eaf

Browse files
committed
gh-100445: Improve error message for unterminated strings with escapes
1 parent e7d5433 commit a844eaf

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

Lib/test/test_syntax.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,8 +2262,14 @@ def test_error_parenthesis(self):
22622262

22632263
def test_error_string_literal(self):
22642264

2265-
self._check_error("'blech", "unterminated string literal")
2266-
self._check_error('"blech', "unterminated string literal")
2265+
self._check_error("'blech", r"unterminated string literal \(.*\)$")
2266+
self._check_error('"blech', r"unterminated string literal \(.*\)$")
2267+
self._check_error(
2268+
r'"blech\"', r"unterminated string literal \(.*\); perhaps you escaped the end quote"
2269+
)
2270+
self._check_error(
2271+
r'r"blech\"', r"unterminated string literal \(.*\); perhaps you escaped the end quote"
2272+
)
22672273
self._check_error("'''blech", "unterminated triple-quoted string literal")
22682274
self._check_error('"""blech', "unterminated triple-quoted string literal")
22692275

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve error message for unterminated strings with escapes.

Parser/tokenizer.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,7 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
23972397
int quote = c;
23982398
int quote_size = 1; /* 1 or 3 */
23992399
int end_quote_size = 0;
2400+
int has_escaped_quote = 0;
24002401

24012402
/* Nodes of type STRING, especially multi line strings
24022403
must be handled differently in order to get both
@@ -2462,8 +2463,13 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
24622463
return MAKE_TOKEN(ERRORTOKEN);
24632464
}
24642465
else {
2465-
syntaxerror(tok, "unterminated string literal (detected at"
2466-
" line %d)", start);
2466+
if (has_escaped_quote) {
2467+
syntaxerror(tok, "unterminated string literal (detected at"
2468+
" line %d); perhaps you escaped the end quote?", start);
2469+
} else {
2470+
syntaxerror(tok, "unterminated string literal (detected at"
2471+
" line %d)", start);
2472+
}
24672473
if (c != '\n') {
24682474
tok->done = E_EOLS;
24692475
}
@@ -2480,6 +2486,10 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
24802486
if (c == '\r') {
24812487
c = tok_nextc(tok);
24822488
}
2489+
// but record whether the escaped char was a quote
2490+
if (c == quote) {
2491+
has_escaped_quote = 1;
2492+
}
24832493
}
24842494
}
24852495
}

0 commit comments

Comments
 (0)