From 3e173af582c0c10e206c88be01f4de85b0877745 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Wed, 26 Oct 2022 15:35:54 -0700 Subject: [PATCH 1/3] DEPR: Enforce disallowing loc with positionals --- doc/source/whatsnew/v2.0.0.rst | 1 + pandas/core/indexes/base.py | 7 ++----- pandas/tests/indexing/test_loc.py | 15 ++++++--------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 78ea78ec97a3a..f3aadc0404f9e 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -245,6 +245,7 @@ Removal of prior version deprecations/changes - Removed ``pandas.SparseSeries`` and ``pandas.SparseDataFrame``, including pickle support. (:issue:`30642`) - Enforced disallowing a string column label into ``times`` in :meth:`DataFrame.ewm` (:issue:`43265`) - Enforced disallowing a tuple of column labels into :meth:`.DataFrameGroupBy.__getitem__` (:issue:`30546`) +- Enforced disallowing setting values with ``.loc`` using a positional slice. Use ``.loc`` with labels or ``.iloc`` with positions instead (:issue:`31840`) - Removed setting Categorical._codes directly (:issue:`41429`) - Enforced :meth:`Rolling.count` with ``min_periods=None`` to default to the size of the window (:issue:`31302`) - Renamed ``fname`` to ``path`` in :meth:`DataFrame.to_parquet`, :meth:`DataFrame.to_stata` and :meth:`DataFrame.to_feather` (:issue:`30338`) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 1c9e67fdc2fd0..65008f2b6a211 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4198,12 +4198,9 @@ def is_int(v): elif is_positional: if kind == "loc": # GH#16121, GH#24612, GH#31810 - warnings.warn( - "Slicing a positional slice with .loc is not supported, " - "and will raise TypeError in a future version. " + raise TypeError( + "Slicing a positional slice with .loc is not allowed, " "Use .loc with labels or .iloc with positions instead.", - FutureWarning, - stacklevel=find_stack_level(), ) indexer = key else: diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 3490d05f13e9d..88ae431fb1baf 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2795,16 +2795,13 @@ def test_loc_mixed_int_float(): assert result == 0 -def test_loc_with_positional_slice_deprecation(): +def test_loc_with_positional_slice_raises(): # GH#31840 ser = Series(range(4), index=["A", "B", "C", "D"]) - with tm.assert_produces_warning(FutureWarning): + with pytest.raises(TypeError, match="Slicing a positional slice with .loc"): ser.loc[:3] = 2 - expected = Series([2, 2, 2, 3], index=["A", "B", "C", "D"]) - tm.assert_series_equal(ser, expected) - def test_loc_slice_disallows_positional(): # GH#16121, GH#24612, GH#31810 @@ -2822,15 +2819,15 @@ def test_loc_slice_disallows_positional(): with pytest.raises(TypeError, match=msg): obj.loc[1:3] - with tm.assert_produces_warning(FutureWarning): - # GH#31840 deprecated incorrect behavior + with pytest.raises(TypeError, match="Slicing a positional slice with .loc"): + # GH#31840 enforce incorrect behavior obj.loc[1:3] = 1 with pytest.raises(TypeError, match=msg): df.loc[1:3, 1] - with tm.assert_produces_warning(FutureWarning): - # GH#31840 deprecated incorrect behavior + with pytest.raises(TypeError, match="Slicing a positional slice with .loc"): + # GH#31840 enforce incorrect behavior df.loc[1:3, 1] = 2 From 819b73869d827979ac5ad61039ca890d2df9cf1d Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 27 Oct 2022 09:57:55 -0700 Subject: [PATCH 2/3] Fix asv usage --- asv_bench/benchmarks/io/sql.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asv_bench/benchmarks/io/sql.py b/asv_bench/benchmarks/io/sql.py index fb8b7dafa0ade..c1f378e8075e9 100644 --- a/asv_bench/benchmarks/io/sql.py +++ b/asv_bench/benchmarks/io/sql.py @@ -38,7 +38,7 @@ def setup(self, connection): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) @@ -88,7 +88,7 @@ def setup(self, connection, dtype): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) @@ -117,7 +117,7 @@ def setup(self): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) @@ -164,7 +164,7 @@ def setup(self, dtype): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) From 8d29d14845b5919611a3cea136f9ba4bb78d6b7b Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 27 Oct 2022 13:30:54 -0700 Subject: [PATCH 3/3] Trigger CI