Search code examples
pythonwindowspython-2.7versioningsoftware-distribution

Use setuptools to create an executable distribution of a package with --multi-version?


I'm trying to create simple Windows executable installers for a Python package that will only be delivered internally to other developers on my team. I'd like to let them install multiple versions of the package at the same time and specify which to run by using different commands: <package>-0.1,<package>-0.2, etc.

It looks like setuptools offers a fairly standard way to install multiple versions of a package: just create an egg for each version of the package, then install each egg using the --multi-version option with easy_install.

However, rather than providing the eggs and asking developers to use easy_install via the command-line, I'd like to just offer something they can run that will automatically perform the installation. python setup.py bdist_wininst does almost exactly what I want, but as far as I can tell, there's no way to create a bdist_wininst that uses the --multi-version option (or does anything similar).

Is there a way to accomplish this? I realize I could just manually write an executable program to call easy_install --multi-version, but that seems like a ridiculous workaround for something that I'd hope is achievable just using the built-in capabilities of setuptools.


Tangentially, is there an easy way to have the installer automatically create <package>-<version>.bat files for each installed version of the package?


Solution

  • The setup.py script for the SCons project implements this feature using vanilla distutils, and the method is also usable with setuptools. At the time of writing, the current version of setup.py is here. The trick is the use of the cmdclass argument to replace install_lib with a modified class that inherits from the default install_lib class used by distutils.

    A pared-down version of the same trick, using setuptools (note that this is done by simply replacing all instances of distutils with setuptools):

    import setuptools.command.install_lib
    _install_lib = setuptools.command.install_lib.install_lib
    class install_lib(_install_lib):
        def finalize_options(self):
            _install_lib.finalize_options(self)
            self.install_dir = join(self.install_dir,'PKG_NAME-'+PKGVERSION)