Sometimes I want to install a Python dependency into my working environment just to try out something quickly, and decide afterwards if I want to keep it or not. This is a case where a good old run of pip install would do just fine.
Installing inside of nix-shell
When using nix-shell for Python development, it will create a temporary directory to do a develop install of the Python package under development. In the current implementation it will create a different directory per running nix-shell.
This makes up a nice base to be exploited for a quick run of pip install to make something available for an experiment. The key to make it work is to use the parameter --install-option, so that the package will be installed into the desired prefix:
pip install --install-option="--prefix=$tmp_path" my-dependency
How it works
As mentioned already, nix-shell prepares a temporary directory already for us and sets up things like the environment variable PYTHONPATH, so that the Python interpreter can find packages in there. It also sets up an environment variable tmp_path which points to that directory.
pip install will call at some point setup.py install to set up the Python package. The parameter --install-option allows to pass options down to this call. Note that I used intentionally double quotes, so that $tmp_path will be replaced by the shell.
Using setup.py directly
If the package to be installed is already available locally, setup.py can be called directly as follows to achieve the same result:
python setup.py install --prefix=$tmp_install
Comparison to virtualenv
In a virtualenv based setup I would just go and run pip install to make a package available. At the first glance, this appears to be even a bit easier.
There is one subtle difference though: An environment based on virtualenv is more like a persistent environment, the new package will stay in there and I have to remember to clean up at some point. Without cleaning up I would end up with an environment where I might use dependencies by accident without noticing.
In the case of nix-shell I will end up with a new fresh and empty temporary directory after each invocation of nix-shell. Due to that fact, "abusing" the temporary directory for quick ad-hoc experiments works so well.