classification
Title: "if 0: return" not raising SyntaxError
Type: Stage:
Components: Interpreter Core Versions: Python 2.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: amaury.forgeotdarc Nosy List: amaury.forgeotdarc, arigo, benjamin.peterson, cfbolz, fijal, mark.dickinson, mastrodomenico (7)
Priority: low Keywords needs review, patch

Created on 2008-01-19 18:55 by arigo, last changed 2009-08-23 21:42 by mastrodomenico.

Files
File name Uploaded Description Edit Remove
x.py arigo, 2008-01-19 18:55
return_outside_func.patch amaury.forgeotdarc, 2009-02-02 23:48
Messages (6)
msg60213 - (view) Author: Armin Rigo (arigo) Date: 2008-01-19 18:55
Can you guess why importing the attached x.py does nothing, without
printing "hello" at all?

The real issue shown in that example is that 'return' and 'yield'
outside a function are ignored instead of giving a SyntaxError if they
are optimized away by 'if 0:'.  

(Hint about x.py: the yield sets the CO_GENERATOR flag before it gets
optimized away.  So clearly, that's a way to comment out a whole module
-- just put "if 0: yield" anywhere at top-level...)
msg61638 - (view) Author: Mark Dickinson (mark.dickinson) Date: 2008-01-24 16:24
See also issue #1920
msg80955 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) Date: 2009-02-02 17:00
This was corrected by Benjamin with r69158.
Now the yield statement is still optimized away, but at least the
CO_GENERATOR flag is set only when compiling a function.
msg80961 - (view) Author: Armin Rigo (arigo) Date: 2009-02-02 17:11
...which does not really solve anything, as "if 0: yield" at
module-level is now just ignored instead of raising a SyntaxError (e.g.
like "if False: yield").
msg81019 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) Date: 2009-02-02 23:48
Here is a patch that properly raises SyntaxError when 'return' or  
'yield' statements appear outside a function.

I did not bother to update the (deprecated) compiler package: it seems 
to be completely foreign to this kind of checks...

>>> dis.dis(compiler.compile("return 1", "module.py", "exec"))
  1           0 LOAD_CONST               1 (1)
              3 RETURN_VALUE
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE
msg81023 - (view) Author: Benjamin Peterson (benjamin.peterson) Date: 2009-02-03 01:56
You should remove the error logic compile.c for "return" and "yield" in
function calls.

The problem with this approach is that every SyntaxError generated
during bytecode compilation must be moved to earlier. For example, I can
still use "break" and "continue" outside loops with your patch. The only
way I can think of around this is to compile the block anyway and remove
the extra code later. Maybe this optimization could be moved to the peep
holer?
History
Date User Action Args
2009-08-23 21:42:05mastrodomenicosetnosy: + mastrodomenico
2009-02-03 01:56:05benjamin.petersonsetmessages: + msg81023
2009-02-02 23:48:25amaury.forgeotdarcsetstatus: closed -> open
files: + return_outside_func.patch
messages: + msg81019
assignee: amaury.forgeotdarc
keywords: + needs review, patch
resolution: fixed ->
2009-02-02 17:11:58arigosetmessages: + msg80961
2009-02-02 17:00:52amaury.forgeotdarcsetstatus: open -> closed
nosy: + amaury.forgeotdarc, benjamin.peterson
resolution: fixed
messages: + msg80955
2008-01-24 16:24:25mark.dickinsonsetnosy: + mark.dickinson
messages: + msg61638
2008-01-19 18:59:32fijalsetnosy: + fijal, cfbolz
2008-01-19 18:55:49arigocreate