Skip to content

Commit cc94708

Browse files
committed
ENH/CLN: use @jtratner's decorator to check for raised warnings
1 parent 7e4b27f commit cc94708

File tree

3 files changed

+54
-25
lines changed

3 files changed

+54
-25
lines changed

pandas/tests/test_graphics.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,12 @@ def test_invalid_plot_data(self):
199199

200200
@slow
201201
def test_valid_object_plot(self):
202-
from pandas.io.pytables import PerformanceWarning
202+
from pandas.io.common import PerformanceWarning
203203
s = Series(range(10), dtype=object)
204204
kinds = 'line', 'bar', 'barh', 'kde', 'density'
205205

206206
for kind in kinds:
207-
tm.assert_warns(PerformanceWarning, _check_plot_works, s.plot,
208-
kind=kind)
207+
_check_plot_works(s.plot, kind=kind)
209208

210209
def test_partially_invalid_plot_data(self):
211210
s = Series(['a', 'b', 1.0, 2])

pandas/tools/plotting.py

+10-13
Original file line numberDiff line numberDiff line change
@@ -877,25 +877,21 @@ def _get_layout(self):
877877
return (len(self.data.columns), 1)
878878

879879
def _compute_plot_data(self):
880-
from pandas.io.pytables import PerformanceWarning
881880
try:
882-
# might be a frame
881+
# might be an ndframe
883882
numeric_data = self.data._get_numeric_data()
884-
except AttributeError:
883+
except AttributeError: # TODO: rm in 0.12 (series-inherit-ndframe)
885884
numeric_data = self.data
886885
orig_dtype = numeric_data.dtype
887886

887+
# possible object array of numeric data
888888
if orig_dtype == np.object_:
889-
# attempt soft conversion, but raise a perf warning
890-
numeric_data = numeric_data.convert_objects()
891-
num_data_dtype = numeric_data.dtype
889+
numeric_data = numeric_data.convert_objects() # soft convert
892890

893-
if num_data_dtype == np.object_:
894-
raise TypeError('No numeric data to plot')
895-
else:
896-
warnings.warn('Coerced object dtype to numeric dtype, '
897-
'you should avoid object dtyped Series if '
898-
'possible', PerformanceWarning)
891+
# still an object dtype so we can't plot it
892+
if numeric_data.dtype == np.object_:
893+
raise TypeError('Series has object dtype and cannot be'
894+
' converted: no numeric data to plot')
899895

900896
try:
901897
is_empty = numeric_data.empty
@@ -904,7 +900,8 @@ def _compute_plot_data(self):
904900

905901
# no empty frames or series allowed
906902
if is_empty:
907-
raise TypeError('No numeric data to plot')
903+
raise TypeError('Empty {0!r}: no numeric data to '
904+
'plot'.format(numeric_data.__class__.__name__))
908905

909906
self.data = numeric_data
910907

pandas/util/testing.py

+42-9
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
def rands(n):
4242
choices = string.ascii_letters + string.digits
43-
return ''.join([random.choice(choices) for _ in xrange(n)])
43+
return ''.join(random.choice(choices) for _ in xrange(n))
4444

4545

4646
def randu(n):
@@ -749,13 +749,46 @@ def stdin_encoding(encoding=None):
749749
sys.stdin = _stdin
750750

751751

752-
def assert_warns(warning, f, *args, **kwargs):
752+
@contextmanager
753+
def assert_produces_warning(expected_warning=Warning, filter_level="always"):
753754
"""
754-
From: http://stackoverflow.com/questions/3892218/how-to-test-with-pythons-unittest-that-a-warning-has-been-thrown
755+
Context manager for running code that expects to raise (or not raise)
756+
warnings. Checks that code raises the expected warning and only the
757+
expected warning. Pass ``False`` or ``None`` to check that it does *not*
758+
raise a warning. Defaults to ``exception.Warning``, baseclass of all
759+
Warnings. (basically a wrapper around ``warnings.catch_warnings``).
760+
761+
>>> import warnings
762+
>>> with assert_produces_warning():
763+
... warnings.warn(UserWarning())
764+
...
765+
>>> with assert_produces_warning(False):
766+
... warnings.warn(RuntimeWarning())
767+
...
768+
Traceback (most recent call last):
769+
...
770+
AssertionError: Caused unexpected warning(s): ['RuntimeWarning'].
771+
>>> with assert_produces_warning(UserWarning):
772+
... warnings.warn(RuntimeWarning())
773+
Traceback (most recent call last):
774+
...
775+
AssertionError: Did not see expected warning of class 'UserWarning'.
776+
777+
..warn:: This is *not* thread-safe.
755778
"""
756-
with warnings.catch_warnings(record=True) as warning_list:
757-
warnings.simplefilter('always')
758-
f(*args, **kwargs)
759-
msg = '{0!r} not raised'.format(warning)
760-
assert any(issubclass(item.category, warning)
761-
for item in warning_list), msg
779+
with warnings.catch_warnings(record=True) as w:
780+
saw_warning = False
781+
warnings.simplefilter(filter_level)
782+
yield w
783+
extra_warnings = []
784+
for actual_warning in w:
785+
if (expected_warning and issubclass(actual_warning.category,
786+
expected_warning)):
787+
saw_warning = True
788+
else:
789+
extra_warnings.append(actual_warning.category.__name__)
790+
if expected_warning:
791+
assert saw_warning, ("Did not see expected warning of class %r."
792+
% expected_warning.__name__)
793+
assert not extra_warnings, ("Caused unexpected warning(s): %r."
794+
% extra_warnings)

0 commit comments

Comments
 (0)