From 8a0770aec5ea164e1e8d513ea76093d626c6ed54 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Fri, 17 Apr 2026 13:18:37 +0200 Subject: [PATCH] lib.ExecContext.run(): Pass LC_ALL=C by default Pass LC_ALL="C" to _run() by default. This is necessary to be able to parse error messages and raise FileNotFound if need be. Signed-off-by: Jan Lindemann --- src/python/jw/pkg/lib/ExecContext.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/python/jw/pkg/lib/ExecContext.py b/src/python/jw/pkg/lib/ExecContext.py index 327948f8..7105dfe5 100644 --- a/src/python/jw/pkg/lib/ExecContext.py +++ b/src/python/jw/pkg/lib/ExecContext.py @@ -21,9 +21,10 @@ class ExecContext(Base): def __init__( self, parent: ExecContext, - title: str, + title: str|None, cmd: list[str], cmd_input: Input, + env: dict[str, str]|None, wd: str|None, log_prefix: str, throw: bool, @@ -38,6 +39,7 @@ class ExecContext(Base): self.__delim = title if title is not None else f'---- {parent.uri}: Running {self.pretty_cmd} -' delim_len = 120 self.__delim += '-' * max(0, delim_len - len(self.__delim)) + self.__env = {'LC_ALL': 'C'} if env is None else env # -- At the end of this dance, interactive needs to be either True # or False @@ -98,6 +100,10 @@ class ExecContext(Base): def cmd_input(self) -> bytes|None: return self.__cmd_input + @property + def env(self) -> dict[str, str]: + return self.__env + @property def throw(self) -> bool: return self.__throw @@ -190,7 +196,7 @@ class ExecContext(Base): assert cmd_input is not None ret = Result(None, None, 1) - with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, wd=wd, + with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, env=env, wd=wd, log_prefix='|', throw=throw, verbose=verbose) as cc: try: ret = await self._run( @@ -198,7 +204,7 @@ class ExecContext(Base): wd=wd, verbose=cc.verbose, cmd_input=cc.cmd_input, - env=env, + env=cc.env, interactive=cc.interactive, log_prefix=cc.log_prefix ) @@ -231,9 +237,7 @@ class ExecContext(Base): ret = Result(None, None, 1) if opts is None: opts = {} - if mod_env is None: - mod_env = {} - with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, wd=wd, + with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, env=env, wd=wd, log_prefix='|', throw=throw, verbose=verbose) as cc: try: ret = await self._sudo( @@ -243,7 +247,7 @@ class ExecContext(Base): wd=wd, verbose=cc.verbose, cmd_input=cc.cmd_input, - env=env, + env=cc.env, interactive=cc.interactive, log_prefix=cc.log_prefix, ) @@ -264,7 +268,7 @@ class ExecContext(Base): if wd is not None: path = wd + '/' + path with self.CallContext(self, title=title, cmd=['cat', path], - cmd_input=InputMode.NonInteractive, wd=None, + cmd_input=InputMode.NonInteractive, wd=None, env=None, log_prefix='|', throw=throw, verbose=verbose) as cc: try: ret = await self._run( @@ -272,7 +276,7 @@ class ExecContext(Base): wd=wd, verbose=cc.verbose, cmd_input=cc.cmd_input, - env=None, + env=cc.env, interactive=cc.interactive, log_prefix=cc.log_prefix )