mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-25 17:45:55 +02:00
lib.ExecContext: Support bytes-typed cmd_input
The Input instance passed as cmd_input to ExecContext.run() and .sudo() currently may be of type str. Allow to pass bytes, too. At the same time, disallow None to be passed as cmd_input. Force the caller to be more explicit how it wants input to be handled, notably with respect to interactivity. Along the way fix a bug: Content in cmd_input should result in CallContext.interactive == False but doesn't. Fix that. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
8ef478e63f
commit
04b294917f
9 changed files with 46 additions and 29 deletions
|
|
@ -18,7 +18,7 @@ class InputMode(Enum):
|
|||
OptInteractive = auto()
|
||||
Auto = auto()
|
||||
|
||||
Input: TypeAlias = InputMode | None | str
|
||||
Input: TypeAlias = InputMode | bytes | str
|
||||
|
||||
class Result(NamedTuple):
|
||||
|
||||
|
|
@ -61,19 +61,27 @@ class ExecContext(abc.ABC):
|
|||
# -- At the end of this dance, interactive needs to be either True
|
||||
# or False
|
||||
interactive: bool|None = None
|
||||
match cmd_input:
|
||||
case InputMode.Interactive:
|
||||
interactive = True
|
||||
case InputMode.NonInteractive:
|
||||
interactive = False
|
||||
case InputMode.OptInteractive:
|
||||
if not isinstance(cmd_input, InputMode):
|
||||
interactive = False
|
||||
self.__cmd_input = (
|
||||
cmd_input if isinstance(cmd_input, bytes) else
|
||||
cmd_input.encode(sys.stdout.encoding or "utf-8")
|
||||
)
|
||||
else:
|
||||
match cmd_input:
|
||||
case InputMode.Interactive:
|
||||
interactive = True
|
||||
case InputMode.NonInteractive:
|
||||
interactive = False
|
||||
case InputMode.OptInteractive:
|
||||
interactive = parent.interactive
|
||||
case InputMode.Auto:
|
||||
interactive = sys.stdin.isatty()
|
||||
if interactive is None:
|
||||
interactive = parent.interactive
|
||||
case InputMode.Auto:
|
||||
if interactive is None:
|
||||
interactive = sys.stdin.isatty()
|
||||
if interactive is None:
|
||||
interactive = parent.interactive
|
||||
if interactive is None:
|
||||
interactive = sys.stdin.isatty()
|
||||
self.__cmd_input = None
|
||||
assert interactive in [ True, False ]
|
||||
self.__interactive = interactive
|
||||
|
||||
|
|
@ -106,7 +114,7 @@ class ExecContext(abc.ABC):
|
|||
return self.__verbose
|
||||
|
||||
@property
|
||||
def cmd_input(self) -> bool:
|
||||
def cmd_input(self) -> bytes|None:
|
||||
return self.__cmd_input
|
||||
|
||||
@property
|
||||
|
|
@ -211,6 +219,10 @@ class ExecContext(abc.ABC):
|
|||
In PTY mode stderr is always None because PTY merges stdout/stderr.
|
||||
"""
|
||||
|
||||
# Note that in the calls to the wrapped method, cmd_input == None can
|
||||
# be returned by CallContext and is very much allowed
|
||||
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,
|
||||
log_prefix='|', throw=throw, verbose=verbose) as cc:
|
||||
|
|
@ -246,6 +258,10 @@ class ExecContext(abc.ABC):
|
|||
title: str=None,
|
||||
) -> Result:
|
||||
|
||||
# Note that in the calls to the wrapped method, cmd_input == None can
|
||||
# be returned by CallContext and is very much allowed
|
||||
assert cmd_input is not None
|
||||
|
||||
ret = Result(None, None, 1)
|
||||
if opts is None:
|
||||
opts = {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue