From 1cb75f9d45654d2e72704ee38c43957717959b4e Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Fri, 19 Apr 2019 17:52:14 +0530 Subject: [PATCH 01/16] 'BUG14885' --- pandas/core/indexing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 0b7958a4e7b67..a53305e06f73f 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -944,6 +944,8 @@ def _handle_lowerdim_multi_index_axis0(self, tup): except TypeError: # slices are unhashable pass + except KeyError: + return self._get_label(tup, axis=self.axis) except Exception as e1: if isinstance(tup[0], (slice, Index)): raise IndexingError("Handle elsewhere") From ff3a81f40c7d6b3259054ee17d8a754ff35afcb8 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sat, 20 Apr 2019 01:46:09 +0530 Subject: [PATCH 02/16] Added KeyError Exception for MultiIndexes --- pandas/core/indexing.py | 6 +++++- pandas/tests/indexing/multiindex/test_getitem.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index a53305e06f73f..0fa5720ede08e 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -945,7 +945,7 @@ def _handle_lowerdim_multi_index_axis0(self, tup): # slices are unhashable pass except KeyError: - return self._get_label(tup, axis=self.axis) + return None except Exception as e1: if isinstance(tup[0], (slice, Index)): raise IndexingError("Handle elsewhere") @@ -978,6 +978,10 @@ def _getitem_lowerdim(self, tup): return result if len(tup) > self.obj.ndim: + try: + self._get_label(tup, axis=self.axis) + except KeyError: + return self._get_label(tup, axis=self.axis) raise IndexingError("Too many indexers. handle elsewhere") # to avoid wasted computation diff --git a/pandas/tests/indexing/multiindex/test_getitem.py b/pandas/tests/indexing/multiindex/test_getitem.py index 1080c3ecdcf1f..b0fac937dc873 100644 --- a/pandas/tests/indexing/multiindex/test_getitem.py +++ b/pandas/tests/indexing/multiindex/test_getitem.py @@ -85,7 +85,7 @@ def test_series_getitem_returns_scalar( @pytest.mark.parametrize('indexer,expected_error,expected_error_msg', [ (lambda s: s.__getitem__((2000, 3, 4)), KeyError, r"^356L?$"), (lambda s: s[(2000, 3, 4)], KeyError, r"^356L?$"), - (lambda s: s.loc[(2000, 3, 4)], IndexingError, 'Too many indexers'), + (lambda s: s.loc[(2000, 3, 4)], KeyError, r"^356L?$"), (lambda s: s.__getitem__(len(s)), IndexError, 'index out of bounds'), (lambda s: s[len(s)], IndexError, 'index out of bounds'), (lambda s: s.iloc[len(s)], IndexError, From 0369704ba44b67ab73706d3782374fa95ef84601 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sat, 20 Apr 2019 04:53:51 +0530 Subject: [PATCH 03/16] added KeyError and Exception blocks --- pandas/core/indexing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 0fa5720ede08e..639ae16a91629 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -982,7 +982,8 @@ def _getitem_lowerdim(self, tup): self._get_label(tup, axis=self.axis) except KeyError: return self._get_label(tup, axis=self.axis) - raise IndexingError("Too many indexers. handle elsewhere") + except Exception: + raise IndexingError("Too many indexers. handle elsewhere") # to avoid wasted computation # df.ix[d1:d2, 0] -> columns first (True) From 2fdacb548f5c96c8b887a5d079f0b84ce008cf1c Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sat, 20 Apr 2019 17:08:29 +0530 Subject: [PATCH 04/16] removed unused import statement --- pandas/tests/indexing/multiindex/test_getitem.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/indexing/multiindex/test_getitem.py b/pandas/tests/indexing/multiindex/test_getitem.py index b0fac937dc873..bbbd95116c0b8 100644 --- a/pandas/tests/indexing/multiindex/test_getitem.py +++ b/pandas/tests/indexing/multiindex/test_getitem.py @@ -2,7 +2,6 @@ import pytest from pandas import DataFrame, Index, MultiIndex, Series -from pandas.core.indexing import IndexingError from pandas.util import testing as tm # ---------------------------------------------------------------------------- From 2c1b85b2577746a9db6d34b8b4ded3501d88aee1 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sat, 20 Apr 2019 23:36:40 +0530 Subject: [PATCH 05/16] shifted KeyError check position --- pandas/core/indexing.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 639ae16a91629..e1487ba430b24 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -944,8 +944,9 @@ def _handle_lowerdim_multi_index_axis0(self, tup): except TypeError: # slices are unhashable pass - except KeyError: - return None + except KeyError as ek: + if len(tup) > self.obj.ndim: + raise ek except Exception as e1: if isinstance(tup[0], (slice, Index)): raise IndexingError("Handle elsewhere") @@ -978,12 +979,7 @@ def _getitem_lowerdim(self, tup): return result if len(tup) > self.obj.ndim: - try: - self._get_label(tup, axis=self.axis) - except KeyError: - return self._get_label(tup, axis=self.axis) - except Exception: - raise IndexingError("Too many indexers. handle elsewhere") + raise IndexingError("Too many indexers. handle elsewhere") # to avoid wasted computation # df.ix[d1:d2, 0] -> columns first (True) From 0f85550f3697a7b991808444e2860fd9f4ff96c6 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sat, 20 Apr 2019 23:23:37 +0530 Subject: [PATCH 06/16] added tests and fixed if statement --- pandas/core/indexing.py | 5 ++++- pandas/tests/indexing/multiindex/test_loc.py | 9 +++++++++ pandas/tests/indexing/test_loc.py | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index e1487ba430b24..c04265e05e4fc 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -945,7 +945,10 @@ def _handle_lowerdim_multi_index_axis0(self, tup): # slices are unhashable pass except KeyError as ek: - if len(tup) > self.obj.ndim: + # raise KeyError if number of indexers match + # else IndexingError will be raised + if (len(tup) == len(self.obj.index._levels) + and len(tup) > self.obj.ndim): raise ek except Exception as e1: if isinstance(tup[0], (slice, Index)): diff --git a/pandas/tests/indexing/multiindex/test_loc.py b/pandas/tests/indexing/multiindex/test_loc.py index 073d40001a16b..8b7fd8dd3ec34 100644 --- a/pandas/tests/indexing/multiindex/test_loc.py +++ b/pandas/tests/indexing/multiindex/test_loc.py @@ -7,6 +7,7 @@ import pandas as pd from pandas import DataFrame, Index, MultiIndex, Series from pandas.util import testing as tm +from pandas.core.indexing import IndexingError @pytest.fixture @@ -130,6 +131,14 @@ def test_loc_multiindex(self): with pytest.raises(KeyError, match=r"^2L?$"): mi_int.ix[2] + s = Series(range(8), index=MultiIndex.from_product( + [['a', 'b'], ['c', 'd'], ['e', 'f']])) + + with pytest.raises(KeyError, match=r"^\('a', 'd', 'g'\)$"): + s.loc['a', 'd', 'g'] + with pytest.raises(IndexingError, match='Too many indexers'): + s.loc['a', 'd', 'g', 'j'] + def test_loc_multiindex_indexer_none(self): # GH6788 diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 56401897afa94..bee6c586b65ae 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -122,7 +122,7 @@ def test_loc_getitem_label_out_of_range(self): self.check_result('label range', 'loc', 20, 'ix', 20, typs=['ints', 'uints', 'mixed'], fails=KeyError) self.check_result('label range', 'loc', 20, 'ix', 20, - typs=['labels'], fails=TypeError) + typs=['labels'], fails=KeyError) self.check_result('label range', 'loc', 20, 'ix', 20, typs=['ts'], axes=0, fails=TypeError) self.check_result('label range', 'loc', 20, 'ix', 20, typs=['floats'], From 51a1a3c1abfe0fad8df0902adb0d873da905b5f8 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sun, 21 Apr 2019 03:12:25 +0530 Subject: [PATCH 07/16] undo testcase change --- pandas/tests/indexing/test_loc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index bee6c586b65ae..56401897afa94 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -122,7 +122,7 @@ def test_loc_getitem_label_out_of_range(self): self.check_result('label range', 'loc', 20, 'ix', 20, typs=['ints', 'uints', 'mixed'], fails=KeyError) self.check_result('label range', 'loc', 20, 'ix', 20, - typs=['labels'], fails=KeyError) + typs=['labels'], fails=TypeError) self.check_result('label range', 'loc', 20, 'ix', 20, typs=['ts'], axes=0, fails=TypeError) self.check_result('label range', 'loc', 20, 'ix', 20, typs=['floats'], From 0ee36cdd560efccf7ad17b7d4aef3c3886bdce54 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Sun, 21 Apr 2019 03:39:03 +0530 Subject: [PATCH 08/16] import statements - linting --- pandas/tests/indexing/multiindex/test_loc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexing/multiindex/test_loc.py b/pandas/tests/indexing/multiindex/test_loc.py index 8b7fd8dd3ec34..46fcb181099a7 100644 --- a/pandas/tests/indexing/multiindex/test_loc.py +++ b/pandas/tests/indexing/multiindex/test_loc.py @@ -6,8 +6,8 @@ import pandas as pd from pandas import DataFrame, Index, MultiIndex, Series -from pandas.util import testing as tm from pandas.core.indexing import IndexingError +from pandas.util import testing as tm @pytest.fixture From 5e06afef937a590e69e6a6f8162b7134b4fadf7c Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Mon, 22 Apr 2019 02:16:34 +0530 Subject: [PATCH 09/16] Added whatsnew note and a DataFrame TestCase --- doc/source/whatsnew/v0.25.0.rst | 2 +- pandas/tests/indexing/multiindex/test_getitem.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 20d4f46348be6..582a3b63d58b1 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -328,7 +328,7 @@ Indexing ^^^^^^^^ - Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`). -- +- Bug in :meth:`_NDFrameIndexer._handle_lowerdim_multi_index_axis0` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`) - diff --git a/pandas/tests/indexing/multiindex/test_getitem.py b/pandas/tests/indexing/multiindex/test_getitem.py index bbbd95116c0b8..db588deab30f1 100644 --- a/pandas/tests/indexing/multiindex/test_getitem.py +++ b/pandas/tests/indexing/multiindex/test_getitem.py @@ -2,6 +2,7 @@ import pytest from pandas import DataFrame, Index, MultiIndex, Series +from pandas.core.indexing import IndexingError from pandas.util import testing as tm # ---------------------------------------------------------------------------- @@ -85,6 +86,7 @@ def test_series_getitem_returns_scalar( (lambda s: s.__getitem__((2000, 3, 4)), KeyError, r"^356L?$"), (lambda s: s[(2000, 3, 4)], KeyError, r"^356L?$"), (lambda s: s.loc[(2000, 3, 4)], KeyError, r"^356L?$"), + (lambda s: s.loc[(2000, 3, 4, 5)], IndexingError, 'Too many indexers'), (lambda s: s.__getitem__(len(s)), IndexError, 'index out of bounds'), (lambda s: s[len(s)], IndexError, 'index out of bounds'), (lambda s: s.iloc[len(s)], IndexError, From 467e1e7a16c68c8cd43d7c9f0504fb28330977dc Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Mon, 22 Apr 2019 02:26:14 +0530 Subject: [PATCH 10/16] removed blank line --- doc/source/whatsnew/v0.25.0.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 08b3a1ab53c7b..3d84ce47a514a 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -329,7 +329,6 @@ Indexing - Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`). - Bug in :meth:`_NDFrameIndexer._handle_lowerdim_multi_index_axis0` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`) - Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`). - - From c7ce8619175329448af866ba840b3f1f55b12687 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Mon, 22 Apr 2019 11:31:50 +0530 Subject: [PATCH 11/16] created new test_function --- pandas/tests/indexing/multiindex/test_loc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/tests/indexing/multiindex/test_loc.py b/pandas/tests/indexing/multiindex/test_loc.py index e803dc16d3922..9b454aeca118d 100644 --- a/pandas/tests/indexing/multiindex/test_loc.py +++ b/pandas/tests/indexing/multiindex/test_loc.py @@ -131,6 +131,8 @@ def test_loc_multiindex(self): with pytest.raises(KeyError, match=r"^2L?$"): mi_int.ix[2] + def test_loc_multiindex_fails(self): + # GH 14885 s = Series(range(8), index=MultiIndex.from_product( [['a', 'b'], ['c', 'd'], ['e', 'f']])) From b6ede73303b6fbf02e319920e10db8d9335338f0 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Mon, 22 Apr 2019 12:29:34 +0530 Subject: [PATCH 12/16] edited whats new --- doc/source/whatsnew/v0.25.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 3d84ce47a514a..53efe536f7788 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -327,7 +327,7 @@ Indexing ^^^^^^^^ - Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`). -- Bug in :meth:`_NDFrameIndexer._handle_lowerdim_multi_index_axis0` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`) +- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`) - Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`). - From ac544afc1fb0f5fee0295a07f57c3769c09e04b6 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Tue, 23 Apr 2019 19:03:50 +0530 Subject: [PATCH 13/16] add full stop --- doc/source/whatsnew/v0.25.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 53efe536f7788..ff21d7cb46480 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -327,7 +327,7 @@ Indexing ^^^^^^^^ - Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`). -- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`) +- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`). - Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`). - From de63fbefa2c70529cd523eb634e4c4be32229879 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Tue, 23 Apr 2019 21:08:33 +0530 Subject: [PATCH 14/16] minor changes --- pandas/core/indexing.py | 2 +- pandas/tests/indexing/multiindex/test_loc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 761d627741f79..369d009000efa 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -947,7 +947,7 @@ def _handle_lowerdim_multi_index_axis0(self, tup): except KeyError as ek: # raise KeyError if number of indexers match # else IndexingError will be raised - if (len(tup) == len(self.obj.index._levels) + if (len(tup) == self.obj.index.nlevels and len(tup) > self.obj.ndim): raise ek except Exception as e1: diff --git a/pandas/tests/indexing/multiindex/test_loc.py b/pandas/tests/indexing/multiindex/test_loc.py index 9b454aeca118d..dff5a59e8935a 100644 --- a/pandas/tests/indexing/multiindex/test_loc.py +++ b/pandas/tests/indexing/multiindex/test_loc.py @@ -131,7 +131,7 @@ def test_loc_multiindex(self): with pytest.raises(KeyError, match=r"^2L?$"): mi_int.ix[2] - def test_loc_multiindex_fails(self): + def test_loc_multiindex_too_many_dims(self): # GH 14885 s = Series(range(8), index=MultiIndex.from_product( [['a', 'b'], ['c', 'd'], ['e', 'f']])) From b95ae88091d786661ccccade4e58a19afa5de138 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Wed, 24 Apr 2019 19:35:57 +0530 Subject: [PATCH 15/16] more fixes --- doc/source/whatsnew/v0.25.0.rst | 2 +- pandas/core/indexing.py | 2 +- pandas/tests/indexing/multiindex/test_loc.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index ff21d7cb46480..f4ca11a577662 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -327,7 +327,7 @@ Indexing ^^^^^^^^ - Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`). -- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where KeyError was not raised for a ``MultiIndex``. Now, IndexingError takes precedence over KeyError (:issue:`14885`). +- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where ``KeyError`` was not raised for a ``MultiIndex`` when the key was less than ot equal to the number of levels in the :class:`MultiIndex` (:issue:`14885`). - Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`). - diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 369d009000efa..b42745b1a6619 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -947,7 +947,7 @@ def _handle_lowerdim_multi_index_axis0(self, tup): except KeyError as ek: # raise KeyError if number of indexers match # else IndexingError will be raised - if (len(tup) == self.obj.index.nlevels + if (len(tup) <= self.obj.index.nlevels and len(tup) > self.obj.ndim): raise ek except Exception as e1: diff --git a/pandas/tests/indexing/multiindex/test_loc.py b/pandas/tests/indexing/multiindex/test_loc.py index dff5a59e8935a..90d9791107eb3 100644 --- a/pandas/tests/indexing/multiindex/test_loc.py +++ b/pandas/tests/indexing/multiindex/test_loc.py @@ -136,6 +136,8 @@ def test_loc_multiindex_too_many_dims(self): s = Series(range(8), index=MultiIndex.from_product( [['a', 'b'], ['c', 'd'], ['e', 'f']])) + with pytest.raises(KeyError, match=r"^\('a', 'b'\)$"): + s.loc['a', 'b'] with pytest.raises(KeyError, match=r"^\('a', 'd', 'g'\)$"): s.loc['a', 'd', 'g'] with pytest.raises(IndexingError, match='Too many indexers'): From 2309e147592b6bd932fae40086b73d9e68aa60d4 Mon Sep 17 00:00:00 2001 From: Ryan Rehman Date: Wed, 24 Apr 2019 20:01:43 +0530 Subject: [PATCH 16/16] typo --- doc/source/whatsnew/v0.25.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index f4ca11a577662..e73c5c441608a 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -327,7 +327,7 @@ Indexing ^^^^^^^^ - Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`). -- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where ``KeyError`` was not raised for a ``MultiIndex`` when the key was less than ot equal to the number of levels in the :class:`MultiIndex` (:issue:`14885`). +- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where ``KeyError`` was not raised for a ``MultiIndex`` when the key was less than or equal to the number of levels in the :class:`MultiIndex` (:issue:`14885`). - Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`). -