10

I have a script that should only be run with Python 3. I want to give a nice error message saying that this script should not be run with python2 if a user tries to run it with Python 2.x

How do I do this? When I try checking the Python version, it still throws an error, as Python parses the whole file before executing my if condition.

If possible, I'd rather not make another script.

6
  • 3
    If it's a SyntaxError, you can't avoid it; as you say, the error comes before any code you've written runs. You have to write code that is syntactically valid in both versions. Commented Jul 6, 2015 at 8:24
  • You need to first fix your syntax error, then worry about version checking. Commented Jul 6, 2015 at 8:28
  • There are some interesting ideas in How can I check for Python version in a program that uses new language features? Commented Jul 6, 2015 at 8:29
  • 2
    @BurhanKhalid: The script uses Python 3 features that are illegal in Python 2, so the syntax errors are only syntax errors to the Python 2 interpreter. Someone writing in Python 3 shouldn't be obliged to write code that is also legal in Python 2. Commented Jul 6, 2015 at 8:31
  • 1
    @PM2Ring they should if they want it to run in 2.x! Even though it's only to customise the error message... Commented Jul 6, 2015 at 8:33

5 Answers 5

14

You can write a wrapper start-script in which you only import your actual script and catch for syntax errors:

try:
    import real_module
except SyntaxError:
    print('You need to run this with Python 3')

Then, when real_module.py uses Python 3 syntax that would throw an exception when used with Python 3, the above message is printed out instead.

Of course, instead of just importing the script, you could also first check the version, and then import it when the version is 3. This has the benefit that you will still see syntax errors of your actual script even when you run it with Python 3:

import sys
if sys.version_info[0] < 3:
    print('You need to run this with Python 3')
    sys.exit(1)

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

3 Comments

Was hoping for a method without making another script. Isnt it possible to do it with 1 script ?
No, as others said in the comments, the whole script is parsed before the interpreter runs any code. So a syntax error would throw before any code you could possibly add there will run.
@AJK this is your only option, for all of the reasons that have already been explained to you.
2

None of these properly work as, as others have mentioned SyntaxErrors are parsed first, also doing except SyntaxError does not work either.

The best solution is a wrapper module, but if due to other technical or political reasons you cannot create another module in your code you can do the following very dirty trick:

z, *y=1,2,3,4 #This script requires requires python 3! A Syntax error here means you are running it in python2!

The result in python2.7 will be:

  File "notpython2.py", line 3
    z, *y=1,2,3,4 #This script requires requires python 3! A Syntax error here means you are running it in python2!
       ^
SyntaxError: invalid syntax

Yes the code is ugly, but if anyone can think of a better solution notwithstanding a new module please add it here.

3 Comments

Thank you for this idea. Just today I got a report about an error with my script and it took me too long to figure out that Python 2 was the reason. I really didn't want to have to distribute 2 files to handle this, and this solution would make it so an error report would hit me over the head with the answer (heck , many users might figure it out for themselves). I used a slightly more in-your-face version: Python_2_is_running, *Python_3_is_needed=["py3", "needed"] # this script needs to be run with python 3
Probably not the place for this comment, but I think the python devs should make one more rev to python2 so that it looks for a shebang and if it's #!python3 or some reasonable variant then the interpreter can give a nice error message. It's hard for me to understand why that wasn't done long ago.
@MichaelBurr A good Idea, although from what I have seen, a lot of python scripts seem to not have a shebang, it seems to be an unofficial convention. On the point of a final python2 update, most environments could still be running python2 because they will not / cannot update their python interpreter in the first place, so it may make no difference at all.
1

Try this:

import sys
#sys.version gives you version number in this format
#(2, 5, 2, 'final', 0)
version=sys.version_info[0]

if version == 2:
   sys.exit("This script shouldn't be run by python 2 ")

1 Comment

Again, syntax errors may get thrown before this script is run.
1
import sys
if (sys.version_info > (2, 0)):
   raise Exception('script should not be run with python2.x')

This will raise error if script is running under 2.x python version

3 Comments

Again, if there is a syntax error it won't get this far.
Above line must the 1st line of script. When code execute it will check the python version at the beginning.
It doesn't matter where in the script it is, Python will not start running the file if there is an actual SyntaxError in the code.
0

You can use the fact that in Python 2 strings are byte strings, while in Python 3 they are unicode strings. So any of

if ' ' == b' ':
    raise Exception ('Running this script with Python 2 is not supported')

or

if isinstance (b' ', str):
    raise Exception ('Running this script with Python 2 is not supported')

will do. Note that this does not need any imports - just language features.

Comments

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.