Skip to content

Commit be2a65c

Browse files
committed
Merge pull request #4721 from jtratner/change-bare-exceptions-pt-2
CLN: Improve Exceptions in core/common, io/excel and core/format
2 parents 8f9adb7 + 56c73a4 commit be2a65c

File tree

6 files changed

+51
-41
lines changed

6 files changed

+51
-41
lines changed

doc/source/release.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ pandas 0.13
7171
when the key is a column
7272
- Support for using a ``DatetimeIndex/PeriodsIndex`` directly in a datelike calculation
7373
e.g. s-s.index (:issue:`4629`)
74+
- Better/cleaned up exceptions in core/common, io/excel and core/format.
75+
(:issue:`4721`, :issue:`3954`)
7476

7577
**API Changes**
7678

pandas/core/common.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ def take_nd(arr, indexer, axis=0, out=None, fill_value=np.nan,
541541
mask_info = mask, needs_masking
542542
if needs_masking:
543543
if out is not None and out.dtype != dtype:
544-
raise Exception('Incompatible type for fill_value')
544+
raise TypeError('Incompatible type for fill_value')
545545
else:
546546
# if not, then depromote, set fill_value to dummy
547547
# (it won't be used but we don't want the cython code
@@ -612,7 +612,7 @@ def take_2d_multi(arr, indexer, out=None, fill_value=np.nan,
612612
mask_info = (row_mask, col_mask), (row_needs, col_needs)
613613
if row_needs or col_needs:
614614
if out is not None and out.dtype != dtype:
615-
raise Exception('Incompatible type for fill_value')
615+
raise TypeError('Incompatible type for fill_value')
616616
else:
617617
# if not, then depromote, set fill_value to dummy
618618
# (it won't be used but we don't want the cython code
@@ -857,8 +857,8 @@ def changeit():
857857

858858
# if we are trying to do something unsafe
859859
# like put a bigger dtype in a smaller one, use the smaller one
860-
if change.dtype.itemsize < r.dtype.itemsize:
861-
raise Exception(
860+
if change.dtype.itemsize < r.dtype.itemsize: # pragma: no cover
861+
raise AssertionError(
862862
"cannot change dtype of input to smaller size")
863863
change.dtype = r.dtype
864864
change[:] = r
@@ -1159,8 +1159,8 @@ def interpolate_2d(values, method='pad', axis=0, limit=None, fill_value=None):
11591159
# reshape a 1 dim if needed
11601160
ndim = values.ndim
11611161
if values.ndim == 1:
1162-
if axis != 0:
1163-
raise Exception("cannot interpolate on a ndim == 1 with axis != 0")
1162+
if axis != 0: # pragma: no cover
1163+
raise AssertionError("cannot interpolate on a ndim == 1 with axis != 0")
11641164
values = values.reshape(tuple((1,) + values.shape))
11651165

11661166
if fill_value is None:
@@ -1434,13 +1434,17 @@ def ensure_float(arr):
14341434
return arr
14351435

14361436

1437-
def _mut_exclusive(arg1, arg2):
1438-
if arg1 is not None and arg2 is not None:
1439-
raise Exception('mutually exclusive arguments')
1440-
elif arg1 is not None:
1441-
return arg1
1437+
def _mut_exclusive(**kwargs):
1438+
item1, item2 = kwargs.items()
1439+
label1, val1 = item1
1440+
label2, val2 = item2
1441+
if val1 is not None and val2 is not None:
1442+
raise TypeError('mutually exclusive arguments: %r and %r' %
1443+
(label1, label2))
1444+
elif val1 is not None:
1445+
return val1
14421446
else:
1443-
return arg2
1447+
return val2
14441448

14451449

14461450
def _any_none(*args):

pandas/core/format.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from __future__ import print_function
22
# pylint: disable=W0141
33

4-
from pandas import compat
54
import sys
65

7-
from pandas.compat import StringIO, lzip, range, map, zip, reduce, u, OrderedDict
86
from pandas.core.common import adjoin, isnull, notnull
97
from pandas.core.index import Index, MultiIndex, _ensure_index
108
from pandas import compat
9+
from pandas.compat import(StringIO, lzip, range, map, zip, reduce, u,
10+
OrderedDict)
1111
from pandas.util.terminal import get_terminal_size
1212
from pandas.core.config import get_option, set_option, reset_option
1313
import pandas.core.common as com
@@ -356,7 +356,7 @@ def get_col_type(dtype):
356356
column_format = 'l%s' % ''.join(map(get_col_type, dtypes))
357357
else:
358358
column_format = '%s' % ''.join(map(get_col_type, dtypes))
359-
elif not isinstance(column_format, compat.string_types):
359+
elif not isinstance(column_format, compat.string_types): # pragma: no cover
360360
raise AssertionError(('column_format must be str or unicode, not %s'
361361
% type(column_format)))
362362

@@ -820,8 +820,9 @@ def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None,
820820

821821
# validate mi options
822822
if self.has_mi_columns:
823-
if cols is not None:
824-
raise Exception("cannot specify cols with a multi_index on the columns")
823+
# guarded against in to_csv itself
824+
if cols is not None: # pragma: no cover
825+
raise AssertionError("cannot specify cols with a multi_index on the columns")
825826

826827
if cols is not None:
827828
if isinstance(cols,Index):

pandas/io/excel.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def __init__(self, path_or_buf, **kwds):
7373
import xlrd # throw an ImportError if we need to
7474

7575
ver = tuple(map(int, xlrd.__VERSION__.split(".")[:2]))
76-
if ver < (0, 9):
76+
if ver < (0, 9): # pragma: no cover
7777
raise ImportError("pandas requires xlrd >= 0.9.0 for excel "
7878
"support, current version " + xlrd.__VERSION__)
7979

@@ -382,8 +382,8 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0):
382382
if sheet_name is None:
383383
sheet_name = self.cur_sheet
384384
if sheet_name is None: # pragma: no cover
385-
raise Exception('Must pass explicit sheet_name or set '
386-
'cur_sheet property')
385+
raise ValueError('Must pass explicit sheet_name or set '
386+
'cur_sheet property')
387387
if self.use_xlsx:
388388
self._writecells_xlsx(cells, sheet_name, startrow, startcol)
389389
else:

pandas/sparse/panel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ def reindex(self, major=None, items=None, minor=None, major_axis=None,
319319
-------
320320
reindexed : SparsePanel
321321
"""
322-
major = com._mut_exclusive(major, major_axis)
323-
minor = com._mut_exclusive(minor, minor_axis)
322+
major = com._mut_exclusive(major=major, major_axis=major_axis)
323+
minor = com._mut_exclusive(minor=minor, minor_axis=minor_axis)
324324

325325
if com._all_none(items, major, minor):
326326
raise ValueError('Must specify at least one axis')

pandas/tests/test_common.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
_multiprocess_can_split_ = True
2121

2222

23+
def test_mut_exclusive():
24+
msg = "mutually exclusive arguments: '[ab]' and '[ab]'"
25+
with tm.assertRaisesRegexp(TypeError, msg):
26+
com._mut_exclusive(a=1, b=2)
27+
assert com._mut_exclusive(a=1, b=None) == 1
28+
assert com._mut_exclusive(major=None, major_axis=None) is None
29+
30+
2331
def test_is_sequence():
2432
is_seq = com._is_sequence
2533
assert(is_seq((1, 2)))
@@ -360,6 +368,8 @@ def test_is_recompilable():
360368

361369

362370
class TestTake(unittest.TestCase):
371+
# standard incompatible fill error
372+
fill_error = re.compile("Incompatible type for fill_value")
363373

364374
_multiprocess_can_split_ = True
365375

@@ -381,8 +391,8 @@ def _test_dtype(dtype, can_hold_na):
381391
expected[3] = np.nan
382392
tm.assert_almost_equal(out, expected)
383393
else:
384-
self.assertRaises(Exception, com.take_1d, data,
385-
indexer, out=out)
394+
with tm.assertRaisesRegexp(TypeError, self.fill_error):
395+
com.take_1d(data, indexer, out=out)
386396
# no exception o/w
387397
data.take(indexer, out=out)
388398

@@ -466,13 +476,11 @@ def _test_dtype(dtype, can_hold_na):
466476
tm.assert_almost_equal(out0, expected0)
467477
tm.assert_almost_equal(out1, expected1)
468478
else:
469-
self.assertRaises(Exception, com.take_nd, data,
470-
indexer, out=out0, axis=0)
471-
self.assertRaises(Exception, com.take_nd, data,
472-
indexer, out=out1, axis=1)
473-
# no exception o/w
474-
data.take(indexer, out=out0, axis=0)
475-
data.take(indexer, out=out1, axis=1)
479+
for i, out in enumerate([out0, out1]):
480+
with tm.assertRaisesRegexp(TypeError, self.fill_error):
481+
com.take_nd(data, indexer, out=out, axis=i)
482+
# no exception o/w
483+
data.take(indexer, out=out, axis=i)
476484

477485
_test_dtype(np.float64, True)
478486
_test_dtype(np.float32, True)
@@ -572,16 +580,11 @@ def _test_dtype(dtype, can_hold_na):
572580
tm.assert_almost_equal(out1, expected1)
573581
tm.assert_almost_equal(out2, expected2)
574582
else:
575-
self.assertRaises(Exception, com.take_nd, data,
576-
indexer, out=out0, axis=0)
577-
self.assertRaises(Exception, com.take_nd, data,
578-
indexer, out=out1, axis=1)
579-
self.assertRaises(Exception, com.take_nd, data,
580-
indexer, out=out2, axis=2)
581-
# no exception o/w
582-
data.take(indexer, out=out0, axis=0)
583-
data.take(indexer, out=out1, axis=1)
584-
data.take(indexer, out=out2, axis=2)
583+
for i, out in enumerate([out0, out1, out2]):
584+
with tm.assertRaisesRegexp(TypeError, self.fill_error):
585+
com.take_nd(data, indexer, out=out, axis=i)
586+
# no exception o/w
587+
data.take(indexer, out=out, axis=i)
585588

586589
_test_dtype(np.float64, True)
587590
_test_dtype(np.float32, True)

0 commit comments

Comments
 (0)