Index: Python/symtable.c =================================================================== --- Python/symtable.c (revision 68142) +++ Python/symtable.c (working copy) @@ -22,7 +22,12 @@ #define RETURN_VAL_IN_GENERATOR \ "'return' with argument inside generator" +#define RETURN_OUTSIDE_FUNCTION \ + "'return' outside function" +#define YIELD_OUTSIDE_FUNCTION \ + "'yield' outside function" + static PySTEntryObject * ste_new(struct symtable *st, identifier name, _Py_block_ty block, void *key, int lineno) @@ -1063,6 +1068,12 @@ break; } case Return_kind: + if (st->st_cur->ste_type != FunctionBlock) { + PyErr_SetString(PyExc_SyntaxError, + RETURN_OUTSIDE_FUNCTION); + PyErr_SyntaxLocation(st->st_filename, + s->lineno); + } if (s->v.Return.value) { VISIT(st, expr, s->v.Return.value); st->st_cur->ste_returns_value = 1; @@ -1278,6 +1289,12 @@ return 0; break; case Yield_kind: + if (st->st_cur->ste_type != FunctionBlock) { + PyErr_SetString(PyExc_SyntaxError, + YIELD_OUTSIDE_FUNCTION); + PyErr_SyntaxLocation(st->st_filename, + e->lineno); + } if (e->v.Yield.value) VISIT(st, expr, e->v.Yield.value); st->st_cur->ste_generator = 1; Index: Lib/test/test_syntax.py =================================================================== --- Lib/test/test_syntax.py (revision 68142) +++ Lib/test/test_syntax.py (working copy) @@ -528,6 +528,16 @@ def test_break_outside_loop(self): self._check_error("break", "outside loop") + def test_yield_outside_function(self): + # Issue XXXX: raise a SyntaxError even if the compiler + # trims the code because of a "if 0" + self._check_error("if 0: yield", "outside function") + self._check_error("class C:\n if 0: yield", "outside function") + + def test_return_outside_function(self): + self._check_error("if 0: return", "outside function") + self._check_error("class C:\n if 0: return", "outside function") + def test_delete_deref(self): source = re.sub('(?m)^ *:', '', """\ :def foo(x):