Files
nixpkgs/pkgs/development/interpreters/python/build-python-package.nix
T

127 lines
3.5 KiB
Nix
Raw Normal View History

2009-05-24 21:02:59 +00:00
/* This function provides a generic Python package builder. It is
intended to work with packages that use `distutils/setuptools'
2009-05-24 21:02:59 +00:00
(http://pypi.python.org/pypi/setuptools/), which represents a large
number of Python packages nowadays. */
{ lib
, python
, mkPythonDerivation
, bootstrapped-pip
}:
2009-05-24 21:02:59 +00:00
{ buildInputs ? []
# propagate build dependencies so in case we have A -> B -> C,
# C can import package A propagated by B
#, propagatedBuildInputs ? []
2012-12-03 05:20:50 +01:00
2015-11-26 17:31:10 +01:00
# passed to "python setup.py build_ext"
# https://github.com/pypa/pip/issues/881
, setupPyBuildFlags ? []
# Execute before shell hook
, preShellHook ? ""
# Execute after shell hook
, postShellHook ? ""
2016-02-16 17:45:15 +03:00
# Additional flags to pass to "pip install".
, installFlags ? []
2016-04-26 17:57:13 +02:00
, format ? "setup"
, ... } @ attrs:
2009-05-24 21:02:59 +00:00
let
2015-11-26 17:31:10 +01:00
# use setuptools shim (so that setuptools is imported before distutils)
# pip does the same thing: https://github.com/pypa/pip/pull/3265
setuppy = ./run_setup.py;
2016-04-26 17:57:13 +02:00
formatspecific =
if format == "wheel" then
{
unpackPhase = ''
mkdir dist
cp $src dist/"''${src#*-}"
'';
# Wheels are pre-compiled
buildPhase = attrs.buildPhase or ":";
installCheckPhase = attrs.checkPhase or ":";
# Wheels don't have any checks to run
doCheck = attrs.doCheck or false;
2016-04-26 17:57:13 +02:00
}
else if format == "setup" then
{
# we copy nix_run_setup.py over so it's executed relative to the root of the source
# many project make that assumption
buildPhase = attrs.buildPhase or ''
runHook preBuild
cp ${setuppy} nix_run_setup.py
${python.interpreter} nix_run_setup.py ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
runHook postBuild
'';
installCheckPhase = attrs.checkPhase or ''
runHook preCheck
${python.interpreter} nix_run_setup.py test
runHook postCheck
'';
2016-05-09 18:33:43 +02:00
# Python packages that are installed with setuptools
# are typically distributed with tests.
# With Python it's a common idiom to run the tests
# after the software has been installed.
doCheck = attrs.doCheck or true;
2016-04-26 17:57:13 +02:00
}
else
throw "Unsupported format ${format}";
2009-05-24 21:02:59 +00:00
in mkPythonDerivation ( attrs // {
2009-05-24 21:02:59 +00:00
# To build and install a wheel we need pip
buildInputs = buildInputs ++ [ bootstrapped-pip ];
#inherit propagatedBuildInputs;
2015-11-27 11:44:34 +01:00
configurePhase = attrs.configurePhase or ''
runHook preConfigure
# patch python interpreter to write null timestamps when compiling python files
# this way python doesn't try to update them when we freeze timestamps in nix store
export DETERMINISTIC_BUILD=1
runHook postConfigure
'';
2009-05-24 21:02:59 +00:00
installPhase = attrs.installPhase or ''
runHook preInstall
mkdir -p "$out/${python.sitePackages}"
export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
2009-05-24 21:02:59 +00:00
pushd dist
2016-02-16 17:45:15 +03:00
${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache ${toString installFlags}
popd
runHook postInstall
2009-05-24 21:02:59 +00:00
'';
shellHook = attrs.shellHook or ''
2015-11-15 13:49:20 +01:00
${preShellHook}
2014-06-15 16:05:09 +02:00
if test -e setup.py; then
2015-11-15 13:49:20 +01:00
tmp_path=$(mktemp -d)
export PATH="$tmp_path/bin:$PATH"
2015-11-15 13:49:20 +01:00
export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
2015-11-23 17:47:35 +01:00
mkdir -p $tmp_path/${python.sitePackages}
${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path
2014-06-15 16:05:09 +02:00
fi
2015-11-15 13:49:20 +01:00
${postShellHook}
'';
2016-04-26 17:57:13 +02:00
} // formatspecific)