From 5baccd46441e94fca4b40f25da70a563f642fae3 Mon Sep 17 00:00:00 2001 From: fathomer Date: Sun, 4 Apr 2021 00:59:53 +0530 Subject: [PATCH] STY: remove --keep-runtime-typing from pyupgrade #40759 Part-1 --- pandas/_testing/__init__.py | 34 ++-- pandas/_typing.py | 4 +- pandas/compat/pickle_compat.py | 7 +- pandas/core/aggregation.py | 27 ++- pandas/core/algorithms.py | 27 ++- pandas/core/apply.py | 28 ++- pandas/core/arrays/_mixins.py | 11 +- pandas/core/arrays/base.py | 33 ++-- pandas/core/arrays/boolean.py | 30 ++- pandas/core/common.py | 18 +- pandas/core/construction.py | 28 ++- pandas/core/describe.py | 21 +-- pandas/core/frame.py | 336 ++++++++++++++++----------------- pandas/core/generic.py | 208 ++++++++++---------- pandas/core/indexing.py | 35 ++-- pandas/core/missing.py | 42 ++--- pandas/core/nanops.py | 115 ++++++----- pandas/core/resample.py | 24 +-- pandas/core/series.py | 66 +++---- pandas/core/sorting.py | 27 ++- 20 files changed, 516 insertions(+), 605 deletions(-) diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py index 9bacb30b78a64..63c9ebb1dd98d 100644 --- a/pandas/_testing/__init__.py +++ b/pandas/_testing/__init__.py @@ -14,8 +14,6 @@ ContextManager, Counter, Iterable, - List, - Type, ) import warnings @@ -116,24 +114,24 @@ _N = 30 _K = 4 -UNSIGNED_INT_DTYPES: List[Dtype] = ["uint8", "uint16", "uint32", "uint64"] -UNSIGNED_EA_INT_DTYPES: List[Dtype] = ["UInt8", "UInt16", "UInt32", "UInt64"] -SIGNED_INT_DTYPES: List[Dtype] = [int, "int8", "int16", "int32", "int64"] -SIGNED_EA_INT_DTYPES: List[Dtype] = ["Int8", "Int16", "Int32", "Int64"] +UNSIGNED_INT_DTYPES: list[Dtype] = ["uint8", "uint16", "uint32", "uint64"] +UNSIGNED_EA_INT_DTYPES: list[Dtype] = ["UInt8", "UInt16", "UInt32", "UInt64"] +SIGNED_INT_DTYPES: list[Dtype] = [int, "int8", "int16", "int32", "int64"] +SIGNED_EA_INT_DTYPES: list[Dtype] = ["Int8", "Int16", "Int32", "Int64"] ALL_INT_DTYPES = UNSIGNED_INT_DTYPES + SIGNED_INT_DTYPES ALL_EA_INT_DTYPES = UNSIGNED_EA_INT_DTYPES + SIGNED_EA_INT_DTYPES -FLOAT_DTYPES: List[Dtype] = [float, "float32", "float64"] -FLOAT_EA_DTYPES: List[Dtype] = ["Float32", "Float64"] -COMPLEX_DTYPES: List[Dtype] = [complex, "complex64", "complex128"] -STRING_DTYPES: List[Dtype] = [str, "str", "U"] +FLOAT_DTYPES: list[Dtype] = [float, "float32", "float64"] +FLOAT_EA_DTYPES: list[Dtype] = ["Float32", "Float64"] +COMPLEX_DTYPES: list[Dtype] = [complex, "complex64", "complex128"] +STRING_DTYPES: list[Dtype] = [str, "str", "U"] -DATETIME64_DTYPES: List[Dtype] = ["datetime64[ns]", "M8[ns]"] -TIMEDELTA64_DTYPES: List[Dtype] = ["timedelta64[ns]", "m8[ns]"] +DATETIME64_DTYPES: list[Dtype] = ["datetime64[ns]", "M8[ns]"] +TIMEDELTA64_DTYPES: list[Dtype] = ["timedelta64[ns]", "m8[ns]"] -BOOL_DTYPES: List[Dtype] = [bool, "bool"] -BYTES_DTYPES: List[Dtype] = [bytes, "bytes"] -OBJECT_DTYPES: List[Dtype] = [object, "object"] +BOOL_DTYPES: list[Dtype] = [bool, "bool"] +BYTES_DTYPES: list[Dtype] = [bytes, "bytes"] +OBJECT_DTYPES: list[Dtype] = [object, "object"] ALL_REAL_DTYPES = FLOAT_DTYPES + ALL_INT_DTYPES ALL_NUMPY_DTYPES = ( @@ -428,7 +426,7 @@ def all_timeseries_index_generator(k: int = 10) -> Iterable[Index]: ---------- k: length of each of the index instances """ - make_index_funcs: List[Callable[..., Index]] = [ + make_index_funcs: list[Callable[..., Index]] = [ makeDateIndex, makePeriodIndex, makeTimedeltaIndex, @@ -876,7 +874,7 @@ def skipna_wrapper(x): return skipna_wrapper -def convert_rows_list_to_csv_str(rows_list: List[str]): +def convert_rows_list_to_csv_str(rows_list: list[str]): """ Convert list of CSV rows to single CSV-formatted string for current OS. @@ -896,7 +894,7 @@ def convert_rows_list_to_csv_str(rows_list: List[str]): return sep.join(rows_list) + sep -def external_error_raised(expected_exception: Type[Exception]) -> ContextManager: +def external_error_raised(expected_exception: type[Exception]) -> ContextManager: """ Helper function to mark pytest.raises that have an external error message. diff --git a/pandas/_typing.py b/pandas/_typing.py index f90ef33434773..7c74fc54b8d67 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -25,7 +25,7 @@ Optional, Sequence, Tuple, - Type, + Type as type_t, TypeVar, Union, ) @@ -119,7 +119,7 @@ # dtypes NpDtype = Union[str, np.dtype] Dtype = Union[ - "ExtensionDtype", NpDtype, Type[Union[str, float, int, complex, bool, object]] + "ExtensionDtype", NpDtype, type_t[Union[str, float, int, complex, bool, object]] ] # DtypeArg specifies all allowable dtypes in a functions its dtype argument DtypeArg = Union[Dtype, Dict[Hashable, Dtype]] diff --git a/pandas/compat/pickle_compat.py b/pandas/compat/pickle_compat.py index 25ebd3d3ddc62..008a90d64663e 100644 --- a/pandas/compat/pickle_compat.py +++ b/pandas/compat/pickle_compat.py @@ -7,10 +7,7 @@ import copy import io import pickle as pkl -from typing import ( - TYPE_CHECKING, - Optional, -) +from typing import TYPE_CHECKING import warnings from pandas._libs.tslibs import BaseOffset @@ -235,7 +232,7 @@ def load_newobj_ex(self): pass -def load(fh, encoding: Optional[str] = None, is_verbose: bool = False): +def load(fh, encoding: str | None = None, is_verbose: bool = False): """ Load a pickle, with a provided encoding, diff --git a/pandas/core/aggregation.py b/pandas/core/aggregation.py index 7a1a5f5b30590..b1e7e3c1fda1f 100644 --- a/pandas/core/aggregation.py +++ b/pandas/core/aggregation.py @@ -12,14 +12,9 @@ Any, Callable, DefaultDict, - Dict, Hashable, Iterable, - List, - Optional, Sequence, - Tuple, - Union, ) from pandas._typing import ( @@ -42,8 +37,8 @@ def reconstruct_func( - func: Optional[AggFuncType], **kwargs -) -> Tuple[bool, Optional[AggFuncType], Optional[List[str]], Optional[List[int]]]: + func: AggFuncType | None, **kwargs +) -> tuple[bool, AggFuncType | None, list[str] | None, list[int] | None]: """ This is the internal function to reconstruct func given if there is relabeling or not and also normalize the keyword to get new order of columns. @@ -81,8 +76,8 @@ def reconstruct_func( (False, 'min', None, None) """ relabeling = func is None and is_multi_agg_with_relabel(**kwargs) - columns: Optional[List[str]] = None - order: Optional[List[int]] = None + columns: list[str] | None = None + order: list[int] | None = None if not relabeling: if isinstance(func, list) and len(func) > len(set(func)): @@ -129,7 +124,7 @@ def is_multi_agg_with_relabel(**kwargs) -> bool: ) -def normalize_keyword_aggregation(kwargs: dict) -> Tuple[dict, List[str], List[int]]: +def normalize_keyword_aggregation(kwargs: dict) -> tuple[dict, list[str], list[int]]: """ Normalize user-provided "named aggregation" kwargs. Transforms from the new ``Mapping[str, NamedAgg]`` style kwargs @@ -187,8 +182,8 @@ def normalize_keyword_aggregation(kwargs: dict) -> Tuple[dict, List[str], List[i def _make_unique_kwarg_list( - seq: Sequence[Tuple[Any, Any]] -) -> Sequence[Tuple[Any, Any]]: + seq: Sequence[tuple[Any, Any]] +) -> Sequence[tuple[Any, Any]]: """ Uniquify aggfunc name of the pairs in the order list @@ -292,10 +287,10 @@ def maybe_mangle_lambdas(agg_spec: Any) -> Any: def relabel_result( result: FrameOrSeries, - func: Dict[str, List[Union[Callable, str]]], + func: dict[str, list[Callable | str]], columns: Iterable[Hashable], order: Iterable[int], -) -> Dict[Hashable, Series]: +) -> dict[Hashable, Series]: """ Internal function to reorder result if relabelling is True for dataframe.agg, and return the reordered result in dict. @@ -322,7 +317,7 @@ def relabel_result( reordered_indexes = [ pair[0] for pair in sorted(zip(columns, order), key=lambda t: t[1]) ] - reordered_result_in_dict: Dict[Hashable, Series] = {} + reordered_result_in_dict: dict[Hashable, Series] = {} idx = 0 reorder_mask = not isinstance(result, ABCSeries) and len(result.columns) > 1 @@ -366,7 +361,7 @@ def relabel_result( def validate_func_kwargs( kwargs: dict, -) -> Tuple[List[str], List[Union[str, Callable[..., Any]]]]: +) -> tuple[list[str], list[str | Callable[..., Any]]]: """ Validates types of user-provided "named aggregation" kwargs. `TypeError` is raised if aggfunc is not `str` or callable. diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 0c8a5bbc33c91..f4d0d43ccd123 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -8,9 +8,6 @@ from textwrap import dedent from typing import ( TYPE_CHECKING, - Dict, - Optional, - Tuple, Union, cast, ) @@ -103,13 +100,13 @@ TimedeltaArray, ) -_shared_docs: Dict[str, str] = {} +_shared_docs: dict[str, str] = {} # --------------- # # dtype access # # --------------- # -def _ensure_data(values: ArrayLike) -> Tuple[np.ndarray, DtypeObj]: +def _ensure_data(values: ArrayLike) -> tuple[np.ndarray, DtypeObj]: """ routine to ensure that our data is of the correct input dtype for lower-level routines @@ -542,10 +539,10 @@ def f(c, v): def factorize_array( values: np.ndarray, na_sentinel: int = -1, - size_hint: Optional[int] = None, + size_hint: int | None = None, na_value=None, - mask: Optional[np.ndarray] = None, -) -> Tuple[np.ndarray, np.ndarray]: + mask: np.ndarray | None = None, +) -> tuple[np.ndarray, np.ndarray]: """ Factorize an array-like to codes and uniques. @@ -608,9 +605,9 @@ def factorize_array( def factorize( values, sort: bool = False, - na_sentinel: Optional[int] = -1, - size_hint: Optional[int] = None, -) -> Tuple[np.ndarray, Union[np.ndarray, Index]]: + na_sentinel: int | None = -1, + size_hint: int | None = None, +) -> tuple[np.ndarray, np.ndarray | Index]: """ Encode the object as an enumerated type or categorical variable. @@ -926,7 +923,7 @@ def value_counts_arraylike(values, dropna: bool): return keys, counts -def duplicated(values: ArrayLike, keep: Union[str, bool] = "first") -> np.ndarray: +def duplicated(values: ArrayLike, keep: str | bool = "first") -> np.ndarray: """ Return boolean ndarray denoting duplicate values. @@ -1062,8 +1059,8 @@ def rank( def checked_add_with_arr( arr: np.ndarray, b, - arr_mask: Optional[np.ndarray] = None, - b_mask: Optional[np.ndarray] = None, + arr_mask: np.ndarray | None = None, + b_mask: np.ndarray | None = None, ) -> np.ndarray: """ Perform array addition that checks for underflow and overflow. @@ -1741,7 +1738,7 @@ def safe_sort( na_sentinel: int = -1, assume_unique: bool = False, verify: bool = True, -) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: +) -> np.ndarray | tuple[np.ndarray, np.ndarray]: """ Sort ``values`` and reorder corresponding ``codes``. diff --git a/pandas/core/apply.py b/pandas/core/apply.py index ee92630403ed3..305b4eafd0cec 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -9,10 +9,6 @@ Hashable, Iterator, List, - Optional, - Tuple, - Type, - Union, cast, ) import warnings @@ -77,13 +73,13 @@ def frame_apply( func: AggFuncType, axis: Axis = 0, raw: bool = False, - result_type: Optional[str] = None, + result_type: str | None = None, args=None, kwargs=None, ) -> FrameApply: """ construct and return a row or column based frame apply object """ axis = obj._get_axis_number(axis) - klass: Type[FrameApply] + klass: type[FrameApply] if axis == 0: klass = FrameRowApply elif axis == 1: @@ -107,7 +103,7 @@ def __init__( obj: AggObjType, func, raw: bool, - result_type: Optional[str], + result_type: str | None, args, kwargs, ): @@ -152,7 +148,7 @@ def agg_axis(self) -> Index: def apply(self) -> FrameOrSeriesUnion: pass - def agg(self) -> Optional[FrameOrSeriesUnion]: + def agg(self) -> FrameOrSeriesUnion | None: """ Provide an implementation for the aggregators. @@ -265,7 +261,7 @@ def transform_dict_like(self, func): func = self.normalize_dictlike_arg("transform", obj, func) - results: Dict[Hashable, FrameOrSeriesUnion] = {} + results: dict[Hashable, FrameOrSeriesUnion] = {} failed_names = [] all_type_errors = True for name, how in func.items(): @@ -459,7 +455,7 @@ def agg_dict_like(self) -> FrameOrSeriesUnion: return result - def maybe_apply_str(self) -> Optional[FrameOrSeriesUnion]: + def maybe_apply_str(self) -> FrameOrSeriesUnion | None: """ Compute apply in case of a string. @@ -492,7 +488,7 @@ def maybe_apply_str(self) -> Optional[FrameOrSeriesUnion]: raise ValueError(f"Operation {f} does not support axis=1") return obj._try_aggregate_string_function(f, *self.args, **self.kwargs) - def maybe_apply_multiple(self) -> Optional[FrameOrSeriesUnion]: + def maybe_apply_multiple(self) -> FrameOrSeriesUnion | None: """ Compute apply in case of a list-like or dict-like. @@ -754,7 +750,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.f) series_gen = self.series_generator @@ -1039,11 +1035,11 @@ def apply_standard(self) -> FrameOrSeriesUnion: class GroupByApply(Apply): - obj: Union[SeriesGroupBy, DataFrameGroupBy] + obj: SeriesGroupBy | DataFrameGroupBy def __init__( self, - obj: Union[SeriesGroupBy, DataFrameGroupBy], + obj: SeriesGroupBy | DataFrameGroupBy, func: AggFuncType, args, kwargs, @@ -1068,11 +1064,11 @@ def transform(self): class ResamplerWindowApply(Apply): axis = 0 - obj: Union[Resampler, BaseWindow] + obj: Resampler | BaseWindow def __init__( self, - obj: Union[Resampler, BaseWindow], + obj: Resampler | BaseWindow, func: AggFuncType, args, kwargs, diff --git a/pandas/core/arrays/_mixins.py b/pandas/core/arrays/_mixins.py index 08061eb1ec28c..0b208d4f2ab72 100644 --- a/pandas/core/arrays/_mixins.py +++ b/pandas/core/arrays/_mixins.py @@ -3,11 +3,8 @@ from functools import wraps from typing import ( Any, - Optional, Sequence, - Type, TypeVar, - Union, cast, ) @@ -233,7 +230,7 @@ def unique(self: NDArrayBackedExtensionArrayT) -> NDArrayBackedExtensionArrayT: @classmethod @doc(ExtensionArray._concat_same_type) def _concat_same_type( - cls: Type[NDArrayBackedExtensionArrayT], + cls: type[NDArrayBackedExtensionArrayT], to_concat: Sequence[NDArrayBackedExtensionArrayT], axis: int = 0, ) -> NDArrayBackedExtensionArrayT: @@ -277,8 +274,8 @@ def _validate_setitem_value(self, value): return value def __getitem__( - self: NDArrayBackedExtensionArrayT, key: Union[int, slice, np.ndarray] - ) -> Union[NDArrayBackedExtensionArrayT, Any]: + self: NDArrayBackedExtensionArrayT, key: int | slice | np.ndarray + ) -> NDArrayBackedExtensionArrayT | Any: if lib.is_integer(key): # fast-path result = self._ndarray[key] @@ -349,7 +346,7 @@ def _reduce(self, name: str, *, skipna: bool = True, **kwargs): msg = f"'{type(self).__name__}' does not implement reduction '{name}'" raise TypeError(msg) - def _wrap_reduction_result(self, axis: Optional[int], result): + def _wrap_reduction_result(self, axis: int | None, result): if axis is None or self.ndim == 1: return self._box_func(result) return self._from_backing_data(result) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index c45528d657404..ac3ae6407305c 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -13,13 +13,8 @@ TYPE_CHECKING, Any, Callable, - Dict, - Optional, Sequence, - Tuple, - Type, TypeVar, - Union, cast, ) @@ -82,7 +77,7 @@ def all(self, *, skipna: bool = True) -> bool: pass -_extension_array_shared_docs: Dict[str, str] = {} +_extension_array_shared_docs: dict[str, str] = {} ExtensionArrayT = TypeVar("ExtensionArrayT", bound="ExtensionArray") @@ -223,7 +218,7 @@ class ExtensionArray: # ------------------------------------------------------------------------ @classmethod - def _from_sequence(cls, scalars, *, dtype: Optional[Dtype] = None, copy=False): + def _from_sequence(cls, scalars, *, dtype: Dtype | None = None, copy=False): """ Construct a new ExtensionArray from a sequence of scalars. @@ -246,7 +241,7 @@ def _from_sequence(cls, scalars, *, dtype: Optional[Dtype] = None, copy=False): @classmethod def _from_sequence_of_strings( - cls, strings, *, dtype: Optional[Dtype] = None, copy=False + cls, strings, *, dtype: Dtype | None = None, copy=False ): """ Construct a new ExtensionArray from a sequence of strings. @@ -293,9 +288,7 @@ def _from_factorized(cls, values, original): # Must be a Sequence # ------------------------------------------------------------------------ - def __getitem__( - self, item: Union[int, slice, np.ndarray] - ) -> Union[ExtensionArray, Any]: + def __getitem__(self, item: int | slice | np.ndarray) -> ExtensionArray | Any: """ Select a subset of self. @@ -326,7 +319,7 @@ def __getitem__( """ raise AbstractMethodError(self) - def __setitem__(self, key: Union[int, slice, np.ndarray], value: Any) -> None: + def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None: """ Set one or more values inplace. @@ -391,7 +384,7 @@ def __iter__(self): for i in range(len(self)): yield self[i] - def __contains__(self, item) -> Union[bool, np.bool_]: + def __contains__(self, item) -> bool | np.bool_: """ Return for `item in self`. """ @@ -430,7 +423,7 @@ def __ne__(self, other: Any) -> ArrayLike: # type: ignore[override] def to_numpy( self, - dtype: Optional[Dtype] = None, + dtype: Dtype | None = None, copy: bool = False, na_value=lib.no_default, ) -> np.ndarray: @@ -553,7 +546,7 @@ def astype(self, dtype, copy=True): return np.array(self, dtype=dtype, copy=copy) - def isna(self) -> Union[np.ndarray, ExtensionArraySupportsAnyAll]: + def isna(self) -> np.ndarray | ExtensionArraySupportsAnyAll: """ A 1-D array indicating if each value is missing. @@ -909,7 +902,7 @@ def isin(self, values) -> np.ndarray: """ return isin(np.asarray(self), values) - def _values_for_factorize(self) -> Tuple[np.ndarray, Any]: + def _values_for_factorize(self) -> tuple[np.ndarray, Any]: """ Return an array and missing value suitable for factorization. @@ -933,7 +926,7 @@ def _values_for_factorize(self) -> Tuple[np.ndarray, Any]: """ return self.astype(object), np.nan - def factorize(self, na_sentinel: int = -1) -> Tuple[np.ndarray, ExtensionArray]: + def factorize(self, na_sentinel: int = -1) -> tuple[np.ndarray, ExtensionArray]: """ Encode the extension array as an enumerated type. @@ -1143,7 +1136,7 @@ def copy(self: ExtensionArrayT) -> ExtensionArrayT: """ raise AbstractMethodError(self) - def view(self, dtype: Optional[Dtype] = None) -> ArrayLike: + def view(self, dtype: Dtype | None = None) -> ArrayLike: """ Return a view on the array. @@ -1181,7 +1174,7 @@ def __repr__(self) -> str: class_name = f"<{type(self).__name__}>\n" return f"{class_name}{data}\nLength: {len(self)}, dtype: {self.dtype}" - def _formatter(self, boxed: bool = False) -> Callable[[Any], Optional[str]]: + def _formatter(self, boxed: bool = False) -> Callable[[Any], str | None]: """ Formatting function for scalar values. @@ -1247,7 +1240,7 @@ def ravel(self, order="C") -> ExtensionArray: @classmethod def _concat_same_type( - cls: Type[ExtensionArrayT], to_concat: Sequence[ExtensionArrayT] + cls: type[ExtensionArrayT], to_concat: Sequence[ExtensionArrayT] ) -> ExtensionArrayT: """ Concatenate multiple array of this dtype. diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 5455b0b92a179..0a0bfccc0ea15 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -1,14 +1,7 @@ from __future__ import annotations import numbers -from typing import ( - TYPE_CHECKING, - List, - Optional, - Tuple, - Type, - Union, -) +from typing import TYPE_CHECKING import warnings import numpy as np @@ -20,6 +13,7 @@ from pandas._typing import ( ArrayLike, Dtype, + type_t, ) from pandas.compat.numpy import function as nv @@ -79,7 +73,7 @@ class BooleanDtype(BaseMaskedDtype): # https://github.com/python/mypy/issues/4125 # error: Signature of "type" incompatible with supertype "BaseMaskedDtype" @property - def type(self) -> Type: # type: ignore[override] + def type(self) -> type: # type: ignore[override] return np.bool_ @property @@ -91,7 +85,7 @@ def numpy_dtype(self) -> np.dtype: return np.dtype("bool") @classmethod - def construct_array_type(cls) -> Type[BooleanArray]: + def construct_array_type(cls) -> type_t[BooleanArray]: """ Return the array type associated with this dtype. @@ -113,7 +107,7 @@ def _is_numeric(self) -> bool: return True def __from_arrow__( - self, array: Union[pyarrow.Array, pyarrow.ChunkedArray] + self, array: pyarrow.Array | pyarrow.ChunkedArray ) -> BooleanArray: """ Construct BooleanArray from pyarrow Array/ChunkedArray. @@ -137,7 +131,7 @@ def __from_arrow__( def coerce_to_array( values, mask=None, copy: bool = False -) -> Tuple[np.ndarray, np.ndarray]: +) -> tuple[np.ndarray, np.ndarray]: """ Coerce the input values array to numpy arrays with a mask. @@ -296,7 +290,7 @@ def dtype(self) -> BooleanDtype: @classmethod def _from_sequence( - cls, scalars, *, dtype: Optional[Dtype] = None, copy: bool = False + cls, scalars, *, dtype: Dtype | None = None, copy: bool = False ) -> BooleanArray: if dtype: assert dtype == "boolean" @@ -306,12 +300,12 @@ def _from_sequence( @classmethod def _from_sequence_of_strings( cls, - strings: List[str], + strings: list[str], *, - dtype: Optional[Dtype] = None, + dtype: Dtype | None = None, copy: bool = False, - true_values: Optional[List[str]] = None, - false_values: Optional[List[str]] = None, + true_values: list[str] | None = None, + false_values: list[str] | None = None, ) -> BooleanArray: true_values_union = cls._TRUE_VALUES.union(true_values or []) false_values_union = cls._FALSE_VALUES.union(false_values or []) @@ -376,7 +370,7 @@ def reconstruct(x): else: return reconstruct(result) - def _coerce_to_array(self, value) -> Tuple[np.ndarray, np.ndarray]: + def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]: return coerce_to_array(value) def astype(self, dtype, copy: bool = True) -> ArrayLike: diff --git a/pandas/core/common.py b/pandas/core/common.py index 98606f5d3d240..e0c00fc419bf1 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -19,10 +19,6 @@ Collection, Iterable, Iterator, - List, - Optional, - Tuple, - Union, cast, ) import warnings @@ -223,7 +219,7 @@ def count_not_none(*args) -> int: return sum(x is not None for x in args) -def asarray_tuplesafe(values, dtype: Optional[NpDtype] = None) -> np.ndarray: +def asarray_tuplesafe(values, dtype: NpDtype | None = None) -> np.ndarray: if not (isinstance(values, (list, tuple)) or hasattr(values, "__array__")): values = list(values) @@ -253,7 +249,7 @@ def asarray_tuplesafe(values, dtype: Optional[NpDtype] = None) -> np.ndarray: return result -def index_labels_to_array(labels, dtype: Optional[NpDtype] = None) -> np.ndarray: +def index_labels_to_array(labels, dtype: NpDtype | None = None) -> np.ndarray: """ Transform label or iterable of labels to array, for use in Index. @@ -286,7 +282,7 @@ def maybe_make_list(obj): return obj -def maybe_iterable_to_list(obj: Union[Iterable[T], T]) -> Union[Collection[T], T]: +def maybe_iterable_to_list(obj: Iterable[T] | T) -> Collection[T] | T: """ If obj is Iterable but not list-like, consume into list. """ @@ -308,7 +304,7 @@ def is_null_slice(obj) -> bool: ) -def is_true_slices(line) -> List[bool]: +def is_true_slices(line) -> list[bool]: """ Find non-trivial slices in "line": return a list of booleans with same length. """ @@ -437,7 +433,7 @@ def random_state(state=None): def pipe( - obj, func: Union[Callable[..., T], Tuple[Callable[..., T], str]], *args, **kwargs + obj, func: Callable[..., T] | tuple[Callable[..., T], str], *args, **kwargs ) -> T: """ Apply a function ``func`` to object ``obj`` either by passing obj as the @@ -493,8 +489,8 @@ def f(x): def convert_to_list_like( - values: Union[Scalar, Iterable, AnyArrayLike] -) -> Union[List, AnyArrayLike]: + values: Scalar | Iterable | AnyArrayLike, +) -> list | AnyArrayLike: """ Convert list-like or scalar input to list-like. List, numpy and pandas array-like inputs are returned unmodified whereas others are converted to list. diff --git a/pandas/core/construction.py b/pandas/core/construction.py index 98dfad72142f6..c20cca57afff1 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -10,9 +10,7 @@ from typing import ( TYPE_CHECKING, Any, - Optional, Sequence, - Union, cast, ) @@ -75,8 +73,8 @@ def array( - data: Union[Sequence[object], AnyArrayLike], - dtype: Optional[Dtype] = None, + data: Sequence[object] | AnyArrayLike, + dtype: Dtype | None = None, copy: bool = True, ) -> ExtensionArray: """ @@ -369,7 +367,7 @@ def array( return PandasArray._from_sequence(data, dtype=dtype, copy=copy) -def extract_array(obj: object, extract_numpy: bool = False) -> Union[Any, ArrayLike]: +def extract_array(obj: object, extract_numpy: bool = False) -> Any | ArrayLike: """ Extract the ndarray or ExtensionArray from a Series or Index. @@ -454,8 +452,8 @@ def sanitize_masked_array(data: ma.MaskedArray) -> np.ndarray: def sanitize_array( data, - index: Optional[Index], - dtype: Optional[DtypeObj] = None, + index: Index | None, + dtype: DtypeObj | None = None, copy: bool = False, raise_cast_failure: bool = True, ) -> ArrayLike: @@ -565,7 +563,7 @@ def sanitize_array( def _sanitize_ndim( - result: ArrayLike, data, dtype: Optional[DtypeObj], index: Optional[Index] + result: ArrayLike, data, dtype: DtypeObj | None, index: Index | None ) -> ArrayLike: """ Ensure we have a 1-dimensional result array. @@ -597,7 +595,7 @@ def _sanitize_ndim( def _sanitize_str_dtypes( - result: np.ndarray, data, dtype: Optional[np.dtype], copy: bool + result: np.ndarray, data, dtype: np.dtype | None, copy: bool ) -> np.ndarray: """ Ensure we have a dtype that is supported by pandas. @@ -616,7 +614,7 @@ def _sanitize_str_dtypes( return result -def _maybe_repeat(arr: ArrayLike, index: Optional[Index]) -> ArrayLike: +def _maybe_repeat(arr: ArrayLike, index: Index | None) -> ArrayLike: """ If we have a length-1 array and an index describing how long we expect the result to be, repeat the array. @@ -628,8 +626,8 @@ def _maybe_repeat(arr: ArrayLike, index: Optional[Index]) -> ArrayLike: def _try_cast( - arr: Union[list, np.ndarray], - dtype: Optional[DtypeObj], + arr: list | np.ndarray, + dtype: DtypeObj | None, copy: bool, raise_cast_failure: bool, ) -> ArrayLike: @@ -727,9 +725,9 @@ def is_empty_data(data: Any) -> bool: def create_series_with_explicit_dtype( data: Any = None, - index: Optional[Union[ArrayLike, Index]] = None, - dtype: Optional[Dtype] = None, - name: Optional[str] = None, + index: ArrayLike | Index | None = None, + dtype: Dtype | None = None, + name: str | None = None, copy: bool = False, fastpath: bool = False, dtype_if_empty: Dtype = object, diff --git a/pandas/core/describe.py b/pandas/core/describe.py index 57a33e7f90e51..dfb18b2c40698 100644 --- a/pandas/core/describe.py +++ b/pandas/core/describe.py @@ -12,10 +12,7 @@ from typing import ( TYPE_CHECKING, Callable, - List, - Optional, Sequence, - Union, cast, ) import warnings @@ -51,10 +48,10 @@ def describe_ndframe( *, obj: FrameOrSeries, - include: Optional[Union[str, Sequence[str]]], - exclude: Optional[Union[str, Sequence[str]]], + include: str | Sequence[str] | None, + exclude: str | Sequence[str] | None, datetime_is_numeric: bool, - percentiles: Optional[Sequence[float]], + percentiles: Sequence[float] | None, ) -> FrameOrSeries: """Describe series or dataframe. @@ -157,8 +154,8 @@ def __init__( self, obj: DataFrame, *, - include: Optional[Union[str, Sequence[str]]], - exclude: Optional[Union[str, Sequence[str]]], + include: str | Sequence[str] | None, + exclude: str | Sequence[str] | None, datetime_is_numeric: bool, ): self.include = include @@ -172,7 +169,7 @@ def __init__( def describe(self, percentiles: Sequence[float]) -> DataFrame: data = self._select_data() - ldesc: List[Series] = [] + ldesc: list[Series] = [] for _, series in data.items(): describe_func = select_describe_func(series, self.datetime_is_numeric) ldesc.append(describe_func(series, percentiles)) @@ -211,9 +208,9 @@ def _select_data(self): return data -def reorder_columns(ldesc: Sequence[Series]) -> List[Hashable]: +def reorder_columns(ldesc: Sequence[Series]) -> list[Hashable]: """Set a convenient order for rows for display.""" - names: List[Hashable] = [] + names: list[Hashable] = [] ldesc_indexes = sorted((x.index for x in ldesc), key=len) for idxnames in ldesc_indexes: for name in idxnames: @@ -391,7 +388,7 @@ def select_describe_func( return describe_categorical_1d -def refine_percentiles(percentiles: Optional[Sequence[float]]) -> Sequence[float]: +def refine_percentiles(percentiles: Sequence[float] | None) -> Sequence[float]: """Ensure that percentiles are unique and sorted. Parameters diff --git a/pandas/core/frame.py b/pandas/core/frame.py index d1d1993931062..5d7a994c4b1f6 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -24,18 +24,10 @@ Any, AnyStr, Callable, - Dict, - FrozenSet, Hashable, Iterable, Iterator, - List, - Optional, Sequence, - Set, - Tuple, - Type, - Union, cast, overload, ) @@ -554,14 +546,14 @@ class DataFrame(NDFrame, OpsMixin): _internal_names_set = {"columns", "index"} | NDFrame._internal_names_set _typ = "dataframe" _HANDLED_TYPES = (Series, Index, ExtensionArray, np.ndarray) - _accessors: Set[str] = {"sparse"} - _hidden_attrs: FrozenSet[str] = NDFrame._hidden_attrs | frozenset([]) + _accessors: set[str] = {"sparse"} + _hidden_attrs: frozenset[str] = NDFrame._hidden_attrs | frozenset([]) @property - def _constructor(self) -> Type[DataFrame]: + def _constructor(self) -> type[DataFrame]: return DataFrame - _constructor_sliced: Type[Series] = Series + _constructor_sliced: type[Series] = Series # ---------------------------------------------------------------------- # Constructors @@ -569,10 +561,10 @@ def _constructor(self) -> Type[DataFrame]: def __init__( self, data=None, - index: Optional[Axes] = None, - columns: Optional[Axes] = None, - dtype: Optional[Dtype] = None, - copy: Optional[bool] = None, + index: Axes | None = None, + columns: Axes | None = None, + dtype: Dtype | None = None, + copy: bool | None = None, ): if copy is None: @@ -765,7 +757,7 @@ def __init__( # ---------------------------------------------------------------------- @property - def axes(self) -> List[Index]: + def axes(self) -> list[Index]: """ Return a list representing the axes of the DataFrame. @@ -782,7 +774,7 @@ def axes(self) -> List[Index]: return [self.index, self.columns] @property - def shape(self) -> Tuple[int, int]: + def shape(self) -> tuple[int, int]: """ Return a tuple representing the dimensionality of the DataFrame. @@ -956,7 +948,7 @@ def __repr__(self) -> str: return buf.getvalue() - def _repr_html_(self) -> Optional[str]: + def _repr_html_(self) -> str | None: """ Return a html representation for a particular DataFrame. @@ -1011,26 +1003,26 @@ def _repr_html_(self) -> Optional[str]: @Substitution(shared_params=fmt.common_docstring, returns=fmt.return_docstring) def to_string( self, - buf: Optional[FilePathOrBuffer[str]] = None, - columns: Optional[Sequence[str]] = None, - col_space: Optional[int] = None, - header: Union[bool, Sequence[str]] = True, + buf: FilePathOrBuffer[str] | None = None, + columns: Sequence[str] | None = None, + col_space: int | None = None, + header: bool | Sequence[str] = True, index: bool = True, na_rep: str = "NaN", - formatters: Optional[fmt.FormattersType] = None, - float_format: Optional[fmt.FloatFormatType] = None, - sparsify: Optional[bool] = None, + formatters: fmt.FormattersType | None = None, + float_format: fmt.FloatFormatType | None = None, + sparsify: bool | None = None, index_names: bool = True, - justify: Optional[str] = None, - max_rows: Optional[int] = None, - min_rows: Optional[int] = None, - max_cols: Optional[int] = None, + justify: str | None = None, + max_rows: int | None = None, + min_rows: int | None = None, + max_cols: int | None = None, show_dimensions: bool = False, decimal: str = ".", - line_width: Optional[int] = None, - max_colwidth: Optional[int] = None, - encoding: Optional[str] = None, - ) -> Optional[str]: + line_width: int | None = None, + max_colwidth: int | None = None, + encoding: str | None = None, + ) -> str | None: """ Render a DataFrame to a console-friendly tabular output. %(shared_params)s @@ -1155,7 +1147,7 @@ def style(self) -> Styler: """ @Appender(_shared_docs["items"]) - def items(self) -> Iterable[Tuple[Hashable, Series]]: + def items(self) -> Iterable[tuple[Hashable, Series]]: if self.columns.is_unique and hasattr(self, "_item_cache"): for k in self.columns: yield k, self._get_item_cache(k) @@ -1164,10 +1156,10 @@ def items(self) -> Iterable[Tuple[Hashable, Series]]: yield k, self._ixs(i, axis=1) @Appender(_shared_docs["items"]) - def iteritems(self) -> Iterable[Tuple[Hashable, Series]]: + def iteritems(self) -> Iterable[tuple[Hashable, Series]]: yield from self.items() - def iterrows(self) -> Iterable[Tuple[Hashable, Series]]: + def iterrows(self) -> Iterable[tuple[Hashable, Series]]: """ Iterate over DataFrame rows as (index, Series) pairs. @@ -1216,8 +1208,8 @@ def iterrows(self) -> Iterable[Tuple[Hashable, Series]]: yield k, s def itertuples( - self, index: bool = True, name: Optional[str] = "Pandas" - ) -> Iterable[Tuple[Any, ...]]: + self, index: bool = True, name: str | None = "Pandas" + ) -> Iterable[tuple[Any, ...]]: """ Iterate over DataFrame rows as namedtuples. @@ -1312,10 +1304,10 @@ def dot(self, other: Series) -> Series: ... @overload - def dot(self, other: Union[DataFrame, Index, ArrayLike]) -> DataFrame: + def dot(self, other: DataFrame | Index | ArrayLike) -> DataFrame: ... - def dot(self, other: Union[AnyArrayLike, FrameOrSeriesUnion]) -> FrameOrSeriesUnion: + def dot(self, other: AnyArrayLike | FrameOrSeriesUnion) -> FrameOrSeriesUnion: """ Compute the matrix multiplication between the DataFrame and other. @@ -1431,12 +1423,12 @@ def __matmul__(self, other: Series) -> Series: @overload def __matmul__( - self, other: Union[AnyArrayLike, FrameOrSeriesUnion] + self, other: AnyArrayLike | FrameOrSeriesUnion ) -> FrameOrSeriesUnion: ... def __matmul__( - self, other: Union[AnyArrayLike, FrameOrSeriesUnion] + self, other: AnyArrayLike | FrameOrSeriesUnion ) -> FrameOrSeriesUnion: """ Matrix multiplication using binary `@` operator in Python>=3.5. @@ -1464,7 +1456,7 @@ def from_dict( cls, data, orient: str = "columns", - dtype: Optional[Dtype] = None, + dtype: Dtype | None = None, columns=None, ) -> DataFrame: """ @@ -1546,7 +1538,7 @@ def from_dict( def to_numpy( self, - dtype: Optional[NpDtype] = None, + dtype: NpDtype | None = None, copy: bool = False, na_value=lib.no_default, ) -> np.ndarray: @@ -1790,13 +1782,13 @@ def to_dict(self, orient: str = "dict", into=dict): def to_gbq( self, destination_table: str, - project_id: Optional[str] = None, - chunksize: Optional[int] = None, + project_id: str | None = None, + chunksize: int | None = None, reauth: bool = False, if_exists: str = "fail", auth_local_webserver: bool = False, - table_schema: Optional[List[Dict[str, str]]] = None, - location: Optional[str] = None, + table_schema: list[dict[str, str]] | None = None, + location: str | None = None, progress_bar: bool = True, credentials=None, ) -> None: @@ -1903,7 +1895,7 @@ def from_records( exclude=None, columns=None, coerce_float: bool = False, - nrows: Optional[int] = None, + nrows: int | None = None, ) -> DataFrame: """ Convert structured or record ndarray to DataFrame. @@ -2249,7 +2241,7 @@ def _from_arrays( arrays, columns, index, - dtype: Optional[Dtype] = None, + dtype: Dtype | None = None, verify_integrity: bool = True, ) -> DataFrame: """ @@ -2296,14 +2288,14 @@ def _from_arrays( def to_stata( self, path: FilePathOrBuffer, - convert_dates: Optional[Dict[Hashable, str]] = None, + convert_dates: dict[Hashable, str] | None = None, write_index: bool = True, - byteorder: Optional[str] = None, - time_stamp: Optional[datetime.datetime] = None, - data_label: Optional[str] = None, - variable_labels: Optional[Dict[Hashable, str]] = None, - version: Optional[int] = 114, - convert_strl: Optional[Sequence[Hashable]] = None, + byteorder: str | None = None, + time_stamp: datetime.datetime | None = None, + data_label: str | None = None, + variable_labels: dict[Hashable, str] | None = None, + version: int | None = 114, + convert_strl: Sequence[Hashable] | None = None, compression: CompressionOptions = "infer", storage_options: StorageOptions = None, ) -> None: @@ -2428,7 +2420,7 @@ def to_stata( StataWriterUTF8 as statawriter, ) - kwargs: Dict[str, Any] = {} + kwargs: dict[str, Any] = {} if version is None or version >= 117: # strl conversion is only supported >= 117 kwargs["convert_strl"] = convert_strl @@ -2501,12 +2493,12 @@ def to_feather(self, path: FilePathOrBuffer[AnyStr], **kwargs) -> None: ) def to_markdown( self, - buf: Optional[Union[IO[str], str]] = None, + buf: IO[str] | str | None = None, mode: str = "wt", index: bool = True, storage_options: StorageOptions = None, **kwargs, - ) -> Optional[str]: + ) -> str | None: if "showindex" in kwargs: warnings.warn( "'showindex' is deprecated. Only 'index' will be used " @@ -2532,14 +2524,14 @@ def to_markdown( @deprecate_kwarg(old_arg_name="fname", new_arg_name="path") def to_parquet( self, - path: Optional[FilePathOrBuffer] = None, + path: FilePathOrBuffer | None = None, engine: str = "auto", - compression: Optional[str] = "snappy", - index: Optional[bool] = None, - partition_cols: Optional[List[str]] = None, + compression: str | None = "snappy", + index: bool | None = None, + partition_cols: list[str] | None = None, storage_options: StorageOptions = None, **kwargs, - ) -> Optional[bytes]: + ) -> bytes | None: """ Write a DataFrame to the binary parquet format. @@ -2657,29 +2649,29 @@ def to_parquet( @Substitution(shared_params=fmt.common_docstring, returns=fmt.return_docstring) def to_html( self, - buf: Optional[FilePathOrBuffer[str]] = None, - columns: Optional[Sequence[str]] = None, - col_space: Optional[ColspaceArgType] = None, - header: Union[bool, Sequence[str]] = True, + buf: FilePathOrBuffer[str] | None = None, + columns: Sequence[str] | None = None, + col_space: ColspaceArgType | None = None, + header: bool | Sequence[str] = True, index: bool = True, na_rep: str = "NaN", - formatters: Optional[FormattersType] = None, - float_format: Optional[FloatFormatType] = None, - sparsify: Optional[bool] = None, + formatters: FormattersType | None = None, + float_format: FloatFormatType | None = None, + sparsify: bool | None = None, index_names: bool = True, - justify: Optional[str] = None, - max_rows: Optional[int] = None, - max_cols: Optional[int] = None, - show_dimensions: Union[bool, str] = False, + justify: str | None = None, + max_rows: int | None = None, + max_cols: int | None = None, + show_dimensions: bool | str = False, decimal: str = ".", bold_rows: bool = True, - classes: Optional[Union[str, List, Tuple]] = None, + classes: str | list | tuple | None = None, escape: bool = True, notebook: bool = False, - border: Optional[int] = None, - table_id: Optional[str] = None, + border: int | None = None, + table_id: str | None = None, render_links: bool = False, - encoding: Optional[str] = None, + encoding: str | None = None, ): """ Render a DataFrame as an HTML table. @@ -2747,23 +2739,23 @@ def to_html( @doc(storage_options=generic._shared_docs["storage_options"]) def to_xml( self, - path_or_buffer: Optional[FilePathOrBuffer] = None, + path_or_buffer: FilePathOrBuffer | None = None, index: bool = True, - root_name: Optional[str] = "data", - row_name: Optional[str] = "row", - na_rep: Optional[str] = None, - attr_cols: Optional[Union[str, List[str]]] = None, - elem_cols: Optional[Union[str, List[str]]] = None, - namespaces: Optional[Dict[Optional[str], str]] = None, - prefix: Optional[str] = None, + root_name: str | None = "data", + row_name: str | None = "row", + na_rep: str | None = None, + attr_cols: str | list[str] | None = None, + elem_cols: str | list[str] | None = None, + namespaces: dict[str | None, str] | None = None, + prefix: str | None = None, encoding: str = "utf-8", - xml_declaration: Optional[bool] = True, - pretty_print: Optional[bool] = True, - parser: Optional[str] = "lxml", - stylesheet: Optional[FilePathOrBuffer] = None, + xml_declaration: bool | None = True, + pretty_print: bool | None = True, + parser: str | None = "lxml", + stylesheet: FilePathOrBuffer | None = None, compression: CompressionOptions = "infer", storage_options: StorageOptions = None, - ) -> Optional[str]: + ) -> str | None: """ Render a DataFrame to an XML document. @@ -2910,7 +2902,7 @@ def to_xml( lxml = import_optional_dependency("lxml.etree", errors="ignore") - TreeBuilder: Union[Type[EtreeXMLFormatter], Type[LxmlXMLFormatter]] + TreeBuilder: type[EtreeXMLFormatter] | type[LxmlXMLFormatter] if parser == "lxml": if lxml is not None: @@ -3066,12 +3058,12 @@ def to_xml( @doc(BaseInfo.render) def info( self, - verbose: Optional[bool] = None, - buf: Optional[IO[str]] = None, - max_cols: Optional[int] = None, - memory_usage: Optional[Union[bool, str]] = None, - show_counts: Optional[bool] = None, - null_counts: Optional[bool] = None, + verbose: bool | None = None, + buf: IO[str] | None = None, + max_cols: int | None = None, + memory_usage: bool | str | None = None, + show_counts: bool | None = None, + null_counts: bool | None = None, ) -> None: if null_counts is not None: if show_counts is not None: @@ -4221,8 +4213,8 @@ def check_int_infer_dtype(dtypes): keep_these = np.full(self.shape[1], True) def extract_unique_dtypes_from_dtypes_set( - dtypes_set: FrozenSet[Dtype], unique_dtypes: np.ndarray - ) -> List[Dtype]: + dtypes_set: frozenset[Dtype], unique_dtypes: np.ndarray + ) -> list[Dtype]: extracted_dtypes = [ unique_dtype for unique_dtype in unique_dtypes @@ -4592,14 +4584,14 @@ def align( self, other, join: str = "outer", - axis: Optional[Axis] = None, - level: Optional[Level] = None, + axis: Axis | None = None, + level: Level | None = None, copy: bool = True, fill_value=None, - method: Optional[str] = None, + method: str | None = None, limit=None, fill_axis: Axis = 0, - broadcast_axis: Optional[Axis] = None, + broadcast_axis: Axis | None = None, ) -> DataFrame: return super().align( other, @@ -4631,7 +4623,7 @@ def set_axis(self, labels, *, inplace: Literal[True]) -> None: @overload def set_axis( self, labels, axis: Axis = ..., inplace: bool = ... - ) -> Optional[DataFrame]: + ) -> DataFrame | None: ... @Appender( @@ -4703,7 +4695,7 @@ def drop( axis: Axis = 0, index=None, columns=None, - level: Optional[Level] = None, + level: Level | None = None, inplace: bool = False, errors: str = "raise", ): @@ -4843,16 +4835,16 @@ def drop( ) def rename( self, - mapper: Optional[Renamer] = None, + mapper: Renamer | None = None, *, - index: Optional[Renamer] = None, - columns: Optional[Renamer] = None, - axis: Optional[Axis] = None, + index: Renamer | None = None, + columns: Renamer | None = None, + axis: Axis | None = None, copy: bool = True, inplace: bool = False, - level: Optional[Level] = None, + level: Level | None = None, errors: str = "ignore", - ) -> Optional[DataFrame]: + ) -> DataFrame | None: """ Alter axes labels. @@ -4975,12 +4967,12 @@ def rename( def fillna( self, value=None, - method: Optional[str] = None, - axis: Optional[Axis] = None, + method: str | None = None, + axis: Axis | None = None, inplace: bool = False, limit=None, downcast=None, - ) -> Optional[DataFrame]: + ) -> DataFrame | None: return super().fillna( value=value, method=method, @@ -5053,7 +5045,7 @@ def replace( ) def _replace_columnwise( - self, mapping: Dict[Hashable, Tuple[Any, Any]], inplace: bool, regex + self, mapping: dict[Hashable, tuple[Any, Any]], inplace: bool, regex ): """ Dispatch to Series.replace column-wise. @@ -5091,7 +5083,7 @@ def _replace_columnwise( def shift( self, periods=1, - freq: Optional[Frequency] = None, + freq: Frequency | None = None, axis: Axis = 0, fill_value=lib.no_default, ) -> DataFrame: @@ -5252,7 +5244,7 @@ def set_index( "one-dimensional arrays." ) - missing: List[Hashable] = [] + missing: list[Hashable] = [] for col in keys: if isinstance(col, (Index, Series, np.ndarray, list, abc.Iterator)): # arrays are fine as long as they are one-dimensional @@ -5280,7 +5272,7 @@ def set_index( frame = self.copy() arrays = [] - names: List[Hashable] = [] + names: list[Hashable] = [] if append: names = list(self.index.names) if isinstance(self.index, MultiIndex): @@ -5289,7 +5281,7 @@ def set_index( else: arrays.append(self.index) - to_remove: List[Hashable] = [] + to_remove: list[Hashable] = [] for col in keys: if isinstance(col, MultiIndex): for n in range(col.nlevels): @@ -5348,7 +5340,7 @@ def set_index( @overload def reset_index( self, - level: Optional[Union[Hashable, Sequence[Hashable]]] = ..., + level: Hashable | Sequence[Hashable] | None = ..., drop: bool = ..., inplace: Literal[False] = ..., col_level: Hashable = ..., @@ -5359,7 +5351,7 @@ def reset_index( @overload def reset_index( self, - level: Optional[Union[Hashable, Sequence[Hashable]]], + level: Hashable | Sequence[Hashable] | None, drop: bool, inplace: Literal[True], col_level: Hashable = ..., @@ -5382,7 +5374,7 @@ def reset_index( def reset_index( self, *, - level: Optional[Union[Hashable, Sequence[Hashable]]], + level: Hashable | Sequence[Hashable] | None, inplace: Literal[True], col_level: Hashable = ..., col_fill: Hashable = ..., @@ -5402,22 +5394,22 @@ def reset_index( @overload def reset_index( self, - level: Optional[Union[Hashable, Sequence[Hashable]]] = ..., + level: Hashable | Sequence[Hashable] | None = ..., drop: bool = ..., inplace: bool = ..., col_level: Hashable = ..., col_fill: Hashable = ..., - ) -> Optional[DataFrame]: + ) -> DataFrame | None: ... def reset_index( self, - level: Optional[Union[Hashable, Sequence[Hashable]]] = None, + level: Hashable | Sequence[Hashable] | None = None, drop: bool = False, inplace: bool = False, col_level: Hashable = 0, col_fill: Hashable = "", - ) -> Optional[DataFrame]: + ) -> DataFrame | None: """ Reset the index, or a level of it. @@ -5575,7 +5567,7 @@ class max type new_index = self.index.droplevel(level) if not drop: - to_insert: Iterable[Tuple[Any, Optional[Any]]] + to_insert: Iterable[tuple[Any, Any | None]] if isinstance(self.index, MultiIndex): names = [ (n if n is not None else f"level_{i}") @@ -5798,11 +5790,11 @@ def dropna( def drop_duplicates( self, - subset: Optional[Union[Hashable, Sequence[Hashable]]] = None, - keep: Union[str, bool] = "first", + subset: Hashable | Sequence[Hashable] | None = None, + keep: str | bool = "first", inplace: bool = False, ignore_index: bool = False, - ) -> Optional[DataFrame]: + ) -> DataFrame | None: """ Return DataFrame with duplicate rows removed. @@ -5895,8 +5887,8 @@ def drop_duplicates( def duplicated( self, - subset: Optional[Union[Hashable, Sequence[Hashable]]] = None, - keep: Union[str, bool] = "first", + subset: Hashable | Sequence[Hashable] | None = None, + keep: str | bool = "first", ) -> Series: """ Return boolean Series denoting duplicate rows. @@ -6103,8 +6095,8 @@ def sort_values( # type: ignore[override] def sort_index( self, axis: Axis = 0, - level: Optional[Level] = None, - ascending: Union[Union[bool, int], Sequence[Union[bool, int]]] = True, + level: Level | None = None, + ascending: bool | int | Sequence[bool | int] = True, inplace: bool = False, kind: str = "quicksort", na_position: str = "last", @@ -6215,7 +6207,7 @@ def sort_index( def value_counts( self, - subset: Optional[Sequence[Hashable]] = None, + subset: Sequence[Hashable] | None = None, normalize: bool = False, sort: bool = True, ascending: bool = False, @@ -6657,7 +6649,7 @@ def _arith_method(self, other, op): _logical_method = _arith_method - def _dispatch_frame_op(self, right, func: Callable, axis: Optional[int] = None): + def _dispatch_frame_op(self, right, func: Callable, axis: int | None = None): """ Evaluate the frame operation func(left, right) by evaluating column-by-column, dispatching to the Series implementation. @@ -6771,13 +6763,13 @@ def _construct_result(self, result) -> DataFrame: out.index = self.index return out - def __divmod__(self, other) -> Tuple[DataFrame, DataFrame]: + def __divmod__(self, other) -> tuple[DataFrame, DataFrame]: # Naive implementation, room for optimization div = self // other mod = self - div * other return div, mod - def __rdivmod__(self, other) -> Tuple[DataFrame, DataFrame]: + def __rdivmod__(self, other) -> tuple[DataFrame, DataFrame]: # Naive implementation, room for optimization div = other // self mod = other - div * self @@ -7392,7 +7384,7 @@ def groupby( self, by=None, axis: Axis = 0, - level: Optional[Level] = None, + level: Level | None = None, as_index: bool = True, sort: bool = True, group_keys: bool = True, @@ -7918,9 +7910,7 @@ def stack(self, level: Level = -1, dropna: bool = True): return result.__finalize__(self, method="stack") - def explode( - self, column: Union[str, Tuple], ignore_index: bool = False - ) -> DataFrame: + def explode(self, column: str | tuple, ignore_index: bool = False) -> DataFrame: """ Transform each element of a list-like to a row, replicating index values. @@ -8067,7 +8057,7 @@ def melt( value_vars=None, var_name=None, value_name="value", - col_level: Optional[Level] = None, + col_level: Level | None = None, ignore_index: bool = True, ) -> DataFrame: @@ -8177,7 +8167,7 @@ def _gotitem( self, key: IndexLabel, ndim: int, - subset: Optional[FrameOrSeriesUnion] = None, + subset: FrameOrSeriesUnion | None = None, ) -> FrameOrSeriesUnion: """ Sub-classes to define. Return a sliced object. @@ -8475,7 +8465,7 @@ def apply( return op.apply() def applymap( - self, func: PythonFuncType, na_action: Optional[str] = None, **kwargs + self, func: PythonFuncType, na_action: str | None = None, **kwargs ) -> DataFrame: """ Apply a function to a Dataframe elementwise. @@ -8710,7 +8700,7 @@ def append( def join( self, other: FrameOrSeriesUnion, - on: Optional[IndexLabel] = None, + on: IndexLabel | None = None, how: str = "left", lsuffix: str = "", rsuffix: str = "", @@ -8840,7 +8830,7 @@ def join( def _join_compat( self, other: FrameOrSeriesUnion, - on: Optional[IndexLabel] = None, + on: IndexLabel | None = None, how: str = "left", lsuffix: str = "", rsuffix: str = "", @@ -8911,16 +8901,16 @@ def merge( self, right: FrameOrSeriesUnion, how: str = "inner", - on: Optional[IndexLabel] = None, - left_on: Optional[IndexLabel] = None, - right_on: Optional[IndexLabel] = None, + on: IndexLabel | None = None, + left_on: IndexLabel | None = None, + right_on: IndexLabel | None = None, left_index: bool = False, right_index: bool = False, sort: bool = False, suffixes: Suffixes = ("_x", "_y"), copy: bool = True, indicator: bool = False, - validate: Optional[str] = None, + validate: str | None = None, ) -> DataFrame: from pandas.core.reshape.merge import merge @@ -8941,7 +8931,7 @@ def merge( ) def round( - self, decimals: Union[int, Dict[IndexLabel, int], Series] = 0, *args, **kwargs + self, decimals: int | dict[IndexLabel, int] | Series = 0, *args, **kwargs ) -> DataFrame: """ Round a DataFrame to a variable number of decimal places. @@ -9058,7 +9048,7 @@ def _series_round(s, decimals): def corr( self, - method: Union[str, Callable[[np.ndarray, np.ndarray], float]] = "pearson", + method: str | Callable[[np.ndarray, np.ndarray], float] = "pearson", min_periods: int = 1, ) -> DataFrame: """ @@ -9150,9 +9140,7 @@ def corr( return self._constructor(correl, index=idx, columns=cols) - def cov( - self, min_periods: Optional[int] = None, ddof: Optional[int] = 1 - ) -> DataFrame: + def cov(self, min_periods: int | None = None, ddof: int | None = 1) -> DataFrame: """ Compute pairwise covariance of columns, excluding NA/null values. @@ -9365,7 +9353,7 @@ def c(x): # ndarray-like stats methods def count( - self, axis: Axis = 0, level: Optional[Level] = None, numeric_only: bool = False + self, axis: Axis = 0, level: Level | None = None, numeric_only: bool = False ): """ Count non-NA cells for each column or row. @@ -9522,7 +9510,7 @@ def _reduce( *, axis: Axis = 0, skipna: bool = True, - numeric_only: Optional[bool] = None, + numeric_only: bool | None = None, filter_type=None, **kwds, ): @@ -10037,7 +10025,7 @@ def asfreq( self, freq: Frequency, method=None, - how: Optional[str] = None, + how: str | None = None, normalize: bool = False, fill_value=None, ) -> DataFrame: @@ -10054,16 +10042,16 @@ def resample( self, rule, axis=0, - closed: Optional[str] = None, - label: Optional[str] = None, + closed: str | None = None, + label: str | None = None, convention: str = "start", - kind: Optional[str] = None, + kind: str | None = None, loffset=None, - base: Optional[int] = None, + base: int | None = None, on=None, level=None, - origin: Union[str, TimestampConvertibleTypes] = "start_day", - offset: Optional[TimedeltaConvertibleTypes] = None, + origin: str | TimestampConvertibleTypes = "start_day", + offset: TimedeltaConvertibleTypes | None = None, ) -> Resampler: return super().resample( rule=rule, @@ -10082,7 +10070,7 @@ def resample( def to_timestamp( self, - freq: Optional[Frequency] = None, + freq: Frequency | None = None, how: str = "start", axis: Axis = 0, copy: bool = True, @@ -10119,7 +10107,7 @@ def to_timestamp( return new_obj def to_period( - self, freq: Optional[Frequency] = None, axis: Axis = 0, copy: bool = True + self, freq: Frequency | None = None, axis: Axis = 0, copy: bool = True ) -> DataFrame: """ Convert DataFrame from DatetimeIndex to PeriodIndex. @@ -10249,7 +10237,7 @@ def isin(self, values) -> DataFrame: # ---------------------------------------------------------------------- # Add index and columns _AXIS_ORDERS = ["index", "columns"] - _AXIS_TO_AXIS_NUMBER: Dict[Axis, int] = { + _AXIS_TO_AXIS_NUMBER: dict[Axis, int] = { **NDFrame._AXIS_TO_AXIS_NUMBER, 1: 1, "columns": 1, @@ -10267,13 +10255,13 @@ def isin(self, values) -> DataFrame: ) @property - def _AXIS_NUMBERS(self) -> Dict[str, int]: + def _AXIS_NUMBERS(self) -> dict[str, int]: """.. deprecated:: 1.1.0""" super()._AXIS_NUMBERS return {"index": 0, "columns": 1} @property - def _AXIS_NAMES(self) -> Dict[int, str]: + def _AXIS_NAMES(self) -> dict[int, str]: """.. deprecated:: 1.1.0""" super()._AXIS_NAMES return {0: "index", 1: "columns"} diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 25c10c215e8cc..4ef5aa1109074 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -12,17 +12,9 @@ TYPE_CHECKING, Any, Callable, - Dict, - FrozenSet, Hashable, - List, Mapping, - Optional, Sequence, - Set, - Tuple, - Type, - Union, cast, overload, ) @@ -207,7 +199,7 @@ class NDFrame(PandasObject, SelectionMixin, indexing.IndexingMixin): copy : bool, default False """ - _internal_names: List[str] = [ + _internal_names: list[str] = [ "_mgr", "_cacher", "_item_cache", @@ -223,15 +215,15 @@ class NDFrame(PandasObject, SelectionMixin, indexing.IndexingMixin): "__array_interface__", "_flags", ] - _internal_names_set: Set[str] = set(_internal_names) - _accessors: Set[str] = set() - _hidden_attrs: FrozenSet[str] = frozenset( + _internal_names_set: set[str] = set(_internal_names) + _accessors: set[str] = set() + _hidden_attrs: frozenset[str] = frozenset( ["_AXIS_NAMES", "_AXIS_NUMBERS", "get_values", "tshift"] ) - _metadata: List[str] = [] - _is_copy: Optional[weakref.ReferenceType[NDFrame]] = None + _metadata: list[str] = [] + _is_copy: weakref.ReferenceType[NDFrame] | None = None _mgr: Manager - _attrs: Dict[Hashable, Any] + _attrs: dict[Hashable, Any] _typ: str # ---------------------------------------------------------------------- @@ -241,7 +233,7 @@ def __init__( self, data: Manager, copy: bool = False, - attrs: Optional[Mapping[Hashable, Any]] = None, + attrs: Mapping[Hashable, Any] | None = None, ): # copy kwarg is retained for mypy compat, is not used @@ -257,7 +249,7 @@ def __init__( @classmethod def _init_mgr( - cls, mgr, axes, dtype: Optional[Dtype] = None, copy: bool = False + cls, mgr, axes, dtype: Dtype | None = None, copy: bool = False ) -> Manager: """ passed a manager and a axes dict """ for a, axe in axes.items(): @@ -320,7 +312,7 @@ def _as_manager(self: FrameOrSeries, typ: str) -> FrameOrSeries: # attrs and flags @property - def attrs(self) -> Dict[Hashable, Any]: + def attrs(self) -> dict[Hashable, Any]: """ Dictionary of global attributes of this dataset. @@ -386,7 +378,7 @@ def set_flags( self: FrameOrSeries, *, copy: bool = False, - allows_duplicate_labels: Optional[bool] = None, + allows_duplicate_labels: bool | None = None, ) -> FrameOrSeries: """ Return a new object with updated flags. @@ -434,7 +426,7 @@ def set_flags( @final @classmethod - def _validate_dtype(cls, dtype) -> Optional[DtypeObj]: + def _validate_dtype(cls, dtype) -> DtypeObj | None: """ validate the passed dtype """ if dtype is not None: dtype = pandas_dtype(dtype) @@ -452,7 +444,7 @@ def _validate_dtype(cls, dtype) -> Optional[DtypeObj]: # Construction @property - def _constructor(self: FrameOrSeries) -> Type[FrameOrSeries]: + def _constructor(self: FrameOrSeries) -> type[FrameOrSeries]: """ Used when a manipulation result has the same dimensions as the original. @@ -473,21 +465,21 @@ def _data(self): # Axis _stat_axis_number = 0 _stat_axis_name = "index" - _AXIS_ORDERS: List[str] - _AXIS_TO_AXIS_NUMBER: Dict[Axis, int] = {0: 0, "index": 0, "rows": 0} + _AXIS_ORDERS: list[str] + _AXIS_TO_AXIS_NUMBER: dict[Axis, int] = {0: 0, "index": 0, "rows": 0} _AXIS_REVERSED: bool _info_axis_number: int _info_axis_name: str _AXIS_LEN: int @property - def _AXIS_NUMBERS(self) -> Dict[str, int]: + def _AXIS_NUMBERS(self) -> dict[str, int]: """.. deprecated:: 1.1.0""" warnings.warn("_AXIS_NUMBERS has been deprecated.", FutureWarning, stacklevel=3) return {"index": 0} @property - def _AXIS_NAMES(self) -> Dict[int, str]: + def _AXIS_NAMES(self) -> dict[int, str]: """.. deprecated:: 1.1.0""" warnings.warn("_AXIS_NAMES has been deprecated.", FutureWarning, stacklevel=3) return {0: "index"} @@ -562,7 +554,7 @@ def _get_block_manager_axis(cls, axis: Axis) -> int: return axis @final - def _get_axis_resolvers(self, axis: str) -> Dict[str, Union[Series, MultiIndex]]: + def _get_axis_resolvers(self, axis: str) -> dict[str, Series | MultiIndex]: # index or columns axis_index = getattr(self, axis) d = {} @@ -593,17 +585,17 @@ def _get_axis_resolvers(self, axis: str) -> Dict[str, Union[Series, MultiIndex]] return d @final - def _get_index_resolvers(self) -> Dict[Hashable, Union[Series, MultiIndex]]: + def _get_index_resolvers(self) -> dict[Hashable, Series | MultiIndex]: from pandas.core.computation.parsing import clean_column_name - d: Dict[str, Union[Series, MultiIndex]] = {} + d: dict[str, Series | MultiIndex] = {} for axis_name in self._AXIS_ORDERS: d.update(self._get_axis_resolvers(axis_name)) return {clean_column_name(k): v for k, v in d.items() if not isinstance(k, int)} @final - def _get_cleaned_column_resolvers(self) -> Dict[Hashable, Series]: + def _get_cleaned_column_resolvers(self) -> dict[Hashable, Series]: """ Return the special character free column resolvers of a dataframe. @@ -629,14 +621,14 @@ def _stat_axis(self) -> Index: return getattr(self, self._stat_axis_name) @property - def shape(self) -> Tuple[int, ...]: + def shape(self) -> tuple[int, ...]: """ Return a tuple of axis dimensions """ return tuple(len(self._get_axis(a)) for a in self._AXIS_ORDERS) @property - def axes(self) -> List[Index]: + def axes(self) -> list[Index]: """ Return index label(s) of the internal NDFrame """ @@ -723,7 +715,7 @@ def set_axis(self: FrameOrSeries, labels, *, inplace: Literal[True]) -> None: @overload def set_axis( self: FrameOrSeries, labels, axis: Axis = ..., inplace: bool = ... - ) -> Optional[FrameOrSeries]: + ) -> FrameOrSeries | None: ... def set_axis(self, labels, axis: Axis = 0, inplace: bool = False): @@ -873,7 +865,7 @@ def droplevel(self: FrameOrSeries, level, axis=0) -> FrameOrSeries: new_labels = labels.droplevel(level) return self.set_axis(new_labels, axis=axis, inplace=False) - def pop(self, item: Hashable) -> Union[Series, Any]: + def pop(self, item: Hashable) -> Series | Any: result = self[item] del self[item] if self.ndim == 2: @@ -998,16 +990,16 @@ def squeeze(self, axis=None): def rename( self: FrameOrSeries, - mapper: Optional[Renamer] = None, + mapper: Renamer | None = None, *, - index: Optional[Renamer] = None, - columns: Optional[Renamer] = None, - axis: Optional[Axis] = None, + index: Renamer | None = None, + columns: Renamer | None = None, + axis: Axis | None = None, copy: bool = True, inplace: bool = False, - level: Optional[Level] = None, + level: Level | None = None, errors: str = "ignore", - ) -> Optional[FrameOrSeries]: + ) -> FrameOrSeries | None: """ Alter axes input function or functions. Function / dict values must be unique (1-to-1). Labels not contained in a dict / Series will be left @@ -2002,13 +1994,13 @@ def empty(self) -> bool_t: # GH#23114 Ensure ndarray.__op__(DataFrame) returns NotImplemented __array_priority__ = 1000 - def __array__(self, dtype: Optional[NpDtype] = None) -> np.ndarray: + def __array__(self, dtype: NpDtype | None = None) -> np.ndarray: return np.asarray(self._values, dtype=dtype) def __array_wrap__( self, result: np.ndarray, - context: Optional[Tuple[Callable, Tuple[Any, ...], int]] = None, + context: tuple[Callable, tuple[Any, ...], int] | None = None, ): """ Gets called after a ufunc and other functions. @@ -2056,7 +2048,7 @@ def __array_ufunc__( # Picklability @final - def __getstate__(self) -> Dict[str, Any]: + def __getstate__(self) -> dict[str, Any]: meta = {k: getattr(self, k, None) for k in self._metadata} return { "_mgr": self._mgr, @@ -2146,7 +2138,7 @@ def to_excel( excel_writer, sheet_name: str = "Sheet1", na_rep: str = "", - float_format: Optional[str] = None, + float_format: str | None = None, columns=None, header=True, index=True, @@ -2308,19 +2300,19 @@ def to_excel( @doc(storage_options=_shared_docs["storage_options"]) def to_json( self, - path_or_buf: Optional[FilePathOrBuffer] = None, - orient: Optional[str] = None, - date_format: Optional[str] = None, + path_or_buf: FilePathOrBuffer | None = None, + orient: str | None = None, + date_format: str | None = None, double_precision: int = 10, force_ascii: bool_t = True, date_unit: str = "ms", - default_handler: Optional[Callable[[Any], JSONSerializable]] = None, + default_handler: Callable[[Any], JSONSerializable] | None = None, lines: bool_t = False, compression: CompressionOptions = "infer", index: bool_t = True, - indent: Optional[int] = None, + indent: int | None = None, storage_options: StorageOptions = None, - ) -> Optional[str]: + ) -> str | None: """ Convert the object to a JSON string. @@ -2593,15 +2585,15 @@ def to_hdf( path_or_buf, key: str, mode: str = "a", - complevel: Optional[int] = None, - complib: Optional[str] = None, + complevel: int | None = None, + complib: str | None = None, append: bool_t = False, - format: Optional[str] = None, + format: str | None = None, index: bool_t = True, - min_itemsize: Optional[Union[int, Dict[str, int]]] = None, + min_itemsize: int | dict[str, int] | None = None, nan_rep=None, - dropna: Optional[bool_t] = None, - data_columns: Optional[Union[bool_t, List[str]]] = None, + dropna: bool_t | None = None, + data_columns: bool_t | list[str] | None = None, errors: str = "strict", encoding: str = "UTF-8", ) -> None: @@ -2744,7 +2736,7 @@ def to_sql( index: bool_t = True, index_label=None, chunksize=None, - dtype: Optional[DtypeArg] = None, + dtype: DtypeArg | None = None, method=None, ) -> None: """ @@ -2984,7 +2976,7 @@ def to_pickle( @final def to_clipboard( - self, excel: bool_t = True, sep: Optional[str] = None, **kwargs + self, excel: bool_t = True, sep: str | None = None, **kwargs ) -> None: r""" Copy object to the system clipboard. @@ -3318,28 +3310,28 @@ def to_latex( @doc(storage_options=_shared_docs["storage_options"]) def to_csv( self, - path_or_buf: Optional[FilePathOrBuffer] = None, + path_or_buf: FilePathOrBuffer | None = None, sep: str = ",", na_rep: str = "", - float_format: Optional[str] = None, - columns: Optional[Sequence[Hashable]] = None, - header: Union[bool_t, List[str]] = True, + float_format: str | None = None, + columns: Sequence[Hashable] | None = None, + header: bool_t | list[str] = True, index: bool_t = True, - index_label: Optional[IndexLabel] = None, + index_label: IndexLabel | None = None, mode: str = "w", - encoding: Optional[str] = None, + encoding: str | None = None, compression: CompressionOptions = "infer", - quoting: Optional[int] = None, + quoting: int | None = None, quotechar: str = '"', - line_terminator: Optional[str] = None, - chunksize: Optional[int] = None, - date_format: Optional[str] = None, + line_terminator: str | None = None, + chunksize: int | None = None, + date_format: str | None = None, doublequote: bool_t = True, - escapechar: Optional[str] = None, + escapechar: str | None = None, decimal: str = ".", errors: str = "strict", storage_options: StorageOptions = None, - ) -> Optional[str]: + ) -> str | None: r""" Write object to a comma-separated values (csv) file. @@ -3604,7 +3596,7 @@ def _clear_item_cache(self) -> None: # Indexing Methods def take( - self: FrameOrSeries, indices, axis=0, is_copy: Optional[bool_t] = None, **kwargs + self: FrameOrSeries, indices, axis=0, is_copy: bool_t | None = None, **kwargs ) -> FrameOrSeries: """ Return the elements in the given *positional* indices along an axis. @@ -4113,7 +4105,7 @@ def _is_view(self) -> bool_t: def reindex_like( self: FrameOrSeries, other, - method: Optional[str] = None, + method: str | None = None, copy: bool_t = True, limit=None, tolerance=None, @@ -4623,7 +4615,7 @@ def sort_index( self, axis=0, level=None, - ascending: Union[Union[bool_t, int], Sequence[Union[bool_t, int]]] = True, + ascending: bool_t | int | Sequence[bool_t | int] = True, inplace: bool_t = False, kind: str = "quicksort", na_position: str = "last", @@ -4996,8 +4988,8 @@ def _reindex_with_indexers( def filter( self: FrameOrSeries, items=None, - like: Optional[str] = None, - regex: Optional[str] = None, + like: str | None = None, + regex: str | None = None, axis=None, ) -> FrameOrSeries: """ @@ -5461,7 +5453,7 @@ def sample( @doc(klass=_shared_doc_kwargs["klass"]) def pipe( self, - func: Union[Callable[..., T], Tuple[Callable[..., T], str]], + func: Callable[..., T] | tuple[Callable[..., T], str], *args, **kwargs, ) -> T: @@ -5522,7 +5514,7 @@ def pipe( @final def __finalize__( - self: FrameOrSeries, other, method: Optional[str] = None, **kwargs + self: FrameOrSeries, other, method: str | None = None, **kwargs ) -> FrameOrSeries: """ Propagate metadata from other to self. @@ -5616,7 +5608,7 @@ def __setattr__(self, name: str, value) -> None: object.__setattr__(self, name, value) @final - def _dir_additions(self) -> Set[str]: + def _dir_additions(self) -> set[str]: """ add the string-like attributes from the info_axis. If info_axis is a MultiIndex, its first level values are used. @@ -6380,7 +6372,7 @@ def fillna( inplace: bool_t = False, limit=None, downcast=None, - ) -> Optional[FrameOrSeries]: + ) -> FrameOrSeries | None: """ Fill NA/NaN values using the specified method. @@ -6578,7 +6570,7 @@ def ffill( inplace: bool_t = False, limit=None, downcast=None, - ) -> Optional[FrameOrSeries]: + ) -> FrameOrSeries | None: """ Synonym for :meth:`DataFrame.fillna` with ``method='ffill'``. @@ -6601,7 +6593,7 @@ def bfill( inplace: bool_t = False, limit=None, downcast=None, - ) -> Optional[FrameOrSeries]: + ) -> FrameOrSeries | None: """ Synonym for :meth:`DataFrame.fillna` with ``method='bfill'``. @@ -6627,7 +6619,7 @@ def replace( to_replace=None, value=None, inplace: bool_t = False, - limit: Optional[int] = None, + limit: int | None = None, regex=False, method="pad", ): @@ -6804,13 +6796,13 @@ def interpolate( self: FrameOrSeries, method: str = "linear", axis: Axis = 0, - limit: Optional[int] = None, + limit: int | None = None, inplace: bool_t = False, - limit_direction: Optional[str] = None, - limit_area: Optional[str] = None, - downcast: Optional[str] = None, + limit_direction: str | None = None, + limit_area: str | None = None, + downcast: str | None = None, **kwargs, - ) -> Optional[FrameOrSeries]: + ) -> FrameOrSeries | None: """ Fill NaN values using an interpolation method. @@ -7590,7 +7582,7 @@ def asfreq( self: FrameOrSeries, freq, method=None, - how: Optional[str] = None, + how: str | None = None, normalize: bool_t = False, fill_value=None, ) -> FrameOrSeries: @@ -7859,16 +7851,16 @@ def resample( self, rule, axis=0, - closed: Optional[str] = None, - label: Optional[str] = None, + closed: str | None = None, + label: str | None = None, convention: str = "start", - kind: Optional[str] = None, + kind: str | None = None, loffset=None, - base: Optional[int] = None, + base: int | None = None, on=None, level=None, - origin: Union[str, TimestampConvertibleTypes] = "start_day", - offset: Optional[TimedeltaConvertibleTypes] = None, + origin: str | TimestampConvertibleTypes = "start_day", + offset: TimedeltaConvertibleTypes | None = None, ) -> Resampler: """ Resample time-series data. @@ -8428,7 +8420,7 @@ def rank( self: FrameOrSeries, axis=0, method: str = "average", - numeric_only: Optional[bool_t] = None, + numeric_only: bool_t | None = None, na_option: str = "keep", ascending: bool_t = True, pct: bool_t = False, @@ -10973,13 +10965,13 @@ def min(self, axis=None, skipna=None, level=None, numeric_only=None, **kwargs): @doc(Rolling) def rolling( self, - window: Union[int, timedelta, BaseOffset, BaseIndexer], - min_periods: Optional[int] = None, + window: int | timedelta | BaseOffset | BaseIndexer, + min_periods: int | None = None, center: bool_t = False, - win_type: Optional[str] = None, - on: Optional[str] = None, + win_type: str | None = None, + on: str | None = None, axis: Axis = 0, - closed: Optional[str] = None, + closed: str | None = None, method: str = "single", ): axis = self._get_axis_number(axis) @@ -11014,7 +11006,7 @@ def rolling( def expanding( self, min_periods: int = 1, - center: Optional[bool_t] = None, + center: bool_t | None = None, axis: Axis = 0, method: str = "single", ) -> Expanding: @@ -11036,15 +11028,15 @@ def expanding( @doc(ExponentialMovingWindow) def ewm( self, - com: Optional[float] = None, - span: Optional[float] = None, - halflife: Optional[Union[float, TimedeltaConvertibleTypes]] = None, - alpha: Optional[float] = None, + com: float | None = None, + span: float | None = None, + halflife: float | TimedeltaConvertibleTypes | None = None, + alpha: float | None = None, min_periods: int = 0, adjust: bool_t = True, ignore_na: bool_t = False, axis: Axis = 0, - times: Optional[Union[str, np.ndarray, FrameOrSeries]] = None, + times: str | np.ndarray | FrameOrSeries | None = None, ) -> ExponentialMovingWindow: axis = self._get_axis_number(axis) # error: Value of type variable "FrameOrSeries" of "ExponentialMovingWindow" @@ -11139,7 +11131,7 @@ def __ixor__(self, other): # Misc methods @final - def _find_valid_index(self, *, how: str) -> Optional[Hashable]: + def _find_valid_index(self, *, how: str) -> Hashable | None: """ Retrieves the index of the first valid value. @@ -11159,7 +11151,7 @@ def _find_valid_index(self, *, how: str) -> Optional[Hashable]: @final @doc(position="first", klass=_shared_doc_kwargs["klass"]) - def first_valid_index(self) -> Optional[Hashable]: + def first_valid_index(self) -> Hashable | None: """ Return index for {position} non-NA value or None, if no NA value is found. @@ -11176,7 +11168,7 @@ def first_valid_index(self) -> Optional[Hashable]: @final @doc(first_valid_index, position="last", klass=_shared_doc_kwargs["klass"]) - def last_valid_index(self) -> Optional[Hashable]: + def last_valid_index(self) -> Hashable | None: return self._find_valid_index(how="last") diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 4c8a6a200b196..923c610c22161 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -5,10 +5,7 @@ TYPE_CHECKING, Any, Hashable, - List, Sequence, - Tuple, - Union, ) import warnings @@ -737,7 +734,7 @@ def _validate_key(self, key, axis: int): """ raise AbstractMethodError(self) - def _has_valid_tuple(self, key: Tuple): + def _has_valid_tuple(self, key: tuple): """ Check the key for valid keys across my indexer. """ @@ -751,7 +748,7 @@ def _has_valid_tuple(self, key: Tuple): f"[{self._valid_types}] types" ) from err - def _is_nested_tuple_indexer(self, tup: Tuple) -> bool: + def _is_nested_tuple_indexer(self, tup: tuple) -> bool: """ Returns ------- @@ -784,7 +781,7 @@ def _validate_key_length(self, key: Sequence[Any]) -> None: if len(key) > self.ndim: raise IndexingError("Too many indexers") - def _getitem_tuple_same_dim(self, tup: Tuple): + def _getitem_tuple_same_dim(self, tup: tuple): """ Index with indexers that should return an object of the same dimension as self.obj. @@ -803,7 +800,7 @@ def _getitem_tuple_same_dim(self, tup: Tuple): return retval - def _getitem_lowerdim(self, tup: Tuple): + def _getitem_lowerdim(self, tup: tuple): # we can directly get the axis result since the axis is specified if self.axis is not None: @@ -856,7 +853,7 @@ def _getitem_lowerdim(self, tup: Tuple): raise IndexingError("not applicable") - def _getitem_nested_tuple(self, tup: Tuple): + def _getitem_nested_tuple(self, tup: tuple): # we have a nested tuple so have at least 1 multi-index level # we should be able to match up the dimensionality here @@ -927,10 +924,10 @@ def __getitem__(self, key): maybe_callable = com.apply_if_callable(key, self.obj) return self._getitem_axis(maybe_callable, axis=axis) - def _is_scalar_access(self, key: Tuple): + def _is_scalar_access(self, key: tuple): raise NotImplementedError() - def _getitem_tuple(self, tup: Tuple): + def _getitem_tuple(self, tup: tuple): raise AbstractMethodError(self) def _getitem_axis(self, key, axis: int): @@ -971,7 +968,7 @@ def _validate_key(self, key, axis: int): def _has_valid_setitem_indexer(self, indexer) -> bool: return True - def _is_scalar_access(self, key: Tuple) -> bool: + def _is_scalar_access(self, key: tuple) -> bool: """ Returns ------- @@ -1005,7 +1002,7 @@ def _is_scalar_access(self, key: Tuple) -> bool: # ------------------------------------------------------------------- # MultiIndex Handling - def _multi_take_opportunity(self, tup: Tuple) -> bool: + def _multi_take_opportunity(self, tup: tuple) -> bool: """ Check whether there is the possibility to use ``_multi_take``. @@ -1029,7 +1026,7 @@ def _multi_take_opportunity(self, tup: Tuple) -> bool: # just too complicated return not any(com.is_bool_indexer(x) for x in tup) - def _multi_take(self, tup: Tuple): + def _multi_take(self, tup: tuple): """ Create the indexers for the passed tuple of keys, and executes the take operation. This allows the take operation to be @@ -1085,7 +1082,7 @@ def _getitem_iterable(self, key, axis: int): {axis: [keyarr, indexer]}, copy=True, allow_dups=True ) - def _getitem_tuple(self, tup: Tuple): + def _getitem_tuple(self, tup: tuple): with suppress(IndexingError): return self._getitem_lowerdim(tup) @@ -1102,7 +1099,7 @@ def _get_label(self, label, axis: int): # GH#5667 this will fail if the label is not present in the axis. return self.obj.xs(label, axis=axis) - def _handle_lowerdim_multi_index_axis0(self, tup: Tuple): + def _handle_lowerdim_multi_index_axis0(self, tup: tuple): # we have an axis0 multi-index, handle or raise axis = self.axis or 0 try: @@ -1448,7 +1445,7 @@ def _has_valid_setitem_indexer(self, indexer) -> bool: return True - def _is_scalar_access(self, key: Tuple) -> bool: + def _is_scalar_access(self, key: tuple) -> bool: """ Returns ------- @@ -1485,7 +1482,7 @@ def _validate_integer(self, key: int, axis: int) -> None: # ------------------------------------------------------------------- - def _getitem_tuple(self, tup: Tuple): + def _getitem_tuple(self, tup: tuple): self._has_valid_tuple(tup) with suppress(IndexingError): @@ -2254,7 +2251,7 @@ def _convert_key(self, key, is_setter: bool = False): return key -def _tuplify(ndim: int, loc: Hashable) -> Tuple[Union[Hashable, slice], ...]: +def _tuplify(ndim: int, loc: Hashable) -> tuple[Hashable | slice, ...]: """ Given an indexer for the first dimension, create an equivalent tuple for indexing over all dimensions. @@ -2268,7 +2265,7 @@ def _tuplify(ndim: int, loc: Hashable) -> Tuple[Union[Hashable, slice], ...]: ------- tuple """ - _tup: List[Union[Hashable, slice]] + _tup: list[Hashable | slice] _tup = [slice(None, None) for _ in range(ndim)] _tup[0] = loc return tuple(_tup) diff --git a/pandas/core/missing.py b/pandas/core/missing.py index 2fd39588a3da6..8849eb0670faa 100644 --- a/pandas/core/missing.py +++ b/pandas/core/missing.py @@ -10,10 +10,6 @@ from typing import ( TYPE_CHECKING, Any, - List, - Optional, - Set, - Union, cast, ) @@ -168,7 +164,7 @@ def clean_interp_method(method: str, index: Index, **kwargs) -> str: return method -def find_valid_index(values, *, how: str) -> Optional[int]: +def find_valid_index(values, *, how: str) -> int | None: """ Retrieves the index of the first valid value. @@ -209,13 +205,13 @@ def interpolate_array_2d( data: np.ndarray, method: str = "pad", axis: int = 0, - index: Optional[Index] = None, - limit: Optional[int] = None, + index: Index | None = None, + limit: int | None = None, limit_direction: str = "forward", - limit_area: Optional[str] = None, - fill_value: Optional[Any] = None, + limit_area: str | None = None, + fill_value: Any | None = None, coerce: bool = False, - downcast: Optional[str] = None, + downcast: str | None = None, **kwargs, ): """ @@ -260,10 +256,10 @@ def interpolate_2d_with_fill( index: Index, axis: int, method: str = "linear", - limit: Optional[int] = None, + limit: int | None = None, limit_direction: str = "forward", - limit_area: Optional[str] = None, - fill_value: Optional[Any] = None, + limit_area: str | None = None, + fill_value: Any | None = None, **kwargs, ) -> np.ndarray: """ @@ -304,13 +300,13 @@ def func(yvalues: np.ndarray) -> np.ndarray: def interpolate_1d( xvalues: Index, yvalues: np.ndarray, - method: Optional[str] = "linear", - limit: Optional[int] = None, + method: str | None = "linear", + limit: int | None = None, limit_direction: str = "forward", - limit_area: Optional[str] = None, - fill_value: Optional[Any] = None, + limit_area: str | None = None, + fill_value: Any | None = None, bounds_error: bool = False, - order: Optional[int] = None, + order: int | None = None, **kwargs, ): """ @@ -384,7 +380,7 @@ def interpolate_1d( # are more than'limit' away from the prior non-NaN. # set preserve_nans based on direction using _interp_limit - preserve_nans: Union[List, Set] + preserve_nans: list | set if limit_direction == "forward": preserve_nans = start_nans | set(_interp_limit(invalid, limit, 0)) elif limit_direction == "backward": @@ -685,7 +681,7 @@ def _cubicspline_interpolate(xi, yi, x, axis=0, bc_type="not-a-knot", extrapolat def _interpolate_with_limit_area( - values: ArrayLike, method: str, limit: Optional[int], limit_area: Optional[str] + values: ArrayLike, method: str, limit: int | None, limit_area: str | None ) -> ArrayLike: """ Apply interpolation and limit_area logic to values along a to-be-specified axis. @@ -737,8 +733,8 @@ def interpolate_2d( values, method: str = "pad", axis: Axis = 0, - limit: Optional[int] = None, - limit_area: Optional[str] = None, + limit: int | None = None, + limit_area: str | None = None, ): """ Perform an actual interpolation of values, values will be make 2-d if @@ -798,7 +794,7 @@ def interpolate_2d( return result -def _fillna_prep(values, mask: Optional[np.ndarray] = None) -> np.ndarray: +def _fillna_prep(values, mask: np.ndarray | None = None) -> np.ndarray: # boilerplate for _pad_1d, _backfill_1d, _pad_2d, _backfill_2d if mask is None: diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index de324561de030..43a61ed799e8f 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -5,9 +5,6 @@ import operator from typing import ( Any, - Optional, - Tuple, - Union, cast, ) import warnings @@ -123,7 +120,7 @@ def __call__(self, alt: F) -> F: def f( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, **kwds, ): @@ -192,7 +189,7 @@ def _has_infs(result) -> bool: def _get_fill_value( - dtype: DtypeObj, fill_value: Optional[Scalar] = None, fill_value_typ=None + dtype: DtypeObj, fill_value: Scalar | None = None, fill_value_typ=None ): """ return the correct fill value for the dtype of the values """ if fill_value is not None: @@ -214,8 +211,8 @@ def _get_fill_value( def _maybe_get_mask( - values: np.ndarray, skipna: bool, mask: Optional[np.ndarray] -) -> Optional[np.ndarray]: + values: np.ndarray, skipna: bool, mask: np.ndarray | None +) -> np.ndarray | None: """ Compute a mask if and only if necessary. @@ -261,9 +258,9 @@ def _get_values( values: np.ndarray, skipna: bool, fill_value: Any = None, - fill_value_typ: Optional[str] = None, - mask: Optional[np.ndarray] = None, -) -> Tuple[np.ndarray, Optional[np.ndarray], np.dtype, np.dtype, Any]: + fill_value_typ: str | None = None, + mask: np.ndarray | None = None, +) -> tuple[np.ndarray, np.ndarray | None, np.dtype, np.dtype, Any]: """ Utility to get the values view, mask, dtype, dtype_max, and fill_value. @@ -399,9 +396,9 @@ def _datetimelike_compat(func: F) -> F: def new_func( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, **kwargs, ): orig_values = values @@ -423,9 +420,7 @@ def new_func( return cast(F, new_func) -def _na_for_min_count( - values: np.ndarray, axis: Optional[int] -) -> Union[Scalar, np.ndarray]: +def _na_for_min_count(values: np.ndarray, axis: int | None) -> Scalar | np.ndarray: """ Return the missing value for `values`. @@ -459,9 +454,9 @@ def _na_for_min_count( def nanany( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> bool: """ Check if any elements along an axis evaluate to True. @@ -499,9 +494,9 @@ def nanany( def nanall( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> bool: """ Check if all elements along an axis evaluate to True. @@ -541,10 +536,10 @@ def nanall( def nansum( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, min_count: int = 0, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> float: """ Sum the elements along an axis ignoring NaNs @@ -595,11 +590,11 @@ def nansum( def _mask_datetimelike_result( - result: Union[np.ndarray, np.datetime64, np.timedelta64], - axis: Optional[int], + result: np.ndarray | np.datetime64 | np.timedelta64, + axis: int | None, mask: np.ndarray, orig_values: np.ndarray, -) -> Union[np.ndarray, np.datetime64, np.timedelta64, NaTType]: +) -> np.ndarray | np.datetime64 | np.timedelta64 | NaTType: if isinstance(result, np.ndarray): # we need to apply the mask result = result.astype("i8").view(orig_values.dtype) @@ -617,9 +612,9 @@ def _mask_datetimelike_result( def nanmean( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> float: """ Compute the mean of the element along an axis ignoring NaNs @@ -756,7 +751,7 @@ def get_median(x): def get_empty_reduction_result( - shape: Tuple[int, ...], axis: int, dtype: np.dtype, fill_value: Any + shape: tuple[int, ...], axis: int, dtype: np.dtype, fill_value: Any ) -> np.ndarray: """ The result from a reduction on an empty ndarray. @@ -781,11 +776,11 @@ def get_empty_reduction_result( def _get_counts_nanvar( values_shape: Shape, - mask: Optional[np.ndarray], - axis: Optional[int], + mask: np.ndarray | None, + axis: int | None, ddof: int, dtype: Dtype = float, -) -> Tuple[Union[int, np.ndarray], Union[int, np.ndarray]]: +) -> tuple[int | np.ndarray, int | np.ndarray]: """ Get the count of non-null values along an axis, accounting for degrees of freedom. @@ -944,10 +939,10 @@ def nanvar(values, *, axis=None, skipna=True, ddof=1, mask=None): def nansem( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, ddof: int = 1, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> float: """ Compute the standard error in the mean along given axis while ignoring NaNs @@ -996,9 +991,9 @@ def _nanminmax(meth, fill_value_typ): def reduction( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> Dtype: values, mask, dtype, dtype_max, fill_value = _get_values( @@ -1028,10 +1023,10 @@ def reduction( def nanargmax( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, -) -> Union[int, np.ndarray]: + mask: np.ndarray | None = None, +) -> int | np.ndarray: """ Parameters ---------- @@ -1074,10 +1069,10 @@ def nanargmax( def nanargmin( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, -) -> Union[int, np.ndarray]: + mask: np.ndarray | None = None, +) -> int | np.ndarray: """ Parameters ---------- @@ -1120,9 +1115,9 @@ def nanargmin( def nanskew( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> float: """ Compute the sample skewness. @@ -1207,9 +1202,9 @@ def nanskew( def nankurt( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> float: """ Compute the sample excess kurtosis @@ -1303,10 +1298,10 @@ def nankurt( def nanprod( values: np.ndarray, *, - axis: Optional[int] = None, + axis: int | None = None, skipna: bool = True, min_count: int = 0, - mask: Optional[np.ndarray] = None, + mask: np.ndarray | None = None, ) -> float: """ Parameters @@ -1346,8 +1341,8 @@ def nanprod( def _maybe_arg_null_out( - result: np.ndarray, axis: Optional[int], mask: Optional[np.ndarray], skipna: bool -) -> Union[np.ndarray, int]: + result: np.ndarray, axis: int | None, mask: np.ndarray | None, skipna: bool +) -> np.ndarray | int: # helper function for nanargmin/nanargmax if mask is None: return result @@ -1374,11 +1369,11 @@ def _maybe_arg_null_out( def _get_counts( - values_shape: Tuple[int, ...], - mask: Optional[np.ndarray], - axis: Optional[int], + values_shape: tuple[int, ...], + mask: np.ndarray | None, + axis: int | None, dtype: Dtype = float, -) -> Union[int, float, np.ndarray]: +) -> int | float | np.ndarray: """ Get the count of non-null values along an axis @@ -1434,9 +1429,9 @@ def _get_counts( def _maybe_null_out( result: np.ndarray | float | NaTType, - axis: Optional[int], - mask: Optional[np.ndarray], - shape: Tuple[int, ...], + axis: int | None, + mask: np.ndarray | None, + shape: tuple[int, ...], min_count: int = 1, ) -> np.ndarray | float | NaTType: """ @@ -1465,7 +1460,7 @@ def _maybe_null_out( def check_below_min_count( - shape: Tuple[int, ...], mask: Optional[np.ndarray], min_count: int + shape: tuple[int, ...], mask: np.ndarray | None, min_count: int ) -> bool: """ Check for the `min_count` keyword. Returns True if below `min_count` (when @@ -1506,7 +1501,7 @@ def _zero_out_fperr(arg): @disallow("M8", "m8") def nancorr( - a: np.ndarray, b: np.ndarray, *, method="pearson", min_periods: Optional[int] = None + a: np.ndarray, b: np.ndarray, *, method="pearson", min_periods: int | None = None ): """ a, b: ndarrays @@ -1564,8 +1559,8 @@ def nancov( a: np.ndarray, b: np.ndarray, *, - min_periods: Optional[int] = None, - ddof: Optional[int] = 1, + min_periods: int | None = None, + ddof: int | None = 1, ): if len(a) != len(b): raise AssertionError("Operands to nancov must have same size") @@ -1645,7 +1640,7 @@ def f(x, y): def _nanpercentile_1d( values: np.ndarray, mask: np.ndarray, q: np.ndarray, na_value: Scalar, interpolation -) -> Union[Scalar, np.ndarray]: +) -> Scalar | np.ndarray: """ Wrapper for np.percentile that skips missing values, specialized to 1-dimensional case. diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 70c9d2bc1e4e5..c7d71d4531d11 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -5,10 +5,6 @@ from textwrap import dedent from typing import ( Callable, - Dict, - Optional, - Tuple, - Union, no_type_check, ) @@ -86,7 +82,7 @@ Tick, ) -_shared_docs_kwargs: Dict[str, str] = {} +_shared_docs_kwargs: dict[str, str] = {} class Resampler(BaseGroupBy, ShallowMixin): @@ -274,7 +270,7 @@ def _assure_grouper(self): @Appender(_pipe_template) def pipe( self, - func: Union[Callable[..., T], Tuple[Callable[..., T], str]], + func: Callable[..., T] | tuple[Callable[..., T], str], *args, **kwargs, ) -> T: @@ -1393,18 +1389,18 @@ class TimeGrouper(Grouper): def __init__( self, freq="Min", - closed: Optional[str] = None, - label: Optional[str] = None, + closed: str | None = None, + label: str | None = None, how="mean", axis=0, fill_method=None, limit=None, loffset=None, - kind: Optional[str] = None, - convention: Optional[str] = None, - base: Optional[int] = None, - origin: Union[str, TimestampConvertibleTypes] = "start_day", - offset: Optional[TimedeltaConvertibleTypes] = None, + kind: str | None = None, + convention: str | None = None, + base: int | None = None, + origin: str | TimestampConvertibleTypes = "start_day", + offset: TimedeltaConvertibleTypes | None = None, **kwargs, ): # Check for correctness of the keyword arguments which would @@ -1883,7 +1879,7 @@ def _get_period_range_edges( def _insert_nat_bin( binner: PeriodIndex, bins: np.ndarray, labels: PeriodIndex, nat_count: int -) -> Tuple[PeriodIndex, np.ndarray, PeriodIndex]: +) -> tuple[PeriodIndex, np.ndarray, PeriodIndex]: # NaT handling as in pandas._lib.lib.generate_bins_dt64() # shift bins by the number of NaT assert nat_count > 0 diff --git a/pandas/core/series.py b/pandas/core/series.py index 4ade9992e9e3e..36623695d7569 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -13,11 +13,7 @@ Callable, Hashable, Iterable, - List, - Optional, Sequence, - Tuple, - Type, Union, cast, overload, @@ -260,7 +256,7 @@ class Series(base.IndexOpsMixin, generic.NDFrame): _HANDLED_TYPES = (Index, ExtensionArray, np.ndarray) _name: Hashable - _metadata: List[str] = ["name"] + _metadata: list[str] = ["name"] _internal_names_set = {"index"} | generic.NDFrame._internal_names_set _accessors = {"dt", "cat", "str", "sparse"} _hidden_attrs = ( @@ -287,7 +283,7 @@ def __init__( self, data=None, index=None, - dtype: Optional[Dtype] = None, + dtype: Dtype | None = None, name=None, copy: bool = False, fastpath: bool = False, @@ -421,7 +417,7 @@ def __init__( self.name = name self._set_axis(0, index, fastpath=True) - def _init_dict(self, data, index=None, dtype: Optional[Dtype] = None): + def _init_dict(self, data, index=None, dtype: Dtype | None = None): """ Derive the "_mgr" and "index" attributes of a new Series from a dictionary input. @@ -478,11 +474,11 @@ def _init_dict(self, data, index=None, dtype: Optional[Dtype] = None): # ---------------------------------------------------------------------- @property - def _constructor(self) -> Type[Series]: + def _constructor(self) -> type[Series]: return Series @property - def _constructor_expanddim(self) -> Type[DataFrame]: + def _constructor_expanddim(self) -> type[DataFrame]: """ Used when a manipulation result has one higher dimension as the original, such as Series.to_frame() @@ -496,7 +492,7 @@ def _constructor_expanddim(self) -> Type[DataFrame]: def _can_hold_na(self) -> bool: return self._mgr._can_hold_na - _index: Optional[Index] = None + _index: Index | None = None def _set_axis(self, axis: int, labels, fastpath: bool = False) -> None: """ @@ -706,7 +702,7 @@ def __len__(self) -> int: """ return len(self._mgr) - def view(self, dtype: Optional[Dtype] = None) -> Series: + def view(self, dtype: Dtype | None = None) -> Series: """ Create a new view of the Series. @@ -780,7 +776,7 @@ def view(self, dtype: Optional[Dtype] = None) -> Series: # NDArray Compat _HANDLED_TYPES = (Index, ExtensionArray, np.ndarray) - def __array__(self, dtype: Optional[NpDtype] = None) -> np.ndarray: + def __array__(self, dtype: NpDtype | None = None) -> np.ndarray: """ Return the values as a NumPy array. @@ -841,7 +837,7 @@ def __array__(self, dtype: Optional[NpDtype] = None) -> np.ndarray: # indexers @property - def axes(self) -> List[Index]: + def axes(self) -> list[Index]: """ Return a list of the row axis labels. """ @@ -1473,12 +1469,12 @@ def to_string( ) def to_markdown( self, - buf: Optional[IO[str]] = None, + buf: IO[str] | None = None, mode: str = "wt", index: bool = True, storage_options: StorageOptions = None, **kwargs, - ) -> Optional[str]: + ) -> str | None: """ Print {klass} in Markdown-friendly format. @@ -1543,7 +1539,7 @@ def to_markdown( # ---------------------------------------------------------------------- - def items(self) -> Iterable[Tuple[Hashable, Any]]: + def items(self) -> Iterable[tuple[Hashable, Any]]: """ Lazily iterate over (index, value) tuples. @@ -1573,7 +1569,7 @@ def items(self) -> Iterable[Tuple[Hashable, Any]]: return zip(iter(self.index), iter(self)) @Appender(items.__doc__) - def iteritems(self) -> Iterable[Tuple[Hashable, Any]]: + def iteritems(self) -> Iterable[tuple[Hashable, Any]]: return self.items() # ---------------------------------------------------------------------- @@ -1937,7 +1933,7 @@ def unique(self) -> ArrayLike: """ return super().unique() - def drop_duplicates(self, keep="first", inplace=False) -> Optional[Series]: + def drop_duplicates(self, keep="first", inplace=False) -> Series | None: """ Return Series with duplicate values removed. @@ -2400,8 +2396,8 @@ def corr(self, other, method="pearson", min_periods=None) -> float: def cov( self, other: Series, - min_periods: Optional[int] = None, - ddof: Optional[int] = 1, + min_periods: int | None = None, + ddof: int | None = 1, ) -> float: """ Compute covariance with Series, excluding missing values. @@ -2794,8 +2790,8 @@ def _binop(self, other, func, level=None, fill_value=None): return this._construct_result(result, name) def _construct_result( - self, result: Union[ArrayLike, Tuple[ArrayLike, ArrayLike]], name: Hashable - ) -> Union[Series, Tuple[Series, Series]]: + self, result: ArrayLike | tuple[ArrayLike, ArrayLike], name: Hashable + ) -> Series | tuple[Series, Series]: """ Construct an appropriately-labelled Series from the result of an op. @@ -3149,7 +3145,7 @@ def update(self, other) -> None: def sort_values( self, axis=0, - ascending: Union[Union[bool, int], Sequence[Union[bool, int]]] = True, + ascending: bool | int | Sequence[bool | int] = True, inplace: bool = False, kind: str = "quicksort", na_position: str = "last", @@ -3360,7 +3356,7 @@ def sort_index( self, axis=0, level=None, - ascending: Union[Union[bool, int], Sequence[Union[bool, int]]] = True, + ascending: bool | int | Sequence[bool | int] = True, inplace: bool = False, kind: str = "quicksort", na_position: str = "last", @@ -4077,7 +4073,7 @@ def apply( self, func: AggFuncType, convert_dtype: bool = True, - args: Tuple[Any, ...] = (), + args: tuple[Any, ...] = (), **kwargs, ) -> FrameOrSeriesUnion: """ @@ -4359,9 +4355,7 @@ def set_axis(self, labels, *, inplace: Literal[True]) -> None: ... @overload - def set_axis( - self, labels, axis: Axis = ..., inplace: bool = ... - ) -> Optional[Series]: + def set_axis(self, labels, axis: Axis = ..., inplace: bool = ...) -> Series | None: ... @Appender( @@ -4517,7 +4511,7 @@ def fillna( inplace=False, limit=None, downcast=None, - ) -> Optional[Series]: + ) -> Series | None: return super().fillna( value=value, method=method, @@ -4950,7 +4944,7 @@ def asfreq( self, freq, method=None, - how: Optional[str] = None, + how: str | None = None, normalize: bool = False, fill_value=None, ) -> Series: @@ -4967,16 +4961,16 @@ def resample( self, rule, axis=0, - closed: Optional[str] = None, - label: Optional[str] = None, + closed: str | None = None, + label: str | None = None, convention: str = "start", - kind: Optional[str] = None, + kind: str | None = None, loffset=None, - base: Optional[int] = None, + base: int | None = None, on=None, level=None, - origin: Union[str, TimestampConvertibleTypes] = "start_day", - offset: Optional[TimedeltaConvertibleTypes] = None, + origin: str | TimestampConvertibleTypes = "start_day", + offset: TimedeltaConvertibleTypes | None = None, ) -> Resampler: return super().resample( rule=rule, diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 816c1d9195778..9de2563863b41 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -6,13 +6,8 @@ TYPE_CHECKING, Callable, DefaultDict, - Dict, Iterable, - List, - Optional, Sequence, - Tuple, - Union, ) import numpy as np @@ -44,13 +39,13 @@ def get_indexer_indexer( target: Index, - level: Union[str, int, List[str], List[int]], - ascending: Union[Sequence[Union[bool, int]], Union[bool, int]], + level: str | int | list[str] | list[int], + ascending: Sequence[bool | int] | bool | int, kind: str, na_position: str, sort_remaining: bool, key: IndexKeyFunc, -) -> Optional[np.ndarray]: +) -> np.ndarray | None: """ Helper method that return the indexer according to input parameters for the sort_index method of DataFrame and Series. @@ -269,7 +264,7 @@ def indexer_from_factorized(labels, shape, compress: bool = True): def lexsort_indexer( - keys, orders=None, na_position: str = "last", key: Optional[Callable] = None + keys, orders=None, na_position: str = "last", key: Callable | None = None ): """ Performs lexical sorting on a set of keys @@ -336,8 +331,8 @@ def nargsort( kind: str = "quicksort", ascending: bool = True, na_position: str = "last", - key: Optional[Callable] = None, - mask: Optional[np.ndarray] = None, + key: Callable | None = None, + mask: np.ndarray | None = None, ): """ Intended to be a drop-in replacement for np.argsort which handles NaNs. @@ -491,7 +486,7 @@ def _ensure_key_mapped_multiindex( return type(index).from_arrays(mapped) -def ensure_key_mapped(values, key: Optional[Callable], levels=None): +def ensure_key_mapped(values, key: Callable | None, levels=None): """ Applies a callable key function to the values function and checks that the resulting value has the same shape. Can be called on Index @@ -540,10 +535,10 @@ def get_flattened_list( ngroups: int, levels: Iterable[Index], labels: Iterable[np.ndarray], -) -> List[Tuple]: +) -> list[tuple]: """Map compressed group id -> key tuple.""" comp_ids = comp_ids.astype(np.int64, copy=False) - arrays: DefaultDict[int, List[int]] = defaultdict(list) + arrays: DefaultDict[int, list[int]] = defaultdict(list) for labs, level in zip(labels, levels): table = hashtable.Int64HashTable(ngroups) table.map(comp_ids, labs.astype(np.int64, copy=False)) @@ -553,8 +548,8 @@ def get_flattened_list( def get_indexer_dict( - label_list: List[np.ndarray], keys: List[Index] -) -> Dict[Union[str, Tuple], np.ndarray]: + label_list: list[np.ndarray], keys: list[Index] +) -> dict[str | tuple, np.ndarray]: """ Returns -------