Use a nametuple for `readouterr()` results

This allows accessing `out` and `err` directly by attribute,
while preserving tuple unpacking.

Also added tests, one for the `capsys` fixture, and one for the
`MultiCapture` class itself.
This commit is contained in:
Samuel Dion-Girardeau 2017-10-28 14:53:19 -04:00
parent def471b975
commit b27dde24d6
2 changed files with 22 additions and 2 deletions

View File

@ -4,6 +4,7 @@ per-test stdout/stderr capturing mechanism.
"""
from __future__ import absolute_import, division, print_function
import collections
import contextlib
import sys
import os
@ -306,6 +307,9 @@ class EncodedFile(object):
return getattr(object.__getattribute__(self, "buffer"), name)
CaptureResult = collections.namedtuple("CaptureResult", ["out", "err"])
class MultiCapture(object):
out = err = in_ = None
@ -366,8 +370,8 @@ class MultiCapture(object):
def readouterr(self):
""" return snapshot unicode value of stdout/stderr capturings. """
return (self.out.snap() if self.out is not None else "",
self.err.snap() if self.err is not None else "")
return CaptureResult(self.out.snap() if self.out is not None else "",
self.err.snap() if self.err is not None else "")
class NoCapture:

View File

@ -922,6 +922,14 @@ class TestStdCapture(object):
out, err = cap.readouterr()
assert err == "error2"
def test_capture_results_accessible_by_attribute(self):
with self.getcapture() as cap:
sys.stdout.write("hello")
sys.stderr.write("world")
capture_result = cap.readouterr()
assert capture_result.out == "hello"
assert capture_result.err == "world"
def test_capturing_readouterr_unicode(self):
with self.getcapture() as cap:
print("hx\xc4\x85\xc4\x87")
@ -1083,6 +1091,14 @@ def test_using_capsys_fixture_works_with_sys_stdout_encoding(capsys):
assert err == ''
def test_capsys_results_accessible_by_attribute(capsys):
sys.stdout.write("spam")
sys.stderr.write("eggs")
capture_result = capsys.readouterr()
assert capture_result.out == "spam"
assert capture_result.err == "eggs"
@needsosdup
@pytest.mark.parametrize('use', [True, False])
def test_fdcapture_tmpfile_remains_the_same(tmpfile, use):