Coverage for .tox/cov/lib/python3.11/site-packages/confattr/subprocess_pipe.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-03-14 14:14 +0100

1#!./runmodule.sh 

2 

3import subprocess 

4import typing 

5from collections.abc import Sequence, Mapping 

6 

7PIPE = '|' 

8 

9T = typing.TypeVar('T') 

10CompletedProcess = subprocess.CompletedProcess 

11 

12def run_and_pipe(cmds: 'Sequence[str]', *, get_output: bool = False, env: 'Mapping[str, str]|None' = None) -> 'subprocess.CompletedProcess[bytes]': 

13 ''' 

14 Run an external program and return when the program is finished. 

15 

16 :param cmds: One or several commands to be executed. If several commands are passed they are seperated by a '|' and stdout of the former command is piped to stdin of the following command. 

17 :param env: The environment variables to be passed to the subprocess. If env is None :py:data:`os.environ` is used. 

18 :param get_output: Make stdout and stderr available in the returned completed process object. 

19 :return: The completed process 

20 :raises OSError: e.g. if the program was not found 

21 :raises CalledProcessError: if the called program failed 

22 

23 https://docs.python.org/3/library/subprocess.html#exceptions 

24 ''' 

25 # I am not using shell=True because that is platform dependend 

26 # and shlex is for UNIX like shells only, so it may not work on Windows 

27 if get_output: 

28 def run(cmd: 'Sequence[str]', input: 'bytes|None' = None) -> 'subprocess.CompletedProcess[bytes]': 

29 return subprocess.run(cmd, env=env, input=input, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

30 else: 

31 def run(cmd: 'Sequence[str]', input: 'bytes|None' = None) -> 'subprocess.CompletedProcess[bytes]': 

32 return subprocess.run(cmd, env=env, input=input) 

33 

34 cmd_list = split_list(cmds, PIPE) 

35 n = len(cmd_list) 

36 if n == 1: 

37 return run(cmd_list[0]) 

38 

39 p = subprocess.run(cmd_list[0], env=env, stdout=subprocess.PIPE) 

40 for cmd in cmd_list[1:-1]: 

41 p = subprocess.run(cmd, env=env, input=p.stdout, stdout=subprocess.PIPE) 

42 return run(cmd_list[-1], input=p.stdout) 

43 

44def split_list(l: 'Sequence[T]', sep: T) -> 'Sequence[Sequence[T]]': 

45 ''' 

46 Like str.split but for lists/tuples. 

47 Splits a sequence into several sequences. 

48 ''' 

49 out: 'list[Sequence[T]]' = [] 

50 i0 = 0 

51 while True: 

52 try: 

53 i1 = l.index(sep, i0) 

54 except ValueError: 

55 break 

56 out.append(l[i0:i1]) 

57 i0 = i1 + 1 

58 out.append(l[i0:]) 

59 return out