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.
Setuptools is a package development process library designed to facilitate packaging Python projects by enhancing the Python standard library distutils (distribution utilities). It includes: Python package and module definitions. Distribution package metadata.
Follow the below steps to install the Setuptools package on Linux using the setup.py file: Step 1: Download the latest source package of Setuptools for Python3 from the website. Step 3: Go to the setuptools-60.5. 0 folder and enter the following command to install the package.
The distutils package provides support for building and installing additional modules into a Python installation. The new modules may be either 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C.
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.
I think the easiest way to perform the post-install, and keep the requirements, is to decorate the call to setup(...)
:
from setup tools import setup def _post_install(setup): def _post_actions(): do_things() _post_actions() return setup setup = _post_install( setup( name='NAME', install_requires=['... ) )
This will run setup()
when declaring setup
. Once done with the requirements installation, it will run the _post_install()
function, which will run the inner function _post_actions()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With