bpo-1875: Raise SyntaxError in invalid blocks that will be optimised … · python/cpython@af8646c (original) (raw)
File tree
4 files changed
lines changed
- Misc/NEWS.d/next/Core and Builtins
4 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -696,6 +696,20 @@ def error2(): | ||
696 | 696 | def test_break_outside_loop(self): |
697 | 697 | self._check_error("break", "outside loop") |
698 | 698 | |
699 | +def test_yield_outside_function(self): | |
700 | +self._check_error("if 0: yield", "outside function") | |
701 | +self._check_error("class C:\n if 0: yield", "outside function") | |
702 | + | |
703 | +def test_return_outside_function(self): | |
704 | +self._check_error("if 0: return", "outside function") | |
705 | +self._check_error("class C:\n if 0: return", "outside function") | |
706 | + | |
707 | +def test_break_outside_loop(self): | |
708 | +self._check_error("if 0: break", "outside loop") | |
709 | + | |
710 | +def test_continue_outside_loop(self): | |
711 | +self._check_error("if 0: continue", "not properly in loop") | |
712 | + | |
699 | 713 | def test_unexpected_indent(self): |
700 | 714 | self._check_error("foo()\n bar()\n", "unexpected indent", |
701 | 715 | subclass=IndentationError) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
1 | +A :exc:`SyntaxError` is now raised if a code blocks that will be optimized | |
2 | +away (e.g. if conditions that are always false) contains syntax errors. | |
3 | +Patch by Pablo Galindo. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -2546,13 +2546,12 @@ compiler_if(struct compiler *c, stmt_ty s) | ||
2546 | 2546 | return 0; |
2547 | 2547 | |
2548 | 2548 | constant = expr_constant(s->v.If.test); |
2549 | -/* constant = 0: "if 0" | |
2549 | +/* constant = 0: "if 0" Leave the optimizations to | |
2550 | + * the pephole optimizer to check for syntax errors | |
2551 | + * in the block. | |
2550 | 2552 | * constant = 1: "if 1", "if 2", ... |
2551 | 2553 | * constant = -1: rest */ |
2552 | -if (constant == 0) { | |
2553 | -if (s->v.If.orelse) | |
2554 | -VISIT_SEQ(c, stmt, s->v.If.orelse); | |
2555 | - } else if (constant == 1) { | |
2554 | +if (constant == 1) { | |
2556 | 2555 | VISIT_SEQ(c, stmt, s->v.If.body); |
2557 | 2556 | } else { |
2558 | 2557 | if (asdl_seq_LEN(s->v.If.orelse)) { |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -302,11 +302,19 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | ||
302 | 302 | case LOAD_CONST: |
303 | 303 | cumlc = lastlc + 1; |
304 | 304 | if (nextop != POP_JUMP_IF_FALSE | |
305 | - !ISBASICBLOCK(blocks, op_start, i + 1) | | |
306 | - !PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i)))) | |
305 | + !ISBASICBLOCK(blocks, op_start, i + 1)) { | |
307 | 306 | break; |
308 | -fill_nops(codestr, op_start, nexti + 1); | |
309 | -cumlc = 0; | |
307 | + } | |
308 | +PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); | |
309 | +int is_true = PyObject_IsTrue(cnt); | |
310 | +if (is_true == 1) { | |
311 | +fill_nops(codestr, op_start, nexti + 1); | |
312 | +cumlc = 0; | |
313 | + } else if (is_true == 0) { | |
314 | +h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT); | |
315 | +tgt = find_op(codestr, codelen, h); | |
316 | +fill_nops(codestr, op_start, tgt); | |
317 | + } | |
310 | 318 | break; |
311 | 319 | |
312 | 320 | /* Try to fold tuples of constants. |