Search code examples
pythonprogramming-languagesdistribution

Installing Python Script, Maintaining Reference to Python 2.6


I am trying to distribute my Python program. The program relies on version 2.6. I went through the distribution documentation: http://docs.python.org/distutils/index.html and what I have figured out so far is that I basically need to write a setup.py script. Something like:

setup(name='Distutils',
  version='1.0',
  description='Python Distribution Utilities',
  author='My Name',
  author_email='My Email',
  url='some URL',
  package_dir={'': 'src'},
  packages=[''],
 )

I would like to ensure that my program uses 2.6 interpreter library when user install it on their box. What would be the best approach to ensure that my program uses 2.6 ? Shall I distribute python 2.6 library along with my program ? Is there any alternative approach ?


Solution

  • One option is to specify the specific version of the Python interpreter using the hash bang:

    #! /usr/bin/env python2.6
    

    Another option is to check sys.version_info, for example:

    if (sys.version_info[0] != 2) or (sys.version_info[1]<6):
        if sys.version_info[0] > 2:
            print("Version 2.6+, and not 3.0+ needed.")
            sys.exit(1)
        else:
            print "Version 2.6+, needed. Please upgrade Python."
            sys.exit(1)
    

    The hash bang is probably the best option, as it actually ensures that the script will be interpreted by "python2.6" instead of some other interpreter; however, there are some disadvantages:

    • This will only work on UNIX-like systems that use the hash bang.
    • This will won't work if Python2.7 is installed, but not Python 2.6.

    As a workaround, what you can do is create a "launcher" Python script that checks for "python2.6"... "python2.9", which is the last possible version of the 2.6+ line before Python 3.0+. This launcher script can then invoke your main program using whichever python interpreter it finds in the search process. You will have to make your launcher script in a way that uses elements common to most Python versions.

    Borrowing from test if executable exists in Python:

    def which(program):
        import os
        def is_exe(fpath):
            return os.path.exists(fpath) and os.access(fpath, os.X_OK)
    
        fpath, fname = os.path.split(program)
        if fpath:
            if is_exe(program):
                return program
        else:
            for path in os.environ["PATH"].split(os.pathsep):
                exe_file = os.path.join(path, program)
                if is_exe(exe_file):
                    return exe_file
    
        return None
    
    def first_which(progs):
        for prog in progs:
            progloc = which(prog)
            if progloc != None:
                return progloc
        return None
    
    def main():
        interpreter=first_which(["python2.6","python2.7","python2.8","python2.9"])
        # Invoke your program using "interpreter"
        # You will need to use os.popen or subprocess,
        # depending on the version of Python which which
        # this launcher script was invoked...
    

    My own opinion is that the method above is more complicated than necessary, and I would just go with the hash bang... or I would write out the hash bang to the Python file at deployment time, using a language other than Python (for which the version wouldn't be an issue... otherwise, it becomes a recursive problem).

    I would also strongly urge you NOT to include a copy of Python in your software distribution. This will make your download much larger, and it will annoy users who already have a valid installation of Python available. Instead, you should simply direct users to download and install the appropriate version if it isn't available.