Albert
Albert

Reputation: 68260

Python: why is `return` not allowed in a module

If you look at the Python bytecode compiled from modules, you'll see at the end:

10 LOAD_CONST               0 (None)
13 RETURN_VALUE        

I.e. a return is perfectly valid at the root level of a module. However, if you try to use it in the source code, you get:

SyntaxError: 'return' outside function

Why?


This is of course a language design decision. But why was it taken? A return is often quite useful in a module. E.g. I sometimes want to write this code at the beginning of a module:

import sys
if sys.platform != "linux2":
    print "your platform is not yet supported"
    # define some stubs
    def foo(): pass
    def bar(): pass
    return

And I don't want to raise an exception there (because that would result in the module not loading which I don't want).


Actually, I hacked some code together which can manipulate the Python bytecode on the fly and just do the return (or in my case jump to the end where the return is done). This works. The only reason it is CPython only is because there is no standard way to manipulate a code object.

Here is the code.


For possible answers: I would prefer real evidence, some past statements from Guido van Rossum or so about this, not so much just any random discussion. I of course can this of both advantages (as presented already) and disadvantages myself but I don't really see the big reason against it.

Upvotes: 28

Views: 6096

Answers (2)

Matthias Fripp
Matthias Fripp

Reputation: 18635

This isn't a "why" (I suspect the answer to that is just "return belongs in a function and there's no compelling reason to put it in top-level module code"). But it's a tidy workaround that you may not know about. Your code can be refactored as follows without adding much complexity:

import sys

def main():
    global foo, bar
    if sys.platform != "linux2":
        print "your platform is not yet supported"
        # define some stubs
        def foo(): pass
        def bar(): pass
        return

main()

Upvotes: 0

mgilson
mgilson

Reputation: 310097

I would guess that this is a decision on the part of the python devs because it forces the user of the module to deal with the fact that their system isn't supported (rather than getting the developers of the module to guess what should happen). Imagine their surprise when they run the code on a windows machine and all of a sudden module.foo() doesn't work as they expected. (Your warning print statement could be completely buried in all sorts of other garbage that might get dumped to stdout).

I think that the most idomatic way to handle this is to raise an ImportError or NotImplementedError. Then the user can decide if they can live without this module and proceed, (by catching the exceptions), or if their program should crash and burn right there.

Upvotes: 7

Related Questions