Skip to content

Commit 78b3bf9

Browse files
committed
BUG/API: disallow boolean arithmetic operations
1 parent 7c073c4 commit 78b3bf9

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

doc/source/release.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ API Changes
156156
- ``to_excel`` now converts ``np.inf`` into a string representation,
157157
customizable by the ``inf_rep`` keyword argument (Excel has no native inf
158158
representation) (:issue:`6782`)
159+
- Arithmetic ops are now disallowed when passed two bool dtype Series or
160+
DataFrames (:issue:`6762`).
159161

160162
Deprecations
161163
~~~~~~~~~~~~
@@ -307,6 +309,9 @@ Bug Fixes
307309
- Bug in ``DataFrame.replace()`` where regex metacharacters were being treated
308310
as regexs even when ``regex=False`` (:issue:`6777`).
309311
- Bug in timedelta ops on 32-bit platforms (:issue:`6808`)
312+
- Bug in setting a tz-aware index directly via ``.index`` (:issue:`6785`)
313+
- Bug in expressions.py where numexpr would try to evaluate arithmetic ops
314+
(:issue:`6762`).
310315

311316
pandas 0.13.1
312317
-------------

pandas/computation/expressions.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ def _where_numexpr(cond, a, b, raise_on_error=False):
154154
set_use_numexpr(True)
155155

156156

157+
def _bool_arith_check(op_str, a, b, not_allowed=('+', '*', '-', '/',
158+
'//', '**')):
159+
if op_str in not_allowed and a.dtype == bool and b.dtype == bool:
160+
raise NotImplementedError("operator %r not implemented for bool "
161+
"dtypes" % op_str)
162+
163+
157164
def evaluate(op, op_str, a, b, raise_on_error=False, use_numexpr=True,
158165
**eval_kwargs):
159166
""" evaluate and return the expression of the op on a and b
@@ -170,7 +177,7 @@ def evaluate(op, op_str, a, b, raise_on_error=False, use_numexpr=True,
170177
return the results
171178
use_numexpr : whether to try to use numexpr (default True)
172179
"""
173-
180+
_bool_arith_check(op_str, a, b)
174181
if use_numexpr:
175182
return _evaluate(op, op_str, a, b, raise_on_error=raise_on_error,
176183
**eval_kwargs)

pandas/tests/test_frame.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4769,6 +4769,22 @@ def test_logical_typeerror(self):
47694769
self.assertRaises(TypeError, self.frame.__gt__, 'foo')
47704770
self.assertRaises(TypeError, self.frame.__ne__, 'foo')
47714771

4772+
def test_bool_ops_raise_on_arithmetic(self):
4773+
df = DataFrame({'a': np.random.rand(10) > 0.5,
4774+
'b': np.random.rand(10) > 0.5})
4775+
df2 = DataFrame({'a': np.random.rand(10) > 0.5,
4776+
'b': np.random.rand(10) > 0.5})
4777+
ops = 'add', 'mul', 'sub', 'div', 'truediv', 'floordiv', 'pow'
4778+
names = '+', '*', '-', '/', '/', '//', '**'
4779+
msg = 'operator %r not implemented for bool dtypes'
4780+
for op, name in zip(ops, names):
4781+
if not compat.PY3 or op != 'div':
4782+
with tm.assertRaisesRegexp(NotImplementedError,
4783+
re.escape(msg % name)):
4784+
f = getattr(operator, op)
4785+
f(df, df2)
4786+
f(df.a, df.b)
4787+
47724788
def test_constructor_lists_to_object_dtype(self):
47734789
# from #1074
47744790
d = DataFrame({'a': [np.nan, False]})

0 commit comments

Comments
 (0)