8000 Check for unused `pyright: ignore` and differentiate from mypy ignores by Avasam · Pull Request #9397 · python/typeshed · GitHub
[go: up one dir, main page]

Skip to content

Check for unused pyright: ignore and differentiate from mypy ignores #9397

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
Next Next commit
Check for unused pyright: ignore
Prevent type: ignore[*] comments from supressing all pyright errors
Added more comments to pyright config
  • Loading branch information
Avasam committed Dec 21, 2022
< 8000 span class="text-small color-fg-muted text-mono">commit af804b664f1b0e1f7ca8ddeb95d44f791fc8507b
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ all = true
disable_all_dunder_policy = true

[tool.typeshed]
pyright_version = "1.1.284"
pyright_version = "1.1.285"
6 changes: 6 additions & 0 deletions pyrightconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"reportInconsistentConstructor": "error",
"reportTypeCommentUsage": "error",
"reportUnnecessaryComparison": "error",
"reportUnnecessaryTypeIgnoreComment": "error",
// Leave "type: ignore" comments to mypy
"enableTypeIgnoreComments": false,
// Stubs are allowed to use private variables
"reportPrivateUsage": "none",
// Stubs don't need the actual modules to be installed
"reportMissingModuleSource": "none",
// Incompatible overrides and property type mismatches are out of typeshed's control
// as they are inherited from the implementation.
Expand Down
6 changes: 6 additions & 0 deletions pyrightconfig.stricter.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,14 @@
"stubs/vobject",
],
"typeCheckingMode": "strict",
"reportUnnecessaryTypeIgnoreComment": "error",
// Leave "type: ignore" comments to mypy
"enableTypeIgnoreComments": false,
// Stubs are allowed to use private variables
"reportPrivateUsage": "none",
// TODO: Complete incomplete stubs
"reportIncompleteStub": "none",
// Stubs don't need the actual modules to be installed
"reportMissingModuleSource": "none",
// Incompatible overrides and property type mismatches are out of typeshed's control
// as they are inherited from the implementation.
Expand Down
3 changes: 3 additions & 0 deletions pyrightconfig.testcases.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"test_cases",
],
"typeCheckingMode": "strict",
// Using unspecific "type ignore" comments in test_cases.
// See https://github.com/python/typeshed/pull/8083
"enableTypeIgnoreComments": true,
"reportPropertyTypeMismatch": "error",
"reportUnnecessaryTypeIgnoreComment": "error",
"reportMissingModuleSource": "none",
Expand Down
2 changes: 1 addition & 1 deletion stdlib/asyncio/tasks.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ else:
# While this is true in general, here it's sort-of okay to have a covariant subclass,
# since the only reason why `asyncio.Future` is invariant is the `set_result()` method,
# and `asyncio.Task.set_result()` always raises.
class Task(Future[_T_co], Generic[_T_co]): # type: ignore[type-var]
class Task(Future[_T_co], Generic[_T_co]): # type: ignore[type-var] # pyright: ignore[reportGeneralTypeIssues]
if sys.version_info >= (3, 8):
def __init__(
self,
Expand Down
2 changes: 1 addition & 1 deletion stdlib/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ class property:
class _NotImplementedType(Any): # type: ignore[misc]
# A little weird, but typing the __call__ as NotImplemented makes the error message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to your PR but we should probably revisit this and see if it actually makes things better for all type checkers.

# for NotImplemented() much better
__call__: NotImplemented # type: ignore[valid-type]
__call__: NotImplemented # type: ignore[valid-type] # pyright: ignore[reportGeneralTypeIssues]

NotImplemented: _NotImplementedType

Expand Down
6 changes: 3 additions & 3 deletions stdlib/collections/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,15 @@ class _OrderedDictValuesView(ValuesView[_VT_co], Reversible[_VT_co]):
# (At runtime, these are called `odict_keys`, `odict_items` and `odict_values`,
# but they are not exposed anywhere)
@final
class _odict_keys(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc]
class _odict_keys(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc] # pyright: ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we able to add the pyright error codes for these pyright: ignores?

Copy link
Collaborator Author
@Avasam Avasam Dec 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no code!
image

Base class "dict_keys[_KT_co@_odict_keys, _VT_co@_odict_keys]" is marked final and cannot be subclassed Pylance

image

E:\Users\Avasam\Documents\Git\typeshed\stdlib\collections_init_.pyi
E:\Users\Avasam\Documents\Git\typeshed\stdlib\collections_init_.pyi:331:19 - error: Base class "dict_keys[_KT_co@_odict_keys, _VT_co@_odict_keys]" is marked final and cannot be subclassed

Copy link
Member

Choose a reason for hiding this comment F438

The reason will be displayed to describe this comment to others. Learn more.

Oh, strange! In that case, can we leave a comment to that effect? (Same below for the other one)

Suggested change
class _odict_keys(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc] # pyright: ignore
# pyright doesn't have a specific error code for this error!
class _odict_keys(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc] # pyright: ignore

def __reversed__(self) -> Iterator[_KT_co]: ...

@final
class _odict_items(dict_items[_KT_co, _VT_co], Reversible[tuple[_KT_co, _VT_co]]): # type: ignore[misc]
class _odict_items(dict_items[_KT_co, _VT_co], Reversible[tuple[_KT_co, _VT_co]]): # type: ignore[misc] # pyright: ignore
def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ...

@final
class _odict_values(dict_values[_KT_co, _VT_co], Reversible[_VT_co], Generic[_KT_co, _VT_co]): # type: ignore[misc]
class _odict_values(dict_values[_KT_co, _VT_co], Reversible[_VT_co], Generic[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore
def __reversed__(self) -> Iterator[_VT_co]: ...

class OrderedDict(dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]):
Expand Down
4 changes: 2 additions & 2 deletions stdlib/ctypes/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ class _CDataMeta(type):
# By default mypy complains about the following two methods, because strictly speaking cls
# might not be a Type[_CT]. However this can never actually happen, because the only class that
# uses _CDataMeta as its metaclass is _CData. So it's safe to ignore the errors here.
def __mul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc]
def __rmul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc]
def __mul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
def __rmul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]

class _CData(metaclass=_CDataMeta):
_b_base: int
Expand Down
2 changes: 1 addition & 1 deletion stdlib/subprocess.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class CompletedProcess(Generic[_T]):
args: _CMD,
returncode: int,
stdout: _T | None = ..., # pyright: ignore[reportInvalidTypeVarUse]
stderr: _T | None = ..., # pyright: ignore[reportInvalidTypeVarUse]
stderr: _T | None = ...,
) -> None: ...
def check_returncode(self) -> None: ...
if sys.version_info >= (3, 9):
Expand Down
3 changes: 2 additions & 1 deletion stubs/SQLAlchemy/sqlalchemy/orm/path_registry.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from _typeshed import Incomplete
from typing import Any, ClassVar

from ..sql.traversals import HasCacheKey
Expand Down Expand Up @@ -100,7 +101,7 @@ class AbstractEntityRegistry(PathRegistry):
class SlotsEntityRegistry(AbstractEntityRegistry):
inherit_cache: bool

class CachingEntityRegistry(AbstractEntityRegistry, dict): # type: ignore[misc]
class CachingEntityRegistry(AbstractEntityRegistry, dict[Incomplete, Incomplete]): # type: ignore[misc]
inherit_cache: bool
def __getitem__(self, entity): ...
def __missing__(self, key): ...
8 changes: 4 additions & 4 deletions stubs/SQLAlchemy/sqlalchemy/util/_collections.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ class OrderedSet(set[_T], Generic[_T]):
def update(self: Self, iterable: Iterable[_T]) -> Self: ... # type: ignore[override]
__ior__ = update # type: ignore[assignment]
def union(self, other: Iterable[_S]) -> OrderedSet[_S | _T]: ... # type: ignore[override]
__or__ = union # type: ignore[assignment]
__or__ = union # type: ignore[assignment] # pyright: ignore[reportGeneralTypeIssues]
def intersection(self: Self, other: Iterable[Any]) -> Self: ... # type: ignore[override]
__and__ = intersection # type: ignore[assignment]
__and__ = intersection # type: ignore[assignment] # pyright: ignore[reportGeneralTypeIssues]
def symmetric_difference(self, other: Iterable[_S]) -> OrderedSet[_S | _T]: ...
__xor__ = symmetric_difference # type: ignore[assignment]
__xor__ = symmetric_difference # type: ignore[assignment] # pyright: ignore[reportGeneralTypeIssues]
def difference(self: Self, other: Iterable[Any]) -> Self: ... # type: ignore[override]
__sub__ = difference # type: ignore[assignment]
__sub__ = difference # type: ignore[assignment] # pyright: ignore[reportGeneralTypeIssues]
def intersection_update(self: Self, other: Iterable[Any]) -> Self: ... # type: ignore[override]
__iand__ = intersection_update # type: ignore[assignment]
def symmetric_difference_update(self: Self, other: Iterable[_T]) -> Self: ... # type: ignore[override]
Expand Down
4 changes: 2 additions & 2 deletions stubs/invoke/invoke/tasks.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from _typeshed import Self
from _typeshed import Incomplete, Self
from collections.abc import Callable, Iterable
from typing import Any, Generic, TypeVar, overload
from typing_extensions import ParamSpec
Expand Down Expand Up @@ -48,7 +48,7 @@ class Task(Generic[_P, _R_co]):
) -> None: ...
@property
def name(self): ...
def __eq__(self, other: Task) -> bool: ... # type: ignore[override]
def __eq__(self, other: Task[Incomplete, Incomplete]) -> bool: ... # type: ignore[override]
def __hash__(self) -> int: ...
def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _R_co: ...
@property
Expand Down
2 changes: 1 addition & 1 deletion stubs/prettytable/prettytable/colortable.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Theme:
junction_color: str = ...,
) -> None: ...
# The following method is broken in upstream code.
def format_code(s: str) -> str: ... # type: ignore[misc]
def format_code(s: str) -> str: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]

class Themes:
DEFAULT: ClassVar[Theme]
Expand Down
2 changes: 1 addition & 1 deletion stubs/pywin32/win32comext/axdebug/documents.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class DebugDocumentProvider(gateways.DebugDocumentProvider):
def GetDocument(self): ...

# error: Cannot determine consistent method resolution order (MRO) for "DebugDocumentText"
class DebugDocumentText(gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument): # type: ignore[misc]
class DebugDocumentText(gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument): # type: ignore[misc] # pyright: ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which pyright error are we ignoring here? Can we add the error code?

Copy link
Collaborator Author
@Avasam Avasam Dec 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, no code, and if iirc, this does fail at runtime. I had already added a comment to explain the ignore.

Cannot create consistent method ordering Pylance

I could create a feature request with pyright to add a code for "will fail at runtime". But this should rather be fixed upstream (and pywin32 already has accepted a couple fixes I found through type-checking).

And for the other case above, it's kindof a niche type-stub use-case, and is totally fixable by splitting off into another private/internal protocol (which I didn't do to keep changes minimal)

codeContainer: Incomplete
def __init__(self, codeContainer) -> None: ...
def GetName(self, dnt): ...
Expand Down
2 changes: 1 addition & 1 deletion stubs/redis/redis/client.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ class Pipeline(Redis[_StrType], Generic[_StrType]):
def sscan_iter(self, name: _Key, match: _Key | None = ..., count: int | None = ...) -> Iterator[Any]: ...
def hscan(self, name: _Key, cursor: int = ..., match: _Key | None = ..., count: int | None = ...) -> Pipeline[_StrType]: ... # type: ignore[override]
def hscan_iter(self, name, match: _Key | None = ..., count: int | None = ...) -> Iterator[Any]: ...
def zscan(self, name: _Key, cursor: int = ..., match: _Key | None = ..., count: int | None = ..., score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn] = ...) -> Pipeline[_StrType]: ... # type: ignore[override]
def zscan(self, name: _Key, cursor: int = ..., match: _Key | None = ..., count: int | None = ..., score_cast_func: Callable[[_StrType], Any] = ...) -> Pipeline[_StrType]: ... # type: ignore[override]
def zscan_iter(
self, name: _Key, match: _Key | None = ..., count: int | None = ..., score_cast_func: Callable[[_StrType], Any] = ...
) -> Iterator[Any]: ...
Expand Down
3 changes: 2 additions & 1 deletion stubs/redis/redis/commands/json/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from _typeshed import Incomplete
from typing import Any

from ...client import Pipeline as ClientPipeline
Expand All @@ -11,4 +12,4 @@ class JSON(JSONCommands):
def __init__(self, client, version: Any | None = ..., decoder=..., encoder=...) -> None: ...
def pipeline(self, transaction: bool = ..., shard_hint: Any | None = ...) -> Pipeline: ...

class Pipeline(JSONCommands, ClientPipeline): ... # type: ignore[misc]
class Pipeline(JSONCommands, ClientPipeline[Incomplete]): ... # type: ignore[misc]
3 changes: 2 additions & 1 deletion stubs/redis/redis/commands/timeseries/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from _typeshed import Incomplete
from typing import Any

from ...client import Pipeline as ClientPipeline
Expand All @@ -10,4 +11,4 @@ class TimeSeries(TimeSeriesCommands):
def __init__(self, client: Any | None = ..., **kwargs) -> None: ...
def pipeline(self, transaction: bool = ..., shard_hint: Any | None = ...) -> Pipeline: ...

class Pipeline(TimeSeriesCommands, ClientPipeline): ... # type: ignore[misc]
class Pipeline(TimeSeriesCommands, ClientPipeline[Incomplete]): ... # type: ignore[misc]
0