Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ minimum_pre_commit_version: 2.15.0
ci:
autofix_prs: false
repos:
- repo: https://github.com/psf/black
rev: 25.9.0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
rev: 6.0.1
hooks:
- id: isort
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.3
hooks:
Expand All @@ -21,3 +13,11 @@ repos:
- id: codespell
additional_dependencies: [ tomli ]
args: [-L, "THIRDPARTY"]
- repo: https://github.com/PyCQA/isort
rev: 6.0.1
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 25.9.0
hooks:
- id: black
3 changes: 2 additions & 1 deletion conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from collections.abc import Generator
import gc

import pytest


@pytest.fixture
def mpl_cleanup():
def mpl_cleanup() -> Generator[None, None, None]:
"""
Ensure Matplotlib is cleaned up around a test.

Expand Down
12 changes: 6 additions & 6 deletions pandas-stubs/_libs/tslibs/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
__all__ = [
"Period",
"Timestamp",
"Timedelta",
"BaseOffset",
"NaT",
"NaTType",
"OutOfBoundsDatetime",
"Period",
"Tick",
"Timedelta",
"Timestamp",
"iNaT",
"nat_strings",
"BaseOffset",
"Tick",
"OutOfBoundsDatetime",
]
from pandas._libs.tslibs.nattype import (
NaT,
Expand Down
1 change: 1 addition & 0 deletions pandas-stubs/_typing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ Incomplete: TypeAlias = Any
class Just(Protocol, Generic[T]):
@property # type: ignore[override]
@override
# pyrefly: ignore # bad-override
def __class__(self, /) -> type[T]: ...
@__class__.setter
@override
Expand Down
4 changes: 2 additions & 2 deletions pandas-stubs/core/groupby/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ from pandas.core.groupby.grouper import Grouper as Grouper

__all__ = [
"DataFrameGroupBy",
"NamedAgg",
"SeriesGroupBy",
"GroupBy",
"Grouper",
"NamedAgg",
"SeriesGroupBy",
]
2 changes: 2 additions & 0 deletions pandas-stubs/core/groupby/generic.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class SeriesGroupBy(GroupBy[Series[S2]], Generic[S2, ByT]):
def unique(self) -> Series: ...
# Overrides that provide more precise return types over the GroupBy class
@final # type: ignore[misc]
# pyrefly: ignore # bad-override
def __iter__( # pyright: ignore[reportIncompatibleMethodOverride]
self,
) -> Iterator[tuple[ByT, Series[S2]]]: ...
Expand Down Expand Up @@ -451,6 +452,7 @@ class DataFrameGroupBy(GroupBy[DataFrame], Generic[ByT, _TT]):
def __getattr__(self, name: str) -> SeriesGroupBy[Any, ByT]: ...
# Overrides that provide more precise return types over the GroupBy class
@final # type: ignore[misc]
# pyrefly: ignore # bad-override
def __iter__( # pyright: ignore[reportIncompatibleMethodOverride]
self,
) -> Iterator[tuple[ByT, DataFrame]]: ...
Expand Down
1 change: 1 addition & 0 deletions pandas-stubs/core/indexes/datetimes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class DatetimeIndex(
self, other: timedelta | BaseOffset
) -> Self: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __sub__(
self, other: datetime | np.datetime64 | np_ndarray_dt | Self
) -> TimedeltaIndex: ...
Expand Down
1 change: 1 addition & 0 deletions pandas-stubs/core/indexes/interval.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class IntervalIndex(ExtensionIndex[IntervalT, np.object_], IntervalMixin):
@property
def length(self) -> Index: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __getitem__(
self,
idx: (
Expand Down
1 change: 1 addition & 0 deletions pandas-stubs/core/indexes/multi.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class MultiIndex(Index):
def levshape(self): ...
def __reduce__(self): ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __getitem__(
self,
idx: slice | np_ndarray_anyint | Sequence[int] | Index | MaskType,
Expand Down
2 changes: 2 additions & 0 deletions pandas-stubs/core/indexes/period.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class PeriodIndex(DatetimeIndexOpsMixin[pd.Period, np.object_], PeriodIndexField
self, other: datetime.timedelta
) -> Self: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __sub__(self, other: Period) -> Index: ...
@overload
def __sub__(self, other: Self) -> Index: ...
Expand All @@ -55,6 +56,7 @@ class PeriodIndex(DatetimeIndexOpsMixin[pd.Period, np.object_], PeriodIndexField
self, other: TimedeltaIndex | pd.Timedelta
) -> Self: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __rsub__(self, other: Period) -> Index: ...
@overload
def __rsub__(self, other: Self) -> Index: ...
Expand Down
1 change: 1 addition & 0 deletions pandas-stubs/core/indexes/range.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class RangeIndex(_IndexSubclassBase[int, np.int64]):
self, other: list[HashableT] | Index, sort: bool | None = None
) -> Index | Index[int] | RangeIndex: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __getitem__(
self,
idx: slice | np_ndarray_anyint | Sequence[int] | Index | MaskType,
Expand Down
5 changes: 5 additions & 0 deletions pandas-stubs/core/indexes/timedeltas.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class TimedeltaIndex(
# various ignores needed for mypy, as we do want to restrict what can be used in
# arithmetic for these types
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __add__(self, other: Period) -> PeriodIndex: ...
@overload
def __add__(self, other: dt.datetime | DatetimeIndex) -> DatetimeIndex: ...
Expand All @@ -64,6 +65,7 @@ class TimedeltaIndex(
self, other: dt.timedelta | Self
) -> Self: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __radd__(self, other: Period) -> PeriodIndex: ...
@overload
def __radd__(self, other: dt.datetime | DatetimeIndex) -> DatetimeIndex: ...
Expand All @@ -75,6 +77,7 @@ class TimedeltaIndex(
self, other: dt.timedelta | np.timedelta64 | np_ndarray_td | BaseOffset | Self
) -> Self: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __rsub__(
self, other: dt.timedelta | np.timedelta64 | np_ndarray_td | BaseOffset | Self
) -> Self: ...
Expand Down Expand Up @@ -115,13 +118,15 @@ class TimedeltaIndex(
),
) -> Self: ...
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __truediv__(self, other: float | Sequence[float]) -> Self: ...
@overload
def __truediv__( # pyright: ignore[reportIncompatibleMethodOverride]
self, other: dt.timedelta | Sequence[dt.timedelta]
) -> Index[float]: ...
def __rtruediv__(self, other: dt.timedelta | Sequence[dt.timedelta]) -> Index[float]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __floordiv__(self, other: num | Sequence[float]) -> Self: ...
@overload
def __floordiv__( # pyright: ignore[reportIncompatibleMethodOverride]
Expand Down
6 changes: 6 additions & 0 deletions pandas-stubs/core/series.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2208,6 +2208,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
) -> Series[_str]: ...
# ignore needed for mypy as we want different results based on the arguments
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __and__( # pyright: ignore[reportOverlappingOverload]
self, other: bool | list[int] | MaskType
) -> Series[bool]: ...
Expand Down Expand Up @@ -3060,13 +3061,15 @@ class Series(IndexOpsMixin[S1], NDFrame):
def __pow__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ...
# ignore needed for mypy as we want different results based on the arguments
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __or__( # pyright: ignore[reportOverlappingOverload]
self, other: bool | list[int] | MaskType
) -> Series[bool]: ...
@overload
def __or__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ...
# ignore needed for mypy as we want different results based on the arguments
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __rand__( # pyright: ignore[reportOverlappingOverload]
self, other: bool | MaskType | list[int]
) -> Series[bool]: ...
Expand All @@ -3077,13 +3080,15 @@ class Series(IndexOpsMixin[S1], NDFrame):
def __rpow__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ...
# ignore needed for mypy as we want different results based on the arguments
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __ror__( # pyright: ignore[reportOverlappingOverload]
self, other: bool | MaskType | list[int]
) -> Series[bool]: ...
@overload
def __ror__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ...
# ignore needed for mypy as we want different results based on the arguments
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __rxor__( # pyright: ignore[reportOverlappingOverload]
self, other: bool | MaskType | list[int]
) -> Series[bool]: ...
Expand Down Expand Up @@ -4244,6 +4249,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
rdiv = rtruediv
# ignore needed for mypy as we want different results based on the arguments
@overload # type: ignore[override]
# pyrefly: ignore # bad-override
def __xor__( # pyright: ignore[reportOverlappingOverload]
self, other: bool | MaskType | list[int]
) -> Series[bool]: ...
Expand Down
2 changes: 1 addition & 1 deletion pandas-stubs/io/orc.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def read_orc(
path: FilePath | ReadBuffer[bytes],
columns: list[HashableT] | None = None,
dtype_backend: DtypeBackend | _NoDefaultDoNotUse = "numpy_nullable",
# TODO type with the correct pyarrow types
# TODO: type with the correct pyarrow types
# filesystem: pyarrow.fs.FileSystem | fsspec.spec.AbstractFileSystem
filesystem: Any | None = None,
**kwargs: Any,
Expand Down
2 changes: 1 addition & 1 deletion pandas-stubs/testing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ from pandas._testing import (
__all__ = [
"assert_extension_array_equal",
"assert_frame_equal",
"assert_series_equal",
"assert_index_equal",
"assert_series_equal",
]
60 changes: 53 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ types-pytz = ">= 2022.1.1"
numpy = ">= 1.23.5"

[tool.poetry.group.dev.dependencies]
mypy = "1.18.2"
mypy = ">=1.18.2"
pandas = "2.3.2"
pyarrow = ">=10.0.1"
pytest = ">=8.4.2"
pyright = ">=1.1.406"
ty = ">=0.0.1a21"
pyrefly = ">=0.35.0"
pyrefly = ">=0.36.1"
poethepoet = ">=0.16.5"
loguru = ">=0.6.0"
typing-extensions = ">=4.4.0"
Expand Down Expand Up @@ -176,16 +176,59 @@ fix = true


[tool.ruff.lint]
extend-select = ["B007", "B018", "PYI", "UP", "RUF100", "RUF059"]
extend-select = ["ALL"]
ignore = [
"E501", # https://docs.astral.sh/ruff/rules/line-too-long/
"E731", # https://docs.astral.sh/ruff/rules/lambda-assignment/
"PYI042", # https://docs.astral.sh/ruff/rules/snake-case-type-alias/
# The following rules are ignored permanently for good reasons
"COM", # https://docs.astral.sh/ruff/rules/#flake8-commas-com
"D", # https://docs.astral.sh/ruff/rules/#pydocstyle-d
"E501", # handled by black https://docs.astral.sh/ruff/rules/line-too-long/
"FBT", # https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt
"I", # handled by isort
]


[tool.ruff.lint.per-file-ignores]
"_*.pyi" = ["PYI001"]
"*.pyi" = [
# The following rules are ignored permanently for good reasons
"A002", # https://docs.astral.sh/ruff/rules/builtin-argument-shadowing/
"FIX002", # https://docs.astral.sh/ruff/rules/line-contains-todo/
"N", # https://docs.astral.sh/ruff/rules/#pep8-naming-n
"TD002", # https://docs.astral.sh/ruff/rules/missing-todo-author/
# The following rules are ignored temporarily. Either fix them or move to the permanent list above.
"A001", # https://docs.astral.sh/ruff/rules/builtin-variable-shadowing/
"A004", # https://docs.astral.sh/ruff/rules/builtin-import-shadowing/
"PYI001", # https://docs.astral.sh/ruff/rules/unprefixed-type-param/
"PYI042", # https://docs.astral.sh/ruff/rules/snake-case-type-alias/
"TD003", # https://docs.astral.sh/ruff/rules/missing-todo-link/
"ERA001", "ANN", "PLR0402", "PLC0105"
]
"scripts/*" = [
# The following rules are ignored permanently for good reasons
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
"S603", # https://docs.astral.sh/ruff/rules/subprocess-without-shell-equals-true/
# The following rules are ignored temporarily. Either fix them or move to the permanent list above.
"TRY", "PT", "BLE"
]
"tests/*" = [
# The following rules are ignored permanently for good reasons
"B905", # https://docs.astral.sh/ruff/rules/zip-without-explicit-strict/
"E731", # https://docs.astral.sh/ruff/rules/lambda-assignment/
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
"FIX002", # https://docs.astral.sh/ruff/rules/line-contains-todo/
"PD", # Pandas is here
"PLC0415", # https://docs.astral.sh/ruff/rules/import-outside-top-level/
"S101", # https://docs.astral.sh/ruff/rules/assert/
"TD002", # https://docs.astral.sh/ruff/rules/missing-todo-author/
# The following rules are ignored temporarily. Either fix them or move to the permanent list above.
"A001", # https://docs.astral.sh/ruff/rules/builtin-variable-shadowing/
"PYI042", # https://docs.astral.sh/ruff/rules/snake-case-type-alias/
"SLF001", # https://docs.astral.sh/ruff/rules/private-member-access/
"ANN001", "ANN002", "ANN201", "ANN202", "ANN204", "ANN206", "ANN401", "ARG", "ERA", "RUF", "SIM", "TRY", "PT", "NPY", "N", "DTZ", "PLR", "TC", "PGH", "PTH", "S311", "C901"
]
"tests/test_io.py" = [
# The following rules are ignored permanently for good reasons
"S301", # https://docs.astral.sh/ruff/rules/suspicious-pickle-usage/
]


[tool.mypy]
Expand Down Expand Up @@ -252,6 +295,9 @@ reportPrivateUsage = false
reportMissingModuleSource = true
useLibraryCodeForTypes = false

[tool.pyrefly.errors]
bad-param-name-override = false # TODO: report to pyrefly https://github.com/pandas-dev/pandas-stubs/pull/1412#pullrequestreview-3310645279

[tool.codespell]
ignore-words-list = "indext, mose, sav, ser"

Expand Down
6 changes: 3 additions & 3 deletions scripts/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ def stubtest(allowlist: str, check_missing: bool, nightly: bool) -> None:
steps = _DIST_STEPS[:2]
if nightly:
steps.append(_step.nightly)
run_job(steps + [stubtest])
run_job([*steps, stubtest])


def pytest(nightly: bool) -> None:
setup_steps = []
pytest_step = _step.pytest
if nightly:
setup_steps = [_step.nightly]
run_job(setup_steps + [pytest_step])
run_job([*setup_steps, pytest_step])


def mypy_src(mypy_nightly: bool) -> None:
steps = [_step.mypy_nightly] if mypy_nightly else []
run_job(steps + [_step.mypy_src])
run_job([*steps, _step.mypy_src])
12 changes: 5 additions & 7 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def check(
and get_origin(shape_type) is tuple
and (tuple_args := get_args(shape_type))
and ... not in tuple_args # fixed-length tuple
and (arr_ndim := getattr(actual, "ndim"))
and (arr_ndim := getattr(actual, "ndim")) # noqa: B009
!= (expected_ndim := len(tuple_args))
):
raise RuntimeError(
Expand All @@ -100,7 +100,7 @@ def check(
and (dtype_args := get_args(dtype_type))
and isinstance((expected_dtype := dtype_args[0]), type)
and issubclass(expected_dtype, np.generic)
and (arr_dtype := getattr(actual, "dtype")) != expected_dtype
and (arr_dtype := getattr(actual, "dtype")) != expected_dtype # noqa: B009
):
raise RuntimeError(
f"Array has wrong dtype {arr_dtype}, expected {expected_dtype.__name__}"
Expand Down Expand Up @@ -208,8 +208,6 @@ def pytest_warns_bounded(
current = Version(version_str)
if lb < current < ub:
return pytest.warns(warning, match=match)
else:
if upper_exception is None:
return nullcontext()
else:
return suppress(upper_exception)
if upper_exception is None:
return nullcontext()
return suppress(upper_exception)
Loading