bpo-43933: Force RETURN_VALUE bytecodes to have line numbers (GH-26054)

This commit is contained in:
Mark Shannon 2021-05-12 11:25:44 +01:00 committed by GitHub
parent 6574334a68
commit cb6f3d7163
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 2995 additions and 2944 deletions

View File

@ -976,6 +976,26 @@ class TraceTestCase(unittest.TestCase):
(3, 'return'),
(1, 'return')])
def test_try_in_try(self):
def func():
try:
try:
pass
except Exception as ex:
pass
except Exception:
pass
# This doesn't conform to PEP 626
self.run_and_compare(func,
[(0, 'call'),
(1, 'line'),
(2, 'line'),
(3, 'line'),
(5, 'line'),
(5, 'return')])
class SkipLineEventsTraceTestCase(TraceTestCase):
"""Repeat the trace tests, but with per-line events skipped"""
@ -1647,6 +1667,7 @@ class JumpTestCase(unittest.TestCase):
output.append(1)
async for i in asynciter([1, 2]):
output.append(3)
pass
@jump_test(3, 2, [2, 2], (ValueError, 'into'))
def test_no_jump_backwards_into_for_block(output):

View File

@ -7276,6 +7276,34 @@ insert_generator_prefix(struct compiler *c, basicblock *entryblock) {
return 0;
}
/* Make sure that all returns have a line number, even if early passes
* have failed to propagate a correct line number.
* The resulting line number may not be correct according to PEP 626,
* but should be "good enough", and no worse than in older versions. */
static void
guarantee_lineno_for_exits(struct assembler *a, int firstlineno) {
int lineno = firstlineno;
assert(lineno > 0);
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
if (b->b_iused == 0) {
continue;
}
struct instr *last = &b->b_instr[b->b_iused-1];
if (last->i_lineno < 0) {
if (last->i_opcode == RETURN_VALUE)
{
for (int i = 0; i < b->b_iused; i++) {
assert(b->b_instr[i].i_lineno < 0);
b->b_instr[i].i_lineno = lineno;
}
}
}
else {
lineno = last->i_lineno;
}
}
}
static PyCodeObject *
assemble(struct compiler *c, int addNone)
{
@ -7338,6 +7366,7 @@ assemble(struct compiler *c, int addNone)
if (optimize_cfg(c, &a, consts)) {
goto error;
}
guarantee_lineno_for_exits(&a, c->u->u_firstlineno);
int maxdepth = stackdepth(c);
if (maxdepth < 0) {

3465
Python/importlib.h generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff