Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 56 additions & 3 deletions pkgs/development/interpreters/python/mk-python-derivation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,59 @@ let

name_ = name;

validatePythonMatches = attrName: let
isPythonModule = drv:
# all pythonModules have the pythonModule attribute
(drv ? "pythonModule")
# Some pythonModules are turned in to a pythonApplication by setting the field to false
&& (!builtins.isBool drv.pythonModule);
isMismatchedPython = drv: drv.pythonModule != python;

optionalLocation = let
pos = builtins.unsafeGetAttrPos (if attrs ? "pname" then "pname" else "name") attrs;
in if pos == null then "" else " at ${pos.file}:${toString pos.line}:${toString pos.column}";

leftPadName = name: against: let
len = lib.max (lib.stringLength name) (lib.stringLength against);
in lib.strings.fixedWidthString len " " name;

throwMismatch = drv: let
myName = "'${namePrefix}${name}'";
theirName = "'${drv.name}'";
in throw ''
Python version mismatch in ${myName}:

The Python derivation ${myName} depends on a Python derivation
named ${theirName}, but the two derivations use different versions
of Python:

${leftPadName myName theirName} uses ${python}
${leftPadName theirName myName} uses ${toString drv.pythonModule}

Possible solutions:

* If ${theirName} is a Python library, change the reference to ${theirName}
in the ${attrName} of ${myName} to use a ${theirName} built from the same
version of Python

* If ${theirName} is used as a tool during the build, move the reference to
${theirName} in ${myName} from ${attrName} to nativeBuildInputs

* If ${theirName} provides executables that are called at run time, pass its
bin path to makeWrapperArgs:

makeWrapperArgs = [ "--prefix PATH : ''${lib.makeBinPath [ ${lib.getName drv } ] }" ];

${optionalLocation}
'';

checkDrv = drv:
if (isPythonModule drv) && (isMismatchedPython drv)
then throwMismatch drv
else drv;

in inputs: builtins.map (checkDrv) inputs;

# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
self = toPythonModule (stdenv.mkDerivation ((builtins.removeAttrs attrs [
"disabled" "checkPhase" "checkInputs" "nativeCheckInputs" "doCheck" "doInstallCheck" "dontWrapPythonPrograms" "catchConflicts" "format"
Expand Down Expand Up @@ -149,14 +202,14 @@ let
pythonOutputDistHook
] ++ nativeBuildInputs;

buildInputs = buildInputs ++ pythonPath;
buildInputs = validatePythonMatches "buildInputs" (buildInputs ++ pythonPath);

propagatedBuildInputs = propagatedBuildInputs ++ [
propagatedBuildInputs = validatePythonMatches "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
];
]);

inherit strictDeps;

Expand Down