##// END OF EJS Templates
fix types
M Bussonnier -
Show More
@@ -14,18 +14,19 of subprocess utilities, and it contains tools that are common to all of them.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 import subprocess
17 import os
18 import shlex
18 import shlex
19 import subprocess
19 import sys
20 import sys
20 import os
21 from typing import IO, Any, Callable, List, Union
21 from typing import Callable, Optional, Union, List
22
22 from IPython.utils import py3compat
23 from IPython.utils import py3compat
23
24
24 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
25 # Function definitions
26 # Function definitions
26 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
27
28
28 def read_no_interrupt(p: subprocess.Popen) -> str:
29 def read_no_interrupt(stream: IO[Any]) -> bytes:
29 """Read from a pipe ignoring EINTR errors.
30 """Read from a pipe ignoring EINTR errors.
30
31
31 This is necessary because when reading from pipes with GUI event loops
32 This is necessary because when reading from pipes with GUI event loops
@@ -34,7 +35,7 def read_no_interrupt(p: subprocess.Popen) -> str:
34 import errno
35 import errno
35
36
36 try:
37 try:
37 return p.read()
38 return stream.read()
38 except IOError as err:
39 except IOError as err:
39 if err.errno != errno.EINTR:
40 if err.errno != errno.EINTR:
40 raise
41 raise
@@ -15,23 +15,23 This file is only meant to be imported by process.py, not by end-users.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 # stdlib
17 # stdlib
18 import ctypes
18 import os
19 import os
20 import subprocess
19 import sys
21 import sys
20 import ctypes
21 import time
22 import time
22
23 from ctypes import POINTER, c_int
23 from ctypes import c_int, POINTER
24 from ctypes.wintypes import HLOCAL, LPCWSTR
24 from ctypes.wintypes import LPCWSTR, HLOCAL
25 from subprocess import STDOUT
25 from subprocess import STDOUT, TimeoutExpired
26 from threading import Thread
26 from threading import Thread
27 import subprocess
27 from types import TracebackType
28 from typing import IO, Any, List, Optional
28
29
29 from typing import Optional, List
30 from . import py3compat
30 import traceback
31 from ._process_common import arg_split as py_arg_split
31
32
32 # our own imports
33 # our own imports
33 from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
34 from ._process_common import process_handler, read_no_interrupt
34 from . import py3compat
35 from .encoding import DEFAULT_ENCODING
35 from .encoding import DEFAULT_ENCODING
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
@@ -72,7 +72,7 class AvoidUNCPath:
72 return None
72 return None
73
73
74 def __exit__(
74 def __exit__(
75 self, exc_type: Optional[type], exc_value: Optional[BaseException], traceback
75 self, exc_type: Optional[type[BaseException]], exc_value: Optional[BaseException], traceback:TracebackType
76 ) -> None:
76 ) -> None:
77 if self.is_unc_path:
77 if self.is_unc_path:
78 os.chdir(self.path)
78 os.chdir(self.path)
@@ -82,18 +82,23 def _system_body(p: subprocess.Popen) -> int:
82 """Callback for _system."""
82 """Callback for _system."""
83 enc = DEFAULT_ENCODING
83 enc = DEFAULT_ENCODING
84
84
85 # Dec 2024: in both of these functions, I'm not sure why we .splitlines()
86 # the bytes and then decode each line individually instead of just decoding
87 # the whole thing at once.
85 def stdout_read() -> None:
88 def stdout_read() -> None:
86 try:
89 try:
87 for line in read_no_interrupt(p.stdout).splitlines():
90 assert p.stdout is not None
88 line = line.decode(enc, "replace")
91 for byte_line in read_no_interrupt(p.stdout).splitlines():
92 line = byte_line.decode(enc, "replace")
89 print(line, file=sys.stdout)
93 print(line, file=sys.stdout)
90 except Exception as e:
94 except Exception as e:
91 print(f"Error reading stdout: {e}", file=sys.stderr)
95 print(f"Error reading stdout: {e}", file=sys.stderr)
92
96
93 def stderr_read() -> None:
97 def stderr_read() -> None:
94 try:
98 try:
95 for line in read_no_interrupt(p.stderr).splitlines():
99 assert p.stderr is not None
96 line = line.decode(enc, "replace")
100 for byte_line in read_no_interrupt(p.stderr).splitlines():
101 line = byte_line.decode(enc, "replace")
97 print(line, file=sys.stderr)
102 print(line, file=sys.stderr)
98 except Exception as e:
103 except Exception as e:
99 print(f"Error reading stderr: {e}", file=sys.stderr)
104 print(f"Error reading stderr: {e}", file=sys.stderr)
@@ -204,7 +209,7 try:
204 )
209 )
205 if arg is not None
210 if arg is not None
206 ]
211 ]
207 retval = LocalFree(result_pointer)
212 LocalFree(result_pointer)
208 return result
213 return result
209 except AttributeError:
214 except AttributeError:
210 arg_split = py_arg_split
215 arg_split = py_arg_split
General Comments 0
You need to be logged in to leave comments. Login now