Package: emacs;
Reported by: Liu Hui <liuhui1610 <at> gmail.com>
Date: Tue, 9 Sep 2025 09:54:01 UTC
Severity: normal
Tags: patch
Message #17 received at 79413 <at> debbugs.gnu.org (full text, mbox):
From: Liu Hui <liuhui1610 <at> gmail.com> To: Michael Albinus <michael.albinus <at> gmx.de> Cc: 79413 <at> debbugs.gnu.org Subject: Re: bug#79413: [PATCH] Fix path and environment in remote Python shell Date: Thu, 11 Sep 2025 12:47:13 +0800
Michael Albinus <michael.albinus <at> gmx.de> writes: > Liu Hui <liuhui1610 <at> gmail.com> writes: > > Hi, > >>> This is a Tramp feature. See this comment in tramp-handle-make-process, >>> tramp-sh-handle-make-process and tramp-sh-handle-process-file: >>> >>> --8<---------------cut here---------------start------------->8--- >>> ;; We use as environment the difference to toplevel >>> ;; `process-environment'. >>> --8<---------------cut here---------------end--------------->8--- >>> >>> The reason is, that often a local value of $FOO might be wrong on the >>> remote host. >> >> Thanks for the explanation. Then let-binding process-environment is >> not a reliable way if we want to ensure some environment variables, >> python-shell-process-environment in this case, are applied to the >> remote process. >> >> Could tramp add an option that disables this feature temporarily or >> ensures specific environment variables are always applied in >> tramp-sh-handle-make-process and tramp-sh-handle-process-file? > > You would run into the same problem why this feature exist. You don't > want to expand local environment variables like DISPLAY, SSH_* or > whatever to the remote host. I agree local environment variables should not be applied on the remote host. I meant to propagate specific environment variables (e.g. "PYTHONPATH=/opt/mypackage") in python-shell-process-environment. The problem is that "PYTHONPATH=/opt/mypackage" is skipped for remote processes if it happens to exist in the default process environment (e.g. it is added in local ~/.profile). How about the following change? It doesn't change the default behavior and allows the caller to override tramp-local-environment-variable-p when necessary. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 9d13cdc3a2d..0a454fed69b 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -3052,8 +3052,7 @@ tramp-sh-handle-make-process ;; `process-environment'. env uenv (env (dolist (elt (cons prompt process-environment) env) - (or (member - elt (default-toplevel-value 'process-environment)) + (or (tramp-local-environment-variable-p elt) (if (string-search "=" elt) (setq env (append env `(,elt))) (setq uenv (cons elt uenv)))))) @@ -3288,7 +3287,7 @@ tramp-sh-handle-process-file (cons program args) " ")) ;; We use as environment the difference to toplevel `process-environment'. (dolist (elt process-environment) - (or (member elt (default-toplevel-value 'process-environment)) + (or (tramp-local-environment-variable-p elt) (if (string-search "=" elt) (setq env (append env `(,elt))) (setq uenv (cons elt uenv))))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 9bf1b4ae6c3..3ce25a5c663 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -5342,6 +5342,12 @@ tramp-direct-async-process-p (or (not (stringp buffer)) (not (tramp-tramp-file-p buffer))) (or (not (stringp stderr)) (not (tramp-tramp-file-p stderr)))))) +(defun tramp-local-environment-variable-p (arg) + "Return non-nil if ARG exists in default `process-environment'. +Tramp does not propagate a local environment variable in remote +processes." + (member arg (default-toplevel-value 'process-environment))) + (defun tramp-handle-make-process (&rest args) "An alternative `make-process' implementation for Tramp files." (tramp-skeleton-make-process args nil nil @@ -5360,9 +5366,7 @@ tramp-handle-make-process (env (dolist (elt process-environment env) (when (and (string-search "=" elt) - (not - (member - elt (default-toplevel-value 'process-environment)))) + (not (tramp-local-environment-variable-p elt))) (setq env (cons elt env))))) ;; Add remote path if exists. (env (if-let* ((sh-file-name-handler-p) > You could let-bind and modify tramp-remote-process-environment for > tramp-sh-handle-make-process. Note, that this won't work for direct > async processes, which use tramp-handle-make-process internally. And it > won't work for tramp-sh-handle-process-file. > > Alternatively, you could call "env VAR1=VAL1 VAR2=VAL2 ... program ..." > instead of "program ...". Thanks for the suggestion. The problem is that python-shell-with-environment is just a wrapper that temporarily sets path and environment: (defmacro python-shell-with-environment (&rest body) ... `(python-shell--with-environment (python-shell--calculate-process-environment) (lambda () ,@body))) so we don't know what functions and programs users call.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.