If I have a Python script that requires at least a particular version of Python, what is the correct way to fail gracefully when an earlier version of Python is used to launch the script?
How do I get control early enough to issue an error message and exit?
For example, I have a program that uses the ternery operator (new in 2.5) and "with" blocks (new in 2.6). I wrote a simple little interpreter-version checker routine which is the first thing the script would call ... except it doesn't get that far. Instead, the script fails during python compilation, before my routines are even called. Thus the user of the script sees some very obscure synax error tracebacks - which pretty much require an expert to deduce that it is simply the case of running the wrong version of Python.
I know how to check the version of Python. The issue is that some syntax is illegal in older versions of Python. Consider this program:
import sys if sys.version_info < (2, 4): raise "must use python 2.5 or greater" else: # syntax error in 2.4, ok in 2.5 x = 1 if True else 2 print x
When run under 2.4, I want this result
$ ~/bin/python2.4 tern.py must use python 2.5 or greater
and not this result:
$ ~/bin/python2.4 tern.py File "tern.py", line 5 x = 1 if True else 2 ^ SyntaxError: invalid syntax
(Channeling for a coworker.)
You can test using
try: eval("1 if True else 2") except SyntaxError: # doesn't have ternary
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 *
Have a wrapper around your program that does the following.
import sys req_version = (2,5) cur_version = sys.version_info if cur_version >= req_version: import myApp myApp.run() else: print "Your Python interpreter is too old. Please consider upgrading."
You can also consider using
sys.version(), if you plan to encounter people who are using pre-2.0 Python interpreters, but then you have some regular expressions to do.
And there might be more elegant ways to do this.