Skip to content

Commit 75d9977

Browse files
ashm-devmiss-islington
authored andcommitted
gh-157378: Fix SyntaxError.offset for "Non-UTF-8 code" error (GH-157412)
(cherry picked from commit e66bec0) Co-authored-by: Shamil <ashm.tech@proton.me>
1 parent 38b79e8 commit 75d9977

3 files changed

Lines changed: 15 additions & 4 deletions

File tree

Lib/test/test_exceptions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,16 @@ def testSyntaxErrorRange(self):
249249
self.assertEqual(cm.exception.offset, offset)
250250
self.assertEqual(cm.exception.end_offset, end_offset)
251251

252+
def testSyntaxErrorNonUTF8Offset(self):
253+
# gh-157378: the position was reported one column short for each
254+
# multi-byte character preceding the invalid byte on the same line
255+
check = self.check
256+
check(b'X\x80', 1, 2, 1, 2)
257+
check(b'\xc3\xa9X\x80', 1, 3, 1, 3)
258+
check(b'\t\xc3\xa9X\x80', 1, 4, 1, 4)
259+
check(b'a\xc3\xa9b\x80c', 1, 4, 1, 4)
260+
check(b'a\n\xc3\xa9X\x80', 2, 3, 2, 3)
261+
252262
def testSyntaxErrorOffset(self):
253263
check = self.check
254264
check('def fact(x):\n\treturn x!\n', 2, 10)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix ``SyntaxError.offset`` and ``SyntaxError.end_offset`` for the
2+
"Non-UTF-8 code starting with ..." error when a non-ASCII character precedes
3+
the invalid byte on the same line. Patch by Shamil Abdulaev.

Parser/tokenizer/helpers.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,17 +578,14 @@ _PyTokenizer_ensure_utf8(const char *line, struct tok_state *tok, int lineno)
578578
const char *badchar = NULL;
579579
const char *c;
580580
int length;
581-
int col_offset = 0;
582581
const char *line_start = line;
583582
for (c = line; *c; c += length) {
584583
if (!(length = valid_utf8((const unsigned char *)c))) {
585584
badchar = c;
586585
break;
587586
}
588-
col_offset++;
589587
if (*c == '\n') {
590588
lineno++;
591-
col_offset = 0;
592589
line_start = c + 1;
593590
}
594591
}
@@ -597,7 +594,8 @@ _PyTokenizer_ensure_utf8(const char *line, struct tok_state *tok, int lineno)
597594
tok->line_start = line_start;
598595
tok->cur = (char *)badchar;
599596
_PyTokenizer_syntaxerror_known_range(tok,
600-
col_offset + 1, col_offset + 1,
597+
(int)(badchar - line_start) + 1,
598+
(int)(badchar - line_start) + 1,
601599
"Non-UTF-8 code starting with '\\x%.2x'"
602600
"%s%V on line %i, "
603601
"but no encoding declared; "

0 commit comments

Comments
 (0)