Merge pull request #20894 from FRidh/buildpythonpackage_flit
Python: rewrite buildPythonPackage, support `flit` format
This commit is contained in:
commit
94f92dfb56
8 changed files with 228 additions and 110 deletions
|
@ -523,7 +523,7 @@ All parameters from `mkDerivation` function are still supported.
|
|||
* `postShellHook`: Hook to execute commands after `shellHook`.
|
||||
* `makeWrapperArgs`: A list of strings. Arguments to be passed to `makeWrapper`, which wraps generated binaries. By default, the arguments to `makeWrapper` set `PATH` and `PYTHONPATH` environment variables before calling the binary. Additional arguments here can allow a developer to set environment variables which will be available when the binary is run. For example, `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.
|
||||
* `installFlags`: A list of strings. Arguments to be passed to `pip install`. To pass options to `python setup.py install`, use `--install-option`. E.g., `installFlags=["--install-option='--cpp_implementation'"].
|
||||
* `format`: Format of the source. Options are `setup` for when the source has a `setup.py` and `setuptools` is used to build a wheel, and `wheel` in case the source is already a binary wheel. The default value is `setup`.
|
||||
* `format`: Format of the source. Valid options are `setuptools` (default), `flit`, `wheel`, and `other`. `setuptools` is for when the source has a `setup.py` and `setuptools` is used to build a wheel, `flit`, in case `flit` should be used to build a wheel, and `wheel` in case a wheel is provided. In case you need to provide your own `buildPhase` and `installPhase` you can use `other`.
|
||||
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
||||
* `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`.
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# This function provides generic bits to install a Python wheel.
|
||||
|
||||
{ python
|
||||
, bootstrapped-pip
|
||||
}:
|
||||
|
||||
{ buildInputs ? []
|
||||
# Additional flags to pass to "pip install".
|
||||
, installFlags ? []
|
||||
, ... } @ attrs:
|
||||
|
||||
attrs // {
|
||||
buildInputs = buildInputs ++ [ bootstrapped-pip ];
|
||||
|
||||
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 ${toString installFlags}
|
||||
popd
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# This function provides specific bits for building a flit-based Python package.
|
||||
|
||||
{ flit
|
||||
}:
|
||||
|
||||
{ ... } @ attrs:
|
||||
|
||||
attrs // {
|
||||
buildInputs = [ flit ];
|
||||
buildPhase = attrs.buildPhase or ''
|
||||
runHook preBuild
|
||||
flit wheel
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# Flit packages do not come with tests.
|
||||
installCheckPhase = attrs.checkPhase or ":";
|
||||
doCheck = attrs.doCheck or false;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
# This function provides specific bits for building a setuptools-based Python package.
|
||||
|
||||
{ lib
|
||||
, python
|
||||
, bootstrapped-pip
|
||||
}:
|
||||
|
||||
{
|
||||
# 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 ? ""
|
||||
, ... } @ attrs:
|
||||
|
||||
let
|
||||
# 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;
|
||||
|
||||
in attrs // {
|
||||
# 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
|
||||
'';
|
||||
|
||||
# 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;
|
||||
|
||||
shellHook = attrs.shellHook or ''
|
||||
${preShellHook}
|
||||
if test -e setup.py; then
|
||||
tmp_path=$(mktemp -d)
|
||||
export PATH="$tmp_path/bin:$PATH"
|
||||
export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
|
||||
mkdir -p $tmp_path/${python.sitePackages}
|
||||
${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path
|
||||
fi
|
||||
${postShellHook}
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# This function provides specific bits for building a wheel-based Python package.
|
||||
|
||||
{
|
||||
}:
|
||||
|
||||
{ ... } @ attrs:
|
||||
|
||||
attrs // {
|
||||
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;
|
||||
}
|
|
@ -7,120 +7,31 @@
|
|||
, python
|
||||
, mkPythonDerivation
|
||||
, bootstrapped-pip
|
||||
, flit
|
||||
}:
|
||||
|
||||
{ buildInputs ? []
|
||||
|
||||
# propagate build dependencies so in case we have A -> B -> C,
|
||||
# C can import package A propagated by B
|
||||
#, propagatedBuildInputs ? []
|
||||
|
||||
# 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 ? ""
|
||||
|
||||
# Additional flags to pass to "pip install".
|
||||
, installFlags ? []
|
||||
|
||||
, format ? "setup"
|
||||
let
|
||||
setuptools-specific = import ./build-python-package-setuptools.nix { inherit lib python bootstrapped-pip; };
|
||||
flit-specific = import ./build-python-package-flit.nix { inherit flit; };
|
||||
wheel-specific = import ./build-python-package-wheel.nix { };
|
||||
common = import ./build-python-package-common.nix { inherit python bootstrapped-pip; };
|
||||
in
|
||||
|
||||
{
|
||||
# Several package formats are supported.
|
||||
# "setuptools" : Install a common setuptools/distutils based package. This builds a wheel.
|
||||
# "wheel" : Install from a pre-compiled wheel.
|
||||
# "flit" : Install a flit package. This builds a wheel.
|
||||
# "other" : Provide your own buildPhase and installPhase.
|
||||
format ? "setuptools"
|
||||
, ... } @ attrs:
|
||||
|
||||
|
||||
|
||||
|
||||
let
|
||||
# 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;
|
||||
|
||||
formatspecific =
|
||||
if format == "wheel" then
|
||||
{
|
||||
unpackPhase = ''
|
||||
mkdir dist
|
||||
cp $src dist/"''${src#*-}"
|
||||
'';
|
||||
if format == "setuptools" then common (setuptools-specific attrs)
|
||||
else if format == "flit" then common (flit-specific attrs)
|
||||
else if format == "wheel" then common (wheel-specific attrs)
|
||||
else if format == "other" then {}
|
||||
else throw "Unsupported format ${format}";
|
||||
|
||||
# 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;
|
||||
}
|
||||
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
|
||||
'';
|
||||
|
||||
# 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;
|
||||
}
|
||||
else
|
||||
throw "Unsupported format ${format}";
|
||||
|
||||
in mkPythonDerivation ( attrs // {
|
||||
|
||||
# To build and install a wheel we need pip
|
||||
buildInputs = buildInputs ++ [ bootstrapped-pip ];
|
||||
|
||||
#inherit propagatedBuildInputs;
|
||||
|
||||
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
|
||||
'';
|
||||
|
||||
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 ${toString installFlags}
|
||||
popd
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
shellHook = attrs.shellHook or ''
|
||||
${preShellHook}
|
||||
if test -e setup.py; then
|
||||
tmp_path=$(mktemp -d)
|
||||
export PATH="$tmp_path/bin:$PATH"
|
||||
export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
|
||||
mkdir -p $tmp_path/${python.sitePackages}
|
||||
${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path
|
||||
fi
|
||||
${postShellHook}
|
||||
'';
|
||||
|
||||
} // formatspecific)
|
||||
in mkPythonDerivation ( attrs // formatspecific )
|
|
@ -57,6 +57,10 @@ python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
|
|||
|
||||
inherit pythonPath;
|
||||
|
||||
# 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
|
||||
DETERMINISTIC_BUILD=1;
|
||||
|
||||
buildInputs = [ wrapPython ] ++ buildInputs ++ pythonPath
|
||||
++ [ (ensureNewerSourcesHook { year = "1980"; }) ]
|
||||
++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip)
|
||||
|
|
|
@ -30,6 +30,7 @@ let
|
|||
buildPythonPackage = makeOverridable (callPackage ../development/interpreters/python/build-python-package.nix {
|
||||
inherit mkPythonDerivation;
|
||||
inherit bootstrapped-pip;
|
||||
flit = self.flit;
|
||||
});
|
||||
|
||||
buildPythonApplication = args: buildPythonPackage ({namePrefix="";} // args );
|
||||
|
@ -6563,6 +6564,21 @@ in {
|
|||
propagatedBuildInputs = with self; [ configparser ];
|
||||
};
|
||||
|
||||
entrypoints_flit = buildPythonPackage rec {
|
||||
pname = "entrypoints";
|
||||
version = "0.2.2";
|
||||
name = "${pname}-${version}";
|
||||
format = "flit";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "takluyver";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "1asi3xfym1g9z24p9ivzyp4smnl600w8hghlv5dziabj6csj8s1h";
|
||||
};
|
||||
propagatedBuildInputs = with self; [ configparser ];
|
||||
};
|
||||
|
||||
etcd = buildPythonPackage rec {
|
||||
name = "etcd-${version}";
|
||||
version = "2.0.8";
|
||||
|
@ -6866,6 +6882,29 @@ in {
|
|||
propagatedBuildInputs = with self; [ rpkg offtrac urlgrabber fedora_cert ];
|
||||
});
|
||||
|
||||
flit = buildPythonPackage rec {
|
||||
pname = "flit";
|
||||
version = "0.10";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
format = "wheel";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = https://files.pythonhosted.org/packages/24/98/50a090112a04d9e29155c31a222637668b0a4dd778fefcd3132adc50e877/flit-0.10-py3-none-any.whl;
|
||||
sha256 = "4566b2e1807abeb1fd7bfaa9b444447556f1720518edfb134b56a6a1272b0428";
|
||||
};
|
||||
|
||||
disabled = !isPy3k;
|
||||
propagatedBuildInputs = with self; [ docutils requests2 requests_download zipfile36];
|
||||
|
||||
meta = {
|
||||
description = "A simple packaging tool for simple packages";
|
||||
homepage = https://github.com/takluyver/flit;
|
||||
license = licenses.bsd3;
|
||||
maintainer = maintainers.fridh;
|
||||
};
|
||||
};
|
||||
|
||||
Flootty = buildPythonPackage rec {
|
||||
name = "Flootty-3.2.0";
|
||||
|
||||
|
@ -21731,6 +21770,27 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
requests_download = buildPythonPackage rec {
|
||||
pname = "requests_download";
|
||||
version = "0.1.1";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
format = "wheel";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = https://files.pythonhosted.org/packages/60/af/10f899f0574a81cbc511124c08d7c7dc46c20d4f956a6a3c793ad4330bb4/requests_download-0.1.1-py2.py3-none-any.whl;
|
||||
sha256 = "07832a93314bcd619aaeb08611ae245728e66672efb930bc2a300a115a47dab7";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with self; [ requests2 ];
|
||||
|
||||
meta = {
|
||||
description = "Download files using requests and save them to a target path";
|
||||
homepage = https://www.github.com/takluyver/requests_download;
|
||||
license = licenses.mit;
|
||||
maintainer = maintainers.fridh;
|
||||
};
|
||||
};
|
||||
|
||||
requests_oauthlib = buildPythonPackage rec {
|
||||
version = "0.4.1";
|
||||
|
@ -31330,6 +31390,27 @@ in {
|
|||
zeitgeist = if isPy3k then throw "zeitgeist not supported for interpreter ${python.executable}" else
|
||||
(pkgs.zeitgeist.override{python2Packages=self;}).py;
|
||||
|
||||
zipfile36 = buildPythonPackage rec {
|
||||
pname = "zipfile36";
|
||||
version = "0.1.3";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "mirror://pypi/${builtins.substring 0 1 pname}/${pname}/${name}.tar.gz";
|
||||
sha256 = "a78a8dddf4fa114f7fe73df76ffcce7538e23433b7a6a96c1c904023f122aead";
|
||||
};
|
||||
|
||||
checkPhase = ''
|
||||
${python.interpreter} -m unittest test_zipfile.py
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Read and write ZIP files - backport of the zipfile module from Python 3.6";
|
||||
homepage = https://gitlab.com/takluyver/zipfile36;
|
||||
license = licenses.psfl;
|
||||
maintainer = maintainers.fridh;
|
||||
};
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue