From 8e3169d85d418bcc8df101a73b141d54c7ab9abb 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: Tue, 29 Oct 2024 17:24:39 +0100 Subject: [PATCH] python: remove `LD_LIBRARY_PATH` hack from running python environment Injecting `LD_LIBRARY_PATH` to the Python runtime environment is great to bypass the need of having to patch non-nix binaries loaded into that environment, however it breaks down, when Python executes any other program not compiled for the given Nix system, e.g. a shell script via `subprocess`. To work this around, `devenv` will inject a `pth`[^1] file to the virtual environment it creates, which mangles the `LD_LIBRARY_PATH` variable, undoing any changes to it made by `devenv` but preserving changes from other sources. Fixes #1111 [^1]: https://docs.python.org/3/library/site.html --- src/modules/languages/python.nix | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index 9c6aef053..bb6af3905 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -14,6 +14,9 @@ let python = cfg.package; requiredPythonModules = cfg.package.pkgs.requiredPythonModules; makeWrapperArgs = [ + "--set" + "DEVENV_LD_LIBRARY_PATH_PREFIX" + libraries "--prefix" "LD_LIBRARY_PATH" ":" @@ -39,6 +42,20 @@ let follows = [ "nixpkgs" ]; }; + pth_file = + let + exec_content = '' + ld_library_path = os.environ.get("LD_LIBRARY_PATH") + ld_library_path_prefix = os.environ.get("DEVENV_LD_LIBRARY_PATH_PREFIX") + if ld_library_path and ld_library_path_prefix: + if ld_library_path == ld_library_path_prefix: + del os.environ["LD_LIBRARY_PATH"] + else: + os.environ["LD_LIBRARY_PATH"] = ld_library_path.removeprefix(ld_library_path_prefix + ":") + ''; + in + pkgs.writeText "devenv.pth" ''import os; exec("""${builtins.replaceStrings [ "\n" ] [ "\\n" ] exec_content}""")''; + initVenvScript = let USE_UV_SYNC = cfg.uv.sync.enable && builtins.compareVersions cfg.uv.package.version "0.4.4" >= 0; @@ -80,6 +97,9 @@ let '' } echo "${package.interpreter}" > "$VENV_PATH/.devenv_interpreter" + ${lib.optionalString pkgs.stdenv.isLinux '' + ln -snf ${pth_file} "$VENV_PATH/${package.sitePackages}/devenv.pth" + ''} fi source "$VENV_PATH"/bin/activate @@ -157,6 +177,9 @@ let if "''${UV_SYNC_COMMAND[@]}" then echo "$ACTUAL_UV_CHECKSUM" > "$UV_CHECKSUM_FILE" + ${lib.optionalString pkgs.stdenv.isLinux '' + ln -snf ${pth_file} "$VENV_PATH/${package.sitePackages}/devenv.pth" + ''} else echo "uv sync failed. Run 'uv sync' manually." >&2 fi @@ -206,6 +229,9 @@ let if ''${POETRY_INSTALL_COMMAND[@]} then echo "$ACTUAL_POETRY_CHECKSUM" > "$POETRY_CHECKSUM_FILE" + ${lib.optionalString pkgs.stdenv.isLinux '' + ln -snf ${pth_file} ".venv/${package.sitePackages}/devenv.pth" + ''} else echo "Poetry install failed. Run 'poetry install' manually." fi