views:

193

answers:

7

Is there a standard way to make sure a python script will be interpreted by python2 and not python3? On my distro, I can use #!/usr/bin/env python2 as the shebang, but it seems not all distros ship "python2". I could explicitly call a specific version (eg. 2.6) of python, but that would rule out people who don't have that version.

It seems to me that this is going to be increasingly a problem when distros will start putting python3 as the default python interpreter.

+9  A: 

http://docs.python.org/library/sys.html#sys.version_info

using the sys module you can determine the version of python that is running and raise an exception or exit or whatever you like.

UPDATE:

You could use this to call the appropriate interpreter. For example, set up a small script that does the checking for you, and use it in the shbang. It would check the python version running, and if not what you want, looks for one you want. Then it would run the script in that version of python (or fail if nothing good was found).

Eric Snow
See my comment to jathanism.
static_rtti
A: 

As I understand different distros will be in different locations in your drive. Here are some suggestions that come to mind -

  1. You could use UNIX alias to create shortcuts pointing to the different distros. Eg: alias py2="/usr/bin/python2.X". So when you run your script you could use py2 xx.py
  2. Or other way could be to modify your PYTHON_PATH environment variable.
  3. Or if I am not wrong there is a provision in sys module to get the current python version number. You could get that & deal appropriately.

This should do it...

MovieYoda
I'm distributing a python app, my problem is to make sure **all users** use python2.x to run my app.
static_rtti
+5  A: 

Using sys.version_info you can do a simple value test against it. For example if you only want to support version 2.6 or lower:

import sys
if sys.version_info > (2,6):
    sys.exit("Sorry, only we only support up to Python 2.6!")
jathanism
That's not what I want, I want the good interpreter to be chosen automatically, not to print an error message if the wrong one is chosen :-/
static_rtti
The definitive answer to your question is: "No, there is no standard way to make sure a python script will be interpreted by python2 and not python3." What you asked for was to make sure that Python2 was chosen over 3. You did not specify that you wanted the correct interpreter to be chosen automatically.The only way you might be able to do this for sure would be to implement a check prior to the program being called (such as with a shell script) that then runs your Python code against the desired Python interpreter.
jathanism
Expecting "the good interpreter to be chosen automatically" is absurd. A file can't force which program runs it.
Tim McNamara
A: 

I believe this will do what you want, namely test for a non-specific version of Python less than 3.x. I don't have python3 installed, so haven't tested it with that version to make sure -- instead I used from __future__ import print_function. Perhaps you or someone else can verify whether it works properly in that case, too.

try:
    py3 = True
    eval('type(print)')
except SyntaxError:
    py3 = False

 if py3:
     ...

i.e. If "print" is a built-in function rather than a statement, as it is in python3, the eval() function will not raise an exception, meaning the code is running with a python3.x interpreter.

martineau
+3  A: 

This is a bit of a messy issue during what will be a very long transition time period. Unfortunately, there is no fool-proof, cross-platform way to guarantee which Python version is being invoked, other than to have the Python script itself check once started. Many, if not most, distributions that ship Python 3 are ensuring the generic python command is aliased by default to the most recent Python 2 version while python3 is aliased to the most recent Python 3. Those distributions that don't should be encouraged to do so. But there is no guarantee that a user won't override that. I think the best practice available for the foreseeable future is to for packagers, distributors, and users to assume python refers to Python 2 and, where necessary, build a run-time check into the script.

Ned Deily
And, if necessary, as kwatford points out in his comment, include a check at install time in the package's `setup.py` script or equivalent since `setuptools`, `Distribute`, `pip` et al. generally alter scripts' shebang lines to point to the installing Python instance.
Ned Deily
+2  A: 

Not quite the same situation, but the company I work for has an app that can run Python scripts (among its many features). After numerous support issues involving Python installations on various platforms, we decided to just install our own Python interpreter with the app. That way we know exactly where it is installed and what version it is. This approach may be too heavyweight for your needs (the Python package is only about 10% of our app's bits) but it definitely works.

kindall
This is actually a great approach that cuts out all the jiggering required for such a rigid requirement.
jathanism
+2  A: 

Depends on how you're distributing it, I guess.

If you're using a normal setup.py file to manage your distribution, have it bomb out if the user is trying to install it in Python 3.

Once it's installed, the shebang of the console script created by (say) setuptools will likely be linked to the specific interpreter used to install it.

If you're doing something weird for your installation, you can in whatever installation script you're using look for python interpreters and store a choice. You might first check whether whatever is called "python" is a 2.x. If not, check for "python2.7", "python2.6", etc to see what's available.

kwatford