diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index a5434d6fd512ed..85f05a8dd257f4 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1215,7 +1215,6 @@ def test_multiline_boolean_expression(self): d > 0)): x = 42 """ - compiled_code, _ = self.check_positions_against_ast(snippet) # jump if a is true: self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE', @@ -1233,6 +1232,23 @@ def test_multiline_boolean_expression(self): self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE', line=4, end_line=4, column=8, end_column=13, occurrence=2) + def test_multiline_assert(self): + snippet = """\ +assert (a > 0 and + bb > 0 and + ccc == 4), "error msg" +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_ASSERTION_ERROR', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + # The "error msg": + self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST', + line=3, end_line=3, column=19, end_column=30, occurrence=4) + self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + def test_very_long_line_end_offset(self): # Make sure we get the correct column offset for offsets # too large to store in a byte. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-10-18-16-17-44.gh-issue-98398.x4rYK_.rst b/Misc/NEWS.d/next/Core and Builtins/2022-10-18-16-17-44.gh-issue-98398.x4rYK_.rst new file mode 100644 index 00000000000000..35d33c90a6902b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-10-18-16-17-44.gh-issue-98398.x4rYK_.rst @@ -0,0 +1 @@ +Fix source location of 'assert' bytecodes. diff --git a/Python/compile.c b/Python/compile.c index 4d5b41aa13003c..c888f4064c79da 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3960,7 +3960,6 @@ compiler_from_import(struct compiler *c, stmt_ty s) static int compiler_assert(struct compiler *c, stmt_ty s) { - location loc = LOC(s); /* Always emit a warning if the test is a non-zero length tuple */ if ((s->v.Assert.test->kind == Tuple_kind && asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || @@ -3968,23 +3967,26 @@ compiler_assert(struct compiler *c, stmt_ty s) PyTuple_Check(s->v.Assert.test->v.Constant.value) && PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0)) { - if (!compiler_warn(c, loc, "assertion is always true, " - "perhaps remove parentheses?")) + if (!compiler_warn(c, LOC(s), "assertion is always true, " + "perhaps remove parentheses?")) { return 0; } } - if (c->c_optimize) + if (c->c_optimize) { return 1; + } NEW_JUMP_TARGET_LABEL(c, end); - if (!compiler_jump_if(c, &loc, s->v.Assert.test, end, 1)) + location loc = LOC(s); + if (!compiler_jump_if(c, &loc, s->v.Assert.test, end, 1)) { return 0; - ADDOP(c, loc, LOAD_ASSERTION_ERROR); + } + ADDOP(c, LOC(s), LOAD_ASSERTION_ERROR); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); - ADDOP_I(c, loc, CALL, 0); + ADDOP_I(c, LOC(s), CALL, 0); } - ADDOP_I(c, loc, RAISE_VARARGS, 1); + ADDOP_I(c, LOC(s), RAISE_VARARGS, 1); USE_LABEL(c, end); return 1;