Skip to content

Commit bdd8ddf

Browse files
authored
gh-105724: Add location information to assert errors (GH-105935)
1 parent fd9d70a commit bdd8ddf

File tree

4 files changed

+124
-6
lines changed

4 files changed

+124
-6
lines changed

Lib/test/test_compile.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1315,18 +1315,18 @@ def test_multiline_assert(self):
13151315
snippet = textwrap.dedent("""\
13161316
assert (a > 0 and
13171317
bb > 0 and
1318-
ccc == 4), "error msg"
1318+
ccc == 1000000), "error msg"
13191319
""")
13201320
compiled_code, _ = self.check_positions_against_ast(snippet)
13211321
self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_ASSERTION_ERROR',
1322-
line=1, end_line=3, column=0, end_column=30, occurrence=1)
1322+
line=1, end_line=3, column=0, end_column=36, occurrence=1)
13231323
# The "error msg":
13241324
self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST',
1325-
line=3, end_line=3, column=19, end_column=30, occurrence=4)
1325+
line=3, end_line=3, column=25, end_column=36, occurrence=4)
13261326
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL',
1327-
line=1, end_line=3, column=0, end_column=30, occurrence=1)
1327+
line=1, end_line=3, column=0, end_column=36, occurrence=1)
13281328
self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS',
1329-
line=1, end_line=3, column=0, end_column=30, occurrence=1)
1329+
line=1, end_line=3, column=8, end_column=22, occurrence=1)
13301330

13311331
def test_multiline_generator_expression(self):
13321332
snippet = textwrap.dedent("""\

Lib/test/test_exceptions.py

+117
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,123 @@ def test_copy_pickle(self):
19311931
self.assertEqual(exc.name, orig.name)
19321932
self.assertEqual(exc.path, orig.path)
19331933

1934+
1935+
class AssertionErrorTests(unittest.TestCase):
1936+
def tearDown(self):
1937+
unlink(TESTFN)
1938+
1939+
def write_source(self, source):
1940+
with open(TESTFN, 'w') as testfile:
1941+
testfile.write(dedent(source))
1942+
_rc, _out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN)
1943+
return err.decode('utf-8').splitlines()
1944+
1945+
def test_assertion_error_location(self):
1946+
cases = [
1947+
('assert None',
1948+
[
1949+
' assert None',
1950+
' ^^^^',
1951+
'AssertionError',
1952+
],
1953+
),
1954+
('assert 0',
1955+
[
1956+
' assert 0',
1957+
' ^',
1958+
'AssertionError',
1959+
],
1960+
),
1961+
('assert 1 > 2',
1962+
[
1963+
' assert 1 > 2',
1964+
' ^^^^^',
1965+
'AssertionError',
1966+
],
1967+
),
1968+
('assert 1 > 2 and 3 > 2',
1969+
[
1970+
' assert 1 > 2 and 3 > 2',
1971+
' ^^^^^^^^^^^^^^^',
1972+
'AssertionError',
1973+
],
1974+
),
1975+
('assert 1 > 2, "message"',
1976+
[
1977+
' assert 1 > 2, "message"',
1978+
' ^^^^^',
1979+
'AssertionError: message',
1980+
],
1981+
),
1982+
1983+
# Multiline:
1984+
("""
1985+
assert (
1986+
1 > 2)
1987+
""",
1988+
[
1989+
' 1 > 2)',
1990+
' ^^^^^',
1991+
'AssertionError',
1992+
],
1993+
),
1994+
("""
1995+
assert (
1996+
1 > 2), "Message"
1997+
""",
1998+
[
1999+
' 1 > 2), "Message"',
2000+
' ^^^^^',
2001+
'AssertionError: Message',
2002+
],
2003+
),
2004+
("""
2005+
assert (
2006+
1 > 2), \\
2007+
"Message"
2008+
""",
2009+
[
2010+
' 1 > 2), \\',
2011+
' ^^^^^',
2012+
'AssertionError: Message',
2013+
],
2014+
),
2015+
]
2016+
for source, expected in cases:
2017+
with self.subTest(source):
2018+
result = self.write_source(source)
2019+
self.assertEqual(result[-3:], expected)
2020+
2021+
def test_multiline_not_highlighted(self):
2022+
cases = [
2023+
("""
2024+
assert (
2025+
1 > 2
2026+
)
2027+
""",
2028+
[
2029+
' 1 > 2',
2030+
'AssertionError',
2031+
],
2032+
),
2033+
("""
2034+
assert (
2035+
1 < 2 and
2036+
3 > 4
2037+
)
2038+
""",
2039+
[
2040+
' 1 < 2 and',
2041+
'AssertionError',
2042+
],
2043+
),
2044+
]
2045+
for source, expected in cases:
2046+
with self.subTest(source):
2047+
result = self.write_source(source)
2048+
self.assertEqual(result[-2:], expected)
2049+
2050+
19342051
class SyntaxErrorTests(unittest.TestCase):
19352052
def test_range_of_offsets(self):
19362053
cases = [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve ``assert`` error messages by providing exact error range.

Python/compile.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3952,7 +3952,7 @@ compiler_assert(struct compiler *c, stmt_ty s)
39523952
VISIT(c, expr, s->v.Assert.msg);
39533953
ADDOP_I(c, LOC(s), CALL, 0);
39543954
}
3955-
ADDOP_I(c, LOC(s), RAISE_VARARGS, 1);
3955+
ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1);
39563956

39573957
USE_LABEL(c, end);
39583958
return SUCCESS;

0 commit comments

Comments
 (0)