diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 5f060542526d3..c6d0625de00fa 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -193,12 +193,15 @@ class DatetimeArray(dtl.TimelikeOps, dtl.DatelikeOps): """ _typ = "datetimearray" - _scalar_type = Timestamp _internal_fill_value = np.datetime64("NaT", "ns") _recognized_scalars = (datetime, np.datetime64) _is_recognized_dtype = is_datetime64_any_dtype _infer_matches = ("datetime", "datetime64", "date") + @property + def _scalar_type(self) -> type[Timestamp]: + return Timestamp + # define my properties & methods for delegation _bool_ops: list[str] = [ "is_month_start", diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 1015a54826ac8..e58032c48f8d3 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -8,6 +8,7 @@ import textwrap from typing import ( TYPE_CHECKING, + Literal, Sequence, TypeVar, Union, @@ -204,10 +205,13 @@ } ) class IntervalArray(IntervalMixin, ExtensionArray): - ndim = 1 can_hold_na = True _na_value = _fill_value = np.nan + @property + def ndim(self) -> Literal[1]: + return 1 + # To make mypy recognize the fields _left: np.ndarray _right: np.ndarray diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 291810c5db2f9..7e6ea07c154cd 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -167,12 +167,15 @@ class PeriodArray(dtl.DatelikeOps, libperiod.PeriodMixin): # array priority higher than numpy scalars __array_priority__ = 1000 _typ = "periodarray" # ABCPeriodArray - _scalar_type = Period _internal_fill_value = np.int64(iNaT) _recognized_scalars = (Period,) _is_recognized_dtype = is_period_dtype _infer_matches = ("period",) + @property + def _scalar_type(self) -> type[Period]: + return Period + # Names others delegate to us _other_ops: list[str] = [] _bool_ops: list[str] = ["is_leap_year"] diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index e08518a54fe6b..68f0d73b8556c 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -119,12 +119,15 @@ class TimedeltaArray(dtl.TimelikeOps): """ _typ = "timedeltaarray" - _scalar_type = Timedelta _internal_fill_value = np.timedelta64("NaT", "ns") _recognized_scalars = (timedelta, np.timedelta64, Tick) _is_recognized_dtype = is_timedelta64_dtype _infer_matches = ("timedelta", "timedelta64") + @property + def _scalar_type(self) -> type[Timedelta]: + return Timedelta + __array_priority__ = 1000 # define my properties & methods for delegation _other_ops: list[str] = [] diff --git a/pandas/core/base.py b/pandas/core/base.py index 7541eff9a11d4..3d18194d14bec 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -318,7 +318,7 @@ def __len__(self) -> int: raise AbstractMethodError(self) @property - def ndim(self) -> int: + def ndim(self) -> Literal[1]: """ Number of dimensions of the underlying data, by definition 1. """ diff --git a/pandas/core/internals/array_manager.py b/pandas/core/internals/array_manager.py index ee6c183898079..7d2e4129461a7 100644 --- a/pandas/core/internals/array_manager.py +++ b/pandas/core/internals/array_manager.py @@ -8,6 +8,7 @@ Any, Callable, Hashable, + Literal, TypeVar, ) @@ -704,7 +705,9 @@ def _equal_values(self, other) -> bool: class ArrayManager(BaseArrayManager): - ndim = 2 + @property + def ndim(self) -> Literal[2]: + return 2 def __init__( self, @@ -1191,7 +1194,9 @@ class SingleArrayManager(BaseArrayManager, SingleDataManager): arrays: list[np.ndarray | ExtensionArray] _axes: list[Index] - ndim = 1 + @property + def ndim(self) -> Literal[1]: + return 1 def __init__( self, diff --git a/pandas/core/internals/base.py b/pandas/core/internals/base.py index d8d1b6a34526c..ddc4495318568 100644 --- a/pandas/core/internals/base.py +++ b/pandas/core/internals/base.py @@ -5,6 +5,7 @@ from __future__ import annotations from typing import ( + Literal, TypeVar, final, ) @@ -155,7 +156,9 @@ def _consolidate_inplace(self) -> None: class SingleDataManager(DataManager): - ndim = 1 + @property + def ndim(self) -> Literal[1]: + return 1 @final @property diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index 7cccc9833de6b..435992f7d5cff 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -5,6 +5,7 @@ Any, Callable, Hashable, + Literal, Sequence, TypeVar, cast, @@ -142,7 +143,10 @@ class BaseBlockManager(DataManager): blocks: tuple[Block, ...] axes: list[Index] - ndim: int + @property + def ndim(self) -> int: + raise NotImplementedError + _known_consolidated: bool _is_consolidated: bool @@ -1678,7 +1682,10 @@ def _consolidate_inplace(self) -> None: class SingleBlockManager(BaseBlockManager, SingleDataManager): """manage a single block with""" - ndim = 1 + @property + def ndim(self) -> Literal[1]: + return 1 + _is_consolidated = True _known_consolidated = True __slots__ = () diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 10881495c27b3..ea895e5656ccb 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -564,7 +564,7 @@ def test_shift_fill_int_deprecated(self): expected = arr.copy() if self.array_cls is PeriodArray: - fill_val = PeriodArray._scalar_type._from_ordinal(1, freq=arr.freq) + fill_val = arr._scalar_type._from_ordinal(1, freq=arr.freq) else: fill_val = arr._scalar_type(1) expected[0] = fill_val diff --git a/pyright_reportGeneralTypeIssues.json b/pyright_reportGeneralTypeIssues.json index a8ef1a77aaced..541ae4b198166 100644 --- a/pyright_reportGeneralTypeIssues.json +++ b/pyright_reportGeneralTypeIssues.json @@ -61,7 +61,6 @@ "pandas/core/indexing.py", "pandas/core/internals/api.py", "pandas/core/internals/array_manager.py", - "pandas/core/internals/base.py", "pandas/core/internals/blocks.py", "pandas/core/internals/concat.py", "pandas/core/internals/construction.py",