1818import shlex
1919import subprocess
2020import sys
21- from typing import IO , Any , List , Union
21+ from typing import IO , List , TypeVar , Union
2222from collections .abc import Callable
2323
24+ _T = TypeVar ("_T" )
25+
2426from IPython .utils import py3compat
2527
2628#-----------------------------------------------------------------------------
2729# Function definitions
2830#-----------------------------------------------------------------------------
2931
30- def read_no_interrupt (stream : IO [Any ]) -> bytes | None :
32+ def read_no_interrupt (stream : IO [bytes ]) -> bytes | None :
3133 """Read from a pipe ignoring EINTR errors.
3234
3335 This is necessary because when reading from pipes with GUI event loops
@@ -40,13 +42,14 @@ def read_no_interrupt(stream: IO[Any]) -> bytes | None:
4042 except IOError as err :
4143 if err .errno != errno .EINTR :
4244 raise
45+ return None
4346
4447
4548def process_handler (
4649 cmd : Union [str , List [str ]],
47- callback : Callable [[subprocess .Popen ], int | str | bytes ],
50+ callback : Callable [[subprocess .Popen [ bytes ]], _T ],
4851 stderr : int = subprocess .PIPE ,
49- ) -> int | str | bytes | None :
52+ ) -> _T | None :
5053 """Open a command in a shell subprocess and execute a callback.
5154
5255 This function provides common scaffolding for creating subprocess.Popen()
@@ -137,7 +140,6 @@ def getoutput(cmd: str | list[str]) -> str:
137140 out = process_handler (cmd , lambda p : p .communicate ()[0 ], subprocess .STDOUT )
138141 if out is None :
139142 return ''
140- assert isinstance (out , bytes )
141143 return py3compat .decode (out )
142144
143145
@@ -177,10 +179,10 @@ def get_output_error_code(cmd: str | list[str]) -> tuple[str, str, int | None]:
177179 returncode: int
178180 """
179181
180- out_err , p = process_handler (cmd , lambda p : (p .communicate (), p ))
181- if out_err is None :
182- return '' , '' , p . returncode
183- out , err = out_err
182+ result = process_handler (cmd , lambda p : (p .communicate (), p ))
183+ if result is None :
184+ return '' , '' , None
185+ ( out , err ), p = result
184186 return py3compat .decode (out ), py3compat .decode (err ), p .returncode
185187
186188def arg_split (commandline : str , posix : bool = False , strict : bool = True ) -> list [str ]:
@@ -196,7 +198,7 @@ def arg_split(commandline: str, posix: bool = False, strict: bool = True) -> lis
196198 command-line args.
197199 """
198200
199- lex = shlex .shlex (s , posix = posix )
201+ lex = shlex .shlex (commandline , posix = posix )
200202 lex .whitespace_split = True
201203 # Extract tokens, ensuring that things like leaving open quotes
202204 # does not cause this to raise. This is important, because we
0 commit comments