diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 76483f676a0..89e9e678950 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -511,6 +511,15 @@ while 0: pass while 0: pass else: pass +# Issue1920: "while 0" is optimized away, +# ensure that the "else" clause is still present. +x = 0 +while 0: + x = 1 +else: + x = 2 +assert x == 2 + print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] for i in 1, 2, 3: pass for i, j, k in (): pass diff --git a/Misc/NEWS b/Misc/NEWS index 8b0084aad96..4913c79bcb7 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,11 @@ What's New in Python 2.5.2c1? Core and builtins ----------------- +- Issue #1920: "while 0" statements were completely removed by the compiler, + even in the presence of an "else" clause, which is supposed to be run when + the condition is false. Now the compiler correctly emits bytecode for the + "else" suite. + - A few crashers fixed: weakref_in_del.py (issue #1377858); loosing_dict_ref.py (issue #1303614, test67.py); borrowed_ref_[34].py (not in tracker). diff --git a/Python/compile.c b/Python/compile.c index 0e824caabdb..8e96ddfa62c 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2256,8 +2256,11 @@ compiler_while(struct compiler *c, stmt_ty s) basicblock *loop, *orelse, *end, *anchor = NULL; int constant = expr_constant(s->v.While.test); - if (constant == 0) + if (constant == 0) { + if (s->v.While.orelse) + VISIT_SEQ(c, stmt, s->v.While.orelse); return 1; + } loop = compiler_new_block(c); end = compiler_new_block(c); if (constant == -1) {