jfa
jfa

Reputation: 1101

Is there a way to prevent a python 3 script from being called in python 2?

I have to turn in an assignment, and I'm extremely concerned that, since the single TA has many projects to run, it will be called using python, which will call python 2.7, when the program is written for python3.2 and should be called that way. This would result in a syntax error, and I would loose points. I know when working on side projects, this happens a lot, and if the TA encountered this I don't think he would follow up.

I'm going to submit a readme, but I was wondering if there was a way to catch this in my code without a lot of fuss, and print a statement that said to rerun the project as python3.2 project.py. I could to a try: print "Rerun project…" except:pass, but is there a better way?

Upvotes: 12

Views: 3150

Answers (4)

gmatht
gmatht

Reputation: 835

Ten years later, this old chestnut still bites. In my case, the python2 interpreter itself stopped the script from running due to a SyntaxError at line 434. Alas, the Error wasn't very informative, and because the script never ran at all, platform.python_version() never ran either. Hence platform tests were no help

Since I didn't want the file to run in python2 anyway, I just added a comment to the line in question, so the SyntaxError looks like:

$ python2 alarm_clock.py
  File "alarm_clock.py", line 434
    txt=f"The time is %M minutes past %{AUDIO_H} o'clock" # <- YOU NEED PYTHON3.6+ IF YOU ARE SEEING THIS IN AN ERROR.
                                                        ^
SyntaxError: invalid syntax

On wjandrea's advice I instead put the following line near the top of my code:

f'' # YOU NEED PYTHON 3.6+. TRY: python3 alarm_clock.py

This had three advantages:

  1. Pylint doesn't complain about a too long line
  2. Less distractions in the error message.
  3. Less likely to disappear due to having another python3-ism added above the comment.

Upvotes: 0

dawg
dawg

Reputation: 103834

This is actually a harder problem to implement well that you might at first think.

Suppose you have the following code:

import platform
import sys

if platform.python_version().startswith('2'):
    # This NEVER will be executed no matter the version of Python
    # because of the two syntax errors below...
    sys.stdout.write("You're using python 2.x! Python 3.2+ required!!!")
    sys.exit()     
else:
    # big program or def main(): and calling main() .. whatever
    # later in that file/module:
    x, *y=(1,2,3)      # syntax error on Python 2...
    # or
    print 'test'       # syntax error on Python 3...

One of the two syntax errors under the else clause is generated BEFORE the if is actually executed no matter the version of Python used to run it. Therefore, the program will not gracefully exit as you might expect; it will fail with a syntax error no matter what.

The workaround is to put your actual program in an external file/module and wrap in a try/except this way:

try:
    import Py3program    # make sure it has syntax guaranteed to fail on 
                         # Python 2 like    x, *y=1,2,3
except SyntaxError:
    sys.stdout.write(error message)
    sys.exit()

# rest of the Python 3 program...

If your TA will execute the file with a shebang, that would be a better approach still. Perhaps ask the TA how he will run your script?

Upvotes: 5

Zubo
Zubo

Reputation: 1593

How about starting the program like so:

#!/usr/bin/env python
# -*- coding: utf8 -*-

import sys

if sys.version_info < (3,0,0):
    print(__file__ + ' requires Python 3, while Python ' + str(sys.version[0] + ' was detected. Terminating. '))
    sys.exit(1)

Upvotes: 7

Simeon Visser
Simeon Visser

Reputation: 122376

You can do:

import sys
print(sys.version_info)

As of Python 2.7 you can also use:

print(sys.version_info.major, sys.version_info.minor, sys.version_info.micro)

You can use the value of sys.version_info to print a warning when the Python version currently running isn't as desired.

You can also use:

import platform
print(platform.python_version())

Upvotes: 12

Related Questions