about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArtturi <Artturin@artturin.com>2023-04-28 18:47:17 +0300
committerGitHub <noreply@github.com>2023-04-28 18:47:17 +0300
commit44075d60d27f6719a36d076de6e979e66499716d (patch)
tree2d76cd155fb736030957b335754d7ee98508cad6
parent1f3c4bf6b40ef3a6fd8f6afe19bc5c7ef0db0b62 (diff)
parentd44390ab186273b2043c9f1a6df87f2be3465dbb (diff)
Merge pull request #120220 from grahamc/python-kvetch-on-mismatch
-rw-r--r--pkgs/development/interpreters/python/mk-python-derivation.nix59
1 files 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 b1f35cc2fb137..17b5667e8ee9c 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;