Skip to content
Browse files

TST: test for GH4633, bool(obj) behavior

BUG: GH4633, rever to GH1073, whereby __nonzero__ always raises for all NDFrame objects
  • Loading branch information...
1 parent c472099 commit e47e981f0a72b595e7bdce5e65acee125970e1e4 @jreback jreback committed Aug 23, 2013
View
3 doc/source/release.rst
@@ -130,6 +130,9 @@ pandas 0.13
now returns a ``MultiIndex`` rather than an ``Index``. (:issue:`4039`)
- Infer and downcast dtype if ``downcast='infer'`` is passed to ``fillna/ffill/bfill`` (:issue:`4604`)
+ - Factored out excel_value_to_python_value from ExcelFile::_parse_excel (:issue:`4589`)
+ - ``__nonzero__`` for all NDFrame objects, will now raise a ``ValueError``, this reverts back to (:issue:`1073`, :issue:`4633`)
+ behavior.
**Internal Refactoring**
View
12 doc/source/v0.13.0.txt
@@ -118,6 +118,18 @@ API changes
index.set_names(["bob", "cranberry"], inplace=True)
- Infer and downcast dtype if ``downcast='infer'`` is passed to ``fillna/ffill/bfill`` (:issue:`4604`)
+ - ``__nonzero__`` for all NDFrame objects, will now raise a ``ValueError``, this reverts back to (:issue:`1073`, :issue:`4633`)
+ behavior.
+
+ This prevent behaviors like (which will now all raise ``ValueError``)
+
+ ..code-block ::
+
+ if df:
+ ....
+
+ df1 and df2
+ s1 and s2
Enhancements
~~~~~~~~~~~~
View
3 pandas/core/generic.py
@@ -531,7 +531,8 @@ def empty(self):
return not all(len(self._get_axis(a)) > 0 for a in self._AXIS_ORDERS)
def __nonzero__(self):
- return not self.empty
+ raise ValueError("The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()")
+
__bool__ = __nonzero__
#----------------------------------------------------------------------
View
15 pandas/core/groupby.py
@@ -2101,9 +2101,22 @@ def filter(self, func, dropna=True, *args, **kwargs):
else:
res = path(group)
- if res:
+ def add_indexer():
indexers.append(self.obj.index.get_indexer(group.index))
+ # interpret the result of the filter
+ if isinstance(res,(bool,np.bool_)):
+ if res:
+ add_indexer()
+ else:
+ if getattr(res,'ndim',None) == 1:
+ if res.ravel()[0]:
+ add_indexer()
+ else:
+
+ # in theory you could do .all() on the boolean result ?
+ raise TypeError("the filter must return a boolean result")
+
if len(indexers) == 0:
filtered = self.obj.take([]) # because np.concatenate would fail
else:
View
7 pandas/core/series.py
@@ -798,13 +798,6 @@ def __contains__(self, key):
__long__ = _coerce_method(int)
__int__ = _coerce_method(int)
- def __nonzero__(self):
- # special case of a single element bool series degenerating to a scalar
- if self.dtype == np.bool_ and len(self) == 1:
- return bool(self.iloc[0])
- return not self.empty
- __bool__ = __nonzero__
-
# we are preserving name here
def __getstate__(self):
return dict(_data=self._data, name=self.name)
View
6 pandas/io/tests/test_pytables.py
@@ -1519,19 +1519,19 @@ def test_table_values_dtypes_roundtrip(self):
with ensure_clean(self.path) as store:
df1 = DataFrame({'a': [1, 2, 3]}, dtype='f8')
store.append('df_f8', df1)
- assert df1.dtypes == store['df_f8'].dtypes
+ assert_series_equal(df1.dtypes,store['df_f8'].dtypes)
df2 = DataFrame({'a': [1, 2, 3]}, dtype='i8')
store.append('df_i8', df2)
- assert df2.dtypes == store['df_i8'].dtypes
+ assert_series_equal(df2.dtypes,store['df_i8'].dtypes)
# incompatible dtype
self.assertRaises(ValueError, store.append, 'df_i8', df1)
# check creation/storage/retrieval of float32 (a bit hacky to actually create them thought)
df1 = DataFrame(np.array([[1],[2],[3]],dtype='f4'),columns = ['A'])
store.append('df_f4', df1)
- assert df1.dtypes == store['df_f4'].dtypes
+ assert_series_equal(df1.dtypes,store['df_f4'].dtypes)
assert df1.dtypes[0] == 'float32'
# check with mixed dtypes
View
5 pandas/tests/test_frame.py
@@ -10607,13 +10607,10 @@ def test_index_namedtuple(self):
df = DataFrame([(1, 2), (3, 4)], index=index, columns=["A", "B"])
self.assertEqual(df.ix[IndexType("foo", "bar")]["A"], 1)
- def test_bool_empty_nonzero(self):
+ def test_empty_nonzero(self):
df = DataFrame([1, 2, 3])
- self.assertTrue(bool(df))
self.assertFalse(df.empty)
df = DataFrame(index=['a', 'b'], columns=['c', 'd']).dropna()
- self.assertFalse(bool(df))
- self.assertFalse(bool(df.T))
self.assertTrue(df.empty)
self.assertTrue(df.T.empty)
View
50 pandas/tests/test_generic.py
@@ -73,7 +73,6 @@ def _construct(self, shape, value=None, **kwargs):
arr = np.random.randn(*shape)
return self._typ(arr,**kwargs)
-
def _compare(self, result, expected):
self._comparator(result,expected)
@@ -82,14 +81,14 @@ def test_rename(self):
# single axis
for axis in self._axes():
kwargs = { axis : list('ABCD') }
- o = self._construct(4,**kwargs)
+ obj = self._construct(4,**kwargs)
# no values passed
#self.assertRaises(Exception, o.rename(str.lower))
# rename a single axis
- result = o.rename(**{ axis : str.lower })
- expected = o.copy()
+ result = obj.rename(**{ axis : str.lower })
+ expected = obj.copy()
setattr(expected,axis,list('abcd'))
self._compare(result, expected)
@@ -119,6 +118,41 @@ def test_get_numeric_data(self):
self._compare(result, o)
# _get_numeric_data is includes _get_bool_data, so can't test for non-inclusion
+ def test_nonzero(self):
+
+ # GH 4633
+ # look at the boolean/nonzero behavior for objects
+ obj = self._construct(shape=4)
+ self.assertRaises(ValueError, lambda : bool(obj == 0))
+ self.assertRaises(ValueError, lambda : bool(obj == 1))
+ self.assertRaises(ValueError, lambda : bool(obj))
+
+ obj = self._construct(shape=4,value=1)
+ self.assertRaises(ValueError, lambda : bool(obj == 0))
+ self.assertRaises(ValueError, lambda : bool(obj == 1))
+ self.assertRaises(ValueError, lambda : bool(obj))
+
+ obj = self._construct(shape=4,value=np.nan)
+ self.assertRaises(ValueError, lambda : bool(obj == 0))
+ self.assertRaises(ValueError, lambda : bool(obj == 1))
+ self.assertRaises(ValueError, lambda : bool(obj))
+
+ # empty
+ obj = self._construct(shape=0)
+ self.assertRaises(ValueError, lambda : bool(obj))
+
+ # invalid behaviors
+
+ obj1 = self._construct(shape=4,value=1)
+ obj2 = self._construct(shape=4,value=1)
+
+ def f():
+ if obj1:
+ print("this works and shouldn't")
+ self.assertRaises(ValueError, f)
+ self.assertRaises(ValueError, lambda : obj1 and obj2)
+ self.assertRaises(ValueError, lambda : obj1 or obj2)
+ self.assertRaises(ValueError, lambda : not obj1)
class TestSeries(unittest.TestCase, Generic):
_typ = Series
@@ -154,6 +188,14 @@ def test_get_numeric_data_preserve_dtype(self):
expected = Series([],dtype='M8[ns]')
self._compare(result, expected)
+ def test_nonzero_single_element(self):
+
+ s = Series([True])
+ self.assertRaises(ValueError, lambda : bool(s))
+
+ s = Series([False])
+ self.assertRaises(ValueError, lambda : bool(s))
+
class TestDataFrame(unittest.TestCase, Generic):
_typ = DataFrame
_comparator = lambda self, x, y: assert_frame_equal(x,y)
View
6 pandas/tests/test_series.py
@@ -296,12 +296,6 @@ def test_scalar_conversion(self):
self.assert_(int(Series([1.])) == 1)
self.assert_(long(Series([1.])) == 1)
- self.assert_(bool(Series([True])) == True)
- self.assert_(bool(Series([False])) == False)
-
- self.assert_(bool(Series([True,True])) == True)
- self.assert_(bool(Series([False,True])) == True)
-
def test_astype(self):
s = Series(np.random.randn(5),name='foo')
View
2 pandas/tseries/tests/test_timeseries.py
@@ -256,7 +256,7 @@ def test_indexing(self):
df = DataFrame(randn(5,5),columns=['open','high','low','close','volume'],index=date_range('2012-01-02 18:01:00',periods=5,tz='US/Central',freq='s'))
expected = df.loc[[df.index[2]]]
result = df['2012-01-02 18:01:02']
- self.assert_(result == expected)
+ assert_frame_equal(result,expected)
# this is a single date, so will raise
self.assertRaises(KeyError, df.__getitem__, df.index[2],)

0 comments on commit e47e981

Please sign in to comment.
Something went wrong with that request. Please try again.