From b69c1a26899b38adff8390236ee83ba36af0374e Mon Sep 17 00:00:00 2001 From: Licht Takeuchi Date: Sun, 26 Nov 2017 06:01:21 +0900 Subject: [PATCH] BUG: Fix Index.putmask makes stack overflow with an invalid mask (#18407) --- doc/source/whatsnew/v0.21.1.txt | 2 +- pandas/core/indexes/base.py | 5 ++++- pandas/tests/indexes/common.py | 13 +++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.21.1.txt b/doc/source/whatsnew/v0.21.1.txt index 637ccf0603e0f..51fd3b1076ade 100644 --- a/doc/source/whatsnew/v0.21.1.txt +++ b/doc/source/whatsnew/v0.21.1.txt @@ -73,7 +73,7 @@ Indexing - Bug in a boolean comparison of a ``datetime.datetime`` and a ``datetime64[ns]`` dtype Series (:issue:`17965`) - Bug where a ``MultiIndex`` with more than a million records was not raising ``AttributeError`` when trying to access a missing attribute (:issue:`18165`) - Bug in :class:`IntervalIndex` constructor when a list of intervals is passed with non-default ``closed`` (:issue:`18334`) -- +- Bug in ``Index.putmask`` when an invalid mask passed (:issue:`18368`) - I/O diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index b5d912f4201b5..2696f9f94375d 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1939,7 +1939,10 @@ def putmask(self, mask, value): try: np.putmask(values, mask, self._convert_for_op(value)) return self._shallow_copy(values) - except (ValueError, TypeError): + except (ValueError, TypeError) as err: + if is_object_dtype(self): + raise err + # coerces to object return self.astype(object).putmask(mask, value) diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index ee6434431bcfc..ba7795d005721 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -1032,3 +1032,16 @@ def test_map(self): dict_map = {} tm.assert_index_equal(index.map(dict_map), nan_index) + + def test_putmask_with_wrong_mask(self): + # GH18368 + index = self.create_index() + + with pytest.raises(ValueError): + index.putmask(np.ones(len(index) + 1, np.bool), 1) + + with pytest.raises(ValueError): + index.putmask(np.ones(len(index) - 1, np.bool), 1) + + with pytest.raises(ValueError): + index.putmask('foo', 1)