Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REF/TST: replace capture_stderr with pytest capsys fixture #24496

Merged
merged 9 commits into from
Dec 30, 2018
8 changes: 3 additions & 5 deletions pandas/tests/indexes/datetimes/test_datetime.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from datetime import date
import sys

import dateutil
import numpy as np
Expand Down Expand Up @@ -125,15 +124,14 @@ def test_map(self):
exp = Index([f(x) for x in rng], dtype='<U8')
tm.assert_index_equal(result, exp)

@tm.capture_stderr
def test_map_fallthrough(self):
def test_map_fallthrough(self, capsys):
# GH#22067, check we don't get warnings about silently ignored errors
dti = date_range('2017-01-01', '2018-01-01', freq='B')

dti.map(lambda x: pd.Period(year=x.year, month=x.month, freq='M'))

cv = sys.stderr.getvalue()
assert cv == ''
captured = capsys.readouterr()
assert captured.err == ''

def test_iteration_preserves_tz(self):
# see gh-8890
Expand Down
8 changes: 3 additions & 5 deletions pandas/tests/io/parser/test_c_parser_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from io import TextIOWrapper
import mmap
import os
import sys
import tarfile

import numpy as np
Expand Down Expand Up @@ -449,8 +448,7 @@ def test_data_after_quote(c_parser_only):
tm.assert_frame_equal(result, expected)


@tm.capture_stderr
def test_comment_whitespace_delimited(c_parser_only):
def test_comment_whitespace_delimited(c_parser_only, capsys):
parser = c_parser_only
test_input = """\
1 2
Expand All @@ -466,10 +464,10 @@ def test_comment_whitespace_delimited(c_parser_only):
df = parser.read_csv(StringIO(test_input), comment="#", header=None,
delimiter="\\s+", skiprows=0,
error_bad_lines=False)
error = sys.stderr.getvalue()
captured = capsys.readouterr()
# skipped lines 2, 3, 4, 9
for line_num in (2, 3, 4, 9):
assert "Skipping line {}".format(line_num) in error, error
assert "Skipping line {}".format(line_num) in captured.err
expected = DataFrame([[1, 2],
[5, 2],
[6, 2],
Expand Down
16 changes: 7 additions & 9 deletions pandas/tests/io/parser/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1867,8 +1867,7 @@ def test_error_bad_lines(all_parsers, kwargs, warn_kwargs):
parser.read_csv(StringIO(data), **kwargs)


@tm.capture_stderr
def test_warn_bad_lines(all_parsers):
def test_warn_bad_lines(all_parsers, capsys):
# see gh-15925
parser = all_parsers
data = "a\n1\n1,2,3\n4\n5,6,7"
Expand All @@ -1879,13 +1878,12 @@ def test_warn_bad_lines(all_parsers):
warn_bad_lines=True)
tm.assert_frame_equal(result, expected)

val = sys.stderr.getvalue()
assert "Skipping line 3" in val
assert "Skipping line 5" in val
captured = capsys.readouterr()
assert "Skipping line 3" in captured.err
assert "Skipping line 5" in captured.err


@tm.capture_stderr
def test_suppress_error_output(all_parsers):
def test_suppress_error_output(all_parsers, capsys):
# see gh-15925
parser = all_parsers
data = "a\n1\n1,2,3\n4\n5,6,7"
Expand All @@ -1896,8 +1894,8 @@ def test_suppress_error_output(all_parsers):
warn_bad_lines=False)
tm.assert_frame_equal(result, expected)

val = sys.stderr.getvalue()
assert val == ""
captured = capsys.readouterr()
assert captured.err == ""


def test_read_table_deprecated(all_parsers):
Expand Down
8 changes: 3 additions & 5 deletions pandas/tests/io/parser/test_python_parser_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"""

import csv
import sys

import pytest

Expand Down Expand Up @@ -248,8 +247,7 @@ def fail_read():
fail_read()


@tm.capture_stderr
def test_none_delimiter(python_parser_only):
def test_none_delimiter(python_parser_only, capsys):
# see gh-13374 and gh-17465
parser = python_parser_only
data = "a,b,c\n0,1,2\n3,4,5,6\n7,8,9"
Expand All @@ -263,8 +261,8 @@ def test_none_delimiter(python_parser_only):
error_bad_lines=False)
tm.assert_frame_equal(result, expected)

warning = sys.stderr.getvalue()
assert "Skipping line 3" in warning
captured = capsys.readouterr()
assert "Skipping line 3" in captured.err


@pytest.mark.parametrize("data", [
Expand Down
10 changes: 4 additions & 6 deletions pandas/tests/io/parser/test_textreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"""

import os
import sys

import numpy as np
from numpy import nan
Expand Down Expand Up @@ -135,8 +134,7 @@ def test_integer_thousands_alt(self):
expected = DataFrame([123456, 12500])
tm.assert_frame_equal(result, expected)

@tm.capture_stderr
def test_skip_bad_lines(self):
def test_skip_bad_lines(self, capsys):
# too many lines, see #2430 for why
data = ('a:b:c\n'
'd:e:f\n'
Expand Down Expand Up @@ -164,10 +162,10 @@ def test_skip_bad_lines(self):
error_bad_lines=False,
warn_bad_lines=True)
reader.read()
val = sys.stderr.getvalue()
captured = capsys.readouterr()

assert 'Skipping line 4' in val
assert 'Skipping line 6' in val
assert 'Skipping line 4' in captured.err
assert 'Skipping line 6' in captured.err

def test_header_not_enough_lines(self):
data = ('skip this\n'
Expand Down
8 changes: 3 additions & 5 deletions pandas/tests/series/test_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# pylint: disable-msg=E1101,W0612

from datetime import datetime, timedelta
import sys

import numpy as np

Expand Down Expand Up @@ -121,15 +120,14 @@ def test_tidy_repr(self):
a.name = 'title1'
repr(a) # should not raise exception

@tm.capture_stderr
def test_repr_bool_fails(self):
def test_repr_bool_fails(self, capsys):
s = Series([DataFrame(np.random.randn(2, 2)) for i in range(5)])

# It works (with no Cython exception barf)!
repr(s)

output = sys.stderr.getvalue()
assert output == ''
captured = capsys.readouterr()
assert captured.err == ''

def test_repr_name_iterable_indexable(self):
s = Series([1, 2, 3], name=np.int64(3))
Expand Down
46 changes: 0 additions & 46 deletions pandas/util/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,52 +684,6 @@ def wrapper(*args, **kwargs):
return wrapper


def capture_stderr(f):
r"""
Decorator to capture stderr in a buffer so that it can be checked
(or suppressed) during testing.

Parameters
----------
f : callable
The test that is capturing stderr.

Returns
-------
f : callable
The decorated test ``f``, which captures stderr.

Examples
--------

>>> from pandas.util.testing import capture_stderr
>>> import sys
>>>
>>> @capture_stderr
... def test_stderr_pass():
... sys.stderr.write("foo")
... out = sys.stderr.getvalue()
... assert out == "foo\n"
>>>
>>> @capture_stderr
... def test_stderr_fail():
... sys.stderr.write("foo")
... out = sys.stderr.getvalue()
... assert out == "bar\n"
...
AssertionError: assert 'foo\n' == 'bar\n'
"""

@compat.wraps(f)
def wrapper(*args, **kwargs):
try:
sys.stderr = StringIO()
f(*args, **kwargs)
finally:
sys.stderr = sys.__stderr__

return wrapper

# -----------------------------------------------------------------------------
# Console debugging tools

Expand Down
13 changes: 4 additions & 9 deletions scripts/tests/test_validate_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import textwrap
import pytest
import numpy as np
from pandas.util.testing import capture_stderr
import validate_docstrings
validate_one = validate_docstrings.validate_one

Expand Down Expand Up @@ -739,36 +738,32 @@ def _import_path(self, klass=None, func=None):

return base_path

@capture_stderr
def test_good_class(self):
def test_good_class(self, capsys):
errors = validate_one(self._import_path(
klass='GoodDocStrings'))['errors']
assert isinstance(errors, list)
assert not errors

@capture_stderr
@pytest.mark.parametrize("func", [
'plot', 'sample', 'random_letters', 'sample_values', 'head', 'head1',
'contains', 'mode', 'good_imports'])
def test_good_functions(self, func):
def test_good_functions(self, capsys, func):
errors = validate_one(self._import_path(
klass='GoodDocStrings', func=func))['errors']
assert isinstance(errors, list)
assert not errors

@capture_stderr
def test_bad_class(self):
def test_bad_class(self, capsys):
errors = validate_one(self._import_path(
klass='BadGenericDocStrings'))['errors']
assert isinstance(errors, list)
assert errors

@capture_stderr
@pytest.mark.parametrize("func", [
'func', 'astype', 'astype1', 'astype2', 'astype3', 'plot', 'method',
'private_classes',
])
def test_bad_generic_functions(self, func):
def test_bad_generic_functions(self, capsys, func):
errors = validate_one(self._import_path( # noqa:F821
klass='BadGenericDocStrings', func=func))['errors']
assert isinstance(errors, list)
Expand Down