Skip to content

Commit

Permalink
Using precise code for pyright: ignore and re-enabling various pyri…
Browse files Browse the repository at this point in the history
…ght tests (python#12576)
  • Loading branch information
Avasam authored and max-muoto committed Sep 8, 2024
1 parent 20a1dad commit 529ea3b
Show file tree
Hide file tree
Showing 18 changed files with 60 additions and 75 deletions.
7 changes: 5 additions & 2 deletions stdlib/@tests/test_cases/builtins/check_dict-py39.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,13 @@ def test_dict_dot_or(
assert_type(os.environ | c, dict[str, str])
assert_type(e | c, dict[str, str])

# store "untainted" `CustomMappingWithDunderOr[str, str]` to test `__ior__` against ` dict[str, str]` later
# Invalid `e |= a` causes pyright to join `Unknown` to `e`'s type
f = e

e |= c
e |= a # type: ignore

# TODO: this test passes mypy, but fails pyright for some reason:
# c |= e
c |= f

c |= a # type: ignore
1 change: 1 addition & 0 deletions stdlib/@tests/test_cases/builtins/check_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# mypy and pyright have different opinions about this one:
# mypy raises: 'Need type annotation for "bad"'
# pyright is fine with it.
# https://github.com/python/mypy/issues/12358
# bad = dict()
good: dict[str, str] = dict()
assert_type(good, Dict[str, str])
Expand Down
12 changes: 6 additions & 6 deletions stdlib/@tests/test_cases/builtins/check_pow.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
# assert_type(pow(2, 4, 0), NoReturn)

assert_type(pow(2, 4), int)
# pyright infers a literal type here, but mypy does not. Unfortunately,
# there is no way to ignore an error only for mypy, so we can't check
# pyright's handling (https://github.com/python/mypy/issues/12358).
assert_type(2**4, int) # pyright: ignore
# pyright infers a literal type here, but mypy does not.
# Unfortunately, there is no way to ignore an error only for mypy,
# whilst getting both pyright and mypy to respect `type: ignore`.
# So we can't check pyright's handling (https://github.com/python/mypy/issues/12358).
assert_type(2**4, int) # pyright: ignore[reportAssertTypeFailure]
# pyright version: assert_type(2**4, Literal[16])
assert_type(pow(4, 6, None), int)

Expand All @@ -34,8 +35,7 @@
assert_type(2**8.6, float)
assert_type(pow(2, 8.6, None), float)

# TODO: Why does this pass pyright but not mypy??
# assert_type((-2) ** 0.5, complex)
assert_type((-2) ** 0.5, complex)

assert_type(pow((-5), 8.42, None), complex)

Expand Down
4 changes: 2 additions & 2 deletions stdlib/@tests/test_cases/builtins/check_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __radd__(self, other: Any) -> Baz:

# mypy and pyright infer the types differently for these, so we can't use assert_type
# Just test that no error is emitted for any of these
sum([("foo",), ("bar", "baz")], ()) # mypy: `tuple[str, ...]`; pyright: `tuple[()] | tuple[str] | tuple[str, str]`
sum([("foo",), ("bar", "baz")], ()) # mypy: `tuple[str, ...]`; pyright: `tuple[str] | tuple[str, str] | tuple[()]`
sum([5.6, 3.2]) # mypy: `float`; pyright: `float | Literal[0]`
sum([2.5, 5.8], 5) # mypy: `float`; pyright: `float | int`

Expand All @@ -52,4 +52,4 @@ def __radd__(self, other: Any) -> Baz:

# TODO: these pass pyright with the current stubs, but mypy erroneously emits an error:
# sum([3, Fraction(7, 22), complex(8, 0), 9.83])
# sum([3, Decimal('0.98')])
# sum([3, Decimal("0.98")])
35 changes: 10 additions & 25 deletions stdlib/@tests/test_cases/check_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,9 @@ class Foo:

assert_type(dc.fields(Foo), Tuple[dc.Field[Any], ...])

# Mypy correctly emits errors on these
# due to the fact it's a dataclass class, not an instance.
# Pyright, however, handles ClassVar members in protocols differently.
# See https://github.com/microsoft/pyright/issues/4339
#
# dc.asdict(Foo)
# dc.astuple(Foo)
# dc.replace(Foo)
dc.asdict(Foo) # type: ignore
dc.astuple(Foo) # type: ignore
dc.replace(Foo) # type: ignore

# See #9723 for why we can't make this assertion
# if dc.is_dataclass(Foo):
Expand Down Expand Up @@ -57,7 +52,7 @@ def is_dataclass_type(arg: type) -> None:


def check_other_isdataclass_overloads(x: type, y: object) -> None:
# TODO: pyright correctly emits an error on this, but mypy does not -- why?
# TODO: neither pyright nor mypy emit error on this -- why?
# dc.fields(x)

dc.fields(y) # type: ignore
Expand All @@ -75,27 +70,17 @@ def check_other_isdataclass_overloads(x: type, y: object) -> None:
assert_type(x, Type["DataclassInstance"])
assert_type(dc.fields(x), Tuple[dc.Field[Any], ...])

# Mypy correctly emits an error on these due to the fact
# that it's a dataclass class, not a dataclass instance.
# Pyright, however, handles ClassVar members in protocols differently.
# See https://github.com/microsoft/pyright/issues/4339
#
# dc.asdict(x)
# dc.astuple(x)
# dc.replace(x)
dc.asdict(x) # type: ignore
dc.astuple(x) # type: ignore
dc.replace(x) # type: ignore

if dc.is_dataclass(y):
assert_type(y, Union["DataclassInstance", Type["DataclassInstance"]])
assert_type(dc.fields(y), Tuple[dc.Field[Any], ...])

# Mypy correctly emits an error on these due to the fact we don't know
# whether it's a dataclass class or a dataclass instance.
# Pyright, however, handles ClassVar members in protocols differently.
# See https://github.com/microsoft/pyright/issues/4339
#
# dc.asdict(y)
# dc.astuple(y)
# dc.replace(y)
dc.asdict(y) # type: ignore
dc.astuple(y) # type: ignore
dc.replace(y) # type: ignore

if dc.is_dataclass(y) and not isinstance(y, type):
assert_type(y, "DataclassInstance")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,13 @@ def test_defaultdict_dot_or(
assert_type(os.environ | c, dict[str, str])
assert_type(e | c, dict[str, str])

# store "untainted" `CustomMappingWithDunderOr[str, str]` to test `__ior__` against ` defaultdict[str, str]` later
# Invalid `e |= a` causes pyright to join `Unknown` to `e`'s type
f = e

e |= c
e |= a # type: ignore

# TODO: this test passes mypy, but fails pyright for some reason:
# c |= e
c |= f

c |= a # type: ignore
6 changes: 3 additions & 3 deletions stdlib/collections/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -345,15 +345,15 @@ class _OrderedDictValuesView(ValuesView[_VT_co], Reversible[_VT_co]):
# but they are not exposed anywhere)
# pyright doesn't have a specific error code for subclassing error!
@final
class _odict_keys(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc] # pyright: ignore
class _odict_keys(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
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] # pyright: ignore
class _odict_items(dict_items[_KT_co, _VT_co], Reversible[tuple[_KT_co, _VT_co]]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
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] # pyright: ignore
class _odict_values(dict_values[_KT_co, _VT_co], Reversible[_VT_co], Generic[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
def __reversed__(self) -> Iterator[_VT_co]: ...

class OrderedDict(dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]):
Expand Down
9 changes: 4 additions & 5 deletions stdlib/dataclasses.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,17 @@ if sys.version_info >= (3, 9):
else:
class _InitVarMeta(type):
# Not used, instead `InitVar.__class_getitem__` is called.
# pyright ignore is needed because pyright (not unreasonably) thinks this
# is an invalid use of InitVar.
def __getitem__(self, params: Any) -> InitVar[Any]: ... # pyright: ignore
# pyright (not unreasonably) thinks this is an invalid use of InitVar.
def __getitem__(self, params: Any) -> InitVar[Any]: ... # pyright: ignore[reportInvalidTypeForm]

class InitVar(Generic[_T], metaclass=_InitVarMeta):
type: Type[_T]
def __init__(self, type: Type[_T]) -> None: ...
if sys.version_info >= (3, 9):
@overload
def __class_getitem__(cls, type: Type[_T]) -> InitVar[_T]: ... # pyright: ignore
def __class_getitem__(cls, type: Type[_T]) -> InitVar[_T]: ... # pyright: ignore[reportInvalidTypeForm]
@overload
def __class_getitem__(cls, type: Any) -> InitVar[Any]: ... # pyright: ignore
def __class_getitem__(cls, type: Any) -> InitVar[Any]: ... # pyright: ignore[reportInvalidTypeForm]

if sys.version_info >= (3, 12):
def make_dataclass(
Expand Down
2 changes: 1 addition & 1 deletion stdlib/typing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# ruff: noqa: F811
# TODO: The collections import is required, otherwise mypy crashes.
# https://github.com/python/mypy/issues/16744
import collections # noqa: F401 # pyright: ignore
import collections # noqa: F401 # pyright: ignore[reportUnusedImport]
import sys
import typing_extensions
from _collections_abc import dict_items, dict_keys, dict_values
Expand Down
2 changes: 1 addition & 1 deletion stubs/JACK-Client/jack/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ from numpy.typing import NDArray
# Actual type: _cffi_backend.__CDataOwn <cdata 'struct _jack_position *'>
# This is not a real subclassing. Just ensuring type-checkers sees this type as compatible with _CDataBase
# pyright has no error code for subclassing final
class _JackPositionT(_CDataBase): # type: ignore[misc] # pyright: ignore
class _JackPositionT(_CDataBase): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
audio_frames_per_video_frame: float
bar: int
bar_start_tick: float
Expand Down
20 changes: 10 additions & 10 deletions stubs/Pillow/@tests/test_cases/check_tk_compat.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# Verify that ImageTK images are valid to pass to TK code.
from __future__ import annotations

# The following tests don't work at the moment, due to pyright getting
# The following tests don't work on pyright at the moment, due to it getting
# confused by the existence of these stubs and annotations in the actual
# Pillow package.
# https://github.com/python/typeshed/issues/11688
# pyright: reportArgumentType=false
import tkinter

# import tkinter
from PIL import ImageTk

# from PIL import ImageTk
photo = ImageTk.PhotoImage()
bitmap = ImageTk.BitmapImage()

# photo = ImageTk.PhotoImage()
# bitmap = ImageTk.BitmapImage()
tkinter.Label(image=photo)
tkinter.Label(image=bitmap)

# tkinter.Label(image=photo)
# tkinter.Label(image=bitmap)

# tkinter.Label().configure(image=photo)
# tkinter.Label().configure(image=bitmap)
tkinter.Label().configure(image=photo)
tkinter.Label().configure(image=bitmap)
18 changes: 6 additions & 12 deletions stubs/WebOb/@tests/test_cases/check_wsgify.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,7 @@ def app(request: Request) -> str:
assert_type(app, "wsgify[Request, []]")
assert_type(app(env, start_response), "Iterable[bytes]")
assert_type(app(request), _AnyResponse)
# FIXME: For some reason pyright complains here with
# mismatch: expected "wsgify[Request, ()]" but received "wsgify[Request, ()]"
# can you spot the difference?
# assert_type(app(application), "wsgify[Request, []]")
assert_type(app(application), "wsgify[Request, []]")
application = app(application)


Expand All @@ -78,13 +75,10 @@ def m_app(request: Request) -> str:


application = m_app
# FIXME: same weird pyright error where it complains about the types
# being the same
# assert_type(m_app, "wsgify[Request, [WSGIApplication]]")
assert_type(m_app, "wsgify[Request, [WSGIApplication]]")
assert_type(m_app(env, start_response), "Iterable[bytes]")
assert_type(m_app(request), _AnyResponse)
# FIXME: and also here
# assert_type(m_app(application), "wsgify[Request, [WSGIApplication]]")
assert_type(m_app(application), "wsgify[Request, [WSGIApplication]]")
application = m_app(application)


Expand All @@ -109,13 +103,13 @@ def valid_request_app(request: Request) -> None:


# but the opposite is not allowed
@wsgify # type:ignore
@wsgify # type: ignore
def invalid_request_app(request: MyRequest) -> None:
pass


# we can't really make passing extra arguments directly work
# otherwise we have to give up most of our type safety for
# something that should only be used through wsgify.middleware
wsgify(args=(1,)) # type:ignore
wsgify(kwargs={"ips": ["127.0.0.1"]}) # type:ignore
wsgify(args=(1,)) # type: ignore
wsgify(kwargs={"ips": ["127.0.0.1"]}) # type: ignore
2 changes: 1 addition & 1 deletion stubs/openpyxl/@tests/test_cases/check_base_descriptors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Needed until mypy issues are solved
# Needed until mypy issues are solved or https://github.com/python/mypy/issues/12358
# pyright: reportUnnecessaryTypeIgnoreComment=false
from __future__ import annotations

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Needed until mypy issues are solved
# Needed until mypy issues are solved or https://github.com/python/mypy/issues/12358
# pyright: reportUnnecessaryTypeIgnoreComment=false

# These tests are essentially a mirror of check_base_descriptors
Expand Down
2 changes: 1 addition & 1 deletion stubs/pygit2/pygit2/_pygit2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ class Blob(Object):
# This is not a real subclassing. Just ensuring type-checkers sees this type as compatible with _CDataBase
# pyright has no error code for subclassing final
@final
class Branch(Reference): # type: ignore[misc] # pyright: ignore
class Branch(Reference): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
branch_name: str
raw_branch_name: bytes
remote_name: str
Expand Down
2 changes: 1 addition & 1 deletion stubs/pygit2/pygit2/utils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def strarray_to_strings(arr: _GitStrArray) -> list[str]: ...
# Actual type: _cffi_backend.__CDataOwn <cdata 'struct git_strarray *'>
# This is not a real subclassing. Just ensuring type-checkers sees this type as compatible with _CDataBase
# pyright has no error code for subclassing final
class _GitStrArray(_CDataBase): # type: ignore[misc] # pyright: ignore
class _GitStrArray(_CDataBase): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
count: int
strings: _CDataBase # <cdata 'char * *'>

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 @@ -15,7 +15,7 @@ class DebugDocumentProvider(gateways.DebugDocumentProvider):

# error: Cannot determine consistent method resolution order (MRO) for "DebugDocumentText"
# pyright doesn't have a specific error code for MRO error!
class DebugDocumentText(gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument): # type: ignore[misc] # pyright: ignore
class DebugDocumentText(gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
codeContainer: Incomplete
def __init__(self, codeContainer) -> None: ...
def GetName(self, dnt): ...
Expand Down
2 changes: 1 addition & 1 deletion tests/pytype_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def get_missing_modules(files_to_test: Sequence[str]) -> Iterable[str]:
# Skips comments, empty lines, and stdlib files, which are in
# the exclude list because pytype has its own version.
continue
unused_stubs_prefix, unused_pkg, mod_path = fi.split("/", 2) # pyright: ignore [reportUnusedVariable]
unused_stubs_prefix, unused_pkg, mod_path = fi.split("/", 2) # pyright: ignore[reportUnusedVariable]
missing_modules.add(os.path.splitext(mod_path)[0])
return missing_modules

Expand Down

0 comments on commit 529ea3b

Please sign in to comment.