[Python-checkins] r60579 - in python/branches/release25-maint: Lib/test/test_trace.py Misc/NEWS Python/compile.c
Brett Cannon
brett at python.org
Tue Feb 5 00:41:28 CET 2008
It looks like this broke test_compile.
-Brett
On Feb 4, 2008 2:34 PM, amaury.forgeotdarc <python-checkins at python.org> wrote:
> Author: amaury.forgeotdarc
> Date: Mon Feb 4 23:34:57 2008
> New Revision: 60579
>
> Modified:
> python/branches/release25-maint/Lib/test/test_trace.py
> python/branches/release25-maint/Misc/NEWS
> python/branches/release25-maint/Python/compile.c
> Log:
> backport of r60575 (issue #1750076): Debugger did not step on every iteration of a while statement.
>
> The mapping between bytecode offsets and source lines (lnotab) did not contain
> an entry for the beginning of the loop.
>
> Now it does, and the lnotab can be a bit larger:
> in particular, several statements on the same line generate several entries.
> However, this does not bother the settrace function, which will trigger only
> one 'line' event.
>
> The lnotab seems to be exactly the same as with python2.4.
>
>
> Modified: python/branches/release25-maint/Lib/test/test_trace.py
> ==============================================================================
> --- python/branches/release25-maint/Lib/test/test_trace.py (original)
> +++ python/branches/release25-maint/Lib/test/test_trace.py Mon Feb 4 23:34:57 2008
> @@ -252,14 +252,16 @@
> "\n".join(difflib.ndiff([str(x) for x in expected_events],
> [str(x) for x in events])))
>
> -
> - def run_test(self, func):
> + def run_and_compare(self, func, events):
> tracer = Tracer()
> sys.settrace(tracer.trace)
> func()
> sys.settrace(None)
> self.compare_events(func.func_code.co_firstlineno,
> - tracer.events, func.events)
> + tracer.events, events)
> +
> + def run_test(self, func):
> + self.run_and_compare(func, func.events)
>
> def run_test2(self, func):
> tracer = Tracer()
> @@ -307,6 +309,49 @@
> self.compare_events(generator_example.func_code.co_firstlineno,
> tracer.events, generator_example.events)
>
> + def test_14_onliner_if(self):
> + def onliners():
> + if True: False
> + else: True
> + return 0
> + self.run_and_compare(
> + onliners,
> + [(0, 'call'),
> + (1, 'line'),
> + (3, 'line'),
> + (3, 'return')])
> +
> + def test_15_loops(self):
> + # issue1750076: "while" expression is skipped by debugger
> + def for_example():
> + for x in range(2):
> + pass
> + self.run_and_compare(
> + for_example,
> + [(0, 'call'),
> + (1, 'line'),
> + (2, 'line'),
> + (1, 'line'),
> + (2, 'line'),
> + (1, 'line'),
> + (1, 'return')])
> +
> + def while_example():
> + # While expression should be traced on every loop
> + x = 2
> + while x > 0:
> + x -= 1
> + self.run_and_compare(
> + while_example,
> + [(0, 'call'),
> + (2, 'line'),
> + (3, 'line'),
> + (4, 'line'),
> + (3, 'line'),
> + (4, 'line'),
> + (3, 'line'),
> + (3, 'return')])
> +
> class RaisingTraceFuncTestCase(unittest.TestCase):
> def trace(self, frame, event, arg):
> """A trace function that raises an exception in response to a
>
> Modified: python/branches/release25-maint/Misc/NEWS
> ==============================================================================
> --- python/branches/release25-maint/Misc/NEWS (original)
> +++ python/branches/release25-maint/Misc/NEWS Mon Feb 4 23:34:57 2008
> @@ -80,6 +80,10 @@
> Library
> -------
>
> +- #175006: The debugger used to skip the condition of a "while" statement
> + after the first iteration. Now it correctly steps on the expression, and
> + breakpoints on the "while" statement are honored on each loop.
> +
> - The ctypes int types did not accept objects implementing
> __int__() in the constructor.
>
>
> Modified: python/branches/release25-maint/Python/compile.c
> ==============================================================================
> --- python/branches/release25-maint/Python/compile.c (original)
> +++ python/branches/release25-maint/Python/compile.c Mon Feb 4 23:34:57 2008
> @@ -1298,11 +1298,16 @@
> return b->b_iused++;
> }
>
> -/* Set the i_lineno member of the instruction at offse off if the
> - line number for the current expression/statement (?) has not
> +/* Set the i_lineno member of the instruction at offset off if the
> + line number for the current expression/statement has not
> already been set. If it has been set, the call has no effect.
>
> - Every time a new node is b
> + The line number is reset in the following cases:
> + - when entering a new scope
> + - on each statement
> + - on each expression that start a new line
> + - before the "except" clause
> + - before the "for" and "while" expressions
> */
>
> static void
> @@ -2234,9 +2239,8 @@
> VISIT(c, expr, s->v.For.iter);
> ADDOP(c, GET_ITER);
> compiler_use_next_block(c, start);
> - /* XXX(nnorwitz): is there a better way to handle this?
> - for loops are special, we want to be able to trace them
> - each time around, so we need to set an extra line number. */
> + /* for expressions must be traced on each iteration,
> + so we need to set an extra line number. */
> c->u->u_lineno_set = false;
> ADDOP_JREL(c, FOR_ITER, cleanup);
> VISIT(c, expr, s->v.For.target);
> @@ -2283,6 +2287,9 @@
> if (!compiler_push_fblock(c, LOOP, loop))
> return 0;
> if (constant == -1) {
> + /* while expressions must be traced on each iteration,
> + so we need to set an extra line number. */
> + c->u->u_lineno_set = false;
> VISIT(c, expr, s->v.While.test);
> ADDOP_JREL(c, JUMP_IF_FALSE, anchor);
> ADDOP(c, POP_TOP);
> @@ -2464,8 +2471,8 @@
> s->v.TryExcept.handlers, i);
> if (!handler->type && i < n-1)
> return compiler_error(c, "default 'except:' must be last");
> - c->u->u_lineno_set = false;
> - c->u->u_lineno = handler->lineno;
> + c->u->u_lineno_set = false;
> + c->u->u_lineno = handler->lineno;
> except = compiler_new_block(c);
> if (except == NULL)
> return 0;
> @@ -4184,12 +4191,6 @@
> assert(d_bytecode >= 0);
> assert(d_lineno >= 0);
>
> - /* XXX(nnorwitz): is there a better way to handle this?
> - for loops are special, we want to be able to trace them
> - each time around, so we need to set an extra line number. */
> - if (d_lineno == 0 && i->i_opcode != FOR_ITER)
> - return 1;
> -
> if (d_bytecode > 255) {
> int j, nbytes, ncodes = d_bytecode / 255;
> nbytes = a->a_lnotab_off + 2 * ncodes;
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>
More information about the Python-checkins
mailing list