Skip to content

Commit

Permalink
procs: Add CommandPipeline.raw_out for retreival of the raw stdout bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-shimon committed Oct 23, 2020
1 parent 1ee8e38 commit d85ed4a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
23 changes: 23 additions & 0 deletions news/command-pipeline-raw-out.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* Added ``CommandPipeline.raw_out`` to get stdout as raw bytes.

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
20 changes: 20 additions & 0 deletions tests/test_procs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
Tests for subprocesses and CommandPipeline.
"""

import pytest
from xonsh.procs.pipelines import CommandPipeline


@pytest.mark.parametrize("cmdline, stdout, stderr", (
("!(echo hi)", b"hi\n", None),
("![echo hi]", b"hi\n", None),
("!(echo hi o>e)", b"", "hi\n"),
("![echo hi o>e]", b"", "hi\n"),
(r"!(echo 'hi\nho')", b"hi\nho\n", None),
))
def test_captured(xonsh_execer, cmdline, stdout, stderr):
pipeline: CommandPipeline = xonsh_execer.eval(cmdline)
assert pipeline.raw_out == stdout
assert pipeline.out == stdout.decode()
assert pipeline.err == stderr
13 changes: 13 additions & 0 deletions xonsh/procs/pipelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ def __init__(self, specs):
self.input = self._output = self.errors = self.endtime = None
self._closed_handle_cache = {}
self.lines = []
self.raw_output = b""
self._stderr_prefix = self._stderr_postfix = None
self.term_pgid = None

Expand Down Expand Up @@ -331,6 +332,7 @@ def tee_stdout(self):
enc = env.get("XONSH_ENCODING")
err = env.get("XONSH_ENCODING_ERRORS")
lines = self.lines
raw_lines = []
stream = self.captured not in STDOUT_CAPTURE_KINDS
if stream and not self.spec.stdout:
stream = False
Expand All @@ -346,6 +348,8 @@ def tee_stdout(self):
else:
sys.stdout.write(line.decode(encoding=enc, errors=err))
sys.stdout.flush()
# save the raw bytes
raw_lines.append(line)
# do some munging of the line before we return it
if line.endswith(crnl):
line = line[:-2] + nl
Expand All @@ -357,6 +361,9 @@ def tee_stdout(self):
lines.append(line)
yield line

# using join is more efficient than concatenating in a loop
self.raw_output = b"".join(raw_lines)

def stream_stderr(self, lines):
"""Streams lines to sys.stderr and the errors attribute."""
if not lines:
Expand Down Expand Up @@ -613,6 +620,12 @@ def err(self):
self.end()
return self.errors

@property
def raw_out(self):
"""Output as raw bytes."""
self.end()
return self.raw_output

@property
def pid(self):
"""Process identifier."""
Expand Down

0 comments on commit d85ed4a

Please sign in to comment.