2020-04-24 23:36:52 +00:00
|
|
|
# Generic builder.
|
|
|
|
|
|
|
|
{ lib
|
|
|
|
, config
|
|
|
|
, python
|
|
|
|
, wrapPython
|
|
|
|
, unzip
|
|
|
|
, ensureNewerSourcesForZipFilesHook
|
|
|
|
# Whether the derivation provides a Python module or not.
|
|
|
|
, toPythonModule
|
|
|
|
, namePrefix
|
|
|
|
, update-python-libraries
|
|
|
|
, setuptools
|
|
|
|
, flitBuildHook
|
|
|
|
, pipBuildHook
|
|
|
|
, pipInstallHook
|
|
|
|
, pythonCatchConflictsHook
|
|
|
|
, pythonImportsCheckHook
|
|
|
|
, pythonNamespacesHook
|
2022-09-30 11:47:45 +00:00
|
|
|
, pythonOutputDistHook
|
2020-04-24 23:36:52 +00:00
|
|
|
, pythonRemoveBinBytecodeHook
|
|
|
|
, pythonRemoveTestsDirHook
|
|
|
|
, setuptoolsBuildHook
|
|
|
|
, setuptoolsCheckHook
|
|
|
|
, wheelUnpackHook
|
|
|
|
, eggUnpackHook
|
|
|
|
, eggBuildHook
|
|
|
|
, eggInstallHook
|
|
|
|
}:
|
|
|
|
|
|
|
|
{ name ? "${attrs.pname}-${attrs.version}"
|
|
|
|
|
|
|
|
# Build-time dependencies for the package
|
|
|
|
, nativeBuildInputs ? []
|
|
|
|
|
|
|
|
# Run-time dependencies for the package
|
|
|
|
, buildInputs ? []
|
|
|
|
|
|
|
|
# Dependencies needed for running the checkPhase.
|
|
|
|
# These are added to buildInputs when doCheck = true.
|
|
|
|
, checkInputs ? []
|
2023-02-02 18:25:31 +00:00
|
|
|
, nativeCheckInputs ? []
|
2020-04-24 23:36:52 +00:00
|
|
|
|
|
|
|
# propagate build dependencies so in case we have A -> B -> C,
|
|
|
|
# C can import package A propagated by B
|
|
|
|
, propagatedBuildInputs ? []
|
|
|
|
|
|
|
|
# DEPRECATED: use propagatedBuildInputs
|
|
|
|
, pythonPath ? []
|
|
|
|
|
|
|
|
# Enabled to detect some (native)BuildInputs mistakes
|
|
|
|
, strictDeps ? true
|
|
|
|
|
2022-09-30 11:47:45 +00:00
|
|
|
, outputs ? [ "out" ]
|
|
|
|
|
2020-04-24 23:36:52 +00:00
|
|
|
# used to disable derivation, useful for specific python versions
|
|
|
|
, disabled ? false
|
|
|
|
|
|
|
|
# Raise an error if two packages are installed with the same name
|
2020-12-03 08:41:04 +00:00
|
|
|
# TODO: For cross we probably need a different PYTHONPATH, or not
|
|
|
|
# add the runtime deps until after buildPhase.
|
|
|
|
, catchConflicts ? (python.stdenv.hostPlatform == python.stdenv.buildPlatform)
|
2020-04-24 23:36:52 +00:00
|
|
|
|
|
|
|
# Additional arguments to pass to the makeWrapper function, which wraps
|
|
|
|
# generated binaries.
|
|
|
|
, makeWrapperArgs ? []
|
|
|
|
|
|
|
|
# Skip wrapping of python programs altogether
|
|
|
|
, dontWrapPythonPrograms ? false
|
|
|
|
|
|
|
|
# Don't use Pip to install a wheel
|
|
|
|
# Note this is actually a variable for the pipInstallPhase in pip's setupHook.
|
|
|
|
# It's included here to prevent an infinite recursion.
|
|
|
|
, dontUsePipInstall ? false
|
|
|
|
|
|
|
|
# Skip setting the PYTHONNOUSERSITE environment variable in wrapped programs
|
|
|
|
, permitUserSite ? false
|
|
|
|
|
|
|
|
# Remove bytecode from bin folder.
|
|
|
|
# When a Python script has the extension `.py`, bytecode is generated
|
|
|
|
# Typically, executables in bin have no extension, so no bytecode is generated.
|
|
|
|
# However, some packages do provide executables with extensions, and thus bytecode is generated.
|
|
|
|
, removeBinBytecode ? true
|
|
|
|
|
|
|
|
# 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.
|
2020-09-25 04:45:31 +00:00
|
|
|
# "pyproject": Install a package using a ``pyproject.toml`` file (PEP517). This builds a wheel.
|
|
|
|
# "egg": Install a package from an egg.
|
2020-04-24 23:36:52 +00:00
|
|
|
# "other" : Provide your own buildPhase and installPhase.
|
|
|
|
, format ? "setuptools"
|
|
|
|
|
|
|
|
, meta ? {}
|
|
|
|
|
|
|
|
, passthru ? {}
|
|
|
|
|
|
|
|
, doCheck ? config.doCheckByDefault or false
|
|
|
|
|
2021-05-28 09:39:13 +00:00
|
|
|
, disabledTestPaths ? []
|
|
|
|
|
2020-04-24 23:36:52 +00:00
|
|
|
, ... } @ attrs:
|
|
|
|
|
|
|
|
let
|
|
|
|
inherit (python) stdenv;
|
|
|
|
|
2022-10-30 15:09:59 +00:00
|
|
|
withDistOutput = lib.elem format ["pyproject" "setuptools" "flit" "wheel"];
|
2022-09-30 11:47:45 +00:00
|
|
|
|
2021-04-26 19:14:03 +00:00
|
|
|
name_ = name;
|
|
|
|
|
2023-02-02 18:25:31 +00:00
|
|
|
# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
|
2020-04-24 23:36:52 +00:00
|
|
|
self = toPythonModule (stdenv.mkDerivation ((builtins.removeAttrs attrs [
|
2023-02-02 18:25:31 +00:00
|
|
|
"disabled" "checkPhase" "checkInputs" "nativeCheckInputs" "doCheck" "doInstallCheck" "dontWrapPythonPrograms" "catchConflicts" "format"
|
2022-09-30 11:47:45 +00:00
|
|
|
"disabledTestPaths" "outputs"
|
2020-04-24 23:36:52 +00:00
|
|
|
]) // {
|
|
|
|
|
2021-04-26 19:14:03 +00:00
|
|
|
name = namePrefix + name_;
|
2020-09-25 04:45:31 +00:00
|
|
|
|
|
|
|
nativeBuildInputs = [
|
|
|
|
python
|
|
|
|
wrapPython
|
|
|
|
ensureNewerSourcesForZipFilesHook # move to wheel installer (pip) or builder (setuptools, flit, ...)?
|
|
|
|
pythonRemoveTestsDirHook
|
|
|
|
] ++ lib.optionals catchConflicts [
|
2022-09-30 11:47:45 +00:00
|
|
|
pythonCatchConflictsHook
|
2020-09-25 04:45:31 +00:00
|
|
|
] ++ lib.optionals removeBinBytecode [
|
|
|
|
pythonRemoveBinBytecodeHook
|
|
|
|
] ++ lib.optionals (lib.hasSuffix "zip" (attrs.src.name or "")) [
|
|
|
|
unzip
|
|
|
|
] ++ lib.optionals (format == "setuptools") [
|
|
|
|
setuptoolsBuildHook
|
|
|
|
] ++ lib.optionals (format == "flit") [
|
|
|
|
flitBuildHook
|
|
|
|
] ++ lib.optionals (format == "pyproject") [
|
|
|
|
pipBuildHook
|
|
|
|
] ++ lib.optionals (format == "wheel") [
|
|
|
|
wheelUnpackHook
|
|
|
|
] ++ lib.optionals (format == "egg") [
|
|
|
|
eggUnpackHook eggBuildHook eggInstallHook
|
|
|
|
] ++ lib.optionals (!(format == "other") || dontUsePipInstall) [
|
|
|
|
pipInstallHook
|
|
|
|
] ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [
|
|
|
|
# This is a test, however, it should be ran independent of the checkPhase and checkInputs
|
|
|
|
pythonImportsCheckHook
|
|
|
|
] ++ lib.optionals (python.pythonAtLeast "3.3") [
|
|
|
|
# Optionally enforce PEP420 for python3
|
|
|
|
pythonNamespacesHook
|
2022-09-30 11:47:45 +00:00
|
|
|
] ++ lib.optionals withDistOutput [
|
|
|
|
pythonOutputDistHook
|
2020-09-25 04:45:31 +00:00
|
|
|
] ++ nativeBuildInputs;
|
|
|
|
|
|
|
|
buildInputs = buildInputs ++ pythonPath;
|
|
|
|
|
2022-07-14 12:49:19 +00:00
|
|
|
propagatedBuildInputs = propagatedBuildInputs ++ [
|
|
|
|
# we propagate python even for packages transformed with 'toPythonApplication'
|
|
|
|
# this pollutes the PATH but avoids rebuilds
|
|
|
|
# see https://github.com/NixOS/nixpkgs/issues/170887 for more context
|
|
|
|
python
|
|
|
|
];
|
2020-09-25 04:45:31 +00:00
|
|
|
|
|
|
|
inherit strictDeps;
|
|
|
|
|
|
|
|
LANG = "${if python.stdenv.isDarwin then "en_US" else "C"}.UTF-8";
|
|
|
|
|
|
|
|
# Python packages don't have a checkPhase, only an installCheckPhase
|
|
|
|
doCheck = false;
|
|
|
|
doInstallCheck = attrs.doCheck or true;
|
2023-02-02 18:25:31 +00:00
|
|
|
nativeInstallCheckInputs = [
|
2020-09-25 04:45:31 +00:00
|
|
|
] ++ lib.optionals (format == "setuptools") [
|
|
|
|
# Longer-term we should get rid of this and require
|
|
|
|
# users of this function to set the `installCheckPhase` or
|
|
|
|
# pass in a hook that sets it.
|
|
|
|
setuptoolsCheckHook
|
2023-02-02 18:25:31 +00:00
|
|
|
] ++ nativeCheckInputs;
|
|
|
|
installCheckInputs = checkInputs;
|
2020-09-25 04:45:31 +00:00
|
|
|
|
|
|
|
postFixup = lib.optionalString (!dontWrapPythonPrograms) ''
|
|
|
|
wrapPythonPrograms
|
2021-02-05 17:12:51 +00:00
|
|
|
'' + attrs.postFixup or "";
|
2020-09-25 04:45:31 +00:00
|
|
|
|
|
|
|
# Python packages built through cross-compilation are always for the host platform.
|
|
|
|
disallowedReferences = lib.optionals (python.stdenv.hostPlatform != python.stdenv.buildPlatform) [ python.pythonForBuild ];
|
|
|
|
|
2022-09-30 11:47:45 +00:00
|
|
|
outputs = outputs ++ lib.optional withDistOutput "dist";
|
|
|
|
|
2020-09-25 04:45:31 +00:00
|
|
|
meta = {
|
|
|
|
# default to python's platforms
|
|
|
|
platforms = python.meta.platforms;
|
|
|
|
isBuildPythonPackage = python.meta.platforms;
|
|
|
|
} // meta;
|
|
|
|
} // lib.optionalAttrs (attrs?checkPhase) {
|
|
|
|
# If given use the specified checkPhase, otherwise use the setup hook.
|
|
|
|
# Longer-term we should get rid of `checkPhase` and use `installCheckPhase`.
|
|
|
|
installCheckPhase = attrs.checkPhase;
|
2021-05-28 09:39:13 +00:00
|
|
|
} // lib.optionalAttrs (disabledTestPaths != []) {
|
|
|
|
disabledTestPaths = lib.escapeShellArgs disabledTestPaths;
|
2020-09-25 04:45:31 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
passthru.updateScript = let
|
|
|
|
filename = builtins.head (lib.splitString ":" self.meta.position);
|
|
|
|
in attrs.passthru.updateScript or [ update-python-libraries filename ];
|
2023-02-02 18:25:31 +00:00
|
|
|
in lib.extendDerivation
|
|
|
|
(disabled -> throw "${name} not supported for interpreter ${python.executable}")
|
|
|
|
passthru
|
|
|
|
self
|