diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6514d43209c77..af93c7f6c76b9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -140,7 +140,7 @@ repos: pass_filenames: false types: [python] stages: [manual] - - id: mypy + - id: stubtest # note: assumes python env is setup and activated # note: requires pandas dev to be installed name: mypy (stubtest) diff --git a/pandas/_libs/arrays.pyi b/pandas/_libs/arrays.pyi index dda23d9dec98b..60e4ff3fab74e 100644 --- a/pandas/_libs/arrays.pyi +++ b/pandas/_libs/arrays.pyi @@ -1,4 +1,4 @@ -from typing import Sequence +from collections.abc import Sequence import numpy as np diff --git a/pandas/_libs/hashtable.pyi b/pandas/_libs/hashtable.pyi index 7a810a988e50e..5ee359d84a6ed 100644 --- a/pandas/_libs/hashtable.pyi +++ b/pandas/_libs/hashtable.pyi @@ -1,6 +1,6 @@ +from collections.abc import Hashable from typing import ( Any, - Hashable, Literal, overload, ) diff --git a/pandas/_libs/internals.pyi b/pandas/_libs/internals.pyi index ffe6c7730bcdc..a680304d55ea2 100644 --- a/pandas/_libs/internals.pyi +++ b/pandas/_libs/internals.pyi @@ -1,6 +1,8 @@ -from typing import ( +from collections.abc import ( Iterator, Sequence, +) +from typing import ( final, overload, ) diff --git a/pandas/_libs/json.pyi b/pandas/_libs/json.pyi index bc4fe68573b94..349320d69d707 100644 --- a/pandas/_libs/json.pyi +++ b/pandas/_libs/json.pyi @@ -1,6 +1,6 @@ +from collections.abc import Callable from typing import ( Any, - Callable, ) def ujson_dumps( diff --git a/pandas/_libs/lib.pyi b/pandas/_libs/lib.pyi index daaaacee3487d..331233f37f63d 100644 --- a/pandas/_libs/lib.pyi +++ b/pandas/_libs/lib.pyi @@ -1,12 +1,14 @@ # TODO(npdtypes): Many types specified here can be made more specific/accurate; # the more specific versions are specified in comments +from collections.abc import ( + Callable, + Generator, + Hashable, +) from decimal import Decimal from typing import ( Any, - Callable, Final, - Generator, - Hashable, Literal, TypeAlias, overload, diff --git a/pandas/_libs/ops.pyi b/pandas/_libs/ops.pyi index 6738a1dff4a9e..81fe81930539d 100644 --- a/pandas/_libs/ops.pyi +++ b/pandas/_libs/ops.pyi @@ -1,7 +1,9 @@ -from typing import ( - Any, +from collections.abc import ( Callable, Iterable, +) +from typing import ( + Any, Literal, TypeAlias, overload, diff --git a/pandas/_libs/parsers.pyi b/pandas/_libs/parsers.pyi index 253bb7303cefb..d18f54c546232 100644 --- a/pandas/_libs/parsers.pyi +++ b/pandas/_libs/parsers.pyi @@ -1,5 +1,5 @@ +from collections.abc import Hashable from typing import ( - Hashable, Literal, ) diff --git a/pandas/_libs/properties.pyi b/pandas/_libs/properties.pyi index aaa44a0cf47bf..bbde6ec454202 100644 --- a/pandas/_libs/properties.pyi +++ b/pandas/_libs/properties.pyi @@ -1,5 +1,5 @@ +from collections.abc import Sequence from typing import ( - Sequence, overload, ) diff --git a/pandas/_libs/sparse.pyi b/pandas/_libs/sparse.pyi index 536265b25425e..8727b1a5b0420 100644 --- a/pandas/_libs/sparse.pyi +++ b/pandas/_libs/sparse.pyi @@ -1,4 +1,4 @@ -from typing import Sequence +from collections.abc import Sequence import numpy as np diff --git a/pandas/_libs/testing.pyi b/pandas/_libs/testing.pyi index ab87e58eba9b9..4758483b3b5e7 100644 --- a/pandas/_libs/testing.pyi +++ b/pandas/_libs/testing.pyi @@ -1,4 +1,4 @@ -from typing import Mapping +from collections.abc import Mapping def assert_dict_equal(a: Mapping, b: Mapping, compare_keys: bool = ...) -> bool: ... def assert_almost_equal( diff --git a/pandas/_libs/tslibs/nattype.pyi b/pandas/_libs/tslibs/nattype.pyi index d3b10fbe79cb9..ff3bb5b70801e 100644 --- a/pandas/_libs/tslibs/nattype.pyi +++ b/pandas/_libs/tslibs/nattype.pyi @@ -1,7 +1,5 @@ from datetime import ( - date as date_, datetime, - time as time_, timedelta, tzinfo as _tzinfo, ) @@ -99,7 +97,6 @@ class NaTType: ambiguous: bool | Literal["raise"] | NaTType = ..., nonexistent: TimestampNonexistent = ..., ) -> NaTType: ... - def combine(cls, date: date_, time: time_) -> NoReturn: ... @property def tzinfo(self) -> None: ... @property diff --git a/pandas/_libs/tslibs/offsets.pyi b/pandas/_libs/tslibs/offsets.pyi index f9f56d38c5e0a..ad579a5e41522 100644 --- a/pandas/_libs/tslibs/offsets.pyi +++ b/pandas/_libs/tslibs/offsets.pyi @@ -1,3 +1,4 @@ +from collections.abc import Collection from datetime import ( datetime, time, @@ -5,7 +6,6 @@ from datetime import ( ) from typing import ( Any, - Collection, Literal, TypeVar, overload, diff --git a/pandas/_libs/tslibs/timezones.pyi b/pandas/_libs/tslibs/timezones.pyi index 4e9f0c6ae6c33..26ffa568a8480 100644 --- a/pandas/_libs/tslibs/timezones.pyi +++ b/pandas/_libs/tslibs/timezones.pyi @@ -1,8 +1,8 @@ +from collections.abc import Callable from datetime import ( datetime, tzinfo, ) -from typing import Callable import numpy as np diff --git a/pandas/_libs/tslibs/tzconversion.pyi b/pandas/_libs/tslibs/tzconversion.pyi index 2108fa0f35547..07ee46858577a 100644 --- a/pandas/_libs/tslibs/tzconversion.pyi +++ b/pandas/_libs/tslibs/tzconversion.pyi @@ -1,8 +1,8 @@ +from collections.abc import Iterable from datetime import ( timedelta, tzinfo, ) -from typing import Iterable import numpy as np diff --git a/pandas/_libs/window/aggregations.pyi b/pandas/_libs/window/aggregations.pyi index b4bdd7e05cf0e..99413751cd5c2 100644 --- a/pandas/_libs/window/aggregations.pyi +++ b/pandas/_libs/window/aggregations.pyi @@ -1,6 +1,6 @@ +from collections.abc import Callable from typing import ( Any, - Callable, Literal, ) diff --git a/pandas/_libs/window/aggregations.pyx b/pandas/_libs/window/aggregations.pyx index 04b3f8ab461fa..0c8ea28b60ce8 100644 --- a/pandas/_libs/window/aggregations.pyx +++ b/pandas/_libs/window/aggregations.pyx @@ -1354,8 +1354,8 @@ def roll_quantile(const float64_t[:] values, ndarray[int64_t] start, if interpolation_type == LINEAR: vlow = skiplist_get(skiplist, idx, &ret) vhigh = skiplist_get(skiplist, idx + 1, &ret) - output[i] = ((vlow + (vhigh - vlow) * - (idx_with_fraction - idx))) + output[i] = (vlow + (vhigh - vlow) * + (idx_with_fraction - idx)) elif interpolation_type == LOWER: output[i] = skiplist_get(skiplist, idx, &ret) elif interpolation_type == HIGHER: diff --git a/pandas/_testing/contexts.py b/pandas/_testing/contexts.py index 99826de51e1bf..da147c117ad43 100644 --- a/pandas/_testing/contexts.py +++ b/pandas/_testing/contexts.py @@ -3,6 +3,7 @@ from contextlib import contextmanager import os from pathlib import Path +import sys import tempfile from typing import ( IO, @@ -81,7 +82,9 @@ def setTZ(tz) -> None: pass else: os.environ["TZ"] = tz - time.tzset() + # Next line allows typing checks to pass on Windows + if sys.platform != "win32": + time.tzset() orig_tz = os.environ.get("TZ") setTZ(tz) diff --git a/pandas/_typing.py b/pandas/_typing.py index 4365ee85f72e3..889252bb00438 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -1,5 +1,6 @@ from __future__ import annotations +from builtins import type as type_t # pyright: ignore[reportUnusedImport] from collections.abc import ( Callable, Hashable, @@ -20,22 +21,23 @@ TYPE_CHECKING, Any, Literal, - Optional, Protocol, - Type as type_t, + TypeAlias, TypeVar, Union, overload, ) import numpy as np +import numpy.typing as npt # To prevent import cycles place any internal imports in the branch below # and use a string literal forward reference to it in subsequent types # https://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles -if TYPE_CHECKING: - import numpy.typing as npt +# Note that Union is needed when a Union includes a pandas type + +if TYPE_CHECKING: from pandas._libs import ( NaTType, Period, @@ -76,19 +78,12 @@ from pandas.io.formats.format import EngFormatter from pandas.tseries.holiday import AbstractHolidayCalendar - ScalarLike_co = Union[ - int, - float, - complex, - str, - bytes, - np.generic, - ] + ScalarLike_co: TypeAlias = int | float | complex | str | bytes | np.generic # numpy compatible types - NumpyValueArrayLike = Union[ScalarLike_co, npt.ArrayLike] + NumpyValueArrayLike: TypeAlias = ScalarLike_co | npt.ArrayLike # Name "npt._ArrayLikeInt_co" is not defined [name-defined] - NumpySorter = Optional[npt._ArrayLikeInt_co] # type: ignore[name-defined] + NumpySorter: TypeAlias = npt._ArrayLikeInt_co | None # type: ignore[name-defined] from typing import ( ParamSpec, @@ -107,7 +102,6 @@ from typing_extensions import Unpack # pyright: ignore[reportUnusedImport] else: - npt: Any = None ParamSpec: Any = None Self: Any = None TypeGuard: Any = None @@ -120,10 +114,10 @@ # array-like -ArrayLike = Union["ExtensionArray", np.ndarray] +ArrayLike: TypeAlias = Union["ExtensionArray", np.ndarray] ArrayLikeT = TypeVar("ArrayLikeT", "ExtensionArray", np.ndarray) -AnyArrayLike = Union[ArrayLike, "Index", "Series"] -TimeArrayLike = Union["DatetimeArray", "TimedeltaArray"] +AnyArrayLike: TypeAlias = Union[ArrayLike, "Index", "Series"] +TimeArrayLike: TypeAlias = Union["DatetimeArray", "TimedeltaArray"] # list-like @@ -152,31 +146,31 @@ def count(self, value: Any, /) -> int: ... def __reversed__(self) -> Iterator[_T_co]: ... -ListLike = Union[AnyArrayLike, SequenceNotStr, range] +ListLike: TypeAlias = AnyArrayLike | SequenceNotStr | range # scalars -PythonScalar = Union[str, float, bool] -DatetimeLikeScalar = Union["Period", "Timestamp", "Timedelta"] -PandasScalar = Union["Period", "Timestamp", "Timedelta", "Interval"] -Scalar = Union[PythonScalar, PandasScalar, np.datetime64, np.timedelta64, date] -IntStrT = TypeVar("IntStrT", bound=Union[int, str]) - +PythonScalar: TypeAlias = str | float | bool +DatetimeLikeScalar: TypeAlias = Union["Period", "Timestamp", "Timedelta"] +PandasScalar: TypeAlias = Union["Period", "Timestamp", "Timedelta", "Interval"] +Scalar: TypeAlias = PythonScalar | PandasScalar | np.datetime64 | np.timedelta64 | date +IntStrT = TypeVar("IntStrT", bound=int | str) # timestamp and timedelta convertible types -TimestampConvertibleTypes = Union[ +TimestampConvertibleTypes: TypeAlias = Union[ "Timestamp", date, np.datetime64, np.int64, float, str ] -TimestampNonexistent = Union[ - Literal["shift_forward", "shift_backward", "NaT", "raise"], timedelta -] -TimedeltaConvertibleTypes = Union[ +TimestampNonexistent: TypeAlias = ( + Literal["shift_forward", "shift_backward", "NaT", "raise"] | timedelta +) + +TimedeltaConvertibleTypes: TypeAlias = Union[ "Timedelta", timedelta, np.timedelta64, np.int64, float, str ] -Timezone = Union[str, tzinfo] +Timezone: TypeAlias = str | tzinfo -ToTimestampHow = Literal["s", "e", "start", "end"] +ToTimestampHow: TypeAlias = Literal["s", "e", "start", "end"] # NDFrameT is stricter and ensures that the same subclass of NDFrame always is # used. E.g. `def func(a: NDFrameT) -> NDFrameT: ...` means that if a @@ -188,69 +182,66 @@ def __reversed__(self) -> Iterator[_T_co]: ... FreqIndexT = TypeVar("FreqIndexT", "DatetimeIndex", "PeriodIndex", "TimedeltaIndex") NumpyIndexT = TypeVar("NumpyIndexT", np.ndarray, "Index") -AxisInt = int -Axis = Union[AxisInt, Literal["index", "columns", "rows"]] -IndexLabel = Union[Hashable, Sequence[Hashable]] -Level = Hashable -Shape = tuple[int, ...] -Suffixes = Sequence[Optional[str]] -Ordered = Optional[bool] -JSONSerializable = Optional[Union[PythonScalar, list, dict]] -Frequency = Union[str, "BaseOffset"] -Axes = ListLike - -RandomState = Union[ - int, - np.ndarray, - np.random.Generator, - np.random.BitGenerator, - np.random.RandomState, -] +AxisInt: TypeAlias = int +Axis: TypeAlias = AxisInt | Literal["index", "columns", "rows"] +IndexLabel: TypeAlias = Hashable | Sequence[Hashable] +Level: TypeAlias = Hashable +Shape: TypeAlias = tuple[int, ...] +Suffixes: TypeAlias = Sequence[str | None] +Ordered: TypeAlias = bool | None +JSONSerializable: TypeAlias = PythonScalar | list | dict | None +Frequency: TypeAlias = Union[str, "BaseOffset"] +Axes: TypeAlias = ListLike + +RandomState: TypeAlias = ( + int + | np.ndarray + | np.random.Generator + | np.random.BitGenerator + | np.random.RandomState +) + # dtypes -NpDtype = Union[str, np.dtype, type_t[Union[str, complex, bool, object]]] -Dtype = Union["ExtensionDtype", NpDtype] -AstypeArg = Union["ExtensionDtype", "npt.DTypeLike"] +NpDtype: TypeAlias = str | np.dtype | type[str | complex | bool | object] +Dtype: TypeAlias = Union["ExtensionDtype", NpDtype] +AstypeArg: TypeAlias = Union["ExtensionDtype", npt.DTypeLike] # DtypeArg specifies all allowable dtypes in a functions its dtype argument -DtypeArg = Union[Dtype, Mapping[Hashable, Dtype]] -DtypeObj = Union[np.dtype, "ExtensionDtype"] +DtypeArg: TypeAlias = Dtype | Mapping[Hashable, Dtype] +DtypeObj: TypeAlias = Union[np.dtype, "ExtensionDtype"] # converters -ConvertersArg = dict[Hashable, Callable[[Dtype], Dtype]] +ConvertersArg: TypeAlias = dict[Hashable, Callable[[Dtype], Dtype]] # parse_dates -ParseDatesArg = Union[ - bool, list[Hashable], list[list[Hashable]], dict[Hashable, list[Hashable]] -] +ParseDatesArg: TypeAlias = ( + bool | list[Hashable] | list[list[Hashable]] | dict[Hashable, list[Hashable]] +) # For functions like rename that convert one label to another -Renamer = Union[Mapping[Any, Hashable], Callable[[Any], Hashable]] +Renamer: TypeAlias = Mapping[Any, Hashable] | Callable[[Any], Hashable] # to maintain type information across generic functions and parametrization T = TypeVar("T") # used in decorators to preserve the signature of the function it decorates # see https://mypy.readthedocs.io/en/stable/generics.html#declaring-decorators -FuncType = Callable[..., Any] +FuncType: TypeAlias = Callable[..., Any] F = TypeVar("F", bound=FuncType) TypeT = TypeVar("TypeT", bound=type) # types of vectorized key functions for DataFrame::sort_values and # DataFrame::sort_index, among others -ValueKeyFunc = Optional[Callable[["Series"], Union["Series", AnyArrayLike]]] -IndexKeyFunc = Optional[Callable[["Index"], Union["Index", AnyArrayLike]]] +ValueKeyFunc: TypeAlias = Callable[["Series"], Union["Series", AnyArrayLike]] | None +IndexKeyFunc: TypeAlias = Callable[["Index"], Union["Index", AnyArrayLike]] | None # types of `func` kwarg for DataFrame.aggregate and Series.aggregate -AggFuncTypeBase = Union[Callable, str] -AggFuncTypeDict = MutableMapping[ - Hashable, Union[AggFuncTypeBase, list[AggFuncTypeBase]] +AggFuncTypeBase: TypeAlias = Callable | str +AggFuncTypeDict: TypeAlias = MutableMapping[ + Hashable, AggFuncTypeBase | list[AggFuncTypeBase] ] -AggFuncType = Union[ - AggFuncTypeBase, - list[AggFuncTypeBase], - AggFuncTypeDict, -] -AggObjType = Union[ +AggFuncType: TypeAlias = AggFuncTypeBase | list[AggFuncTypeBase] | AggFuncTypeDict +AggObjType: TypeAlias = Union[ "Series", "DataFrame", "GroupBy", @@ -260,7 +251,7 @@ def __reversed__(self) -> Iterator[_T_co]: ... "Resampler", ] -PythonFuncType = Callable[[Any], Any] +PythonFuncType: TypeAlias = Callable[[Any], Any] # filenames and file-like-objects AnyStr_co = TypeVar("AnyStr_co", str, bytes, covariant=True) @@ -330,31 +321,30 @@ def closed(self) -> bool: ... -FilePath = Union[str, "PathLike[str]"] +FilePath: TypeAlias = str | PathLike[str] # for arbitrary kwargs passed during reading/writing files -StorageOptions = Optional[dict[str, Any]] - +StorageOptions: TypeAlias = dict[str, Any] | None # compression keywords and compression -CompressionDict = dict[str, Any] -CompressionOptions = Optional[ - Union[Literal["infer", "gzip", "bz2", "zip", "xz", "zstd", "tar"], CompressionDict] -] +CompressionDict: TypeAlias = dict[str, Any] +CompressionOptions: TypeAlias = ( + Literal["infer", "gzip", "bz2", "zip", "xz", "zstd", "tar"] | CompressionDict | None +) # types in DataFrameFormatter -FormattersType = Union[ - list[Callable], tuple[Callable, ...], Mapping[Union[str, int], Callable] -] -ColspaceType = Mapping[Hashable, Union[str, int]] -FloatFormatType = Union[str, Callable, "EngFormatter"] -ColspaceArgType = Union[ - str, int, Sequence[Union[str, int]], Mapping[Hashable, Union[str, int]] -] +FormattersType: TypeAlias = ( + list[Callable] | tuple[Callable, ...] | Mapping[str | int, Callable] +) +ColspaceType: TypeAlias = Mapping[Hashable, str | int] +FloatFormatType: TypeAlias = Union[str, Callable, "EngFormatter"] +ColspaceArgType: TypeAlias = ( + str | int | Sequence[str | int] | Mapping[Hashable, str | int] +) # Arguments for fillna() -FillnaOptions = Literal["backfill", "bfill", "ffill", "pad"] -InterpolateOptions = Literal[ +FillnaOptions: TypeAlias = Literal["backfill", "bfill", "ffill", "pad"] +InterpolateOptions: TypeAlias = Literal[ "linear", "time", "index", @@ -376,7 +366,7 @@ def closed(self) -> bool: ] # internals -Manager = Union["BlockManager", "SingleBlockManager"] +Manager: TypeAlias = Union["BlockManager", "SingleBlockManager"] # indexing # PositionalIndexer -> valid 1D positional indexer, e.g. can pass @@ -389,63 +379,62 @@ def closed(self) -> bool: # https://github.com/python/typing/issues/684#issuecomment-548203158 # https://bugs.python.org/issue41810 # Using List[int] here rather than Sequence[int] to disallow tuples. -ScalarIndexer = Union[int, np.integer] -SequenceIndexer = Union[slice, list[int], np.ndarray] -PositionalIndexer = Union[ScalarIndexer, SequenceIndexer] -PositionalIndexerTuple = tuple[PositionalIndexer, PositionalIndexer] -PositionalIndexer2D = Union[PositionalIndexer, PositionalIndexerTuple] -if TYPE_CHECKING: - TakeIndexer = Union[Sequence[int], Sequence[np.integer], npt.NDArray[np.integer]] -else: - TakeIndexer = Any +ScalarIndexer: TypeAlias = int | np.integer +SequenceIndexer: TypeAlias = slice | list[int] | np.ndarray +PositionalIndexer: TypeAlias = ScalarIndexer | SequenceIndexer +PositionalIndexerTuple: TypeAlias = tuple[PositionalIndexer, PositionalIndexer] +PositionalIndexer2D: TypeAlias = PositionalIndexer | PositionalIndexerTuple +TakeIndexer: TypeAlias = Sequence[int] | Sequence[np.integer] | npt.NDArray[np.integer] # Shared by functions such as drop and astype -IgnoreRaise = Literal["ignore", "raise"] +IgnoreRaise: TypeAlias = Literal["ignore", "raise"] # Windowing rank methods -WindowingRankType = Literal["average", "min", "max"] +WindowingRankType: TypeAlias = Literal["average", "min", "max"] # read_csv engines -CSVEngine = Literal["c", "python", "pyarrow", "python-fwf"] +CSVEngine: TypeAlias = Literal["c", "python", "pyarrow", "python-fwf"] # read_json engines -JSONEngine = Literal["ujson", "pyarrow"] +JSONEngine: TypeAlias = Literal["ujson", "pyarrow"] # read_xml parsers -XMLParsers = Literal["lxml", "etree"] +XMLParsers: TypeAlias = Literal["lxml", "etree"] # read_html flavors -HTMLFlavors = Literal["lxml", "html5lib", "bs4"] +HTMLFlavors: TypeAlias = Literal["lxml", "html5lib", "bs4"] # Interval closed type -IntervalLeftRight = Literal["left", "right"] -IntervalClosedType = Union[IntervalLeftRight, Literal["both", "neither"]] +IntervalLeftRight: TypeAlias = Literal["left", "right"] +IntervalClosedType: TypeAlias = IntervalLeftRight | Literal["both", "neither"] # datetime and NaTType -DatetimeNaTType = Union[datetime, "NaTType"] -DateTimeErrorChoices = Literal["raise", "coerce"] +DatetimeNaTType: TypeAlias = Union[datetime, "NaTType"] +DateTimeErrorChoices: TypeAlias = Literal["raise", "coerce"] # sort_index -SortKind = Literal["quicksort", "mergesort", "heapsort", "stable"] -NaPosition = Literal["first", "last"] +SortKind: TypeAlias = Literal["quicksort", "mergesort", "heapsort", "stable"] +NaPosition: TypeAlias = Literal["first", "last"] # Arguments for nsmallest and nlargest -NsmallestNlargestKeep = Literal["first", "last", "all"] +NsmallestNlargestKeep: TypeAlias = Literal["first", "last", "all"] # quantile interpolation -QuantileInterpolation = Literal["linear", "lower", "higher", "midpoint", "nearest"] +QuantileInterpolation: TypeAlias = Literal[ + "linear", "lower", "higher", "midpoint", "nearest" +] # plotting -PlottingOrientation = Literal["horizontal", "vertical"] +PlottingOrientation: TypeAlias = Literal["horizontal", "vertical"] # dropna -AnyAll = Literal["any", "all"] +AnyAll: TypeAlias = Literal["any", "all"] # merge -MergeHow = Literal[ +MergeHow: TypeAlias = Literal[ "left", "right", "inner", "outer", "cross", "left_anti", "right_anti" ] -MergeValidate = Literal[ +MergeValidate: TypeAlias = Literal[ "one_to_one", "1:1", "one_to_many", @@ -457,8 +446,8 @@ def closed(self) -> bool: ] # join -JoinHow = Literal["left", "right", "inner", "outer"] -JoinValidate = Literal[ +JoinHow: TypeAlias = Literal["left", "right", "inner", "outer"] +JoinValidate: TypeAlias = Literal[ "one_to_one", "1:1", "one_to_many", @@ -470,25 +459,28 @@ def closed(self) -> bool: ] # reindex -ReindexMethod = Union[FillnaOptions, Literal["nearest"]] +ReindexMethod: TypeAlias = FillnaOptions | Literal["nearest"] -MatplotlibColor = Union[str, Sequence[float]] -TimeGrouperOrigin = Union[ +MatplotlibColor: TypeAlias = str | Sequence[float] +TimeGrouperOrigin: TypeAlias = Union[ "Timestamp", Literal["epoch", "start", "start_day", "end", "end_day"] ] -TimeAmbiguous = Union[Literal["infer", "NaT", "raise"], "npt.NDArray[np.bool_]"] -TimeNonexistent = Union[ - Literal["shift_forward", "shift_backward", "NaT", "raise"], timedelta -] -DropKeep = Literal["first", "last", False] -CorrelationMethod = Union[ - Literal["pearson", "kendall", "spearman"], Callable[[np.ndarray, np.ndarray], float] -] -AlignJoin = Literal["outer", "inner", "left", "right"] -DtypeBackend = Literal["pyarrow", "numpy_nullable"] +TimeAmbiguous: TypeAlias = Literal["infer", "NaT", "raise"] | npt.NDArray[np.bool_] +TimeNonexistent: TypeAlias = ( + Literal["shift_forward", "shift_backward", "NaT", "raise"] | timedelta +) + +DropKeep: TypeAlias = Literal["first", "last", False] +CorrelationMethod: TypeAlias = ( + Literal["pearson", "kendall", "spearman"] + | Callable[[np.ndarray, np.ndarray], float] +) -TimeUnit = Literal["s", "ms", "us", "ns"] -OpenFileErrors = Literal[ +AlignJoin: TypeAlias = Literal["outer", "inner", "left", "right"] +DtypeBackend: TypeAlias = Literal["pyarrow", "numpy_nullable"] + +TimeUnit: TypeAlias = Literal["s", "ms", "us", "ns"] +OpenFileErrors: TypeAlias = Literal[ "strict", "ignore", "replace", @@ -499,34 +491,32 @@ def closed(self) -> bool: ] # update -UpdateJoin = Literal["left"] +UpdateJoin: TypeAlias = Literal["left"] # applymap -NaAction = Literal["ignore"] +NaAction: TypeAlias = Literal["ignore"] # from_dict -FromDictOrient = Literal["columns", "index", "tight"] +FromDictOrient: TypeAlias = Literal["columns", "index", "tight"] # to_stata -ToStataByteorder = Literal[">", "<", "little", "big"] +ToStataByteorder: TypeAlias = Literal[">", "<", "little", "big"] # ExcelWriter -ExcelWriterIfSheetExists = Literal["error", "new", "replace", "overlay"] -ExcelWriterMergeCells = Union[bool, Literal["columns"]] +ExcelWriterIfSheetExists: TypeAlias = Literal["error", "new", "replace", "overlay"] +ExcelWriterMergeCells: TypeAlias = bool | Literal["columns"] # Offsets -OffsetCalendar = Union[np.busdaycalendar, "AbstractHolidayCalendar"] +OffsetCalendar: TypeAlias = Union[np.busdaycalendar, "AbstractHolidayCalendar"] # read_csv: usecols -UsecolsArgType = Union[ - SequenceNotStr[Hashable], - range, - AnyArrayLike, - Callable[[HashableT], bool], - None, -] +UsecolsArgType: TypeAlias = ( + SequenceNotStr[Hashable] | range | AnyArrayLike | Callable[[HashableT], bool] | None +) # maintain the sub-type of any hashable sequence SequenceT = TypeVar("SequenceT", bound=Sequence[Hashable]) -SliceType = Optional[Hashable] +SliceType: TypeAlias = Hashable | None + +__all__ = ["type_t"] diff --git a/pandas/core/interchange/from_dataframe.py b/pandas/core/interchange/from_dataframe.py index b990eca39b3dd..c2fbef1089d5a 100644 --- a/pandas/core/interchange/from_dataframe.py +++ b/pandas/core/interchange/from_dataframe.py @@ -563,7 +563,6 @@ def set_nulls( if null_kind == ColumnNullType.USE_SENTINEL: null_pos = pd.Series(data) == sentinel_val elif null_kind in (ColumnNullType.USE_BITMASK, ColumnNullType.USE_BYTEMASK): - assert validity, "Expected to have a validity buffer for the mask" valid_buff, valid_dtype = validity null_pos = buffer_to_ndarray( valid_buff, valid_dtype, offset=col.offset, length=col.size() diff --git a/pandas/core/internals/__init__.py b/pandas/core/internals/__init__.py index 202bebde88c2c..d64c7e33657d4 100644 --- a/pandas/core/internals/__init__.py +++ b/pandas/core/internals/__init__.py @@ -6,9 +6,9 @@ ) __all__ = [ - "Block", + "Block", # pyright:ignore[reportUnsupportedDunderAll)] "BlockManager", - "ExtensionBlock", + "ExtensionBlock", # pyright:ignore[reportUnsupportedDunderAll)] "SingleBlockManager", "concatenate_managers", "make_block", diff --git a/scripts/run_stubtest.py b/scripts/run_stubtest.py index df88c61061f12..e87a7d53f4ff3 100644 --- a/scripts/run_stubtest.py +++ b/scripts/run_stubtest.py @@ -85,9 +85,11 @@ ] # create allowlist - with tempfile.NamedTemporaryFile(mode="w+t") as allow: - allow.write("\n".join(_ALLOWLIST)) - allow.flush() + with tempfile.TemporaryDirectory() as td: + allow = os.path.join(td, "test") + with open(allow, "w+t") as allow: + allow.write("\n".join(_ALLOWLIST)) + allow.flush() args = pyi_modules + [ "--ignore-missing-stub",