I'm trying to add a post-install task to Python distutils as described in How to extend distutils with a simple post install script?. The task is supposed to execute a Python script in the installed lib directory. This script generates additional Python modules the installed package requires.
My first attempt is as follows:
from distutils.core import setup
from distutils.command.install import install
class post_install(install):
def run(self):
install.run(self)
from subprocess import call
call(['python', 'scriptname.py'],
cwd=self.install_lib + 'packagename')
setup(
...
cmdclass={'install': post_install},
)
This approach works, but as far as I can tell has two deficiencies:
PATH
, the post install script will be executed with a different interpreter which might cause a problem.distutils.cmd.Command.execute
.How could I improve my solution? Is there a recommended way / best practice for doing this? I'd like to avoid pulling in another dependency if possible.
The way to address these deficiences is:
setup.py
from sys.executable
.Classes inheriting from distutils.cmd.Command
(such as distutils.command.install.install
which we use here) implement the execute
method, which executes a given function in a "safe way" i.e. respecting the dry-run flag.
Note however that the --dry-run
option is currently broken and does not work as intended anyway.
I ended up with the following solution:
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},
)
Note that I use the class name install
for my derived class because that is what python setup.py --help-commands
will use.