Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 2 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,10 @@ repos:
hooks:
- id: isort
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.2
rev: v0.13.3
hooks:
- id: ruff-check
args: [
--exit-non-zero-on-fix,
--target-version, py39,
--extend-select, "PYI,UP,RUF100",
--ignore, "E501,E731,F841,PYI042",
--per-file-ignores, "_*.pyi:PYI001",
--fix
]
args: [--exit-non-zero-on-fix]
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
Expand Down
37 changes: 37 additions & 0 deletions pandas-stubs/core/generic.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ from pandas.core.series import (
import sqlalchemy.engine
from typing_extensions import (
Concatenate,
Never,
Self,
)

Expand Down Expand Up @@ -315,6 +316,42 @@ class NDFrame(indexing.IndexingMixin):
@final
def __delitem__(self, idx: Hashable) -> None: ...
@overload
def drop(
self,
labels=...,
*,
axis=...,
index: None,
columns=...,
level=...,
inplace=...,
errors=...,
) -> Never: ...
@overload
def drop(
self,
labels=...,
*,
axis=...,
index=...,
columns: None,
level=...,
inplace=...,
errors=...,
) -> Never: ...
@overload
def drop(
self,
labels: None,
*,
axis=...,
index=...,
columns=...,
level=...,
inplace=...,
errors=...,
) -> Never: ...
@overload
def drop(
self,
labels: None = ...,
Expand Down
21 changes: 20 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ args = [


[tool.black]
target-version = ['py310']
target-version = ['py39']

[tool.isort]
known_pre_libs = "pandas._config"
Expand Down Expand Up @@ -168,6 +168,25 @@ force_grid_wrap = 2
force_sort_within_sections = true
skip_glob = "env"


[tool.ruff]
target-version = "py39"
fix = true


[tool.ruff.lint]
extend-select = ["PYI", "UP", "RUF100"]
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/
]


[tool.ruff.lint.per-file-ignores]
"_*.pyi" = ["PYI001"]


[tool.mypy]
# Import discovery
namespace_packages = false
Expand Down
2 changes: 1 addition & 1 deletion tests/indexes/test_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,7 @@ def test_index_categorical() -> None:
def test_disallow_empty_index() -> None:
# From GH 826
if TYPE_CHECKING_INVALID_USAGE:
i0 = pd.Index() # type: ignore[call-overload] # pyright: ignore[reportCallIssue]
_0 = pd.Index() # type: ignore[call-overload] # pyright: ignore[reportCallIssue]


def test_datetime_index_max_min_reductions() -> None:
Expand Down
2 changes: 1 addition & 1 deletion tests/scalars/test_scalars.py
Original file line number Diff line number Diff line change
Expand Up @@ -2109,5 +2109,5 @@ def test_period_methods() -> None:

def test_nattype_hashable() -> None:
# GH 827
aset = {pd.NaT}
_aset = {pd.NaT}
check(assert_type(pd.NaT.__hash__(), int), int)
62 changes: 33 additions & 29 deletions tests/series/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,20 @@ def test_types_drop() -> None:

def test_arguments_drop() -> None:
# GH 950
s = pd.Series([0, 1, 2])
if TYPE_CHECKING_INVALID_USAGE:
s = pd.Series([0, 1, 2])
res1 = s.drop() # type: ignore[call-overload] # pyright: ignore[reportCallIssue]
res2 = s.drop([0], columns=["col1"]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
res3 = s.drop([0], index=[0]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
# These should also fail, but `None` is Hasheable and i do not know how
# to type hint a non-None hashable.
# res4 = s.drop(columns=None)
# res5 = s.drop(index=None)
# res6 = s.drop(None)
_res1 = s.drop() # type: ignore[call-overload] # pyright: ignore[reportCallIssue]
_res2 = s.drop([0], columns=["col1"]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
_res3 = s.drop([0], index=[0]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]

def _never_checker0() -> None: # pyright: ignore[reportUnusedFunction]
assert_type(s.drop(columns=None), Never)

def _never_checker1() -> None: # pyright: ignore[reportUnusedFunction]
assert_type(s.drop(index=None), Never)

def _never_checker2() -> None: # pyright: ignore[reportUnusedFunction]
assert_type(s.drop(None), Never)


def test_types_drop_multilevel() -> None:
Expand Down Expand Up @@ -817,14 +821,14 @@ def test_types_element_wise_arithmetic() -> None:
assert_type(s.div(s2, fill_value=0), "pd.Series[float]"), pd.Series, np.float64
)

res_floordiv: pd.Series = s // s2
res_floordiv2: pd.Series = s.floordiv(s2, fill_value=0)
_res_floordiv: pd.Series = s // s2
_res_floordiv2: pd.Series = s.floordiv(s2, fill_value=0)

res_mod: pd.Series = s % s2
res_mod2: pd.Series = s.mod(s2, fill_value=0)
_res_mod: pd.Series = s % s2
_res_mod2: pd.Series = s.mod(s2, fill_value=0)

res_pow: pd.Series = s ** s2.abs()
res_pow2: pd.Series = s.pow(s2.abs(), fill_value=0)
_res_pow: pd.Series = s ** s2.abs()
_res_pow2: pd.Series = s.pow(s2.abs(), fill_value=0)

check(assert_type(divmod(s, s2), tuple["pd.Series[int]", "pd.Series[int]"]), tuple)

Expand All @@ -847,16 +851,16 @@ def test_types_scalar_arithmetic() -> None:
assert_type(s.div(2, fill_value=0), "pd.Series[float]"), pd.Series, np.floating
)

res_floordiv: pd.Series = s // 2
res_floordiv2: pd.Series = s.floordiv(2, fill_value=0)
_res_floordiv: pd.Series = s // 2
_res_floordiv2: pd.Series = s.floordiv(2, fill_value=0)

res_mod: pd.Series = s % 2
res_mod2: pd.Series = s.mod(2, fill_value=0)
_res_mod: pd.Series = s % 2
_res_mod2: pd.Series = s.mod(2, fill_value=0)

res_pow: pd.Series = s**2
res_pow1: pd.Series = s**0
res_pow2: pd.Series = s**0.213
res_pow3: pd.Series = s.pow(0.5)
_res_pow: pd.Series = s**2
_res_pow1: pd.Series = s**0
_res_pow2: pd.Series = s**0.213
_res_pow3: pd.Series = s.pow(0.5)


def test_types_groupby() -> None:
Expand Down Expand Up @@ -1478,7 +1482,7 @@ def add1(x: int) -> int:
)

if TYPE_CHECKING_INVALID_USAGE:
s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[dict-item] # pyright: ignore[reportArgumentType]
_s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[dict-item] # pyright: ignore[reportArgumentType]


def test_types_ne() -> None:
Expand Down Expand Up @@ -1606,7 +1610,7 @@ def test_series_multiindex_getitem() -> None:
s = pd.Series(
[1, 2, 3, 4], index=pd.MultiIndex.from_product([["a", "b"], ["x", "y"]])
)
s1: pd.Series = s["a", :]
_s1: pd.Series = s["a", :]


def test_reset_index() -> None:
Expand Down Expand Up @@ -1800,7 +1804,7 @@ def test_iloc_setitem_ndarray() -> None:

def test_types_iter() -> None:
s = pd.Series([1, 2, 3], dtype=int)
iterable: Iterable[int] = s
_iterable: Iterable[int] = s
check(assert_type(iter(s), Iterator[int]), Iterator, int)
check(assert_type(next(iter(s)), int), int)

Expand Down Expand Up @@ -3114,7 +3118,7 @@ def test_to_json_mode() -> None:
check(assert_type(result2, str), str)
check(assert_type(result4, str), str)
if TYPE_CHECKING_INVALID_USAGE:
result3 = s.to_json(orient="records", lines=False, mode="a") # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue]
_result3 = s.to_json(orient="records", lines=False, mode="a") # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue]


def test_groupby_diff() -> None:
Expand Down Expand Up @@ -3730,7 +3734,7 @@ def test_series_bool_fails() -> None:
# mypy doesn't seem to figure that out, but pyright does
if s == "foo": # pyright: ignore[reportGeneralTypeIssues]
# Next line is unreachable.
a = s[0]
_a = s[0]
assert False
except ValueError:
pass
Expand Down Expand Up @@ -3905,7 +3909,7 @@ def test_series_index_type() -> None:
)

if TYPE_CHECKING_INVALID_USAGE:
t = pd.Series([1, 2], index="ab") # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
_t = pd.Series([1, 2], index="ab") # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]


def test_timedelta_index_cumprod() -> None:
Expand Down
42 changes: 23 additions & 19 deletions tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,22 +177,22 @@ def test_types_append() -> None:
df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]})
df2 = pd.DataFrame({"col1": [10, 20], "col2": [30, 40]})
if TYPE_CHECKING_INVALID_USAGE:
res1: pd.DataFrame = df.append(df2) # type: ignore[operator] # pyright: ignore[reportCallIssue]
res2: pd.DataFrame = df.append([1, 2, 3]) # type: ignore[operator] # pyright: ignore[reportCallIssue]
res3: pd.DataFrame = df.append([[1, 2, 3]]) # type: ignore[operator] # pyright: ignore[reportCallIssue]
res4: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res1: pd.DataFrame = df.append(df2) # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res2: pd.DataFrame = df.append([1, 2, 3]) # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res3: pd.DataFrame = df.append([[1, 2, 3]]) # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res4: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
{("a", 1): [1, 2, 3], "b": df2}, ignore_index=True
)
res5: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res5: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
{1: [1, 2, 3]}, ignore_index=True
)
res6: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res6: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
{1: [1, 2, 3], "col2": [1, 2, 3]}, ignore_index=True
)
res7: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res7: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
pd.Series([5, 6]), ignore_index=True
)
res8: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
_res8: pd.DataFrame = df.append( # type: ignore[operator] # pyright: ignore[reportCallIssue]
pd.Series([5, 6], index=["col1", "col2"]), ignore_index=True
)

Expand Down Expand Up @@ -478,16 +478,20 @@ def test_types_drop() -> None:

def test_arguments_drop() -> None:
# GH 950
df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]})
if TYPE_CHECKING_INVALID_USAGE:
df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]})
res1 = df.drop() # type: ignore[call-overload] # pyright: ignore[reportCallIssue]
res2 = df.drop([0], columns=["col1"]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
res3 = df.drop([0], index=[0]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
# These should also fail, but `None` is Hasheable and i do not know how
# to type hint a non-None hashable.
# res4 = df.drop(columns=None)
# res5 = df.drop(index=None)
# res6 = df.drop(None)
_res1 = df.drop() # type: ignore[call-overload] # pyright: ignore[reportCallIssue]
_res2 = df.drop([0], columns=["col1"]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]
_res3 = df.drop([0], index=[0]) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType]

def _never_checker0() -> None: # pyright: ignore[reportUnusedFunction]
assert_type(df.drop(columns=None), Never)

def _never_checker1() -> None: # pyright: ignore[reportUnusedFunction]
assert_type(df.drop(index=None), Never)

def _never_checker2() -> None: # pyright: ignore[reportUnusedFunction]
assert_type(df.drop(None), Never)


def test_types_dropna() -> None:
Expand Down Expand Up @@ -4404,7 +4408,7 @@ def test_to_json_mode() -> None:
check(assert_type(result2, str), str)
check(assert_type(result4, str), str)
if TYPE_CHECKING_INVALID_USAGE:
result3 = df.to_json(orient="records", lines=False, mode="a") # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue]
_result3 = df.to_json(orient="records", lines=False, mode="a") # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue]


def test_interpolate_inplace() -> None:
Expand Down Expand Up @@ -4547,7 +4551,7 @@ def test_frame_bool_fails() -> None:
# mypy doesn't seem to figure that out, but pyright does
if df == "foo": # pyright: ignore[reportGeneralTypeIssues]
# Next line is unreachable.
s = df["a"]
_s = df["a"]
except ValueError:
pass

Expand Down
4 changes: 2 additions & 2 deletions tests/test_string_accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def test_string_accessors_list_series():
# rsplit doesn't accept compiled pattern
# it doesn't raise at runtime but produces a nan
if TYPE_CHECKING_INVALID_USAGE:
bad_rsplit_result = s.str.rsplit(
_bad_rsplit_result = s.str.rsplit(
re.compile(r"a") # type: ignore[call-overload] # pyright: ignore[reportArgumentType]
)

Expand All @@ -300,7 +300,7 @@ def test_string_accessors_list_index():
# rsplit doesn't accept compiled pattern
# it doesn't raise at runtime but produces a nan
if TYPE_CHECKING_INVALID_USAGE:
bad_rsplit_result = idx.str.rsplit(
_bad_rsplit_result = idx.str.rsplit(
re.compile(r"a") # type: ignore[call-overload] # pyright: ignore[reportArgumentType]
)

Expand Down
10 changes: 5 additions & 5 deletions tests/test_timefuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ def test_fail_on_adding_two_timestamps() -> None:
s1 = pd.Series(pd.to_datetime(["2022-05-01", "2022-06-01"]))
s2 = pd.Series(pd.to_datetime(["2022-05-15", "2022-06-15"]))
if TYPE_CHECKING_INVALID_USAGE:
ssum = s1 + s2 # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
_ssum = s1 + s2 # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
ts = pd.Timestamp("2022-06-30")
tsum = s1 + ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
_tsum = s1 + ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue]


def test_dtindex_tzinfo() -> None:
Expand Down Expand Up @@ -1706,9 +1706,9 @@ def test_timedelta64_and_arithmatic_operator() -> None:
td = np.timedelta64(1, "D")
check(assert_type((s3 / td), "pd.Series[float]"), pd.Series, float)
if TYPE_CHECKING_INVALID_USAGE:
r1 = s1 * td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
r2 = s1 / td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
r3 = s3 * td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
_1 = s1 * td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
_2 = s1 / td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
_3 = s3 * td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]


def test_timedeltaseries_add_timestampseries() -> None:
Expand Down