From 43b81e1769f11cf6cda0f8802ca2c623f1ebb420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 15 Jun 2022 21:46:28 -0400 Subject: [PATCH 1/4] TYP: ndim is consistently a property --- pandas/core/arrays/datetimes.py | 5 ++++- pandas/core/arrays/interval.py | 6 +++++- pandas/core/arrays/period.py | 5 ++++- pandas/core/arrays/timedeltas.py | 6 +++++- pandas/core/base.py | 2 +- pandas/core/internals/array_manager.py | 9 +++++++-- pandas/core/internals/base.py | 5 ++++- pandas/core/internals/managers.py | 11 +++++++++-- pyright_reportGeneralTypeIssues.json | 1 - 9 files changed, 39 insertions(+), 11 deletions(-) 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..3ad3e72ec9cec 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -3,6 +3,7 @@ from datetime import timedelta from typing import ( TYPE_CHECKING, + Literal, cast, ) @@ -119,12 +120,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/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", From 21f664a8c78570018efab97fc4086ee8874a7497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 15 Jun 2022 21:57:36 -0400 Subject: [PATCH 2/4] unused import --- pandas/core/arrays/timedeltas.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 3ad3e72ec9cec..68f0d73b8556c 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -3,7 +3,6 @@ from datetime import timedelta from typing import ( TYPE_CHECKING, - Literal, cast, ) From 46330e3578ebef8ea13863627b189bd7a17acd52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 25 Jun 2022 09:59:46 -0400 Subject: [PATCH 3/4] fix test --- pandas/tests/arrays/test_datetimelike.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 10881495c27b3..2681244c16968 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -564,7 +564,9 @@ 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 = PeriodArray([], freq="1d")._scalar_type._from_ordinal( + 1, freq=arr.freq + ) else: fill_val = arr._scalar_type(1) expected[0] = fill_val From bd14855ee8ae183b09454bc16de0a899dfcf640f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 25 Jun 2022 10:15:08 -0400 Subject: [PATCH 4/4] nicer fix --- pandas/tests/arrays/test_datetimelike.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 2681244c16968..ea895e5656ccb 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -564,9 +564,7 @@ def test_shift_fill_int_deprecated(self): expected = arr.copy() if self.array_cls is PeriodArray: - fill_val = PeriodArray([], freq="1d")._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