Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions pandas-stubs/_libs/tslibs/period.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ from pandas import (
Timedelta,
TimedeltaIndex,
)
from pandas.core.series import (
OffsetSeries,
)
from pandas.core.series import OffsetSeries
from typing_extensions import TypeAlias

from pandas._libs.tslibs import NaTType
Expand Down
3 changes: 1 addition & 2 deletions pandas-stubs/core/base.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ from collections.abc import (
)
from typing import (
Any,
ClassVar,
Generic,
Literal,
TypeAlias,
Expand Down Expand Up @@ -71,7 +70,7 @@ class IndexOpsMixin(OpsMixin, Generic[S1, GenericT_co]):
def nbytes(self) -> int: ...
@property
def size(self) -> int: ...
array: ClassVar = ArrayDescriptor() # noqa
array = ArrayDescriptor()
@overload
def to_numpy(
self,
Expand Down
38 changes: 22 additions & 16 deletions pandas-stubs/core/indexes/accessors.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ from datetime import (
tzinfo as _tzinfo,
)
from typing import (
Any,
Generic,
Literal,
TypeVar,
Expand All @@ -13,36 +14,31 @@ from typing import (
)

import numpy as np
from pandas import (
DatetimeIndex,
Index,
PeriodIndex,
Timedelta,
TimedeltaIndex,
Timestamp,
)
from pandas.core.accessor import PandasDelegate
from pandas.core.arrays import (
DatetimeArray,
PeriodArray,
)
from pandas.core.arrays.base import ExtensionArray
from pandas.core.arrays.categorical import Categorical
from pandas.core.arrays.datetimes import DatetimeArray
from pandas.core.arrays.interval import IntervalArray
from pandas.core.arrays.period import PeriodArray
from pandas.core.arrays.timedeltas import TimedeltaArray
from pandas.core.base import (
IndexOpsMixin,
NoNewAttributesMixin,
)
from pandas.core.frame import DataFrame
from pandas.core.series import (
Series,
)
from pandas.core.indexes.base import Index
from pandas.core.indexes.datetimes import DatetimeIndex
from pandas.core.indexes.period import PeriodIndex
from pandas.core.indexes.timedeltas import TimedeltaIndex
from pandas.core.series import Series
from typing_extensions import Never

from pandas._libs.interval import Interval
from pandas._libs.tslibs import BaseOffset
from pandas._libs.tslibs.offsets import DateOffset
from pandas._libs.tslibs.period import Period
from pandas._libs.tslibs.timedeltas import Timedelta
from pandas._libs.tslibs.timestamps import Timestamp
from pandas._typing import (
TimeAmbiguous,
TimeNonexistent,
Expand Down Expand Up @@ -399,6 +395,8 @@ class CombinedDatetimelikeProperties(
_TimedeltaPropertiesNoRounding[Series[int], Series[float]],
_PeriodProperties,
): ...

@type_check_only
class TimestampProperties(
DatetimeProperties[
Series[int],
Expand Down Expand Up @@ -446,7 +444,7 @@ class TimedeltaIndexProperties(
@type_check_only
class DtDescriptor:
@overload
def __get__(self, instance: Series[Period], owner: Any) -> PeriodProperties: ...
def __get__(self, instance: Series[Never], owner: type[Series]) -> Any: ...
@overload
def __get__(
self, instance: Series[Timestamp], owner: type[Series]
Expand All @@ -455,9 +453,17 @@ class DtDescriptor:
def __get__(
self, instance: Series[Timedelta], owner: type[Series]
) -> TimedeltaProperties: ...
@overload
def __get__(
self, instance: Series[Period], owner: type[Series]
) -> PeriodProperties: ...

@type_check_only
class ArrayDescriptor:
@overload
def __get__(
self, instance: IndexOpsMixin[Never], owner: type[IndexOpsMixin]
) -> ExtensionArray: ...
@overload
def __get__(
self, instance: IndexOpsMixin[CategoricalDtype], owner: type[IndexOpsMixin]
Expand Down
2 changes: 0 additions & 2 deletions pandas-stubs/core/indexes/period.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ from pandas import Index
from pandas.core.indexes.accessors import PeriodIndexFieldOps
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
from pandas.core.indexes.timedeltas import TimedeltaIndex
from pandas.core.series import PeriodSeries
from typing_extensions import Self

from pandas._libs.tslibs import (
Expand Down Expand Up @@ -75,7 +74,6 @@ class PeriodIndex(DatetimeIndexOpsMixin[pd.Period, np.object_], PeriodIndexField
@property
def freqstr(self) -> str: ...
def shift(self, periods: int = 1, freq: Frequency | None = None) -> Self: ...
def to_series(self, index=..., name: Hashable = ...) -> PeriodSeries: ...

def period_range(
start: (
Expand Down
63 changes: 37 additions & 26 deletions pandas-stubs/core/series.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ from typing import (
Literal,
NoReturn,
Protocol,
TypeVar,
final,
overload,
type_check_only,
Expand Down Expand Up @@ -68,10 +69,7 @@ from pandas.core.generic import NDFrame
from pandas.core.groupby.generic import SeriesGroupBy
from pandas.core.groupby.groupby import BaseGroupBy
from pandas.core.indexers import BaseIndexer
from pandas.core.indexes.accessors import (
DtDescriptor,
PeriodProperties,
)
from pandas.core.indexes.accessors import DtDescriptor
from pandas.core.indexes.category import CategoricalIndex
from pandas.core.indexes.datetimes import DatetimeIndex
from pandas.core.indexes.interval import IntervalIndex
Expand Down Expand Up @@ -211,10 +209,16 @@ from pandas.core.dtypes.dtypes import CategoricalDtype

from pandas.plotting import PlotAccessor

_T_INTERVAL_NP = TypeVar("_T_INTERVAL_NP", bound=np.bytes_ | np.str_)

@type_check_only
class _SupportsAdd(Protocol[_T_co]):
def __add__(self, value: Self, /) -> _T_co: ...

@type_check_only
class SupportsSelfSub(Protocol[_T_co]):
def __sub__(self, x: Self, /) -> _T_co: ...

@type_check_only
class _SupportsMul(Protocol[_T_co]):
def __mul__(self, value: Self, /) -> _T_co: ...
Expand Down Expand Up @@ -301,7 +305,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
copy: bool = ...,
) -> Series[float]: ...
@overload
def __new__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
def __new__(
cls,
data: Sequence[Never],
index: AxesData | None = ...,
Expand Down Expand Up @@ -833,22 +837,19 @@ class Series(IndexOpsMixin[S1], NDFrame):
self, other: Series[S1], min_periods: int | None = None, ddof: int = 1
) -> float: ...
@overload
def diff(self: Series[_bool], periods: int = ...) -> Series[type[object]]: ... # type: ignore[overload-overlap]
@overload
def diff(self: Series[complex], periods: int = ...) -> Series[complex]: ... # type: ignore[overload-overlap]
@overload
def diff(
self: Series[bytes] | Series[type] | Series[_str] | Series[Interval],
periods: int = ...,
) -> Never: ...
def diff( # type: ignore[overload-overlap]
self: Series[Never] | Series[int], periods: int = ...
) -> Series[float]: ...
@overload
def diff(self: Series[Timestamp], periods: int = ...) -> Series[Timedelta]: ... # type: ignore[overload-overlap]
def diff(self: Series[_bool], periods: int = ...) -> Series: ...
@overload
def diff(self: Series[Timedelta], periods: int = ...) -> Series[Timedelta]: ... # type: ignore[overload-overlap]
def diff(self: Series[Period], periods: int = ...) -> OffsetSeries: ...
@overload
def diff(self: Series[Period], periods: int = ...) -> OffsetSeries: ... # type: ignore[overload-overlap]
def diff(self: Series[Interval], periods: int = ...) -> Never: ...
@overload
def diff(self, periods: int = ...) -> Series[float]: ...
def diff(
self: SupportsGetItem[Scalar, SupportsSelfSub[S1_CO]], periods: int = ...
) -> Series[S1_CO]: ...
def autocorr(self, lag: int = 1) -> float: ...
@overload
def dot(self, other: Series[S1]) -> Scalar: ...
Expand Down Expand Up @@ -1231,7 +1232,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
Series[_str],
Series,
]: ...
dt: ClassVar = DtDescriptor() # noqa
dt = DtDescriptor()
@property
def plot(self) -> PlotAccessor: ...
sparse = ...
Expand Down Expand Up @@ -4640,6 +4641,22 @@ class Series(IndexOpsMixin[S1], NDFrame):
**kwargs,
) -> np_1darray[GenericT]: ...
@overload
def to_numpy(
self: Series[Period],
dtype: None = None,
copy: bool = False,
na_value: Scalar = ...,
**kwargs,
) -> np_1darray[np.object_]: ...
@overload
def to_numpy(
self: Series[Period],
dtype: type[np.int64],
copy: bool = False,
na_value: Scalar = ...,
**kwargs,
) -> np_1darray[np.int64]: ...
@overload
def to_numpy(
self: Series[Interval],
dtype: type[np.object_] | None = None,
Expand All @@ -4650,11 +4667,11 @@ class Series(IndexOpsMixin[S1], NDFrame):
@overload
def to_numpy(
self: Series[Interval],
dtype: np.dtype[GenericT] | SupportsDType[GenericT] | type[GenericT],
dtype: type[_T_INTERVAL_NP],
copy: bool = False,
na_value: Scalar = ...,
**kwargs,
) -> np_1darray[GenericT]: ...
) -> np_1darray[_T_INTERVAL_NP]: ...
@overload
def to_numpy( # pyright: ignore[reportIncompatibleMethodOverride]
self,
Expand Down Expand Up @@ -4749,12 +4766,6 @@ class _SeriesSubclassBase(Series[S1], Generic[S1, GenericT_co]):
**kwargs,
) -> np_1darray: ...

class PeriodSeries(_SeriesSubclassBase[Period, np.object_]):
@property
def dt(self) -> PeriodProperties: ... # type: ignore[override]
def __sub__(self, other: PeriodSeries) -> OffsetSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
def diff(self, periods: int = ...) -> OffsetSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]

class OffsetSeries(_SeriesSubclassBase[BaseOffset, np.object_]):
@overload # type: ignore[override]
def __radd__(self, other: Period) -> Series[Period]: ...
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ numpy = ">= 1.23.5"
mypy = "1.18.2"
pandas = "2.3.2"
pyarrow = ">=10.0.1"
pytest = ">=7.1.2"
pytest = ">=8.4.2"
pyright = ">=1.1.405"
ty = ">=0.0.1a21"
pyrefly = ">=0.33.1"
pyrefly = ">=0.34.0"
poethepoet = ">=0.16.5"
loguru = ">=0.6.0"
typing-extensions = ">=4.4.0"
matplotlib = ">=3.10.1"
pre-commit = ">=2.19.0"
black = ">=25.1.0"
black = ">=25.9.0"
isort = ">=6.0.1"
openpyxl = ">=3.0.10"
tables = { version = ">=3.10.1", python = "<4" }
Expand All @@ -65,7 +65,7 @@ scipy = { version = ">=1.9.1", python = "<3.14" }
scipy-stubs = ">=1.15.3.0"
SQLAlchemy = ">=2.0.39"
types-python-dateutil = ">=2.8.19"
beautifulsoup4 = "<=4.13.5"
beautifulsoup4 = ">=4.14.2"
html5lib = ">=1.1"
python-calamine = ">=0.2.0"

Expand Down
6 changes: 2 additions & 4 deletions tests/indexes/test_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
)

if TYPE_CHECKING:
from pandas.core.series import PeriodSeries # noqa: F401

from tests import Dtype # noqa: F401


Expand Down Expand Up @@ -1547,7 +1545,6 @@ def test_array_property() -> None:
TimedeltaArray,
pd.Timedelta,
)
# Should be NumpyExtensionArray
check(assert_type(Index([1]).array, ExtensionArray), ExtensionArray, np.integer)


Expand Down Expand Up @@ -1577,7 +1574,8 @@ def test_to_series() -> None:
)
check(
assert_type(
pd.period_range(start="2022-06-01", periods=10).to_series(), "PeriodSeries"
pd.period_range(start="2022-06-01", periods=10).to_series(),
"pd.Series[pd.Period]",
),
pd.Series,
pd.Period,
Expand Down
27 changes: 20 additions & 7 deletions tests/series/test_properties.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from typing import TYPE_CHECKING
from typing import (
TYPE_CHECKING,
Any,
)

import numpy as np
import pandas as pd
Expand All @@ -8,6 +11,7 @@
from pandas.core.arrays.timedeltas import TimedeltaArray
from pandas.core.indexes.accessors import (
DatetimeProperties,
PeriodProperties,
TimedeltaProperties,
)
from typing_extensions import assert_type
Expand All @@ -18,10 +22,7 @@
)

if TYPE_CHECKING:
from pandas.core.indexes.accessors import ( # noqa: F401
TimedeltaProperties,
TimestampProperties,
)
from pandas.core.indexes.accessors import TimestampProperties # noqa: F401


def test_dt_property() -> None:
Expand All @@ -34,9 +35,19 @@ def test_dt_property() -> None:
assert_type(pd.Series([pd.Timedelta(1, "s")]).dt, TimedeltaProperties),
TimedeltaProperties,
)
check(
assert_type(
pd.period_range(start="2022-06-01", periods=10).to_series().dt,
PeriodProperties,
),
PeriodProperties,
)

if TYPE_CHECKING_INVALID_USAGE:
_ = pd.Series([1]).dt # type: ignore[arg-type] # pyright: ignore[reportAttributeAccessIssue]
s = pd.DataFrame({"a": [1]})["a"]
assert_type(s.dt, Any)
assert_type(s.dt.year, Any)
_1 = pd.Series([1]).dt # type: ignore[arg-type] # pyright: ignore[reportAttributeAccessIssue]


def test_array_property() -> None:
Expand All @@ -58,5 +69,7 @@ def test_array_property() -> None:
TimedeltaArray,
pd.Timedelta,
)
# Should be NumpyExtensionArray
check(assert_type(pd.Series([1]).array, ExtensionArray), ExtensionArray, np.integer)
# python/mypy#19952: mypy believes ExtensionArray and its subclasses have a
# conflict and gives Any for s.array
check(assert_type(pd.Series([1, "s"]).array, ExtensionArray), ExtensionArray) # type: ignore[assert-type]
Loading
Loading