Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are all post-install options for python setuptools broken?

I'm trying to package a build of PyQt (installers aren't provided for the configuration I need), but I can't find any packaging configuration that works. The issue is not specific to PyQt though.

The problem: In order for the module to work, it needs a file in python's PREFIX directory. I understand that this may be bad form, but in my case there needs to be a qt.conf file there, and there isn't anything much I can do about it other than make the file available. I need to be able to run a post-install script to create the file with the installed PyQt path included. Or at least that seems like the best solution.

Options I looked at:

  • I can use python setup.py install and override the setuptools.command.install class. However, this works when setup.py is run manually, and requires unzipping the bdist and having a cmd prompt in the package folder. It doesn't work for bdist_wininst, bdist_msi, or bdist_wheel, which are much more convenient to install (the point of packaging). So possible, but not a great solution.

  • bdist_wheel seems like a good option, but it won't run anything post-install, and only puts files in specific folders, not including PREFIX.

  • bdist_wininst supports a post-install script (via --install-script switch when creating the package), but doesn't play nice with virtualenv. There is a stackoverflow answer that suggests running easy_install or wheel convert, but those options only unpack, they won't run the install script. Otherwise you have to change the registry, which is not an acceptable solution.

What am I missing? Is there a viable option?

like image 665
Brett Stottlemyer Avatar asked Feb 01 '14 13:02

Brett Stottlemyer


1 Answers

As kynan explains, to gain control one must define "class install" to override run().

EDIT

To quote the code he supplied:

import os, sys
from distutils.core import setup
from distutils.command.install import install as _install


def _post_install(dir):
    from subprocess import call
    call([sys.executable, 'scriptname.py'],
         cwd=os.path.join(dir, 'packagename'))


class install(_install):
    def run(self):
        _install.run(self)
        self.execute(_post_install, (self.install_lib,),
                     msg="Running post install task")


setup(
    ...
    cmdclass={'install': install},
)
like image 124
J_H Avatar answered Oct 25 '22 15:10

J_H