From d44390ab186273b2043c9f1a6df87f2be3465dbb Mon Sep 17 00:00:00 2001 From: Artturin Date: Sun, 16 Apr 2023 02:02:48 +0300 Subject: [PATCH] mkPythonDerivation: validate propagatedBuildInputs use a matching python mkPythonDerivation: apply checks to buildInputs as well fixup: add a suggestion about nativeBuildInputs Clean up the wording, add reasons for the suggestions switch to throw Adjust error to clarify build-time vs. run-time --- .../python/mk-python-derivation.nix | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/pkgs/development/interpreters/python/mk-python-derivation.nix b/pkgs/development/interpreters/python/mk-python-derivation.nix index b1f35cc2fb13..17b5667e8ee9 100644 --- a/pkgs/development/interpreters/python/mk-python-derivation.nix +++ b/pkgs/development/interpreters/python/mk-python-derivation.nix @@ -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" @@ -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;