145 lines
4.1 KiB
Nix
145 lines
4.1 KiB
Nix
{
|
|
pkgs,
|
|
stdenv,
|
|
lib,
|
|
python,
|
|
}:
|
|
|
|
self:
|
|
|
|
let
|
|
inherit (self) callPackage;
|
|
|
|
namePrefix = python.libPrefix + "-";
|
|
|
|
# Derivations built with `buildPythonPackage` can already be overridden with `override`, `overrideAttrs`, and `overrideDerivation`.
|
|
# This function introduces `overridePythonAttrs` and it overrides the call to `buildPythonPackage`.
|
|
makeOverridablePythonPackage =
|
|
f:
|
|
lib.mirrorFunctionArgs f (
|
|
origArgs:
|
|
let
|
|
args = lib.fix (
|
|
lib.extends (_: previousAttrs: {
|
|
passthru = (previousAttrs.passthru or { }) // {
|
|
overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
|
|
};
|
|
}) (_: origArgs)
|
|
);
|
|
result = f args;
|
|
overrideWith = newArgs: args // (if pkgs.lib.isFunction newArgs then newArgs args else newArgs);
|
|
in
|
|
if builtins.isAttrs result then
|
|
result
|
|
else if builtins.isFunction result then
|
|
{
|
|
overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
|
|
__functor = self: result;
|
|
}
|
|
else
|
|
result
|
|
);
|
|
|
|
mkPythonDerivation =
|
|
if python.isPy3k then ./mk-python-derivation.nix else ./python2/mk-python-derivation.nix;
|
|
|
|
buildPythonPackage = makeOverridablePythonPackage (
|
|
lib.makeOverridable (
|
|
callPackage mkPythonDerivation {
|
|
inherit namePrefix; # We want Python libraries to be named like e.g. "python3.6-${name}"
|
|
inherit toPythonModule; # Libraries provide modules
|
|
}
|
|
)
|
|
);
|
|
|
|
buildPythonApplication = makeOverridablePythonPackage (
|
|
lib.makeOverridable (
|
|
callPackage mkPythonDerivation {
|
|
namePrefix = ""; # Python applications should not have any prefix
|
|
toPythonModule = x: x; # Application does not provide modules.
|
|
}
|
|
)
|
|
);
|
|
|
|
# Check whether a derivation provides a Python module.
|
|
hasPythonModule = drv: drv ? pythonModule && drv.pythonModule == python;
|
|
|
|
# Get list of required Python modules given a list of derivations.
|
|
requiredPythonModules =
|
|
drvs:
|
|
let
|
|
modules = lib.filter hasPythonModule drvs;
|
|
in
|
|
lib.unique (
|
|
[ python ] ++ modules ++ lib.concatLists (lib.catAttrs "requiredPythonModules" modules)
|
|
);
|
|
|
|
# Create a PYTHONPATH from a list of derivations. This function recurses into the items to find derivations
|
|
# providing Python modules.
|
|
makePythonPath = drvs: lib.makeSearchPath python.sitePackages (requiredPythonModules drvs);
|
|
|
|
removePythonPrefix = lib.removePrefix namePrefix;
|
|
|
|
# Convert derivation to a Python module.
|
|
toPythonModule =
|
|
drv:
|
|
drv.overrideAttrs (oldAttrs: {
|
|
# Use passthru in order to prevent rebuilds when possible.
|
|
passthru = (oldAttrs.passthru or { }) // {
|
|
pythonModule = python;
|
|
pythonPath = [ ]; # Deprecated, for compatibility.
|
|
requiredPythonModules = requiredPythonModules drv.propagatedBuildInputs;
|
|
};
|
|
});
|
|
|
|
# Convert a Python library to an application.
|
|
toPythonApplication =
|
|
drv:
|
|
drv.overrideAttrs (oldAttrs: {
|
|
passthru = (oldAttrs.passthru or { }) // {
|
|
# Remove Python prefix from name so we have a "normal" name.
|
|
# While the prefix shows up in the store path, it won't be
|
|
# used by `nix-env`.
|
|
name = removePythonPrefix oldAttrs.name;
|
|
pythonModule = false;
|
|
};
|
|
});
|
|
|
|
disabled =
|
|
drv:
|
|
throw "${
|
|
removePythonPrefix (drv.pname or drv.name)
|
|
} not supported for interpreter ${python.executable}";
|
|
|
|
disabledIf = x: drv: if x then disabled drv else drv;
|
|
|
|
in
|
|
{
|
|
inherit lib pkgs stdenv;
|
|
inherit (python.passthru)
|
|
isPy27
|
|
isPy37
|
|
isPy38
|
|
isPy39
|
|
isPy310
|
|
isPy311
|
|
isPy3k
|
|
isPyPy
|
|
pythonAtLeast
|
|
pythonOlder
|
|
;
|
|
inherit buildPythonPackage buildPythonApplication;
|
|
inherit
|
|
hasPythonModule
|
|
requiredPythonModules
|
|
makePythonPath
|
|
disabled
|
|
disabledIf
|
|
;
|
|
inherit toPythonModule toPythonApplication;
|
|
|
|
python = toPythonModule python;
|
|
# Dont take pythonPackages from "global" pkgs scope to avoid mixing python versions
|
|
pythonPackages = self;
|
|
}
|