Skip to content

Commit fd09897

Browse files
authored
Add tee optional argument (#37)
1 parent ad2a82b commit fd09897

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# subprocess-tee
22

3-
This package provides an drop-in alternative to `subprocess.run` that
4-
captures the output while still printing it in **real time**, just the way `tee` does.
3+
This package provides a drop-in alternative to `subprocess.run` that
4+
captures the output while still printing it in **real-time**, just the way
5+
`tee` does.
56

6-
Printing output in real-time while still capturing is important for
7-
any tool that executes long running child processes, as you may not want
8-
to deprive user from getting instant feedback related to what is happening.
7+
Printing output in real-time while still capturing is valuable for
8+
any tool that executes long-running child processes. For those, you do want
9+
to provide instant feedback (progress) related to what is happening.
910

1011
```python
1112
# from subprocess import run
@@ -14,3 +15,13 @@ from subprocess_tee import run
1415
result = run("echo 123")
1516
result.stdout == "123\n"
1617
```
18+
19+
You can add `tee=False` to disable the tee functionality if you want, this
20+
being a much shorter alternative than adding the well known
21+
`stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL`.
22+
23+
Keep in mind that `universal_newlines=True` is implied as we expect text
24+
processing, this being a divergence from the original `subprocess.run`.
25+
26+
You can still use `check=True` in order to make it raise CompletedProcess
27+
exception when the result code is not zero.

src/subprocess_tee/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ async def _stream_subprocess(args: str, **kwargs: Any) -> CompletedProcess:
3333
platform_settings["env"] = os.environ
3434

3535
# this part keeps behavior backwards compatible with subprocess.run
36+
tee = kwargs.get("tee", True)
3637
stdout = kwargs.get("stdout", sys.stdout)
37-
if stdout == subprocess.DEVNULL:
38+
if stdout == subprocess.DEVNULL or not tee:
3839
stdout = open(os.devnull, "w")
3940
stderr = kwargs.get("stderr", sys.stderr)
40-
if stderr == subprocess.DEVNULL:
41+
if stderr == subprocess.DEVNULL or not tee:
4142
stderr = open(os.devnull, "w")
4243

4344
# We need to tell subprocess which shell to use when running shell-like
@@ -65,7 +66,7 @@ async def _stream_subprocess(args: str, **kwargs: Any) -> CompletedProcess:
6566
out: List[str] = []
6667
err: List[str] = []
6768

68-
def tee(line: bytes, sink: List[str], pipe: Optional[Any]) -> None:
69+
def tee_func(line: bytes, sink: List[str], pipe: Optional[Any]) -> None:
6970
line_str = line.decode("utf-8").rstrip()
7071
sink.append(line_str)
7172
if not kwargs.get("quiet", False):
@@ -76,13 +77,13 @@ def tee(line: bytes, sink: List[str], pipe: Optional[Any]) -> None:
7677
if process.stdout:
7778
tasks.append(
7879
loop.create_task(
79-
_read_stream(process.stdout, lambda l: tee(l, out, stdout))
80+
_read_stream(process.stdout, lambda l: tee_func(l, out, stdout))
8081
)
8182
)
8283
if process.stderr:
8384
tasks.append(
8485
loop.create_task(
85-
_read_stream(process.stderr, lambda l: tee(l, err, stderr))
86+
_read_stream(process.stderr, lambda l: tee_func(l, err, stderr))
8687
)
8788
)
8889

0 commit comments

Comments
 (0)