How to Check for Python Version in a Program That Uses New Language Features

How can I check for Python version in a program that uses new language features?

You can test using eval:

try:
eval("1 if True else 2")
except SyntaxError:
# doesn't have ternary

Also, with is available in Python 2.5, just add from __future__ import with_statement.

EDIT: to get control early enough, you could split it into different .py files and check compatibility in the main file before importing (e.g. in __init__.py in a package):

# __init__.py

# Check compatibility
try:
eval("1 if True else 2")
except SyntaxError:
raise ImportError("requires ternary support")

# import from another module
from impl import *

How do I detect the Python version at runtime?

Sure, take a look at sys.version and sys.version_info.

For example, to check that you are running Python 3.x, use

import sys
if sys.version_info[0] < 3:
raise Exception("Must be using Python 3")

Here, sys.version_info[0] is the major version number. sys.version_info[1] would give you the minor version number.

In Python 2.7 and later, the components of sys.version_info can also be accessed by name, so the major version number is sys.version_info.major.

See also How can I check for Python version in a program that uses new language features?

How do I check which version of Python is running my script?

This information is available in the sys.version string in the sys module:

>>> import sys

Human readable:

>>> print(sys.version)  # parentheses necessary in python 3.       
2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)]

For further processing, use sys.version_info or sys.hexversion:

>>> sys.version_info
(2, 5, 2, 'final', 0)
# or
>>> sys.hexversion
34014192

To ensure a script runs with a minimal version requirement of the Python interpreter add this to your code:

assert sys.version_info >= (2, 5)

This compares major and minor version information. Add micro (=0, 1, etc) and even releaselevel (='alpha','final', etc) to the tuple as you like. Note however, that it is almost always better to "duck" check if a certain feature is there, and if not, workaround (or bail out). Sometimes features go away in newer releases, being replaced by others.

Check if python version is compatible with script before executing

sys.version_info[0] is the major version only. So, it'll be 2 for all python 2.x versions. You're looking for sys.version_info[1], with the minor version:

# check for python 2
if sys.version_info[0] != 2:
raise Exception("Please use Python 2")
# check for 2.7+
if sys.version_info[1] < 7:
raise Exception("Please use Python 2.7+")

Alternatively, for more descriptive naming, you can use sys.version_info.major instead of sys.version_info[0] and sys.version_info.minor instead of sys.version_info[1].

Also, make sure you add this near the top of your script so there are no incompatibilities before the line is hit and the exception is raised.

If your code uses incompatible syntax, then you should put the non-version checking code in a main function in a separate file, then import that after the check so that Python doesn't try to parse it.

Checking Version of Python Interpreter Upon Execution of Script With Invalid Syntax

Create a wrapper script that checks the version and calls your real script -- this gives you a chance to check the version before the interpreter tries to syntax-check the real script.

Python 3: checking version before syntactic analysis

Move code using print() as a function to a separate module and make the main script do the testing only.

It doesn't matter where in the module the print() function call is made, it is a syntax error because you are not using print as a statement. You'd put that in a separate module imported after your test.

try:
eval("print('', end='')")
except SyntaxError:
raise Exception("python 3 needed")

import real_script_using_print_function

However, in Python 2 you can also add:

from __future__ import print_function

at the top to make print() work in Python 2 as well. It is perfectly feasible to write Python code that runs on both Python 2 and 3 if taken care.

How to determine python version in Makefile?

python_version_full := $(wordlist 2,4,$(subst ., ,$(shell python --version 2>&1)))
python_version_major := $(word 1,${python_version_full})
python_version_minor := $(word 2,${python_version_full})
python_version_patch := $(word 3,${python_version_full})

my_cmd.python.2 := python2 some_script.py2
my_cmd.python.3 := python3 some_script.py3
my_cmd := ${my_cmd.python.${python_version_major}}

all :
@echo ${python_version_full}
@echo ${python_version_major}
@echo ${python_version_minor}
@echo ${python_version_patch}
@echo ${my_cmd}

.PHONY : all

how to know which python version I have and how to switch between them and how to know which version has PyObjC

Where have you installed these different versions?

10.7 comes with python 2.5, 2.6, 2.7. I personally use fink, but there is also macports and others for installing libraries. If you want to switch between different versions of python then (unless I'm missing something) you have to call that different python. So you could use /usr/bin/python2.5 or /usr/bin/python2.6 or /usr/bin/python2.7.

I did a quick google search and when I open one of the built-in pythons and run import PyObjCTools that seems to work (and not work in my fink python which is expected). If you have custom installed python environments and you want PyObjC I was suggest reading the manual or rather RTFM. A quick skim looks like you can just do easy_install PyObjC.

Edit to answer your comment:

To add PyObjC to your 2.7.3 you should just have to install it: http://pythonhosted.org/pyobjc/install.html

It doesn't look too complicated, but I've never done it before. Also, note the package dependencies further down the page.

For sharing python modules between python versions...this is probably not a good idea. Unless they are your modules AND pure python AND use compatible syntax between 2.5, 2.6, and 2.7, you shouldn't do this. Some installers are only for a specific version of python or may install things differently depending on what version they are being installed for. You can always install the same packages for each environment with easy_install and pip this isn't difficult at all. But if you really want to I suppose what you could do is make a shared python install directory and add it to your PYTHONPATH:

mkdir ~/my_shared_python
# Add the following line to your .bash_profile or equivalent
export PYTHONPATH=$HOME/my_shared_python:$PYTHONPATH
# You can install packages into there by doing (not sure on the pip syntax):
easy_install -d ~/my_shared_python a_package_im_installing

Then you can run any python you want and it will try to use those modules, but I don't recommend doing this.



Related Topics



Leave a reply



Submit