Skip to content
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ Deprecations
- :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`)
- :meth:`Index.holds_integer` has been deprecated. Use :func:`pandas.api.types.infer_dtype` instead (:issue:`50243`)

.. ---------------------------------------------------------------------------
.. _whatsnew_200.prior_deprecations:
Expand Down
20 changes: 18 additions & 2 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2487,12 +2487,28 @@ def is_interval(self) -> bool:
return self.inferred_type in ["interval"]

@final
def holds_integer(self) -> bool:
def _holds_integer(self) -> bool:
"""
Whether the type is an integer type.
"""
return self.inferred_type in ["integer", "mixed-integer"]

@final
def holds_integer(self) -> bool:
"""
Whether the type is an integer type.

.. deprecated:: 2.0.0
Use `pandas.api.types.infer_dtype` instead
"""
warnings.warn(
f"{type(self).__name__}.holds_integer is deprecated. "
"Use pandas.api.types.infer_dtype instead.",
FutureWarning,
stacklevel=find_stack_level(),
)
return self._holds_integer()

@cache_readonly
def inferred_type(self) -> str_t:
"""
Expand Down Expand Up @@ -5537,7 +5553,7 @@ def _should_fallback_to_positional(self) -> bool:
"""
Should an integer key be treated as positional?
"""
return not self.holds_integer()
return not self._holds_integer()

_index_shared_docs[
"get_indexer_non_unique"
Expand Down
6 changes: 3 additions & 3 deletions pandas/plotting/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,15 +940,15 @@ def __call__(self, *args, **kwargs):
f"{kind} requires either y column or 'subplots=True'"
)
if y is not None:
if is_integer(y) and not data.columns.holds_integer():
if is_integer(y) and not data.columns._holds_integer():
y = data.columns[y]
# converted to series actually. copy to not modify
data = data[y].copy()
data.index.name = y
elif isinstance(data, ABCDataFrame):
data_cols = data.columns
if x is not None:
if is_integer(x) and not data.columns.holds_integer():
if is_integer(x) and not data.columns._holds_integer():
x = data_cols[x]
elif not isinstance(data[x], ABCSeries):
raise ValueError("x must be a label or position")
Expand All @@ -957,7 +957,7 @@ def __call__(self, *args, **kwargs):
# check if we have y as int or list of ints
int_ylist = is_list_like(y) and all(is_integer(c) for c in y)
int_y_arg = is_integer(y) or int_ylist
if int_y_arg and not data.columns.holds_integer():
if int_y_arg and not data.columns._holds_integer():
y = data_cols[y]

label_kw = kwargs["label"] if "label" in kwargs else False
Expand Down
8 changes: 4 additions & 4 deletions pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1137,9 +1137,9 @@ def __init__(self, data, x, y, **kwargs) -> None:
MPLPlot.__init__(self, data, **kwargs)
if x is None or y is None:
raise ValueError(self._kind + " requires an x and y column")
if is_integer(x) and not self.data.columns.holds_integer():
if is_integer(x) and not self.data.columns._holds_integer():
x = self.data.columns[x]
if is_integer(y) and not self.data.columns.holds_integer():
if is_integer(y) and not self.data.columns._holds_integer():
y = self.data.columns[y]

# Scatter plot allows to plot objects data
Expand Down Expand Up @@ -1196,7 +1196,7 @@ def __init__(self, data, x, y, s=None, c=None, **kwargs) -> None:
elif is_hashable(s) and s in data.columns:
s = data[s]
super().__init__(data, x, y, s=s, **kwargs)
if is_integer(c) and not self.data.columns.holds_integer():
if is_integer(c) and not self.data.columns._holds_integer():
c = self.data.columns[c]
self.c = c

Expand Down Expand Up @@ -1291,7 +1291,7 @@ def _kind(self) -> Literal["hexbin"]:

def __init__(self, data, x, y, C=None, **kwargs) -> None:
super().__init__(data, x, y, **kwargs)
if is_integer(C) and not self.data.columns.holds_integer():
if is_integer(C) and not self.data.columns._holds_integer():
C = self.data.columns[C]
self.C = C

Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/indexes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,13 @@ def test_is_integer_is_deprecated(self, simple_index):
with tm.assert_produces_warning(FutureWarning):
idx.is_integer()

def test_holds_integer_deprecated(self, simple_index):
# GH50243
idx = simple_index
msg = f"{type(idx).__name__}.holds_integer is deprecated. "
with tm.assert_produces_warning(FutureWarning, match=msg):
idx.holds_integer()


class NumericBase(Base):
"""
Expand Down