43

I have a large piece of Python 2 only code. It want to check for Python 3 at the beginning, and exit if python3 is used. So I tried:

import sys

if sys.version_info >= (3,0):
    print("Sorry, requires Python 2.x, not Python 3.x")
    sys.exit(1)

print "Here comes a lot of pure Python 2.x stuff ..."
### a lot of python2 code, not just print statements follows

However, the exit does not happen. The output is:

$ python3 testing.py 
  File "testing.py", line 8
        print "Here comes a lot of pure Python 2.x stuff ..."
                                                        ^
SyntaxError: invalid syntax

So, it looks like python checks the whole code before executing anything, and hence the error.

Is there a nice way for python2 code to check for python3 being used, and if so print something friendly and then exit?

1 Answer 1

73

Python will byte-compile your source file before starting to execute it. The whole file must at least parse correctly, otherwise you will get a SyntaxError.

The easiest solution for your problem is to write a small wrapper that parses as both, Python 2.x and 3.x. Example:

import sys
if sys.version_info >= (3, 0):
    sys.stdout.write("Sorry, requires Python 2.x, not Python 3.x\n")
    sys.exit(1)

import the_real_thing
if __name__ == "__main__":
    the_real_thing.main()

The statement import the_real_thing will only be executed after the if statement, so the code in this module is not required to parse as Python 3.x code.

Sign up to request clarification or add additional context in comments.

8 Comments

Wouldn't it be considered more Pythonic to use EAFP and just put the import of the_real_thing inside a try block?
@martineau: I wouldn't do this in the case at hand. The import might very well succeed, and other errors could happen in main(). You don't want to enclose the_real_thing.main() in try/except.
@inspectorG4dget: I don't really get your comment, but I added if __name__ == "__main__": for completeness.
@inspectorG4dget: Those blocks are only executed first if they are at the beginning of the file. Probably I'm dull, but I really don't get it!
@inspectorG4dget: Before Python starts executing a module, the whole file is byte-compiled. This includes parsing the whole file. Adding if __name__ == "foo" doesn't change anything about this.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.