Skip to content

Commit d9de135

Browse files
authored
DOC: ignore comments (#490)
* DOC: ignore comments * re-write docs * add codespell * update wording * typo * adjust wide-narrow example * TYPE_CHECKING_INVALID_USAGE
1 parent 0b46778 commit d9de135

File tree

7 files changed

+40
-10
lines changed

7 files changed

+40
-10
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,8 @@ repos:
3434
# TypeVars in private files are already private
3535
--per-file-ignores=_*.pyi:Y001
3636
]
37+
- repo: https://github.com/codespell-project/codespell
38+
rev: v2.2.2
39+
hooks:
40+
- id: codespell
41+
additional_dependencies: [ tomli ]

docs/philosophy.md

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,36 @@ Here is an example that illustrates this concept, from `tests/test_interval.py`:
100100
i1 = pd.Interval(
101101
pd.Timestamp("2000-01-01"), pd.Timestamp("2000-01-03"), closed="both"
102102
)
103-
if TYPE_CHECKING:
104-
i1 + pd.Timestamp("2000-03-03") # type: ignore
103+
if TYPE_CHECKING_INVALID_USAGE:
104+
i1 + pd.Timestamp("2000-03-03") # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues]
105105

106106
```
107107

108108
In this particular example, the stubs consider that `i1` will have the type
109109
`pd.Interval[pd.Timestamp]`. It is incorrect code to add a `Timestamp` to a
110-
time-based interval. Without the `if TYPE_CHECKING` construct, the code would fail.
111-
However, it is also desirable to have the type checker pick up this failure, and by
112-
placing the `# type: ignore` on the line, an indication is made to the type checker
113-
that we expect this line to not pass the type checker.
110+
time-based interval. Without the `if TYPE_CHECKING_INVALID_USAGE` construct, the
111+
code would fail at runtime. Further, type checkers should report an error for this
112+
incorrect code. By placing the `# type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues]`
113+
on the line, type checkers are told to ignore the type error. To ensure that the
114+
pandas-stubs annotations are not too wide (allow adding a `Timestamp` to a
115+
time-based interval), mypy and pyright are configured to report unused ignore
116+
statements.
117+
118+
## Using ignore comments
119+
120+
Type checkers report errors
121+
122+
- when writing negative tests to reject invalid behavior (inside a
123+
`TYPE_CHECKING_INVALID_USAGE` block),
124+
- when writing `overload`s that return incompatible return values, or
125+
- when type checkers have bugs themselves.
126+
127+
Since mypy and pyright behave slightly differently, we use separate ignore comments
128+
for them.
129+
130+
- If mypy reports an error, please use `# type: ignore[<error code>]`
131+
- If pyright reports an error, please use `# pyright: ignore[<error code>]`
132+
133+
If mypy and pyright report errors, for example, inside a `TYPE_CHECKING_INVALID_USAGE`
134+
block, please ensure that the comment for mypy comes first:
135+
`# type: ignore[<error code>] # pyright: ignore[<error code>]`.

docs/release_procedure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
```shell
99
rm dist/*
10-
poetry pubish --build # you will get prompted for your pypi username/password
10+
poetry publish --build # you will get prompted for your pypi username/password
1111
git commit -a -m "Version a.b.c.yymmdd"
1212
git push upstream main
1313
git tag va.b.c.yymmdd

pandas-stubs/core/groupby/groupby.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class GroupBy(BaseGroupBy[NDFrameT]):
9696
) -> DataFrame | Series: ...
9797
def head(self, n: int = ...) -> DataFrame | Series: ...
9898
def tail(self, n: int = ...) -> DataFrame | Series: ...
99-
# Surplus methodss from original pylance stubs; should they go away?
99+
# Surplus methods from original pylance stubs; should they go away?
100100
def first(self, **kwargs) -> DataFrame | Series: ...
101101
def last(self, **kwargs) -> DataFrame | Series: ...
102102
def max(self, **kwargs) -> DataFrame | Series: ...

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,6 @@ reportUnusedVariable = false
194194
reportPrivateUsage = false
195195
# enable optional checks
196196
reportMissingModuleSource = true
197+
198+
[tool.codespell]
199+
ignore-words-list = "indext, mose, sav, ser"

tests/test_pandas.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ def test_merge() -> None:
973973
),
974974
pd.DataFrame,
975975
)
976-
# TOOD: When cross don't need on??
976+
# TODO: When cross don't need on??
977977
check(assert_type(pd.merge(ls, rs, how="cross"), pd.DataFrame), pd.DataFrame)
978978
check(
979979
assert_type(

tests/test_series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def test_types_shift() -> None:
262262
def test_types_rank() -> None:
263263
s = pd.Series([1, 1, 2, 5, 6, np.nan])
264264
if PD_LTE_15:
265-
s[6] = "milion"
265+
s[6] = "million"
266266
with pytest_warns_bounded(
267267
FutureWarning,
268268
match="Dropping of nuisance columns",

0 commit comments

Comments
 (0)