diff --git a/pandas/core/internals/api.py b/pandas/core/internals/api.py index 3fbe324417c60..9d517fe55f808 100644 --- a/pandas/core/internals/api.py +++ b/pandas/core/internals/api.py @@ -10,6 +10,7 @@ import numpy as np +from pandas._libs.internals import BlockPlacement from pandas._typing import Dtype from pandas.core.dtypes.common import is_datetime64tz_dtype @@ -58,4 +59,17 @@ def make_block( # for e.g. pyarrow? values = DatetimeArray._simple_new(values, dtype=dtype) + if not isinstance(placement, BlockPlacement): + placement = BlockPlacement(placement) + + if ndim is None: + # GH#38134 Block constructor now assumes ndim is not None + if not isinstance(values.dtype, np.dtype): + if len(placement) != 1: + ndim = 1 + else: + ndim = 2 + else: + ndim = values.ndim + return klass(values, ndim=ndim, placement=placement) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index b92ef3ec3b367..0ce746465cce4 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -170,6 +170,10 @@ def __init__(self, values, placement, ndim: int): f"placement implies {len(self.mgr_locs)}" ) + elif self.is_extension and self.ndim == 2 and len(self.mgr_locs) != 1: + # TODO(EA2D): check unnecessary with 2D EAs + raise AssertionError("block.size != values.size") + @classmethod def _maybe_coerce_values(cls, values): """ @@ -185,7 +189,7 @@ def _maybe_coerce_values(cls, values): """ return values - def _check_ndim(self, values, ndim): + def _check_ndim(self, values, ndim: int): """ ndim inference and validation. @@ -196,7 +200,7 @@ def _check_ndim(self, values, ndim): Parameters ---------- values : array-like - ndim : int or None + ndim : int Returns ------- @@ -206,8 +210,7 @@ def _check_ndim(self, values, ndim): ------ ValueError : the number of dimensions do not match """ - if ndim is None: - ndim = values.ndim + assert isinstance(ndim, int) # GH#38134 enforce this if self._validate_ndim: if values.ndim != ndim: @@ -1481,33 +1484,6 @@ class ExtensionBlock(Block): values: ExtensionArray - def __init__(self, values, placement, ndim: int): - """ - Initialize a non-consolidatable block. - - 'ndim' may be inferred from 'placement'. - - This will call continue to call __init__ for the other base - classes mixed in with this Mixin. - """ - - # Placement must be converted to BlockPlacement so that we can check - # its length - if not isinstance(placement, libinternals.BlockPlacement): - placement = libinternals.BlockPlacement(placement) - - # Maybe infer ndim from placement - if ndim is None: - if len(placement) != 1: - ndim = 1 - else: - ndim = 2 - super().__init__(values, placement, ndim=ndim) - - if self.ndim == 2 and len(self.mgr_locs) != 1: - # TODO(EA2D): check unnecessary with 2D EAs - raise AssertionError("block.size != values.size") - @property def shape(self) -> Shape: # TODO(EA2D): override unnecessary with 2D EAs