Skip to content

Commit 7dde997

Browse files
committed
BUG: disallow comparisons in replace_list with malformed types
1 parent a9069f7 commit 7dde997

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

pandas/core/internals.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import itertools
22
import re
3+
import operator
34
from datetime import datetime, timedelta
45
import copy
56
from collections import defaultdict
@@ -2453,7 +2454,8 @@ def replace_list(self, src_list, dest_list, inplace=False, regex=False):
24532454
def comp(s):
24542455
if isnull(s):
24552456
return isnull(values)
2456-
return values == getattr(s, 'asm8', s)
2457+
return _possibly_compare(values, getattr(s, 'asm8', s),
2458+
operator.eq)
24572459
masks = [comp(s) for i, s in enumerate(src_list)]
24582460

24592461
result_blocks = []
@@ -4153,3 +4155,20 @@ def _possibly_convert_to_indexer(loc):
41534155
elif isinstance(loc, slice):
41544156
loc = lrange(loc.start, loc.stop)
41554157
return loc
4158+
4159+
4160+
def _possibly_compare(a, b, op):
4161+
res = op(a, b)
4162+
is_a_array = isinstance(a, np.ndarray)
4163+
is_b_array = isinstance(b, np.ndarray)
4164+
if np.isscalar(res) and (is_a_array or is_b_array):
4165+
type_names = [type(a).__name__, type(b).__name__]
4166+
4167+
if is_a_array:
4168+
type_names[0] = 'ndarray(dtype=%s)' % a.dtype
4169+
4170+
if is_b_array:
4171+
type_names[1] = 'ndarray(dtype=%s)' % b.dtype
4172+
4173+
raise TypeError("Cannot compare types %r and %r" % tuple(type_names))
4174+
return res

pandas/tests/test_frame.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -8005,9 +8005,8 @@ def test_replace_bool_with_bool(self):
80058005

80068006
def test_replace_with_dict_with_bool_keys(self):
80078007
df = DataFrame({0: [True, False], 1: [False, True]})
8008-
result = df.replace({'asdf': 'asdb', True: 'yes'})
8009-
expected = DataFrame({0: ['yes', False], 1: [False, 'yes']})
8010-
tm.assert_frame_equal(expected, result)
8008+
with tm.assertRaisesRegexp(TypeError, 'Cannot compare types .+'):
8009+
df.replace({'asdf': 'asdb', True: 'yes'})
80118010

80128011
def test_combine_multiple_frames_dtypes(self):
80138012
from pandas import concat

pandas/tests/test_series.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -5264,7 +5264,11 @@ def test_replace(self):
52645264

52655265
# malformed
52665266
self.assertRaises(ValueError, ser.replace, [1, 2, 3], [np.nan, 0])
5267-
self.assertRaises(TypeError, ser.replace, range(1, 3), [np.nan, 0])
5267+
5268+
# make sure that we aren't just masking a TypeError because bools don't
5269+
# implement indexing
5270+
with tm.assertRaisesRegexp(TypeError, 'Cannot compare types .+'):
5271+
ser.replace([1, 2], [np.nan, 0])
52685272

52695273
ser = Series([0, 1, 2, 3, 4])
52705274
result = ser.replace([0, 1, 2, 3, 4], [4, 3, 2, 1, 0])
@@ -5369,9 +5373,8 @@ def test_replace_bool_with_bool(self):
53695373

53705374
def test_replace_with_dict_with_bool_keys(self):
53715375
s = Series([True, False, True])
5372-
result = s.replace({'asdf': 'asdb', True: 'yes'})
5373-
expected = Series(['yes', False, 'yes'])
5374-
tm.assert_series_equal(expected, result)
5376+
with tm.assertRaisesRegexp(TypeError, 'Cannot compare types .+'):
5377+
s.replace({'asdf': 'asdb', True: 'yes'})
53755378

53765379
def test_asfreq(self):
53775380
ts = Series([0., 1., 2.], index=[datetime(2009, 10, 30),

0 commit comments

Comments
 (0)