Skip to content

Commit dd93d48

Browse files
authored
CI: run stubtest (#178)
* CI: run stubtest * maybe fix windows bug? * remove allowlist * isort * remove non-existing files * slightly nicer solution? * fix most default arguments * remove very few of the many non-existing things * read_json
1 parent 257e761 commit dd93d48

25 files changed

+54
-94
lines changed

docs/tests.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ Here are the most important options. Fore more details, please use `poe --help`.
1111
- Run only pytest: `poe pytest`
1212
- Run only pre-commit: `poe style`
1313
- Run tests against the installed stubs (this will install and uninstall the stubs): `poe test_dist`
14+
- Optional: Run stubtest to compare the installed pandas-stubs against pandas (this will fail): `poe stubtest`. If you have created an allowlist to ignore certain errors: `poe stubtest path_to_the_allow_list`
1415

1516
These tests originally came from https://github.com/VirtusLab/pandas-stubs.

pandas-stubs/core/arrays/_arrow_utils.pyi

Whitespace-only changes.

pandas-stubs/core/arrays/categorical.pyi

+5-5
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ class Categorical(ExtensionArray, PandasObject):
6767
@overload
6868
def set_ordered(self, value, inplace: Literal[True]) -> None: ...
6969
@overload
70-
def set_ordered(self, value, inplace: Literal[False]) -> Categorical: ...
70+
def set_ordered(self, value, inplace: Literal[False] = ...) -> Categorical: ...
7171
@overload
72-
def set_ordered(self, value, inplace: bool) -> Categorical | None: ...
72+
def set_ordered(self, value, inplace: bool = ...) -> Categorical | None: ...
7373
@overload
7474
def as_ordered(self, inplace: Literal[True]) -> None: ...
7575
@overload
76-
def as_ordered(self, inplace: Literal[False]) -> Categorical: ...
76+
def as_ordered(self, inplace: Literal[False] = ...) -> Categorical: ...
7777
@overload
78-
def as_ordered(self, inplace: bool) -> Categorical | None: ...
78+
def as_ordered(self, inplace: bool = ...) -> Categorical | None: ...
7979
@overload
8080
def as_unordered(self, inplace: Literal[True]) -> None: ...
8181
@overload
@@ -155,7 +155,7 @@ class Categorical(ExtensionArray, PandasObject):
155155
def __ge__(self, other) -> bool: ...
156156
@property
157157
def shape(self): ...
158-
def shift(self, periods, fill_value=...): ...
158+
def shift(self, periods=..., fill_value=...): ...
159159
def __array__(self, dtype=...) -> np.ndarray: ...
160160
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): ...
161161
@property
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
def set_use_numexpr(v: bool = ...) -> None: ...
22
def set_numexpr_threads(n=...) -> None: ...
3-
def evaluate(op, op_str, a, b, use_numexpr: bool = ...): ...
3+
def evaluate(op, a, b, use_numexpr: bool = ...): ...
44
def where(cond, a, b, use_numexpr: bool = ...): ...
55
def set_test_mode(v: bool = ...) -> None: ...
66
def get_test_result(): ...

pandas-stubs/core/computation/ops.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22

33
class UndefinedVariableError(NameError):
4-
def __init__(self, name, is_local: bool) -> None: ...
4+
def __init__(self, name, is_local: bool = ...) -> None: ...
55

66
class Term:
77
def __new__(cls, name, env, side=..., encoding=...): ...

pandas-stubs/core/frame.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ class DataFrame(NDFrame, OpsMixin):
12911291
fill_value: float | None = ...,
12921292
) -> DataFrame: ...
12931293
def droplevel(
1294-
self, level: Level | list[Level] = ..., axis: AxisType = ...
1294+
self, level: Level | list[Level], axis: AxisType = ...
12951295
) -> DataFrame: ...
12961296
def eq(
12971297
self, other, axis: AxisType = ..., level: Level | None = ...

pandas-stubs/core/indexes/base.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class Index(IndexOpsMixin, PandasObject):
191191
def map(self, mapper, na_action=...) -> Index: ...
192192
def isin(self, values, level=...) -> np_ndarray_bool: ...
193193
def slice_indexer(self, start=..., end=..., step=..., kind=...): ...
194-
def get_slice_bound(self, label, side, kind): ...
194+
def get_slice_bound(self, label, side, kind=...): ...
195195
def slice_locs(self, start=..., end=..., step=..., kind=...): ...
196196
def delete(self, loc): ...
197197
def insert(self, loc, item): ...

pandas-stubs/core/indexes/category.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class CategoricalIndex(ExtensionIndex, accessor.PandasDelegate):
2525
def __contains__(self, key) -> bool: ...
2626
def __array__(self, dtype=...) -> np.ndarray: ...
2727
def astype(self, dtype: DtypeArg, copy: bool = ...) -> Index: ...
28-
def fillna(self, value, downcast=...): ...
28+
def fillna(self, value=..., downcast=...): ...
2929
def is_unique(self) -> bool: ...
3030
@property
3131
def is_monotonic_increasing(self) -> bool: ...

pandas-stubs/core/indexes/multi.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class MultiIndex(Index):
117117
def get_indexer_non_unique(self, target): ...
118118
def reindex(self, target, method=..., level=..., limit=..., tolerance=...): ...
119119
def get_slice_bound(
120-
self, label: Hashable | Sequence[Hashable], side: str, kind: str
120+
self, label: Hashable | Sequence[Hashable], side: str, kind: str = ...
121121
) -> int: ...
122122
def slice_locs(self, start=..., end=..., step=..., kind=...): ...
123123
def get_loc(self, key, method=...): ...

pandas-stubs/core/ops/roperator.pyi

-12
This file was deleted.

pandas-stubs/core/resample.pyi

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,15 @@ from pandas.core.groupby.grouper import Grouper as Grouper
66
from pandas._typing import FrameOrSeriesUnion
77

88
class Resampler(BaseGroupBy, ShallowMixin):
9-
def __init__(
10-
self, obj, groupby=..., axis: int = ..., kind=..., **kwargs
11-
) -> None: ...
9+
def __init__(self, obj, groupby, axis: int = ..., kind=..., **kwargs) -> None: ...
1210
def __getattr__(self, attr: str): ...
1311
def __iter__(self): ...
1412
@property
1513
def obj(self): ...
1614
@property
1715
def ax(self): ...
1816
def pipe(self, func, *args, **kwargs): ...
19-
def aggregate(self, func, *args, **kwargs): ...
17+
def aggregate(self, func=..., *args, **kwargs): ...
2018
agg = aggregate
2119
def transform(self, arg, *args, **kwargs): ...
2220
def pad(self, limit=...): ...

pandas-stubs/core/reshape/reshape.pyi

-27
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,6 @@
11
import numpy as np
22
from pandas.core.frame import DataFrame
33

4-
class _Unstacker:
5-
values = ...
6-
value_columns = ...
7-
fill_value = ...
8-
constructor = ...
9-
index = ...
10-
level = ...
11-
lift = ...
12-
new_index_levels = ...
13-
new_index_names = ...
14-
removed_name = ...
15-
removed_level = ...
16-
removed_level_full = ...
17-
def __init__(
18-
self,
19-
values: np.ndarray,
20-
index,
21-
level=...,
22-
value_columns=...,
23-
fill_value=...,
24-
constructor=...,
25-
) -> None: ...
26-
def get_result(self): ...
27-
def get_new_values(self): ...
28-
def get_new_columns(self): ...
29-
def get_new_index(self): ...
30-
314
def unstack(obj, level, fill_value=...): ...
325
def stack(frame, level: int = ..., dropna: bool = ...): ...
336
def stack_multiple(frame, level, dropna: bool = ...): ...

pandas-stubs/core/series.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]):
393393
def count(self, level: None = ...) -> int: ...
394394
@overload
395395
def count(self, level: Hashable) -> Series[S1]: ...
396-
def mode(self, dropna) -> Series[S1]: ...
396+
def mode(self, dropna=...) -> Series[S1]: ...
397397
def unique(self) -> np.ndarray: ...
398398
@overload
399399
def drop_duplicates(

pandas-stubs/core/window/rolling.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class _Window(PandasObject, ShallowMixin, SelectionMixin):
4646
def __getattr__(self, attr: str): ...
4747
def __iter__(self): ...
4848
def aggregate(
49-
self, func: Callable | None = ..., *args, **kwargs
49+
self, func: Callable | None, *args, **kwargs
5050
) -> Scalar | FrameOrSeries: ...
5151
agg = aggregate
5252

pandas-stubs/io/gcs.pyi

-7
This file was deleted.

pandas-stubs/io/parquet.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class FastParquetImpl(BaseImpl):
4343

4444
def to_parquet(
4545
df: DataFrame,
46-
path,
46+
path=...,
4747
engine: str = ...,
4848
compression=...,
4949
index: bool | None = ...,

pandas-stubs/io/s3.pyi

-18
This file was deleted.

pandas-stubs/io/sql.pyi

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ from typing import (
77
from pandas.core.base import PandasObject
88
from pandas.core.frame import DataFrame
99

10-
class SQLAlchemyRequired(ImportError): ...
1110
class DatabaseError(IOError): ...
1211

1312
def execute(sql, con, cur=..., params=...): ...
@@ -33,7 +32,7 @@ def read_sql_query(
3332
) -> DataFrame: ...
3433
def read_sql(
3534
sql: str | Any,
36-
con: str | Any = ...,
35+
con: str | Any,
3736
index_col: str | Sequence[str] | None = ...,
3837
coerce_float: bool = ...,
3938
params: Sequence[str] | tuple[str, ...] | Mapping[str, str] | None = ...,

pandas-stubs/util/_print_versions.pyi

-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
def get_sys_info() -> list[tuple[str, str | int | None]]: ...
21
def show_versions(as_json: bool = ...) -> None: ...
32
def main() -> int: ...

pandas-stubs/util/_test_decorators.pyi

-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
from typing import Callable
22

33
def safe_import(mod_name: str, min_version: str | None = ...): ...
4-
5-
tables = ...
6-
xfail_non_writeable = ...
7-
84
def skip_if_installed(package: str) -> Callable: ...
95
def skip_if_no(package: str, min_version: str | None = ...) -> Callable: ...
106

117
skip_if_no_mpl = ...
128
skip_if_mpl = ...
139
skip_if_32bit = ...
1410
skip_if_windows = ...
15-
skip_if_windows_python_3 = ...
1611
skip_if_has_locale = ...
1712
skip_if_not_us_locale = ...
1813
skip_if_no_scipy = ...

pyproject.toml

+4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ script = "scripts.test.run:pyright_src"
8888
help = "Run pyright on 'tests' using the installed stubs"
8989
script = "scripts.test:test(dist=True, type_checker='pyright')"
9090

91+
[tool.poe.tasks.stubtest]
92+
script = "scripts.test:stubtest(allowlist)"
93+
help = "Run stubtest to compare the installed stubs against pandas"
94+
args = [{ name = "allowlist", positional = true, default = "", required = false, help= "Path to an allowlist (optional)" }]
9195

9296

9397
[tool.black]

scripts/_job.py

+3
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,8 @@ def run_job(steps: List[Step]) -> None:
6363
end = time.perf_counter()
6464
logger.success(f"End: '{step.name}', runtime: {end - start:.3f} seconds.")
6565

66+
if not failed:
67+
__rollback_job(rollback_steps)
68+
6669
if failed:
6770
sys.exit(1)

scripts/test/__init__.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import dataclasses
2+
from functools import partial
13
from typing import Literal
24

35
from scripts._job import run_job
@@ -10,8 +12,6 @@
1012
_step.rename_src,
1113
_step.mypy_dist,
1214
_step.pyright_dist,
13-
_step.uninstall_dist,
14-
_step.restore_src,
1515
]
1616

1717

@@ -33,3 +33,10 @@ def test(
3333
steps = [step for step in steps if remove not in step.name]
3434

3535
run_job(steps)
36+
37+
38+
def stubtest(allowlist: str):
39+
stubtest = dataclasses.replace(
40+
_step.stubtest, run=partial(_step.stubtest.run, allowlist=allowlist)
41+
)
42+
run_job(_DIST_STEPS[:-2] + [stubtest])

scripts/test/_step.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@
2626
pyright_dist = Step(
2727
name="Run pyright on 'tests' using the installed stubs", run=run.pyright_dist
2828
)
29-
uninstall_dist = Step(name="Uninstall pandas-stubs", run=run.uninstall_dist)
30-
restore_src = Step(name="Restore local stubs", run=run.restore_src)
29+
stubtest = Step(
30+
name="Run stubtest to compare the installed stubs against pandas", run=run.stubtest
31+
)

scripts/test/run.py

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pathlib import Path
22
import subprocess
3+
import sys
34

45

56
def mypy_src():
@@ -22,6 +23,22 @@ def style():
2223
subprocess.run(cmd, check=True)
2324

2425

26+
def stubtest(allowlist: str = ""):
27+
cmd = [
28+
sys.executable,
29+
"-m",
30+
"mypy.stubtest",
31+
"pandas",
32+
"--concise",
33+
"--ignore-missing-stub",
34+
"--mypy-config-file",
35+
"pyproject.toml",
36+
]
37+
if allowlist:
38+
cmd += ["--allowlist", allowlist]
39+
subprocess.run(cmd, check=True)
40+
41+
2542
def build_dist():
2643
cmd = ["poetry", "build", "-f", "wheel"]
2744
subprocess.run(cmd, check=True)

0 commit comments

Comments
 (0)