From 024c5ffd4767b19dffcb111e86f72e54a2deb0bf Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Tue, 27 May 2025 09:08:23 -0400 Subject: [PATCH 1/3] use TypeAlias. Make internal types private --- pandas/core/apply.py | 15 ++++---- pandas/core/arrays/datetimelike.py | 16 +++++---- pandas/core/arrays/interval.py | 36 ++++++++++--------- pandas/core/arrays/string_arrow.py | 4 --- pandas/core/groupby/generic.py | 6 ++-- pandas/core/groupby/groupby.py | 20 +++++------ pandas/core/indexing.py | 3 +- pandas/core/tools/datetimes.py | 56 +++++++++++++++--------------- pandas/io/excel/_calamine.py | 4 +-- pandas/io/formats/printing.py | 8 ++--- pandas/io/formats/style_render.py | 17 +++++---- pandas/io/pytables.py | 7 ++-- pandas/util/version/__init__.py | 18 +++++----- 13 files changed, 105 insertions(+), 105 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 2c96f1ef020ac..e9a431c1759a7 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -10,6 +10,7 @@ TYPE_CHECKING, Any, Literal, + TypeAlias, cast, ) @@ -71,7 +72,7 @@ from pandas.core.resample import Resampler from pandas.core.window.rolling import BaseWindow -ResType = dict[int, Any] +_ResType: TypeAlias = dict[int, Any] class BaseExecutionEngine(abc.ABC): @@ -934,7 +935,7 @@ def validate_values_for_numba(self) -> None: @abc.abstractmethod def wrap_results_for_axis( - self, results: ResType, res_index: Index + self, results: _ResType, res_index: Index ) -> DataFrame | Series: pass @@ -1163,7 +1164,7 @@ def apply_standard(self): # wrap results return self.wrap_results(results, res_index) - def apply_series_generator(self) -> tuple[ResType, Index]: + def apply_series_generator(self) -> tuple[_ResType, Index]: assert callable(self.func) series_gen = self.series_generator @@ -1193,7 +1194,7 @@ def apply_series_numba(self): results = self.apply_with_numba() return results, self.result_index - def wrap_results(self, results: ResType, res_index: Index) -> DataFrame | Series: + def wrap_results(self, results: _ResType, res_index: Index) -> DataFrame | Series: from pandas import Series # see if we can infer the results @@ -1289,7 +1290,7 @@ def result_columns(self) -> Index: return self.index def wrap_results_for_axis( - self, results: ResType, res_index: Index + self, results: _ResType, res_index: Index ) -> DataFrame | Series: """return the results for the rows""" @@ -1433,7 +1434,7 @@ def result_columns(self) -> Index: return self.columns def wrap_results_for_axis( - self, results: ResType, res_index: Index + self, results: _ResType, res_index: Index ) -> DataFrame | Series: """return the results for the columns""" result: DataFrame | Series @@ -1453,7 +1454,7 @@ def wrap_results_for_axis( return result - def infer_to_same_shape(self, results: ResType, res_index: Index) -> DataFrame: + def infer_to_same_shape(self, results: _ResType, res_index: Index) -> DataFrame: """infer the results to the same shape as the input object""" result = self.obj._constructor(data=results) result = result.T diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 994d7b1d0081c..7622286fdd053 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -10,6 +10,7 @@ TYPE_CHECKING, Any, Literal, + TypeAlias, Union, cast, final, @@ -161,7 +162,8 @@ TimedeltaArray, ) -DTScalarOrNaT = Union[DatetimeLikeScalar, NaTType] +# underscore at end because of rule PYI043 that private types should not end with 'T' +_DTScalarOrNaT_: TypeAlias = DatetimeLikeScalar | NaTType def _make_unpacked_invalid_op(op_name: str): @@ -236,7 +238,7 @@ def _scalar_type(self) -> type[DatetimeLikeScalar]: """ raise AbstractMethodError(self) - def _scalar_from_string(self, value: str) -> DTScalarOrNaT: + def _scalar_from_string(self, value: str) -> _DTScalarOrNaT_: """ Construct a scalar type from a string. @@ -257,7 +259,7 @@ def _scalar_from_string(self, value: str) -> DTScalarOrNaT: raise AbstractMethodError(self) def _unbox_scalar( - self, value: DTScalarOrNaT + self, value: _DTScalarOrNaT_ ) -> np.int64 | np.datetime64 | np.timedelta64: """ Unbox the integer value of a scalar `value`. @@ -279,7 +281,7 @@ def _unbox_scalar( """ raise AbstractMethodError(self) - def _check_compatible_with(self, other: DTScalarOrNaT) -> None: + def _check_compatible_with(self, other: _DTScalarOrNaT_) -> None: """ Verify that `self` and `other` are compatible. @@ -370,7 +372,7 @@ def __array__( return self._ndarray @overload - def __getitem__(self, key: ScalarIndexer) -> DTScalarOrNaT: ... + def __getitem__(self, key: ScalarIndexer) -> _DTScalarOrNaT_: ... @overload def __getitem__( @@ -378,7 +380,7 @@ def __getitem__( key: SequenceIndexer | PositionalIndexerTuple, ) -> Self: ... - def __getitem__(self, key: PositionalIndexer2D) -> Self | DTScalarOrNaT: + def __getitem__(self, key: PositionalIndexer2D) -> Self | _DTScalarOrNaT_: """ This getitem defers to the underlying array, which by-definition can only handle list-likes, slices, and integer scalars @@ -386,7 +388,7 @@ def __getitem__(self, key: PositionalIndexer2D) -> Self | DTScalarOrNaT: # Use cast as we know we will get back a DatetimeLikeArray or DTScalar, # but skip evaluating the Union at runtime for performance # (see https://github.com/pandas-dev/pandas/pull/44624) - result = cast("Union[Self, DTScalarOrNaT]", super().__getitem__(key)) + result = cast(Union[Self, _DTScalarOrNaT_], super().__getitem__(key)) if lib.is_scalar(result): return result else: diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 6cb79e915c78b..c390dd3942ebc 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -9,7 +9,7 @@ from typing import ( TYPE_CHECKING, Literal, - Union, + TypeAlias, overload, ) @@ -109,8 +109,8 @@ ) -IntervalSide = Union[TimeArrayLike, np.ndarray] -IntervalOrNA = Union[Interval, float] +_IntervalSide: TypeAlias = TimeArrayLike | np.ndarray +_IntervalOrNA: TypeAlias = Interval | float _interval_shared_docs: dict[str, str] = {} @@ -216,8 +216,8 @@ def ndim(self) -> Literal[1]: return 1 # To make mypy recognize the fields - _left: IntervalSide - _right: IntervalSide + _left: _IntervalSide + _right: _IntervalSide _dtype: IntervalDtype # --------------------------------------------------------------------- @@ -234,8 +234,8 @@ def __new__( data = extract_array(data, extract_numpy=True) if isinstance(data, cls): - left: IntervalSide = data._left - right: IntervalSide = data._right + left: _IntervalSide = data._left + right: _IntervalSide = data._right closed = closed or data.closed dtype = IntervalDtype(left.dtype, closed=closed) else: @@ -277,8 +277,8 @@ def __new__( @classmethod def _simple_new( cls, - left: IntervalSide, - right: IntervalSide, + left: _IntervalSide, + right: _IntervalSide, dtype: IntervalDtype, ) -> Self: result = IntervalMixin.__new__(cls) @@ -296,7 +296,7 @@ def _ensure_simple_new_inputs( closed: IntervalClosedType | None = None, copy: bool = False, dtype: Dtype | None = None, - ) -> tuple[IntervalSide, IntervalSide, IntervalDtype]: + ) -> tuple[_IntervalSide, _IntervalSide, IntervalDtype]: """Ensure correctness of input parameters for cls._simple_new.""" from pandas.core.indexes.base import ensure_index @@ -704,12 +704,12 @@ def __len__(self) -> int: return len(self._left) @overload - def __getitem__(self, key: ScalarIndexer) -> IntervalOrNA: ... + def __getitem__(self, key: ScalarIndexer) -> _IntervalOrNA: ... @overload def __getitem__(self, key: SequenceIndexer) -> Self: ... - def __getitem__(self, key: PositionalIndexer) -> Self | IntervalOrNA: + def __getitem__(self, key: PositionalIndexer) -> Self | _IntervalOrNA: key = check_array_indexer(self, key) left = self._left[key] right = self._right[key] @@ -858,7 +858,7 @@ def argsort( ascending=ascending, kind=kind, na_position=na_position, **kwargs ) - def min(self, *, axis: AxisInt | None = None, skipna: bool = True) -> IntervalOrNA: + def min(self, *, axis: AxisInt | None = None, skipna: bool = True) -> _IntervalOrNA: nv.validate_minmax_axis(axis, self.ndim) if not len(self): @@ -875,7 +875,7 @@ def min(self, *, axis: AxisInt | None = None, skipna: bool = True) -> IntervalOr indexer = obj.argsort()[0] return obj[indexer] - def max(self, *, axis: AxisInt | None = None, skipna: bool = True) -> IntervalOrNA: + def max(self, *, axis: AxisInt | None = None, skipna: bool = True) -> _IntervalOrNA: nv.validate_minmax_axis(axis, self.ndim) if not len(self): @@ -1016,8 +1016,10 @@ def _concat_same_type(cls, to_concat: Sequence[IntervalArray]) -> Self: raise ValueError("Intervals must all be closed on the same side.") closed = closed_set.pop() - left: IntervalSide = np.concatenate([interval.left for interval in to_concat]) - right: IntervalSide = np.concatenate([interval.right for interval in to_concat]) + left: _IntervalSide = np.concatenate([interval.left for interval in to_concat]) + right: _IntervalSide = np.concatenate( + [interval.right for interval in to_concat] + ) left, right, dtype = cls._ensure_simple_new_inputs(left, right, closed=closed) @@ -1952,7 +1954,7 @@ def isin(self, values: ArrayLike) -> npt.NDArray[np.bool_]: return isin(self.astype(object), values.astype(object)) @property - def _combined(self) -> IntervalSide: + def _combined(self) -> _IntervalSide: # error: Item "ExtensionArray" of "ExtensionArray | ndarray[Any, Any]" # has no attribute "reshape" [union-attr] left = self.left._values.reshape(-1, 1) # type: ignore[union-attr] diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index 9668981df827b..7264efa3298d9 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -4,7 +4,6 @@ import re from typing import ( TYPE_CHECKING, - Union, ) import warnings @@ -63,9 +62,6 @@ from pandas import Series -ArrowStringScalarOrNAT = Union[str, libmissing.NAType] - - def _chk_pyarrow_available() -> None: if pa_version_under10p1: msg = "pyarrow>=10.0.1 is required for PyArrow backed ArrowExtensionArray." diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index b520ad69aae96..2f5ae0a5c0995 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -17,8 +17,8 @@ Any, Literal, NamedTuple, + TypeAlias, TypeVar, - Union, cast, ) import warnings @@ -102,7 +102,7 @@ from pandas.core.generic import NDFrame # TODO(typing) the return value on this callable should be any *scalar*. -AggScalar = Union[str, Callable[..., Any]] +_AggScalar: TypeAlias = str | Callable[..., Any] # TODO: validate types on ScalarResult and move to _typing # Blocked from using by https://github.com/python/mypy/issues/1484 # See note at _mangle_lambda_list @@ -141,7 +141,7 @@ class NamedAgg(NamedTuple): """ column: Hashable - aggfunc: AggScalar + aggfunc: _AggScalar @set_module("pandas.api.typing") diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 3daee98371844..f29423ce5e77c 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -26,6 +26,7 @@ class providing the base-class of operations. from typing import ( TYPE_CHECKING, Literal, + TypeAlias, TypeVar, Union, cast, @@ -449,13 +450,13 @@ def f(self): return attr -_KeysArgType = Union[ - Hashable, - list[Hashable], - Callable[[Hashable], Hashable], - list[Callable[[Hashable], Hashable]], - Mapping[Hashable, Hashable], -] +_KeysArgType: TypeAlias = ( + Hashable + | list[Hashable] + | Callable[[Hashable], Hashable] + | list[Callable[[Hashable], Hashable]] + | Mapping[Hashable, Hashable] +) class BaseGroupBy(PandasObject, SelectionMixin[NDFrameT], GroupByIndexingMixin): @@ -957,9 +958,8 @@ def __iter__(self) -> Iterator[tuple[Hashable, NDFrameT]]: level = self.level result = self._grouper.get_iterator(self._selected_obj) # mypy: Argument 1 to "len" has incompatible type "Hashable"; expected "Sized" - if ( - (is_list_like(level) and len(level) == 1) # type: ignore[arg-type] - or (isinstance(keys, list) and len(keys) == 1) + if (is_list_like(level) and len(level) == 1) or ( # type: ignore[arg-type] + isinstance(keys, list) and len(keys) == 1 ): # GH#42795 - when keys is a list, return tuples even when length is 1 result = (((key,), group) for key, group in result) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 34a437ba40bd8..994dcd4618a1c 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -5,7 +5,6 @@ from typing import ( TYPE_CHECKING, Any, - TypeVar, cast, final, ) @@ -83,6 +82,7 @@ Axis, AxisInt, Self, + T, npt, ) @@ -91,7 +91,6 @@ Series, ) -T = TypeVar("T") # "null slice" _NS = slice(None, None) _one_ellipsis_message = "indexer may only contain one '...' entry" diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index 0a10001a3113f..d1b3ef007d151 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -6,6 +6,7 @@ from itertools import islice from typing import ( TYPE_CHECKING, + TypeAlias, TypedDict, Union, cast, @@ -93,34 +94,33 @@ # --------------------------------------------------------------------- # types used in annotations -ArrayConvertible = Union[list, tuple, AnyArrayLike] -Scalar = Union[float, str] -DatetimeScalar = Union[Scalar, date, np.datetime64] +_ArrayConvertible: TypeAlias = list | tuple | AnyArrayLike +_Scalar: TypeAlias = float | str +_DatetimeScalar: TypeAlias = _Scalar | date | np.datetime64 -DatetimeScalarOrArrayConvertible = Union[DatetimeScalar, ArrayConvertible] +_DatetimeScalarOrArrayConvertible: TypeAlias = _DatetimeScalar | _ArrayConvertible +_DatetimeDictArg: TypeAlias = list[_Scalar] | tuple[_Scalar, ...] | AnyArrayLike -DatetimeDictArg = Union[list[Scalar], tuple[Scalar, ...], AnyArrayLike] +class _YearMonthDayDict(TypedDict, total=True): + year: _DatetimeDictArg + month: _DatetimeDictArg + day: _DatetimeDictArg -class YearMonthDayDict(TypedDict, total=True): - year: DatetimeDictArg - month: DatetimeDictArg - day: DatetimeDictArg +class _FulldatetimeDict(_YearMonthDayDict, total=False): + hour: _DatetimeDictArg + hours: _DatetimeDictArg + minute: _DatetimeDictArg + minutes: _DatetimeDictArg + second: _DatetimeDictArg + seconds: _DatetimeDictArg + ms: _DatetimeDictArg + us: _DatetimeDictArg + ns: _DatetimeDictArg -class FulldatetimeDict(YearMonthDayDict, total=False): - hour: DatetimeDictArg - hours: DatetimeDictArg - minute: DatetimeDictArg - minutes: DatetimeDictArg - second: DatetimeDictArg - seconds: DatetimeDictArg - ms: DatetimeDictArg - us: DatetimeDictArg - ns: DatetimeDictArg - -DictConvertible = Union[FulldatetimeDict, "DataFrame"] +_DictConvertible = Union[_FulldatetimeDict, "DataFrame"] start_caching_at = 50 @@ -151,7 +151,7 @@ def _guess_datetime_format_for_array(arr, dayfirst: bool | None = False) -> str def should_cache( - arg: ArrayConvertible, unique_share: float = 0.7, check_count: int | None = None + arg: _ArrayConvertible, unique_share: float = 0.7, check_count: int | None = None ) -> bool: """ Decides whether to do caching. @@ -211,7 +211,7 @@ def should_cache( def _maybe_cache( - arg: ArrayConvertible, + arg: _ArrayConvertible, format: str | None, cache: bool, convert_listlike: Callable, @@ -290,7 +290,7 @@ def _box_as_indexlike( def _convert_and_box_cache( - arg: DatetimeScalarOrArrayConvertible, + arg: _DatetimeScalarOrArrayConvertible, cache_array: Series, name: Hashable | None = None, ) -> Index: @@ -622,7 +622,7 @@ def _adjust_to_origin(arg, origin, unit): @overload def to_datetime( - arg: DatetimeScalar, + arg: _DatetimeScalar, errors: DateTimeErrorChoices = ..., dayfirst: bool = ..., yearfirst: bool = ..., @@ -637,7 +637,7 @@ def to_datetime( @overload def to_datetime( - arg: Series | DictConvertible, + arg: Series | _DictConvertible, errors: DateTimeErrorChoices = ..., dayfirst: bool = ..., yearfirst: bool = ..., @@ -666,7 +666,7 @@ def to_datetime( def to_datetime( - arg: DatetimeScalarOrArrayConvertible | DictConvertible, + arg: _DatetimeScalarOrArrayConvertible | _DictConvertible, errors: DateTimeErrorChoices = "raise", dayfirst: bool = False, yearfirst: bool = False, @@ -676,7 +676,7 @@ def to_datetime( unit: str | None = None, origin: str = "unix", cache: bool = True, -) -> DatetimeIndex | Series | DatetimeScalar | NaTType | None: +) -> DatetimeIndex | Series | _DatetimeScalar | NaTType | None: """ Convert argument to datetime. diff --git a/pandas/io/excel/_calamine.py b/pandas/io/excel/_calamine.py index b8994e679d4b1..0bdd2b42aad51 100644 --- a/pandas/io/excel/_calamine.py +++ b/pandas/io/excel/_calamine.py @@ -9,7 +9,7 @@ from typing import ( TYPE_CHECKING, Any, - Union, + TypeAlias, ) from pandas.compat._optional import import_optional_dependency @@ -34,7 +34,7 @@ StorageOptions, ) -_CellValue = Union[int, float, str, bool, time, date, datetime, timedelta] +_CellValue: TypeAlias = int | float | str | bool | time | date | datetime | timedelta class CalamineReader(BaseExcelReader["CalamineWorkbook"]): diff --git a/pandas/io/formats/printing.py b/pandas/io/formats/printing.py index ab27321ffe83c..c8d06d7cf07ba 100644 --- a/pandas/io/formats/printing.py +++ b/pandas/io/formats/printing.py @@ -14,8 +14,8 @@ from typing import ( TYPE_CHECKING, Any, + TypeAlias, TypeVar, - Union, ) from unicodedata import east_asian_width @@ -27,7 +27,7 @@ if TYPE_CHECKING: from pandas._typing import ListLike -EscapeChars = Union[Mapping[str, str], Iterable[str]] +_EscapeChars: TypeAlias = Mapping[str, str] | Iterable[str] _KT = TypeVar("_KT") _VT = TypeVar("_VT") @@ -174,7 +174,7 @@ def _pprint_dict( def pprint_thing( thing: object, _nest_lvl: int = 0, - escape_chars: EscapeChars | None = None, + escape_chars: _EscapeChars | None = None, default_escapes: bool = False, quote_strings: bool = False, max_seq_items: int | None = None, @@ -203,7 +203,7 @@ def pprint_thing( """ def as_escaped_string( - thing: Any, escape_chars: EscapeChars | None = escape_chars + thing: Any, escape_chars: _EscapeChars | None = escape_chars ) -> str: translate = {"\t": r"\t", "\n": r"\n", "\r": r"\r", "'": r"\'"} if isinstance(escape_chars, Mapping): diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 6752c83d5169b..0747e7c84e1b0 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -11,9 +11,8 @@ TYPE_CHECKING, Any, DefaultDict, - Optional, + TypeAlias, TypedDict, - Union, ) from uuid import uuid4 @@ -50,11 +49,11 @@ jinja2 = import_optional_dependency("jinja2", extra="DataFrame.style requires jinja2.") from markupsafe import escape as escape_html # markupsafe is jinja2 dependency -BaseFormatter = Union[str, Callable] -ExtFormatter = Union[BaseFormatter, dict[Any, Optional[BaseFormatter]]] -CSSPair = tuple[str, Union[str, float]] -CSSList = list[CSSPair] -CSSProperties = Union[str, CSSList] +BaseFormatter: TypeAlias = str | Callable +ExtFormatter: TypeAlias = BaseFormatter | dict[Any, BaseFormatter | None] +CSSPair: TypeAlias = tuple[str, str | float] +CSSList: TypeAlias = list[CSSPair] +CSSProperties: TypeAlias = str | CSSList class CSSDict(TypedDict): @@ -62,8 +61,8 @@ class CSSDict(TypedDict): props: CSSProperties -CSSStyles = list[CSSDict] -Subset = Union[slice, Sequence, Index] +CSSStyles: TypeAlias = list[CSSDict] +Subset = slice | Sequence | Index class StylerRenderer: diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index c58b4a4be6df1..e9a45f536a90d 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -20,6 +20,7 @@ Any, Final, Literal, + TypeAlias, cast, overload, ) @@ -160,7 +161,7 @@ def _ensure_str(name): return name -Term = PyTablesExpr +_Term: TypeAlias = PyTablesExpr def _ensure_term(where, scope_level: int): @@ -175,12 +176,12 @@ def _ensure_term(where, scope_level: int): level = scope_level + 1 if isinstance(where, (list, tuple)): where = [ - Term(term, scope_level=level + 1) if maybe_expression(term) else term + _Term(term, scope_level=level + 1) if maybe_expression(term) else term for term in where if term is not None ] elif maybe_expression(where): - where = Term(where, scope_level=level) + where = _Term(where, scope_level=level) return where if where is None or len(where) else None diff --git a/pandas/util/version/__init__.py b/pandas/util/version/__init__.py index bd741140f6542..15696c9292eda 100644 --- a/pandas/util/version/__init__.py +++ b/pandas/util/version/__init__.py @@ -13,7 +13,7 @@ Any, NamedTuple, SupportsInt, - Union, + TypeAlias, ) __all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "parse"] @@ -77,14 +77,14 @@ def __neg__(self: object) -> InfinityType: NegativeInfinity = NegativeInfinityType() -LocalType = tuple[Union[int, str], ...] +LocalType: TypeAlias = tuple[int | str, ...] -CmpPrePostDevType = Union[InfinityType, NegativeInfinityType, tuple[str, int]] -CmpLocalType = Union[ - NegativeInfinityType, - tuple[Union[tuple[int, str], tuple[NegativeInfinityType, Union[int, str]]], ...], -] -CmpKey = tuple[ +CmpPrePostDevType: TypeAlias = InfinityType | NegativeInfinityType | tuple[str, int] +CmpLocalType: TypeAlias = ( + NegativeInfinityType + | tuple[tuple[int, str] | tuple[NegativeInfinityType, int | str], ...] +) +CmpKey: TypeAlias = tuple[ int, tuple[int, ...], CmpPrePostDevType, @@ -92,7 +92,7 @@ def __neg__(self: object) -> InfinityType: CmpPrePostDevType, CmpLocalType, ] -VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool] +VersionComparisonMethod: TypeAlias = Callable[[CmpKey, CmpKey], bool] class _Version(NamedTuple): From a3eb0b755222c7e9ddc7e1c0700d2eb4c1c01cef Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Tue, 27 May 2025 09:47:40 -0400 Subject: [PATCH 2/3] fix usage of Term in tests --- pandas/tests/io/pytables/test_errors.py | 4 ++-- pandas/tests/io/pytables/test_file_handling.py | 2 +- pandas/tests/io/pytables/test_select.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/tests/io/pytables/test_errors.py b/pandas/tests/io/pytables/test_errors.py index b28101c09820f..0173135d0829b 100644 --- a/pandas/tests/io/pytables/test_errors.py +++ b/pandas/tests/io/pytables/test_errors.py @@ -18,8 +18,8 @@ from pandas.tests.io.pytables.common import ensure_clean_store from pandas.io.pytables import ( - Term, _maybe_adjust_name, + _Term as Term, ) pytestmark = [pytest.mark.single_cpu] @@ -45,7 +45,7 @@ def test_pass_spec_to_storer(setup_path): "format store. this store must be selected in its entirety" ) with pytest.raises(TypeError, match=msg): - store.select("df", where=[("columns=A")]) + store.select("df", where=["columns=A"]) def test_table_index_incompatible_dtypes(setup_path): diff --git a/pandas/tests/io/pytables/test_file_handling.py b/pandas/tests/io/pytables/test_file_handling.py index 27b5d34146f85..8081e93b77e85 100644 --- a/pandas/tests/io/pytables/test_file_handling.py +++ b/pandas/tests/io/pytables/test_file_handling.py @@ -31,7 +31,7 @@ ) from pandas.io import pytables -from pandas.io.pytables import Term +from pandas.io.pytables import _Term as Term pytestmark = [pytest.mark.single_cpu] diff --git a/pandas/tests/io/pytables/test_select.py b/pandas/tests/io/pytables/test_select.py index 5e76aae28c147..b42f814135724 100644 --- a/pandas/tests/io/pytables/test_select.py +++ b/pandas/tests/io/pytables/test_select.py @@ -23,7 +23,7 @@ ensure_clean_store, ) -from pandas.io.pytables import Term +from pandas.io.pytables import _Term as Term pytestmark = [pytest.mark.single_cpu] @@ -143,7 +143,7 @@ def test_select(setup_path): tm.assert_frame_equal(expected, result) # equivalently - result = store.select("df", [("columns=['A', 'B']")]) + result = store.select("df", ["columns=['A', 'B']"]) expected = df.reindex(columns=["A", "B"]) tm.assert_frame_equal(expected, result) From caea86384eb3cf538426c24e364b792681cc855d Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Sat, 7 Jun 2025 15:48:58 -0400 Subject: [PATCH 3/3] remove changes that created aliases with leading underscore --- pandas/core/apply.py | 14 ++--- pandas/core/arrays/datetimelike.py | 15 +++--- pandas/core/arrays/interval.py | 34 ++++++------ pandas/core/groupby/generic.py | 4 +- pandas/core/tools/datetimes.py | 54 +++++++++---------- pandas/io/formats/printing.py | 6 +-- pandas/io/pytables.py | 6 +-- pandas/tests/io/pytables/test_errors.py | 2 +- .../tests/io/pytables/test_file_handling.py | 2 +- pandas/tests/io/pytables/test_select.py | 2 +- 10 files changed, 68 insertions(+), 71 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index e9a431c1759a7..e228d20b359c6 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -72,7 +72,7 @@ from pandas.core.resample import Resampler from pandas.core.window.rolling import BaseWindow -_ResType: TypeAlias = dict[int, Any] +ResType: TypeAlias = dict[int, Any] class BaseExecutionEngine(abc.ABC): @@ -935,7 +935,7 @@ def validate_values_for_numba(self) -> None: @abc.abstractmethod def wrap_results_for_axis( - self, results: _ResType, res_index: Index + self, results: ResType, res_index: Index ) -> DataFrame | Series: pass @@ -1164,7 +1164,7 @@ def apply_standard(self): # wrap results return self.wrap_results(results, res_index) - def apply_series_generator(self) -> tuple[_ResType, Index]: + def apply_series_generator(self) -> tuple[ResType, Index]: assert callable(self.func) series_gen = self.series_generator @@ -1194,7 +1194,7 @@ def apply_series_numba(self): results = self.apply_with_numba() return results, self.result_index - def wrap_results(self, results: _ResType, res_index: Index) -> DataFrame | Series: + def wrap_results(self, results: ResType, res_index: Index) -> DataFrame | Series: from pandas import Series # see if we can infer the results @@ -1290,7 +1290,7 @@ def result_columns(self) -> Index: return self.index def wrap_results_for_axis( - self, results: _ResType, res_index: Index + self, results: ResType, res_index: Index ) -> DataFrame | Series: """return the results for the rows""" @@ -1434,7 +1434,7 @@ def result_columns(self) -> Index: return self.columns def wrap_results_for_axis( - self, results: _ResType, res_index: Index + self, results: ResType, res_index: Index ) -> DataFrame | Series: """return the results for the columns""" result: DataFrame | Series @@ -1454,7 +1454,7 @@ def wrap_results_for_axis( return result - def infer_to_same_shape(self, results: _ResType, res_index: Index) -> DataFrame: + def infer_to_same_shape(self, results: ResType, res_index: Index) -> DataFrame: """infer the results to the same shape as the input object""" result = self.obj._constructor(data=results) result = result.T diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 7622286fdd053..9a723a88941b6 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -162,8 +162,7 @@ TimedeltaArray, ) -# underscore at end because of rule PYI043 that private types should not end with 'T' -_DTScalarOrNaT_: TypeAlias = DatetimeLikeScalar | NaTType +DTScalarOrNaT: TypeAlias = DatetimeLikeScalar | NaTType def _make_unpacked_invalid_op(op_name: str): @@ -238,7 +237,7 @@ def _scalar_type(self) -> type[DatetimeLikeScalar]: """ raise AbstractMethodError(self) - def _scalar_from_string(self, value: str) -> _DTScalarOrNaT_: + def _scalar_from_string(self, value: str) -> DTScalarOrNaT: """ Construct a scalar type from a string. @@ -259,7 +258,7 @@ def _scalar_from_string(self, value: str) -> _DTScalarOrNaT_: raise AbstractMethodError(self) def _unbox_scalar( - self, value: _DTScalarOrNaT_ + self, value: DTScalarOrNaT ) -> np.int64 | np.datetime64 | np.timedelta64: """ Unbox the integer value of a scalar `value`. @@ -281,7 +280,7 @@ def _unbox_scalar( """ raise AbstractMethodError(self) - def _check_compatible_with(self, other: _DTScalarOrNaT_) -> None: + def _check_compatible_with(self, other: DTScalarOrNaT) -> None: """ Verify that `self` and `other` are compatible. @@ -372,7 +371,7 @@ def __array__( return self._ndarray @overload - def __getitem__(self, key: ScalarIndexer) -> _DTScalarOrNaT_: ... + def __getitem__(self, key: ScalarIndexer) -> DTScalarOrNaT: ... @overload def __getitem__( @@ -380,7 +379,7 @@ def __getitem__( key: SequenceIndexer | PositionalIndexerTuple, ) -> Self: ... - def __getitem__(self, key: PositionalIndexer2D) -> Self | _DTScalarOrNaT_: + def __getitem__(self, key: PositionalIndexer2D) -> Self | DTScalarOrNaT: """ This getitem defers to the underlying array, which by-definition can only handle list-likes, slices, and integer scalars @@ -388,7 +387,7 @@ def __getitem__(self, key: PositionalIndexer2D) -> Self | _DTScalarOrNaT_: # Use cast as we know we will get back a DatetimeLikeArray or DTScalar, # but skip evaluating the Union at runtime for performance # (see https://github.com/pandas-dev/pandas/pull/44624) - result = cast(Union[Self, _DTScalarOrNaT_], super().__getitem__(key)) + result = cast(Union[Self, DTScalarOrNaT], super().__getitem__(key)) if lib.is_scalar(result): return result else: diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index c390dd3942ebc..4bcbe2eedee47 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -109,8 +109,8 @@ ) -_IntervalSide: TypeAlias = TimeArrayLike | np.ndarray -_IntervalOrNA: TypeAlias = Interval | float +IntervalSide: TypeAlias = TimeArrayLike | np.ndarray +IntervalOrNA: TypeAlias = Interval | float _interval_shared_docs: dict[str, str] = {} @@ -216,8 +216,8 @@ def ndim(self) -> Literal[1]: return 1 # To make mypy recognize the fields - _left: _IntervalSide - _right: _IntervalSide + _left: IntervalSide + _right: IntervalSide _dtype: IntervalDtype # --------------------------------------------------------------------- @@ -234,8 +234,8 @@ def __new__( data = extract_array(data, extract_numpy=True) if isinstance(data, cls): - left: _IntervalSide = data._left - right: _IntervalSide = data._right + left: IntervalSide = data._left + right: IntervalSide = data._right closed = closed or data.closed dtype = IntervalDtype(left.dtype, closed=closed) else: @@ -277,8 +277,8 @@ def __new__( @classmethod def _simple_new( cls, - left: _IntervalSide, - right: _IntervalSide, + left: IntervalSide, + right: IntervalSide, dtype: IntervalDtype, ) -> Self: result = IntervalMixin.__new__(cls) @@ -296,7 +296,7 @@ def _ensure_simple_new_inputs( closed: IntervalClosedType | None = None, copy: bool = False, dtype: Dtype | None = None, - ) -> tuple[_IntervalSide, _IntervalSide, IntervalDtype]: + ) -> tuple[IntervalSide, IntervalSide, IntervalDtype]: """Ensure correctness of input parameters for cls._simple_new.""" from pandas.core.indexes.base import ensure_index @@ -704,12 +704,12 @@ def __len__(self) -> int: return len(self._left) @overload - def __getitem__(self, key: ScalarIndexer) -> _IntervalOrNA: ... + def __getitem__(self, key: ScalarIndexer) -> IntervalOrNA: ... @overload def __getitem__(self, key: SequenceIndexer) -> Self: ... - def __getitem__(self, key: PositionalIndexer) -> Self | _IntervalOrNA: + def __getitem__(self, key: PositionalIndexer) -> Self | IntervalOrNA: key = check_array_indexer(self, key) left = self._left[key] right = self._right[key] @@ -858,7 +858,7 @@ def argsort( ascending=ascending, kind=kind, na_position=na_position, **kwargs ) - def min(self, *, axis: AxisInt | None = None, skipna: bool = True) -> _IntervalOrNA: + def min(self, *, axis: AxisInt | None = None, skipna: bool = True) -> IntervalOrNA: nv.validate_minmax_axis(axis, self.ndim) if not len(self): @@ -875,7 +875,7 @@ def min(self, *, axis: AxisInt | None = None, skipna: bool = True) -> _IntervalO indexer = obj.argsort()[0] return obj[indexer] - def max(self, *, axis: AxisInt | None = None, skipna: bool = True) -> _IntervalOrNA: + def max(self, *, axis: AxisInt | None = None, skipna: bool = True) -> IntervalOrNA: nv.validate_minmax_axis(axis, self.ndim) if not len(self): @@ -1016,10 +1016,8 @@ def _concat_same_type(cls, to_concat: Sequence[IntervalArray]) -> Self: raise ValueError("Intervals must all be closed on the same side.") closed = closed_set.pop() - left: _IntervalSide = np.concatenate([interval.left for interval in to_concat]) - right: _IntervalSide = np.concatenate( - [interval.right for interval in to_concat] - ) + left: IntervalSide = np.concatenate([interval.left for interval in to_concat]) + right: IntervalSide = np.concatenate([interval.right for interval in to_concat]) left, right, dtype = cls._ensure_simple_new_inputs(left, right, closed=closed) @@ -1954,7 +1952,7 @@ def isin(self, values: ArrayLike) -> npt.NDArray[np.bool_]: return isin(self.astype(object), values.astype(object)) @property - def _combined(self) -> _IntervalSide: + def _combined(self) -> IntervalSide: # error: Item "ExtensionArray" of "ExtensionArray | ndarray[Any, Any]" # has no attribute "reshape" [union-attr] left = self.left._values.reshape(-1, 1) # type: ignore[union-attr] diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index db2f2006ea3f4..b2531e2abf7f1 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -102,7 +102,7 @@ from pandas.core.generic import NDFrame # TODO(typing) the return value on this callable should be any *scalar*. -_AggScalar: TypeAlias = str | Callable[..., Any] +AggScalar: TypeAlias = str | Callable[..., Any] # TODO: validate types on ScalarResult and move to _typing # Blocked from using by https://github.com/python/mypy/issues/1484 # See note at _mangle_lambda_list @@ -141,7 +141,7 @@ class NamedAgg(NamedTuple): """ column: Hashable - aggfunc: _AggScalar + aggfunc: AggScalar @set_module("pandas.api.typing") diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index d1b3ef007d151..1b236deff330d 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -94,33 +94,33 @@ # --------------------------------------------------------------------- # types used in annotations -_ArrayConvertible: TypeAlias = list | tuple | AnyArrayLike -_Scalar: TypeAlias = float | str -_DatetimeScalar: TypeAlias = _Scalar | date | np.datetime64 +ArrayConvertible: TypeAlias = list | tuple | AnyArrayLike +Scalar: TypeAlias = float | str +DatetimeScalar: TypeAlias = Scalar | date | np.datetime64 -_DatetimeScalarOrArrayConvertible: TypeAlias = _DatetimeScalar | _ArrayConvertible -_DatetimeDictArg: TypeAlias = list[_Scalar] | tuple[_Scalar, ...] | AnyArrayLike +DatetimeScalarOrArrayConvertible: TypeAlias = DatetimeScalar | ArrayConvertible +DatetimeDictArg: TypeAlias = list[Scalar] | tuple[Scalar, ...] | AnyArrayLike -class _YearMonthDayDict(TypedDict, total=True): - year: _DatetimeDictArg - month: _DatetimeDictArg - day: _DatetimeDictArg +class YearMonthDayDict(TypedDict, total=True): + year: DatetimeDictArg + month: DatetimeDictArg + day: DatetimeDictArg -class _FulldatetimeDict(_YearMonthDayDict, total=False): - hour: _DatetimeDictArg - hours: _DatetimeDictArg - minute: _DatetimeDictArg - minutes: _DatetimeDictArg - second: _DatetimeDictArg - seconds: _DatetimeDictArg - ms: _DatetimeDictArg - us: _DatetimeDictArg - ns: _DatetimeDictArg +class FulldatetimeDict(YearMonthDayDict, total=False): + hour: DatetimeDictArg + hours: DatetimeDictArg + minute: DatetimeDictArg + minutes: DatetimeDictArg + second: DatetimeDictArg + seconds: DatetimeDictArg + ms: DatetimeDictArg + us: DatetimeDictArg + ns: DatetimeDictArg -_DictConvertible = Union[_FulldatetimeDict, "DataFrame"] +DictConvertible = Union[FulldatetimeDict, "DataFrame"] start_caching_at = 50 @@ -151,7 +151,7 @@ def _guess_datetime_format_for_array(arr, dayfirst: bool | None = False) -> str def should_cache( - arg: _ArrayConvertible, unique_share: float = 0.7, check_count: int | None = None + arg: ArrayConvertible, unique_share: float = 0.7, check_count: int | None = None ) -> bool: """ Decides whether to do caching. @@ -211,7 +211,7 @@ def should_cache( def _maybe_cache( - arg: _ArrayConvertible, + arg: ArrayConvertible, format: str | None, cache: bool, convert_listlike: Callable, @@ -290,7 +290,7 @@ def _box_as_indexlike( def _convert_and_box_cache( - arg: _DatetimeScalarOrArrayConvertible, + arg: DatetimeScalarOrArrayConvertible, cache_array: Series, name: Hashable | None = None, ) -> Index: @@ -622,7 +622,7 @@ def _adjust_to_origin(arg, origin, unit): @overload def to_datetime( - arg: _DatetimeScalar, + arg: DatetimeScalar, errors: DateTimeErrorChoices = ..., dayfirst: bool = ..., yearfirst: bool = ..., @@ -637,7 +637,7 @@ def to_datetime( @overload def to_datetime( - arg: Series | _DictConvertible, + arg: Series | DictConvertible, errors: DateTimeErrorChoices = ..., dayfirst: bool = ..., yearfirst: bool = ..., @@ -666,7 +666,7 @@ def to_datetime( def to_datetime( - arg: _DatetimeScalarOrArrayConvertible | _DictConvertible, + arg: DatetimeScalarOrArrayConvertible | DictConvertible, errors: DateTimeErrorChoices = "raise", dayfirst: bool = False, yearfirst: bool = False, @@ -676,7 +676,7 @@ def to_datetime( unit: str | None = None, origin: str = "unix", cache: bool = True, -) -> DatetimeIndex | Series | _DatetimeScalar | NaTType | None: +) -> DatetimeIndex | Series | DatetimeScalar | NaTType | None: """ Convert argument to datetime. diff --git a/pandas/io/formats/printing.py b/pandas/io/formats/printing.py index c8d06d7cf07ba..9de5ac071495b 100644 --- a/pandas/io/formats/printing.py +++ b/pandas/io/formats/printing.py @@ -27,7 +27,7 @@ if TYPE_CHECKING: from pandas._typing import ListLike -_EscapeChars: TypeAlias = Mapping[str, str] | Iterable[str] +EscapeChars: TypeAlias = Mapping[str, str] | Iterable[str] _KT = TypeVar("_KT") _VT = TypeVar("_VT") @@ -174,7 +174,7 @@ def _pprint_dict( def pprint_thing( thing: object, _nest_lvl: int = 0, - escape_chars: _EscapeChars | None = None, + escape_chars: EscapeChars | None = None, default_escapes: bool = False, quote_strings: bool = False, max_seq_items: int | None = None, @@ -203,7 +203,7 @@ def pprint_thing( """ def as_escaped_string( - thing: Any, escape_chars: _EscapeChars | None = escape_chars + thing: Any, escape_chars: EscapeChars | None = escape_chars ) -> str: translate = {"\t": r"\t", "\n": r"\n", "\r": r"\r", "'": r"\'"} if isinstance(escape_chars, Mapping): diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index e9a45f536a90d..64a05c87e0f80 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -161,7 +161,7 @@ def _ensure_str(name): return name -_Term: TypeAlias = PyTablesExpr +Term: TypeAlias = PyTablesExpr def _ensure_term(where, scope_level: int): @@ -176,12 +176,12 @@ def _ensure_term(where, scope_level: int): level = scope_level + 1 if isinstance(where, (list, tuple)): where = [ - _Term(term, scope_level=level + 1) if maybe_expression(term) else term + Term(term, scope_level=level + 1) if maybe_expression(term) else term for term in where if term is not None ] elif maybe_expression(where): - where = _Term(where, scope_level=level) + where = Term(where, scope_level=level) return where if where is None or len(where) else None diff --git a/pandas/tests/io/pytables/test_errors.py b/pandas/tests/io/pytables/test_errors.py index 0173135d0829b..23932b6092998 100644 --- a/pandas/tests/io/pytables/test_errors.py +++ b/pandas/tests/io/pytables/test_errors.py @@ -18,8 +18,8 @@ from pandas.tests.io.pytables.common import ensure_clean_store from pandas.io.pytables import ( + Term, _maybe_adjust_name, - _Term as Term, ) pytestmark = [pytest.mark.single_cpu] diff --git a/pandas/tests/io/pytables/test_file_handling.py b/pandas/tests/io/pytables/test_file_handling.py index 8081e93b77e85..27b5d34146f85 100644 --- a/pandas/tests/io/pytables/test_file_handling.py +++ b/pandas/tests/io/pytables/test_file_handling.py @@ -31,7 +31,7 @@ ) from pandas.io import pytables -from pandas.io.pytables import _Term as Term +from pandas.io.pytables import Term pytestmark = [pytest.mark.single_cpu] diff --git a/pandas/tests/io/pytables/test_select.py b/pandas/tests/io/pytables/test_select.py index b42f814135724..0dffb284fa6d2 100644 --- a/pandas/tests/io/pytables/test_select.py +++ b/pandas/tests/io/pytables/test_select.py @@ -23,7 +23,7 @@ ensure_clean_store, ) -from pandas.io.pytables import _Term as Term +from pandas.io.pytables import Term pytestmark = [pytest.mark.single_cpu]