Post-Install Script with Python Setuptools

Execute a Python script post install using distutils / setuptools

The way to address these deficiences is:

  1. Get the full path to the Python interpreter executing setup.py from sys.executable.
  2. 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.

setuptools post-install: get all packages installed to check versions

I'm not sure if going down this path is best practice, but if you really wanted to you could just run a pip freeze after installation, parse the outputs into an array of sets/dicts and do a Set.difference() across the array items.

subpackage_deps = [
{"foo=1.1.0", "bar=1.0.0"},
{"foo=1.1.0", "baz=2.0.1"}
]

subpackage_deps[0] - sub package_deps[1]

I, however, don't see the purpose in doing this. Why not let setup tools do its job? If you are concerned about consistency between projects, why not write an automated test and enforce it using continuous integration to ensure parity of dependency versions between sub-projects (ie: by comparing dependency versions accross setup.py)?

References

https://docs.python.org/3/tutorial/datastructures.html#sets

Post install script after installing a wheel

PEP 427 which specifies the wheel package format does not leave any provisions for custom pre or post installation scripts.

Therefore running a custom script is not possible during wheel package installation.

You'll have to add the custom script to a place in your package where you expect the developer to execute first.

Execute post installation task with pip

pip doesn't run setup.py from a wheel hence you cannot run any post-installation code from setup.py in a wheel.

setup.py is used to build wheels or used during installation of source distribution (sdist). So if you want post-installation script stop uploading wheels to PyPI, only release source distribution (python3 setup.py sdist). Then pip install funmotd will run code from setup.py.

Installing scripts in setup.py as part of a Python package, on user's path and recognized as Python scripts

To tell your shell what program should be used to execute a script file, you need to add a "hash-bang" declaration as the first line in the script. For Python executing inside of a virtualenv, either

#!python

or

#!/usr/bin/env python

will do the trick. If you're using Python 3, use python3 instead.

Custom post install script not running with pip

Install the package directly from your GitHub repository:

pip install -vvv git+url/for/github/repo@my-branch

You mentioned in the chat that you'd like to add this package to your requirements.txt file. See this question for details:

-e git://github.com/path/to/project

Former answer (rejected by the OP):

I managed to recreate the issue you're having. It seems to be a matter of pip install silencing or redirecting output (as indicated by an answer to this question).

The solution is to add the option -vvv after pip install. I'm guessing the v stands for verbose.



Related Topics



Leave a reply



Submit