nixpkgs/pkgs/development/python-modules/generic/default.nix

132 lines
3.6 KiB
Nix
Raw Normal View History

/* This function provides a generic Python package builder. It is
intended to work with packages that use `distutils/setuptools'
(http://pypi.python.org/pypi/setuptools/), which represents a large
number of Python packages nowadays. */
{ python, setuptools, unzip, wrapPython, lib, bootstrapped-pip }:
{ name
# by default prefix `name` e.g. "python3.3-${name}"
, namePrefix ? python.libPrefix + "-"
, buildInputs ? []
# propagate build dependencies so in case we have A -> B -> C,
# C can import propagated packages by A
, propagatedBuildInputs ? []
# passed to "python setup.py build"
# https://github.com/pypa/pip/issues/881
, setupPyBuildFlags ? []
# enable tests by default
, doCheck ? true
# DEPRECATED: use propagatedBuildInputs
, pythonPath ? []
# used to disable derivation, useful for specific python versions
, disabled ? false
2014-01-10 21:57:28 +01:00
, meta ? {}
# Execute before shell hook
, preShellHook ? ""
# Execute after shell hook
, postShellHook ? ""
# Additional arguments to pass to the makeWrapper function, which wraps
# generated binaries.
, makeWrapperArgs ? []
, ... } @ attrs:
# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
if disabled
then throw "${name} not supported for interpreter ${python.executable}"
else
let
setuppy = ./run_setup.py;
in
python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
name = namePrefix + name;
buildInputs = [ wrapPython bootstrapped-pip ] ++ buildInputs ++ pythonPath
++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip);
# propagate python/setuptools to active setup-hook in nix-shell
propagatedBuildInputs = propagatedBuildInputs ++ [ python setuptools ];
pythonPath = pythonPath;
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
'';
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
'';
installPhase = attrs.installPhase or ''
runHook preInstall
mkdir -p "$out/${python.sitePackages}"
export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
pushd dist
${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache
popd
runHook postInstall
'';
doInstallCheck = doCheck;
doCheck = false;
installCheckPhase = attrs.checkPhase or ''
runHook preCheck
${python.interpreter} nix_run_setup.py test
runHook postCheck
'';
postFixup = attrs.postFixup or ''
wrapPythonPrograms
# check if we have two packagegs with the same name in closure and fail
# this shouldn't happen, something went wrong with dependencies specs
${python.interpreter} ${./catch_conflicts.py}
'';
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"
${python.interpreter} setup.py develop --prefix $tmp_path
2014-06-15 16:05:09 +02:00
fi
2015-11-15 13:49:20 +01:00
${postShellHook}
'';
2014-01-22 10:15:26 +01:00
meta = with lib.maintainers; {
# default to python's platforms
platforms = python.meta.platforms;
2014-01-22 10:15:26 +01:00
} // meta // {
# add extra maintainer(s) to every package
maintainers = (meta.maintainers or []) ++ [ chaoflow iElectric ];
};
})