Skip to content

Commit 2019e7b

Browse files
authored
CLN/DEPR: remove Block._holder, deprecated Block.is_categorical (#40571)
1 parent 3f2599f commit 2019e7b

File tree

3 files changed

+26
-47
lines changed

3 files changed

+26
-47
lines changed

pandas/core/internals/blocks.py

+17-26
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
Union,
1414
cast,
1515
)
16+
import warnings
1617

1718
import numpy as np
1819

@@ -192,16 +193,6 @@ def __init__(self, values, placement: BlockPlacement, ndim: int):
192193
self._mgr_locs = placement
193194
self.values = values
194195

195-
@property
196-
def _holder(self):
197-
"""
198-
The array-like that can hold the underlying values.
199-
200-
None for 'Block', overridden by subclasses that don't
201-
use an ndarray.
202-
"""
203-
return None
204-
205196
@final
206197
@property
207198
def _consolidate_key(self):
@@ -228,7 +219,14 @@ def _can_hold_na(self) -> bool:
228219
@final
229220
@property
230221
def is_categorical(self) -> bool:
231-
return self._holder is Categorical
222+
warnings.warn(
223+
"Block.is_categorical is deprecated and will be removed in a "
224+
"future version. Use isinstance(block.values, Categorical) "
225+
"instead. See https://github.com/pandas-dev/pandas/issues/40226",
226+
DeprecationWarning,
227+
stacklevel=2,
228+
)
229+
return isinstance(self.values, Categorical)
232230

233231
@final
234232
def external_values(self):
@@ -798,8 +796,10 @@ def _replace_list(
798796
"""
799797
See BlockManager._replace_list docstring.
800798
"""
799+
values = self.values
800+
801801
# TODO: dont special-case Categorical
802-
if self.is_categorical and len(algos.unique(dest_list)) == 1:
802+
if isinstance(values, Categorical) and len(algos.unique(dest_list)) == 1:
803803
# We likely got here by tiling value inside NDFrame.replace,
804804
# so un-tile here
805805
return self.replace(src_list, dest_list[0], inplace, regex)
@@ -814,17 +814,17 @@ def _replace_list(
814814

815815
src_len = len(pairs) - 1
816816

817-
if self.is_object:
817+
if values.dtype == _dtype_obj:
818818
# Calculate the mask once, prior to the call of comp
819819
# in order to avoid repeating the same computations
820-
mask = ~isna(self.values)
820+
mask = ~isna(values)
821821
masks = [
822-
compare_or_regex_search(self.values, s[0], regex=regex, mask=mask)
822+
compare_or_regex_search(values, s[0], regex=regex, mask=mask)
823823
for s in pairs
824824
]
825825
else:
826826
# GH#38086 faster if we know we dont need to check for regex
827-
masks = [missing.mask_missing(self.values, s[0]) for s in pairs]
827+
masks = [missing.mask_missing(values, s[0]) for s in pairs]
828828

829829
# error: Argument 1 to "extract_bool_array" has incompatible type
830830
# "Union[ExtensionArray, ndarray, bool]"; expected "Union[ExtensionArray,
@@ -1503,11 +1503,6 @@ def putmask(self, mask, new) -> List[Block]:
15031503
new_values[mask] = new
15041504
return [self.make_block(values=new_values)]
15051505

1506-
@property
1507-
def _holder(self):
1508-
# For extension blocks, the holder is values-dependent.
1509-
return type(self.values)
1510-
15111506
@property
15121507
def is_view(self) -> bool:
15131508
"""Extension arrays are never treated as views."""
@@ -1713,7 +1708,7 @@ def where(self, other, cond, errors="raise") -> List[Block]:
17131708
# NotImplementedError for class not implementing `__setitem__`
17141709
# TypeError for SparseArray, which implements just to raise
17151710
# a TypeError
1716-
result = self._holder._from_sequence(
1711+
result = type(self.values)._from_sequence(
17171712
np.where(cond, self.values, other), dtype=dtype
17181713
)
17191714

@@ -1903,10 +1898,6 @@ class DatetimeLikeBlockMixin(NDArrayBackedExtensionBlock):
19031898
def array_values(self):
19041899
return ensure_wrapped_if_datetimelike(self.values)
19051900

1906-
@property
1907-
def _holder(self):
1908-
return type(self.array_values())
1909-
19101901

19111902
class DatetimeBlock(DatetimeLikeBlockMixin):
19121903
__slots__ = ()

pandas/core/internals/concat.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import pandas.core.algorithms as algos
4141
from pandas.core.arrays import (
42+
Categorical,
4243
DatetimeArray,
4344
ExtensionArray,
4445
)
@@ -367,7 +368,7 @@ def get_reindexed_values(self, empty_dtype: DtypeObj, upcasted_na) -> ArrayLike:
367368
# preserve these for validation in concat_compat
368369
return self.block.values
369370

370-
if self.block.is_bool and not self.block.is_categorical:
371+
if self.block.is_bool and not isinstance(self.block.values, Categorical):
371372
# External code requested filling/upcasting, bool values must
372373
# be upcasted to object to avoid being upcasted to numeric.
373374
values = self.block.astype(np.object_).values

pandas/tests/internals/test_internals.py

+7-20
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@
2727
)
2828
import pandas._testing as tm
2929
import pandas.core.algorithms as algos
30-
from pandas.core.arrays import (
31-
DatetimeArray,
32-
SparseArray,
33-
TimedeltaArray,
34-
)
30+
from pandas.core.arrays import SparseArray
3531
from pandas.core.internals import (
3632
BlockManager,
3733
SingleBlockManager,
@@ -320,6 +316,12 @@ def test_split(self):
320316
for res, exp in zip(result, expected):
321317
assert_block_equal(res, exp)
322318

319+
def test_is_categorical_deprecated(self):
320+
# GH#40571
321+
blk = self.fblock
322+
with tm.assert_produces_warning(DeprecationWarning):
323+
blk.is_categorical
324+
323325

324326
class TestBlockManager:
325327
def test_attrs(self):
@@ -1302,21 +1304,6 @@ def test_should_store_categorical(self):
13021304
assert not blk.should_store(np.asarray(cat))
13031305

13041306

1305-
@pytest.mark.parametrize(
1306-
"typestr, holder",
1307-
[
1308-
("category", Categorical),
1309-
("M8[ns]", DatetimeArray),
1310-
("M8[ns, US/Central]", DatetimeArray),
1311-
("m8[ns]", TimedeltaArray),
1312-
("sparse", SparseArray),
1313-
],
1314-
)
1315-
def test_holder(typestr, holder, block_maker):
1316-
blk = create_block(typestr, [1], maker=block_maker)
1317-
assert blk._holder is holder
1318-
1319-
13201307
def test_validate_ndim(block_maker):
13211308
values = np.array([1.0, 2.0])
13221309
placement = slice(2)

0 commit comments

Comments
 (0)