Show More
@@ -14,18 +14,19 of subprocess utilities, and it contains tools that are common to all of them. | |||
|
14 | 14 | #----------------------------------------------------------------------------- |
|
15 | 15 | # Imports |
|
16 | 16 | #----------------------------------------------------------------------------- |
|
17 |
import |
|
|
17 | import os | |
|
18 | 18 | import shlex |
|
19 | import subprocess | |
|
19 | 20 | import sys |
|
20 | import os | |
|
21 | from typing import Callable, Optional, Union, List | |
|
21 | from typing import IO, Any, Callable, List, Union | |
|
22 | ||
|
22 | 23 | from IPython.utils import py3compat |
|
23 | 24 | |
|
24 | 25 | #----------------------------------------------------------------------------- |
|
25 | 26 | # Function definitions |
|
26 | 27 | #----------------------------------------------------------------------------- |
|
27 | 28 | |
|
28 |
def read_no_interrupt( |
|
|
29 | def read_no_interrupt(stream: IO[Any]) -> bytes: | |
|
29 | 30 | """Read from a pipe ignoring EINTR errors. |
|
30 | 31 | |
|
31 | 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 | 35 | import errno |
|
35 | 36 | |
|
36 | 37 | try: |
|
37 |
return |
|
|
38 | return stream.read() | |
|
38 | 39 | except IOError as err: |
|
39 | 40 | if err.errno != errno.EINTR: |
|
40 | 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 | 17 | # stdlib |
|
18 | import ctypes | |
|
18 | 19 | import os |
|
20 | import subprocess | |
|
19 | 21 | import sys |
|
20 | import ctypes | |
|
21 | 22 | import time |
|
22 | ||
|
23 |
from ctypes import |
|
|
24 | from ctypes.wintypes import LPCWSTR, HLOCAL | |
|
25 | from subprocess import STDOUT, TimeoutExpired | |
|
23 | from ctypes import POINTER, c_int | |
|
24 | from ctypes.wintypes import HLOCAL, LPCWSTR | |
|
25 | from subprocess import STDOUT | |
|
26 | 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 | import traceback | |
|
30 | from . import py3compat | |
|
31 | from ._process_common import arg_split as py_arg_split | |
|
31 | 32 | |
|
32 | 33 | # our own imports |
|
33 |
from ._process_common import |
|
|
34 | from . import py3compat | |
|
34 | from ._process_common import process_handler, read_no_interrupt | |
|
35 | 35 | from .encoding import DEFAULT_ENCODING |
|
36 | 36 | |
|
37 | 37 | #----------------------------------------------------------------------------- |
@@ -72,7 +72,7 class AvoidUNCPath: | |||
|
72 | 72 | return None |
|
73 | 73 | |
|
74 | 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 | 76 | ) -> None: |
|
77 | 77 | if self.is_unc_path: |
|
78 | 78 | os.chdir(self.path) |
@@ -82,18 +82,23 def _system_body(p: subprocess.Popen) -> int: | |||
|
82 | 82 | """Callback for _system.""" |
|
83 | 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 | 88 | def stdout_read() -> None: |
|
86 | 89 | try: |
|
87 | for line in read_no_interrupt(p.stdout).splitlines(): | |
|
88 | line = line.decode(enc, "replace") | |
|
90 | assert p.stdout is not None | |
|
91 | for byte_line in read_no_interrupt(p.stdout).splitlines(): | |
|
92 | line = byte_line.decode(enc, "replace") | |
|
89 | 93 | print(line, file=sys.stdout) |
|
90 | 94 | except Exception as e: |
|
91 | 95 | print(f"Error reading stdout: {e}", file=sys.stderr) |
|
92 | 96 | |
|
93 | 97 | def stderr_read() -> None: |
|
94 | 98 | try: |
|
95 | for line in read_no_interrupt(p.stderr).splitlines(): | |
|
96 | line = line.decode(enc, "replace") | |
|
99 | assert p.stderr is not None | |
|
100 | for byte_line in read_no_interrupt(p.stderr).splitlines(): | |
|
101 | line = byte_line.decode(enc, "replace") | |
|
97 | 102 | print(line, file=sys.stderr) |
|
98 | 103 | except Exception as e: |
|
99 | 104 | print(f"Error reading stderr: {e}", file=sys.stderr) |
@@ -204,7 +209,7 try: | |||
|
204 | 209 | ) |
|
205 | 210 | if arg is not None |
|
206 | 211 | ] |
|
207 |
|
|
|
212 | LocalFree(result_pointer) | |
|
208 | 213 | return result |
|
209 | 214 | except AttributeError: |
|
210 | 215 | arg_split = py_arg_split |
General Comments 0
You need to be logged in to leave comments.
Login now