|
3 | 3 | import unittest |
4 | 4 | from test import support |
5 | 5 | from test.support import script_helper |
6 | | -from test.support.os_helper import TESTFN, unlink, rmtree |
7 | | -from test.support.import_helper import unload |
| 6 | +from test.support.os_helper import TESTFN, TESTFN_ASCII, unlink, rmtree |
| 7 | +from test.support.import_helper import import_module, unload |
8 | 8 | import importlib |
9 | 9 | import os |
10 | 10 | import sys |
@@ -83,12 +83,30 @@ def test_truncated_utf8_at_eof(self): |
83 | 83 | self.assertRaises(SyntaxError, compile, seq, '<test>', 'exec') |
84 | 84 |
|
85 | 85 | def test_invalid_utf8_offset_after_non_ascii(self): |
| 86 | + for name in ('é', 'éé', '𝒜'): |
| 87 | + with self.subTest(name=name): |
| 88 | + source = ('x = ' + name).encode() + b'\xff\n' |
| 89 | + with self.assertRaises(SyntaxError) as caught: |
| 90 | + compile(source, '<test>', 'exec') |
| 91 | + error = caught.exception |
| 92 | + self.assertEqual( |
| 93 | + (error.lineno, error.offset, error.end_lineno, error.end_offset), |
| 94 | + (1, 5 + len(name), 1, 5 + len(name)), |
| 95 | + ) |
| 96 | + |
| 97 | + @support.cpython_only |
| 98 | + def test_invalid_utf8_file_offset_after_non_ascii(self): |
| 99 | + _testcapi = import_module('_testcapi') |
| 100 | + self.addCleanup(unlink, TESTFN_ASCII) |
| 101 | + with open(TESTFN_ASCII, 'wb') as f: |
| 102 | + f.write(b'\nx = \xc3\xa9\xc3\xa9\xff\n') |
86 | 103 | with self.assertRaises(SyntaxError) as caught: |
87 | | - compile(b"x = \xc3\xa9\xff\n", "<test>", "exec") |
| 104 | + _testcapi.run_file( |
| 105 | + os.fsencode(TESTFN_ASCII), _testcapi.Py_file_input, {}) |
88 | 106 | error = caught.exception |
89 | 107 | self.assertEqual( |
90 | 108 | (error.lineno, error.offset, error.end_lineno, error.end_offset), |
91 | | - (1, 6, 1, 6), |
| 109 | + (2, 7, 2, 7), |
92 | 110 | ) |
93 | 111 |
|
94 | 112 | def test_long_bom_conflict_message_is_not_truncated(self): |
|
0 commit comments