Execute a Python script post install using distutils / setuptools
The way to address these deficiences is:
- Get the full path to the Python interpreter executing
setup.py
fromsys.executable
. Classes inheriting from
distutils.cmd.Command
(such asdistutils.command.install.install
which we use here) implement theexecute
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
Python Pandas - Find Difference Between Two Data Frames
What Does the 'U' Symbol Mean in Front of String Values
Fast Haversine Approximation (Python/Pandas)
How to Bind Self Events in Tkinter Text Widget After It Will Binded by Text Widget
How to Get Variable Data from a Class
Nested Arguments Not Compiling
How to Lowercase a String in Python
How to Install Python3 Version of Package via Pip on Ubuntu
How to Calculate the Date Six Months from the Current Date Using the Datetime Python Module
How to Use Python to Login to a Webpage and Retrieve Cookies for Later Usage
What Are "First-Class" Objects
How to Filter Query Objects by Date Range in Django
Install a Module Using Pip for Specific Python Version
How to Use Xpath with Beautifulsoup
How to Add a Constant Column in a Spark Dataframe