bpo-1875: Raise SyntaxError in invalid blocks that will be optimised … · python/cpython@85ed171 (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 |
---|---|---|
@@ -650,6 +650,20 @@ def error2(): | ||
650 | 650 | def test_break_outside_loop(self): |
651 | 651 | self._check_error("break", "outside loop") |
652 | 652 | |
653 | +def test_yield_outside_function(self): | |
654 | +self._check_error("if 0: yield", "outside function") | |
655 | +self._check_error("class C:\n if 0: yield", "outside function") | |
656 | + | |
657 | +def test_return_outside_function(self): | |
658 | +self._check_error("if 0: return", "outside function") | |
659 | +self._check_error("class C:\n if 0: return", "outside function") | |
660 | + | |
661 | +def test_break_outside_loop(self): | |
662 | +self._check_error("if 0: break", "outside loop") | |
663 | + | |
664 | +def test_continue_outside_loop(self): | |
665 | +self._check_error("if 0: continue", "not properly in loop") | |
666 | + | |
653 | 667 | def test_unexpected_indent(self): |
654 | 668 | self._check_error("foo()\n bar()\n", "unexpected indent", |
655 | 669 | 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 |
---|---|---|
@@ -2301,13 +2301,12 @@ compiler_if(struct compiler *c, stmt_ty s) | ||
2301 | 2301 | return 0; |
2302 | 2302 | |
2303 | 2303 | constant = expr_constant(s->v.If.test); |
2304 | -/* constant = 0: "if 0" | |
2304 | +/* constant = 0: "if 0" Leave the optimizations to | |
2305 | + * the pephole optimizer to check for syntax errors | |
2306 | + * in the block. | |
2305 | 2307 | * constant = 1: "if 1", "if 2", ... |
2306 | 2308 | * constant = -1: rest */ |
2307 | -if (constant == 0) { | |
2308 | -if (s->v.If.orelse) | |
2309 | -VISIT_SEQ(c, stmt, s->v.If.orelse); | |
2310 | - } else if (constant == 1) { | |
2309 | +if (constant == 1) { | |
2311 | 2310 | VISIT_SEQ(c, stmt, s->v.If.body); |
2312 | 2311 | } else { |
2313 | 2312 | if (asdl_seq_LEN(s->v.If.orelse)) { |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -304,11 +304,19 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | ||
304 | 304 | case LOAD_CONST: |
305 | 305 | cumlc = lastlc + 1; |
306 | 306 | if (nextop != POP_JUMP_IF_FALSE | |
307 | - !ISBASICBLOCK(blocks, op_start, i + 1) | | |
308 | - !PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i)))) | |
307 | + !ISBASICBLOCK(blocks, op_start, i + 1)) { | |
309 | 308 | break; |
310 | -fill_nops(codestr, op_start, nexti + 1); | |
311 | -cumlc = 0; | |
309 | + } | |
310 | +PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); | |
311 | +int is_true = PyObject_IsTrue(cnt); | |
312 | +if (is_true == 1) { | |
313 | +fill_nops(codestr, op_start, nexti + 1); | |
314 | +cumlc = 0; | |
315 | + } else if (is_true == 0) { | |
316 | +h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT); | |
317 | +tgt = find_op(codestr, codelen, h); | |
318 | +fill_nops(codestr, op_start, tgt); | |
319 | + } | |
312 | 320 | break; |
313 | 321 | |
314 | 322 | /* Try to fold tuples of constants. |