Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mkPythonDerivation: validate propagatedBuildInputs and buildInputs use a matching python #120220

Merged
merged 1 commit into from Apr 28, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 56 additions & 3 deletions pkgs/development/interpreters/python/mk-python-derivation.nix
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);
FRidh marked this conversation as resolved.
Show resolved Hide resolved
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:
cole-h marked this conversation as resolved.
Show resolved Hide resolved

* 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