Skip to content

Commit

Permalink
BUG: Fix pandas-dev#16363 - Prevent visit_BinOp from accessing value …
Browse files Browse the repository at this point in the history
…on UnaryOp (pandas-dev#25928)
  • Loading branch information
alexcwatt authored and yhaque1213 committed Apr 22, 2019
1 parent 14a4838 commit fad68eb
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
3 changes: 2 additions & 1 deletion doc/source/whatsnew/v0.25.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ Bug Fixes
~~~~~~~~~



Categorical
^^^^^^^^^^^

Expand Down Expand Up @@ -295,7 +296,7 @@ Numeric
- Bug in error messages in :meth:`DataFrame.corr` and :meth:`Series.corr`. Added the possibility of using a callable. (:issue:`25729`)
- Bug in :meth:`Series.divmod` and :meth:`Series.rdivmod` which would raise an (incorrect) ``ValueError`` rather than return a pair of :class:`Series` objects as result (:issue:`25557`)
- Raises a helpful exception when a non-numeric index is sent to :meth:`interpolate` with methods which require numeric index. (:issue:`21662`)
-
- Bug in :meth:`~pandas.eval` when comparing floats with scalar operators, for example: ``x < -0.1`` (:issue:`25928`)
-


Expand Down
6 changes: 4 additions & 2 deletions pandas/core/computation/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,13 @@ def _maybe_transform_eq_ne(self, node, left=None, right=None):

def _maybe_downcast_constants(self, left, right):
f32 = np.dtype(np.float32)
if left.is_scalar and not right.is_scalar and right.return_type == f32:
if (left.is_scalar and hasattr(left, 'value') and
not right.is_scalar and right.return_type == f32):
# right is a float32 array, left is a scalar
name = self.env.add_tmp(np.float32(left.value))
left = self.term_type(name, self.env)
if right.is_scalar and not left.is_scalar and left.return_type == f32:
if (right.is_scalar and hasattr(right, 'value') and
not left.is_scalar and left.return_type == f32):
# left is a float32 array, right is a scalar
name = self.env.add_tmp(np.float32(right.value))
right = self.term_type(name, self.env)
Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/computation/test_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,16 @@ def test_unary_in_array(self):
-False, False, ~False, +False,
-37, 37, ~37, +37], dtype=np.object_))

@pytest.mark.parametrize('dtype', [np.float32, np.float64])
def test_float_comparison_bin_op(self, dtype):
# GH 16363
df = pd.DataFrame({'x': np.array([0], dtype=dtype)})
res = df.eval('x < -0.1')
assert res.values == np.array([False])

res = df.eval('-5 > x')
assert res.values == np.array([False])

def test_disallow_scalar_bool_ops(self):
exprs = '1 or 2', '1 and 2'
exprs += 'a and b', 'a or b'
Expand Down

0 comments on commit fad68eb

Please sign in to comment.