From 596ee34dbbb7e25daa3e9764f0ebcd938d4c985b Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Sat, 10 Dec 2022 22:26:38 +0000 Subject: [PATCH 1/2] DEPR: deprecate Index.is_boolean --- doc/source/whatsnew/v2.0.0.rst | 1 + pandas/core/arrays/categorical.py | 3 ++- pandas/core/indexes/base.py | 25 +++++++++++++++++-------- pandas/tests/base/common.py | 3 ++- pandas/tests/indexes/common.py | 6 ++++++ pandas/tests/indexes/test_setops.py | 3 ++- pandas/tests/indexing/test_loc.py | 7 +++++-- 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index b22590759ea3f..19f776162b767 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -569,6 +569,7 @@ Deprecations ~~~~~~~~~~~~ - Deprecated argument ``infer_datetime_format`` in :func:`to_datetime` and :func:`read_csv`, as a strict version of it is now the default (:issue:`48621`) - Deprecated :func:`pandas.io.sql.execute`(:issue:`50185`) +- :meth:`Index.is_boolean` has been deprecated. Use :func:`pandas.api.types.is_bool_dtype` instead (:issue:`50042`) - :meth:`Index.is_integer` has been deprecated. Use :func:`pandas.api.types.is_integer_dtype` instead (:issue:`50042`) - :meth:`Index.is_floating` has been deprecated. Use :func:`pandas.api.types.is_float_dtype` instead (:issue:`50042`) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 07923658cf8f5..14f334d72dbb1 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -47,6 +47,7 @@ from pandas.core.dtypes.common import ( ensure_int64, ensure_platform_int, + is_bool_dtype, is_categorical_dtype, is_datetime64_dtype, is_dict_like, @@ -600,7 +601,7 @@ def _from_inferred_categories( cats = to_datetime(inferred_categories, errors="coerce") elif is_timedelta64_dtype(dtype.categories): cats = to_timedelta(inferred_categories, errors="coerce") - elif dtype.categories.is_boolean(): + elif is_bool_dtype(dtype.categories): if true_values is None: true_values = ["True", "TRUE", "true"] diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index b9727beba1026..437607e089881 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2182,6 +2182,9 @@ def is_boolean(self) -> bool: """ Check if the Index only consists of booleans. + .. deprecated:: 2.0.0 + Use `pandas.api.types.is_bool_dtype` instead. + Returns ------- bool @@ -2210,6 +2213,12 @@ def is_boolean(self) -> bool: >>> idx.is_boolean() False """ + warnings.warn( + f"{type(self).__name__}.is_boolean is deprecated." + "Use pandas.api.types.is_bool_type instead", + FutureWarning, + stacklevel=find_stack_level(), + ) return self.inferred_type in ["boolean"] @final @@ -2227,7 +2236,7 @@ def is_integer(self) -> bool: See Also -------- - is_boolean : Check if the Index only consists of booleans. + is_boolean : Check if the Index only consists of booleans (deprecated). is_floating : Check if the Index is a floating type (deprecated). is_numeric : Check if the Index only consists of numeric data. is_object : Check if the Index is of the object dtype. @@ -2275,7 +2284,7 @@ def is_floating(self) -> bool: See Also -------- - is_boolean : Check if the Index only consists of booleans. + is_boolean : Check if the Index only consists of booleans (deprecated). is_integer : Check if the Index only consists of integers (deprecated). is_numeric : Check if the Index only consists of numeric data. is_object : Check if the Index is of the object dtype. @@ -2320,7 +2329,7 @@ def is_numeric(self) -> bool: See Also -------- - is_boolean : Check if the Index only consists of booleans. + is_boolean : Check if the Index only consists of booleans (deprecated). is_integer : Check if the Index only consists of integers (deprecated). is_floating : Check if the Index is a floating type (deprecated). is_object : Check if the Index is of the object dtype. @@ -2363,7 +2372,7 @@ def is_object(self) -> bool: See Also -------- - is_boolean : Check if the Index only consists of booleans. + is_boolean : Check if the Index only consists of booleans (deprecated). is_integer : Check if the Index only consists of integers (deprecated). is_floating : Check if the Index is a floating type (deprecated). is_numeric : Check if the Index only consists of numeric data. @@ -2404,7 +2413,7 @@ def is_categorical(self) -> bool: See Also -------- CategoricalIndex : Index for categorical data. - is_boolean : Check if the Index only consists of booleans. + is_boolean : Check if the Index only consists of booleans (deprecated). is_integer : Check if the Index only consists of integers (deprecated). is_floating : Check if the Index is a floating type (deprecated). is_numeric : Check if the Index only consists of numeric data. @@ -2447,7 +2456,7 @@ def is_interval(self) -> bool: See Also -------- IntervalIndex : Index for Interval objects. - is_boolean : Check if the Index only consists of booleans. + is_boolean : Check if the Index only consists of booleans (deprecated). is_integer : Check if the Index only consists of integers (deprecated). is_floating : Check if the Index is a floating type (deprecated). is_numeric : Check if the Index only consists of numeric data. @@ -5863,8 +5872,8 @@ def _should_compare(self, other: Index) -> bool: Check if `self == other` can ever have non-False entries. """ - if (other.is_boolean() and self.is_numeric()) or ( - self.is_boolean() and other.is_numeric() + if (is_bool_dtype(other) and self.is_numeric()) or ( + is_bool_dtype(self) and other.is_numeric() ): # GH#16877 Treat boolean labels passed to a numeric index as not # found. Without this fix False and True would be treated as 0 and 1 diff --git a/pandas/tests/base/common.py b/pandas/tests/base/common.py index b09710a974c2a..30cf9311c98bc 100644 --- a/pandas/tests/base/common.py +++ b/pandas/tests/base/common.py @@ -1,9 +1,10 @@ from typing import Any from pandas import Index +from pandas.api.types import is_bool_dtype def allow_na_ops(obj: Any) -> bool: """Whether to skip test cases including NaN""" - is_bool_index = isinstance(obj, Index) and obj.is_boolean() + is_bool_index = isinstance(obj, Index) and is_bool_dtype(obj) return not is_bool_index and obj._can_hold_na diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index 8ddc2b6349bde..60760b5aefe72 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -797,6 +797,12 @@ def test_inv(self, simple_index): with pytest.raises(TypeError, match=msg): ~Series(idx) + def test_is_boolean_is_deprecated(self, simple_index): + # GH50042 + idx = simple_index + with tm.assert_produces_warning(FutureWarning): + idx.is_boolean() + def test_is_floating_is_deprecated(self, simple_index): # GH50042 idx = simple_index diff --git a/pandas/tests/indexes/test_setops.py b/pandas/tests/indexes/test_setops.py index 14cde141d1c60..bdd2c7a7faad9 100644 --- a/pandas/tests/indexes/test_setops.py +++ b/pandas/tests/indexes/test_setops.py @@ -25,6 +25,7 @@ ) import pandas._testing as tm from pandas.api.types import ( + is_bool_dtype, is_datetime64tz_dtype, is_signed_integer_dtype, pandas_dtype, @@ -271,7 +272,7 @@ def test_union_base(self, index): def test_difference_base(self, sort, index): first = index[2:] second = index[:4] - if index.is_boolean(): + if is_bool_dtype(index): # i think (TODO: be sure) there assumptions baked in about # the index fixture that don't hold here? answer = set(first).difference(set(second)) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 61e95de3caf0d..b1372d3b552a0 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -37,7 +37,10 @@ to_timedelta, ) import pandas._testing as tm -from pandas.api.types import is_scalar +from pandas.api.types import ( + is_bool_dtype, + is_scalar, +) from pandas.core.api import Float64Index from pandas.core.indexing import _one_ellipsis_message from pandas.tests.indexing.common import check_indexing_smoketest_or_raises @@ -1658,7 +1661,7 @@ def test_loc_iloc_getitem_leading_ellipses(self, series_with_simple_index, index obj = series_with_simple_index key = 0 if (indexer is tm.iloc or len(obj) == 0) else obj.index[0] - if indexer is tm.loc and obj.index.is_boolean(): + if indexer is tm.loc and is_bool_dtype(obj.index): # passing [False] will get interpreted as a boolean mask # TODO: should it? unambiguous when lengths dont match? return From 77ca7a27b996d9a99730f1cc9982ffb7e8b306dd Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Fri, 13 Jan 2023 23:31:28 +0000 Subject: [PATCH 2/2] small fix --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 437607e089881..ebe18b774d000 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2214,7 +2214,7 @@ def is_boolean(self) -> bool: False """ warnings.warn( - f"{type(self).__name__}.is_boolean is deprecated." + f"{type(self).__name__}.is_boolean is deprecated. " "Use pandas.api.types.is_bool_type instead", FutureWarning, stacklevel=find_stack_level(),