diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 1f77f9b16bb..57a78391895 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -670,6 +670,14 @@ def no_jump_to_non_integers(output): no_jump_to_non_integers.jump = (2, "Spam") no_jump_to_non_integers.output = [True] +def jump_across_with(output): + with open(test_support.TESTFN, "wb") as fp: + pass + with open(test_support.TESTFN, "wb") as fp: + pass +jump_across_with.jump = (1, 3) +jump_across_with.output = [] + # This verifies that you can't set f_lineno via _getframe or similar # trickery. def no_jump_without_trace_function(): @@ -739,6 +747,9 @@ class JumpTestCase(unittest.TestCase): self.run_test(no_jump_to_non_integers) def test_19_no_jump_without_trace_function(self): no_jump_without_trace_function() + def test_jump_across_with(self): + self.addCleanup(test_support.unlink, test_support.TESTFN) + self.run_test(jump_across_with) def test_20_large_function(self): d = {} diff --git a/Misc/NEWS b/Misc/NEWS index 71218d7f4a4..6b278bd8b7d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,8 @@ What's New in Python 2.7.4 Core and Builtins ----------------- +- Issue #14612: Fix jumping around with blocks by setting f_lineno. + - Issue #13889: Check and (if necessary) set FPU control word before calling any of the dtoa.c string <-> float conversion functions, on MSVC builds of Python. This fixes issues when embedding Python in a Delphi app. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index a3476cfff12..f9e4a0ead6e 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -214,6 +214,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case SETUP_LOOP: case SETUP_EXCEPT: case SETUP_FINALLY: + case SETUP_WITH: blockstack[blockstack_top++] = addr; in_finally[blockstack_top-1] = 0; break; @@ -221,7 +222,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case POP_BLOCK: assert(blockstack_top > 0); setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY) { + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) { in_finally[blockstack_top-1] = 1; } else { @@ -236,7 +237,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) * be seeing such an END_FINALLY.) */ if (blockstack_top > 0) { setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY) { + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) { blockstack_top--; } } @@ -298,6 +299,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case SETUP_LOOP: case SETUP_EXCEPT: case SETUP_FINALLY: + case SETUP_WITH: delta_iblock++; break;