Skip to content

Commit 627c59a

Browse files
committed
BUG: Fixed a bug with setting invalid or out-of-range values in indexing
enlargement scenarios (GH4940)
1 parent 30e2c6b commit 627c59a

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed

doc/source/release.rst

+2
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,8 @@ Bug Fixes
449449
- Fixed a bug in ``convert_objects`` for > 2 ndims (:issue:`4937`)
450450
- Fixed a bug in DataFrame/Panel cache insertion and subsequent indexing (:issue:`4939`)
451451
- Fixed string methods for ``FrozenNDArray`` and ``FrozenList`` (:issue:`4929`)
452+
- Fixed a bug with setting invalid or out-of-range values in indexing
453+
enlargement scenarios (:issue:`4940`)
452454

453455
pandas 0.12.0
454456
-------------

pandas/core/indexing.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,13 @@ def _convert_to_indexer(self, obj, axis=0, is_setter=False):
750750
is_int_index = _is_integer_index(labels)
751751

752752
if com.is_integer(obj) and not is_int_index:
753+
754+
# if we are setting and its not a valid location
755+
# its an insert which fails by definition
756+
if is_setter:
757+
if obj >= len(self.obj) and not isinstance(labels, MultiIndex):
758+
raise ValueError("cannot set by positional indexing with enlargement")
759+
753760
return obj
754761

755762
try:
@@ -1340,7 +1347,12 @@ def _safe_append_to_index(index, key):
13401347
try:
13411348
return index.insert(len(index), key)
13421349
except:
1343-
return Index(np.concatenate([index.asobject.values,np.array([key])]))
1350+
1351+
# raise here as this is basically an unsafe operation and we want
1352+
# it to be obvious that you are doing something wrong
1353+
1354+
raise ValueError("unsafe appending to index of "
1355+
"type {0} with a key {1}".format(index.__class__.__name__,key))
13441356

13451357
def _maybe_convert_indices(indices, n):
13461358
""" if we have negative indicies, translate to postive here

pandas/sparse/tests/test_sparse.py

+6
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,12 @@ def test_icol(self):
10781078

10791079
def test_set_value(self):
10801080

1081+
# this is invalid because it is not a valid type for this index
1082+
self.assertRaises(ValueError, self.frame.set_value, 'foobar', 'B', 1.5)
1083+
1084+
res = self.frame
1085+
res.index = res.index.astype(object)
1086+
10811087
res = self.frame.set_value('foobar', 'B', 1.5)
10821088
self.assert_(res is not self.frame)
10831089
self.assert_(res.index[-1] == 'foobar')

pandas/tests/test_indexing.py

+24
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,30 @@ def test_series_partial_set(self):
14801480
result = ser.iloc[[1,1,0,0]]
14811481
assert_series_equal(result, expected)
14821482

1483+
def test_partial_set_invalid(self):
1484+
1485+
# GH 4940
1486+
# allow only setting of 'valid' values
1487+
1488+
df = tm.makeTimeDataFrame()
1489+
1490+
def f():
1491+
df.loc[100.0, :] = df.ix[0]
1492+
self.assertRaises(ValueError, f)
1493+
def f():
1494+
df.loc[100,:] = df.ix[0]
1495+
self.assertRaises(ValueError, f)
1496+
def f():
1497+
df.loc['a',:] = df.ix[0]
1498+
self.assertRaises(ValueError, f)
1499+
1500+
def f():
1501+
df.ix[100.0, :] = df.ix[0]
1502+
self.assertRaises(ValueError, f)
1503+
def f():
1504+
df.ix[100,:] = df.ix[0]
1505+
self.assertRaises(ValueError, f)
1506+
14831507
def test_cache_updating(self):
14841508
# GH 4939, make sure to update the cache on setitem
14851509

0 commit comments

Comments
 (0)