Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Lib/test/test_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,26 @@ def test_bad_numerical_literals(self):
check("1e2_", "invalid decimal literal")
check("1e+", "invalid decimal literal")

def test_end_of_numerical_literals_offset(self):
# gh-149277: verify the error caret points at the first invalid
# character, not the last valid digit.
cases = [
("0xfg", 4),
("0x9g", 4),
("0b1z", 4),
("0o7q", 4),
("9spam", 2),
("0xfspam", 4),
("1.0x", 4),
("1e3w", 4),
("1jz", 3),
]
for source, expected_offset in cases:
with self.subTest(source=source):
with self.assertRaises(SyntaxError) as cm:
compile(source, "<test>", "eval")
self.assertEqual(cm.exception.offset, expected_offset)

def test_end_of_numerical_literals(self):
def check(test, error=False):
with self.subTest(expr=test):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix the :exc:`SyntaxError` caret position for invalid numeric literals to
point at the first invalid character instead of the last valid one.
1 change: 0 additions & 1 deletion Parser/lexer/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,6 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) {
}
else /* In future releases, only error will remain. */
if (c < 128 && is_potential_identifier_char(c)) {
tok_backup(tok, c);
_PyTokenizer_syntaxerror(tok, "invalid %s literal", kind);
return 0;
}
Expand Down
Loading