From 21bcfd09c8aea319cf41f806f2daa555d28eb009 Mon Sep 17 00:00:00 2001 From: Brock Date: Sun, 9 Jul 2023 13:17:27 -0700 Subject: [PATCH 1/2] REF: share block methods --- pandas/core/internals/blocks.py | 49 +++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 4480a1a0c6746..f34a9f7590a5e 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -156,10 +156,34 @@ class Block(PandasObject): __slots__ = () is_numeric = False - is_object = False - is_extension = False - _can_consolidate = True - _validate_ndim = True + + @final + @cache_readonly + def _validate_ndim(self) -> bool: + """ + We validate dimension for blocks that can hold 2D values, which for now + means numpy dtypes or DatetimeTZDtype. + """ + dtype = self.dtype + return not isinstance(dtype, ExtensionDtype) or isinstance( + dtype, DatetimeTZDtype + ) + + @final + @cache_readonly + def is_object(self) -> bool: + return self.values.dtype == _dtype_obj + + @final + @cache_readonly + def is_extension(self) -> bool: + return not lib.is_np_dtype(self.values.dtype) + + @final + @cache_readonly + def _can_consolidate(self) -> bool: + # We _could_ consolidate for DatetimeTZDtype but don't for now. + return not self.is_extension @final @cache_readonly @@ -1905,10 +1929,6 @@ class ExtensionBlock(libinternals.Block, EABackedBlock): ExtensionArrays are limited to 1-D. """ - _can_consolidate = False - _validate_ndim = False - is_extension = True - values: ExtensionArray def fillna( @@ -2172,10 +2192,6 @@ def is_numeric(self) -> bool: # type: ignore[override] return kind in "fciub" - @cache_readonly - def is_object(self) -> bool: # type: ignore[override] - return self.values.dtype.kind == "O" - class NumericBlock(NumpyBlock): # this Block type is kept for backwards-compatibility @@ -2196,12 +2212,6 @@ class NDArrayBackedExtensionBlock(libinternals.NDArrayBackedBlock, EABackedBlock values: NDArrayBackedExtensionArray - # error: Signature of "is_extension" incompatible with supertype "Block" - @cache_readonly - def is_extension(self) -> bool: # type: ignore[override] - # i.e. datetime64tz, PeriodDtype - return not isinstance(self.dtype, np.dtype) - @property def is_view(self) -> bool: """return a boolean if I am possibly a view""" @@ -2239,9 +2249,6 @@ class DatetimeTZBlock(DatetimeLikeBlock): values: DatetimeArray __slots__ = () - is_extension = True - _validate_ndim = True - _can_consolidate = False # Don't use values_for_json from DatetimeLikeBlock since it is # an invalid optimization here(drop the tz) From 50fb950870f25fb6d65f94ddacb6ab336e70d055 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 10 Jul 2023 10:26:19 -0700 Subject: [PATCH 2/2] Remove unnecessary test --- pandas/tests/extension/test_external_block.py | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 pandas/tests/extension/test_external_block.py diff --git a/pandas/tests/extension/test_external_block.py b/pandas/tests/extension/test_external_block.py deleted file mode 100644 index 1b5b46c6a01bb..0000000000000 --- a/pandas/tests/extension/test_external_block.py +++ /dev/null @@ -1,39 +0,0 @@ -import numpy as np -import pytest - -from pandas._libs.internals import BlockPlacement -import pandas.util._test_decorators as td - -import pandas as pd -from pandas.core.internals import BlockManager -from pandas.core.internals.blocks import ExtensionBlock - -pytestmark = td.skip_array_manager_invalid_test - - -class CustomBlock(ExtensionBlock): - _holder = np.ndarray - - # Cannot override final attribute "_can_hold_na" - @property # type: ignore[misc] - def _can_hold_na(self) -> bool: - return False - - -@pytest.fixture -def df(): - df1 = pd.DataFrame({"a": [1, 2, 3]}) - blocks = df1._mgr.blocks - values = np.arange(3, dtype="int64") - bp = BlockPlacement(slice(1, 2)) - custom_block = CustomBlock(values, placement=bp, ndim=2) - blocks = blocks + (custom_block,) - block_manager = BlockManager(blocks, [pd.Index(["a", "b"]), df1.index]) - return pd.DataFrame(block_manager) - - -def test_concat_axis1(df): - # GH17954 - df2 = pd.DataFrame({"c": [0.1, 0.2, 0.3]}) - res = pd.concat([df, df2], axis=1) - assert isinstance(res._mgr.blocks[1], CustomBlock)