bpo-42246: Make sure that line number is correct after a return, as required by PEP 626 by markshannon · Pull Request #23495 · python/cpython
This PR ensures that f_lineno can be correctly computed after a return, by ensuring that all compiler generated return instructions
have a line number.
Any block that has no line numbers and has only one predecessor can inherit the line number from its predecessor.
Any block ending in a return has no successors, and thus can be safely duplicated.
By duplicating all blocks that end in a return, but have no line number, those blocks will have only one predecessor and thus can inherit its predecessor's line number, meaning that all implicit returns now have a line number.
For example,
currently compiles to:
2 0 LOAD_FAST 0 (cond)
2 POP_JUMP_IF_FALSE 8
3 4 LOAD_GLOBAL 0 (a)
6 POP_TOP
None >> 8 LOAD_CONST 0 (None)
10 RETURN_VALUE
with this PR it compiles to:
2 0 LOAD_FAST 0 (cond)
2 POP_JUMP_IF_FALSE 12
3 4 LOAD_GLOBAL 0 (a)
6 POP_TOP
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
2 >> 12 LOAD_CONST 0 (None)
14 RETURN_VALUE
which is equivalent, but produces the correct line number when not cond.