From 60d2a8b3bbd51fa6b58a03c6dc3f464e5c41d19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Vask=C3=B3?= <1771332+vlaci@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:40:34 +0200 Subject: [PATCH] python: adjust wrapper to fix propagating dependencies to virtual envs --- src/modules/languages/python.nix | 2 +- src/python-wrapper.nix | 82 ++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/python-wrapper.nix diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index 9cfb18551..500c044d1 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -10,7 +10,7 @@ let ); readlink = "${pkgs.coreutils}/bin/readlink -f "; - package = pkgs.callPackage "${pkgs.path}/pkgs/development/interpreters/python/wrapper.nix" { + package = pkgs.callPackage ../../python-wrapper.nix { python = cfg.package; requiredPythonModules = cfg.package.pkgs.requiredPythonModules; makeWrapperArgs = [ diff --git a/src/python-wrapper.nix b/src/python-wrapper.nix new file mode 100644 index 000000000..9b0312087 --- /dev/null +++ b/src/python-wrapper.nix @@ -0,0 +1,82 @@ +{ lib, stdenv, buildEnv, makeBinaryWrapper + +# manually pased +, python +, requiredPythonModules + +# extra opts +, extraLibs ? [] +, extraOutputsToInstall ? [] +, postBuild ? "" +, ignoreCollisions ? false +, permitUserSite ? false +# Wrap executables with the given argument. +, makeWrapperArgs ? [] +, }: + +# Create a python executable that knows about additional packages. +let + env = let + paths = requiredPythonModules (extraLibs ++ [ python ] ) ; + pythonPath = "${placeholder "out"}/${python.sitePackages}"; + pythonExecutable = "${placeholder "out"}/bin/${python.executable}"; + in buildEnv { + name = "${python.name}-env"; + + inherit paths; + inherit ignoreCollisions; + extraOutputsToInstall = [ "out" ] ++ extraOutputsToInstall; + + nativeBuildInputs = [ makeBinaryWrapper ]; + + postBuild = '' + if [ -L "$out/bin" ]; then + unlink "$out/bin" + fi + mkdir -p "$out/bin" + + rm -f $out/bin/.*-wrapped + + for path in ${lib.concatStringsSep " " paths}; do + if [ -d "$path/bin" ]; then + cd "$path/bin" + for prg in *; do + if [ -f "$prg" ]; then + rm -f "$out/bin/$prg" + if [ -x "$prg" ]; then + if [ -f ".$prg-wrapped" ]; then + echo "#!${pythonExecutable}" > "$out/bin/$prg" + sed \ + -e '/^#!\/nix\/store\//d' \ + -e '/^import sys;import site;import functools;sys\.argv\[0\] = /d' \ + ".$prg-wrapped" >> "$out/bin/$prg" + chmod +x "$out/bin/$prg" + else + makeWrapper "$path/bin/$prg" "$out/bin/$prg" --inherit-argv0 --resolve-argv0 ${lib.optionalString (!permitUserSite) ''--set PYTHONNOUSERSITE "true"''} ${lib.concatStringsSep " " makeWrapperArgs} + fi + fi + fi + done + fi + done + '' + postBuild; + + inherit (python) meta; + + passthru = python.passthru // { + interpreter = "${env}/bin/${python.executable}"; + inherit python; + env = stdenv.mkDerivation { + name = "interactive-${python.name}-environment"; + nativeBuildInputs = [ env ]; + + buildCommand = '' + echo >&2 "" + echo >&2 "*** Python 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" + echo >&2 "" + exit 1 + ''; + }; + }; + }; +in env