Skip to content

TYP: @final for Block methods #39865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 38 additions & 24 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
Dtype,
DtypeObj,
Shape,
final,
)
from pandas.util._validators import validate_bool_kwarg

Expand Down Expand Up @@ -231,6 +232,7 @@ def _holder(self):
"""
return None

@final
@property
def _consolidate_key(self):
return self._can_consolidate, self.dtype.name
Expand All @@ -242,6 +244,7 @@ def is_view(self) -> bool:
values = cast(np.ndarray, values)
return values.base is not None

@final
@property
def is_categorical(self) -> bool:
return self._holder is Categorical
Expand Down Expand Up @@ -278,6 +281,7 @@ def get_values(self, dtype: Optional[DtypeObj] = None) -> np.ndarray:
return self.values.astype(object)
return self.values

@final
def get_block_values_for_json(self) -> np.ndarray:
"""
This is used in the JSON C code.
Expand All @@ -300,6 +304,7 @@ def mgr_locs(self, new_mgr_locs):

self._mgr_locs = new_mgr_locs

@final
def make_block(self, values, placement=None) -> Block:
"""
Create a new block, with type inference propagate any values that are
Expand All @@ -312,14 +317,14 @@ def make_block(self, values, placement=None) -> Block:

return make_block(values, placement=placement, ndim=self.ndim)

def make_block_same_class(self, values, placement=None, ndim=None) -> Block:
@final
def make_block_same_class(self, values, placement=None) -> Block:
""" Wrap given values in a block of same type as self. """
if placement is None:
placement = self.mgr_locs
if ndim is None:
ndim = self.ndim
return type(self)(values, placement=placement, ndim=ndim)
return type(self)(values, placement=placement, ndim=self.ndim)

@final
def __repr__(self) -> str:
# don't want to print out all of the items here
name = type(self).__name__
Expand All @@ -332,12 +337,15 @@ def __repr__(self) -> str:

return result

@final
def __len__(self) -> int:
return len(self.values)

@final
def __getstate__(self):
return self.mgr_locs.indexer, self.values

@final
def __setstate__(self, state):
self.mgr_locs = libinternals.BlockPlacement(state[0])
self.values = state[1]
Expand All @@ -348,6 +356,7 @@ def _slice(self, slicer):

return self.values[slicer]

@final
def getitem_block(self, slicer, new_mgr_locs=None) -> Block:
"""
Perform __getitem__-like, return result as block.
Expand All @@ -371,6 +380,7 @@ def getitem_block(self, slicer, new_mgr_locs=None) -> Block:
def shape(self) -> Shape:
return self.values.shape

@final
@property
def dtype(self) -> DtypeObj:
return self.values.dtype
Expand All @@ -389,13 +399,15 @@ def set_inplace(self, locs, values):
"""
self.values[locs] = values

@final
def delete(self, loc) -> None:
"""
Delete given loc(-s) from block in-place.
"""
self.values = np.delete(self.values, loc, 0)
self.mgr_locs = self.mgr_locs.delete(loc)

@final
def apply(self, func, **kwargs) -> List[Block]:
"""
apply the function to my values; return a block if we are not
Expand Down Expand Up @@ -427,6 +439,7 @@ def reduce(self, func, ignore_failures: bool = False) -> List[Block]:
nb = self.make_block(res_values)
return [nb]

@final
def _split_op_result(self, result) -> List[Block]:
# See also: split_and_operate
if is_extension_array_dtype(result) and result.ndim > 1:
Expand Down Expand Up @@ -487,6 +500,7 @@ def f(mask, val, idx):

return self.split_and_operate(None, f, inplace)

@final
def _split(self) -> List[Block]:
"""
Split a block into a list of single-column blocks.
Expand All @@ -501,6 +515,7 @@ def _split(self) -> List[Block]:
new_blocks.append(nb)
return new_blocks

@final
def split_and_operate(
self, mask, f, inplace: bool, ignore_failures: bool = False
) -> List[Block]:
Expand Down Expand Up @@ -617,6 +632,7 @@ def f(mask, val, idx):

return self.split_and_operate(None, f, False)

@final
def astype(self, dtype, copy: bool = False, errors: str = "raise"):
"""
Coerce to the new dtype.
Expand Down Expand Up @@ -708,6 +724,7 @@ def _can_hold_element(self, element: Any) -> bool:
""" require the same dtype as ourselves """
raise NotImplementedError("Implemented on subclasses")

@final
def should_store(self, value: ArrayLike) -> bool:
"""
Should we set self.values[indexer] = value inplace or do we need to cast?
Expand Down Expand Up @@ -741,12 +758,13 @@ def to_native_types(self, na_rep="nan", quoting=None, **kwargs):
return self.make_block(values)

# block actions #
@final
def copy(self, deep: bool = True):
""" copy constructor """
values = self.values
if deep:
values = values.copy()
return self.make_block_same_class(values, ndim=self.ndim)
return self.make_block_same_class(values)

# ---------------------------------------------------------------------
# Replace
Expand Down Expand Up @@ -795,6 +813,7 @@ def replace(
blocks = blk.convert(numeric=False, copy=not inplace)
return blocks

@final
def _replace_regex(
self,
to_replace,
Expand Down Expand Up @@ -840,6 +859,7 @@ def _replace_regex(
nbs = [block]
return nbs

@final
def _replace_list(
self,
src_list: List[Any],
Expand Down Expand Up @@ -901,6 +921,7 @@ def _replace_list(
rb = new_rb
return rb

@final
def _replace_coerce(
self,
to_replace,
Expand Down Expand Up @@ -1135,6 +1156,7 @@ def f(mask, val, idx):
new_blocks = self.split_and_operate(mask, f, True)
return new_blocks

@final
def coerce_to_target_dtype(self, other) -> Block:
"""
coerce the current block to a dtype compat for other
Expand All @@ -1150,6 +1172,7 @@ def coerce_to_target_dtype(self, other) -> Block:

return self.astype(new_dtype, copy=False)

@final
def interpolate(
self,
method: str = "pad",
Expand Down Expand Up @@ -1208,6 +1231,7 @@ def interpolate(
**kwargs,
)

@final
def _interpolate_with_fill(
self,
method: str = "pad",
Expand All @@ -1232,9 +1256,10 @@ def _interpolate_with_fill(
limit_area=limit_area,
)

blocks = [self.make_block_same_class(values, ndim=self.ndim)]
blocks = [self.make_block_same_class(values)]
return self._maybe_downcast(blocks, downcast)

@final
def _interpolate(
self,
method: str,
Expand Down Expand Up @@ -1447,7 +1472,7 @@ def _unstack(self, unstacker, fill_value, new_placement):
new_values = new_values.T[mask]
new_placement = new_placement[mask]

blocks = [make_block(new_values, placement=new_placement)]
blocks = [make_block(new_values, placement=new_placement, ndim=2)]
return blocks, mask

def quantile(
Expand Down Expand Up @@ -1747,21 +1772,15 @@ def fillna(
) -> List[Block]:
values = self.values if inplace else self.values.copy()
values = values.fillna(value=value, limit=limit)
return [
self.make_block_same_class(
values=values, placement=self.mgr_locs, ndim=self.ndim
)
]
return [self.make_block_same_class(values=values)]

def interpolate(
self, method="pad", axis=0, inplace=False, limit=None, fill_value=None, **kwargs
):

values = self.values if inplace else self.values.copy()
return self.make_block_same_class(
values=values.fillna(value=fill_value, method=method, limit=limit),
placement=self.mgr_locs,
)
new_values = values.fillna(value=fill_value, method=method, limit=limit)
return self.make_block_same_class(new_values)

def diff(self, n: int, axis: int = 1) -> List[Block]:
if axis == 0 and n != 0:
Expand All @@ -1783,13 +1802,8 @@ def shift(self, periods: int, axis: int = 0, fill_value: Any = None) -> List[Blo
Dispatches to underlying ExtensionArray and re-boxes in an
ExtensionBlock.
"""
return [
self.make_block_same_class(
self.values.shift(periods=periods, fill_value=fill_value),
placement=self.mgr_locs,
ndim=self.ndim,
)
]
new_values = self.values.shift(periods=periods, fill_value=fill_value)
return [self.make_block_same_class(new_values)]

def where(self, other, cond, errors="raise", axis: int = 0) -> List[Block]:

Expand Down Expand Up @@ -1836,7 +1850,7 @@ def where(self, other, cond, errors="raise", axis: int = 0) -> List[Block]:
np.where(cond, self.values, other), dtype=dtype
)

return [self.make_block_same_class(result, placement=self.mgr_locs)]
return [self.make_block_same_class(result)]

def _unstack(self, unstacker, fill_value, new_placement):
# ExtensionArray-safe unstack.
Expand Down
7 changes: 2 additions & 5 deletions pandas/core/internals/concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,8 @@ def concatenate_block_managers(
else:
b = make_block(values, placement=placement, ndim=blk.ndim)
else:
b = make_block(
_concatenate_join_units(join_units, concat_axis, copy=copy),
placement=placement,
ndim=len(axes),
)
new_values = _concatenate_join_units(join_units, concat_axis, copy=copy)
b = make_block(new_values, placement=placement, ndim=len(axes))
blocks.append(b)

return BlockManager(blocks, axes)
Expand Down
10 changes: 3 additions & 7 deletions pandas/core/internals/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def make_empty(self: T, axes=None) -> T:
assert isinstance(self, SingleBlockManager) # for mypy
blk = self.blocks[0]
arr = blk.values[:0]
nb = blk.make_block_same_class(arr, placement=slice(0, 0), ndim=1)
nb = blk.make_block_same_class(arr, placement=slice(0, 0))
blocks = [nb]
else:
blocks = []
Expand Down Expand Up @@ -967,12 +967,8 @@ def iget(self, i: int) -> SingleBlockManager:
values = block.iget(self.blklocs[i])

# shortcut for select a single-dim from a 2-dim BM
return SingleBlockManager(
block.make_block_same_class(
values, placement=slice(0, len(values)), ndim=1
),
self.axes[1],
)
nb = type(block)(values, placement=slice(0, len(values)), ndim=1)
return SingleBlockManager(nb, self.axes[1])

def iget_values(self, i: int) -> ArrayLike:
"""
Expand Down