Use strict mypy checking (#3222)

Co-authored-by: Richard Si <63936253+ichard26@users.noreply.github.com>
This commit is contained in:
Shantanu 2022-08-30 20:46:46 -07:00 committed by GitHub
parent ba618a307a
commit 2c90480e1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 41 deletions

View File

@ -49,6 +49,8 @@ repos:
- types-typed-ast >= 1.4.1 - types-typed-ast >= 1.4.1
- click >= 8.1.0 - click >= 8.1.0
- platformdirs >= 2.1.0 - platformdirs >= 2.1.0
- pytest
- hypothesis
- repo: https://github.com/pre-commit/mirrors-prettier - repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1 rev: v2.7.1

View File

@ -7,33 +7,40 @@ python_version=3.6
mypy_path=src mypy_path=src
show_column_numbers=True show_column_numbers=True
show_error_codes=True
# show error messages from unrelated files
follow_imports=normal
# suppress errors about unsatisfied imports
ignore_missing_imports=True
# be strict # be strict
disallow_untyped_calls=True strict=True
warn_return_any=True
strict_optional=True # except for...
warn_no_return=True no_implicit_reexport = False
warn_redundant_casts=True
warn_unused_ignores=True
disallow_any_generics=True
no_implicit_optional=True
# Unreachable blocks have been an issue when compiling mypyc, let's try # Unreachable blocks have been an issue when compiling mypyc, let's try
# to avoid 'em in the first place. # to avoid 'em in the first place.
warn_unreachable=True warn_unreachable=True
# The following are off by default. Flip them on if you feel
# adventurous.
disallow_untyped_defs=True
check_untyped_defs=True
[mypy-black] [mypy-black]
# The following is because of `patch_click()`. Remove when # The following is because of `patch_click()`. Remove when
# we drop Python 3.6 support. # we drop Python 3.6 support.
warn_unused_ignores=False warn_unused_ignores=False
[mypy-blib2to3.driver.*]
ignore_missing_imports = True
[mypy-IPython.*]
ignore_missing_imports = True
[mypy-colorama.*]
ignore_missing_imports = True
[mypy-pathspec.*]
ignore_missing_imports = True
[mypy-tokenize_rt.*]
ignore_missing_imports = True
[mypy-uvloop.*]
ignore_missing_imports = True
[mypy-_black_version.*]
ignore_missing_imports = True

View File

@ -85,5 +85,8 @@ def test_idempotent_any_syntatically_valid_python(
pass pass
else: else:
test = test_idempotent_any_syntatically_valid_python test = test_idempotent_any_syntatically_valid_python
atheris.Setup(sys.argv, test.hypothesis.fuzz_one_input) atheris.Setup(
sys.argv,
test.hypothesis.fuzz_one_input, # type: ignore[attr-defined]
)
atheris.Fuzz() atheris.Fuzz()

View File

@ -9,7 +9,7 @@
def cors(allow_headers: Iterable[str]) -> Middleware: def cors(allow_headers: Iterable[str]) -> Middleware:
@middleware @middleware # type: ignore[misc]
async def impl(request: Request, handler: Handler) -> StreamResponse: async def impl(request: Request, handler: Handler) -> StreamResponse:
is_options = request.method == "OPTIONS" is_options = request.method == "OPTIONS"
is_preflight = is_options and "Access-Control-Request-Method" in request.headers is_preflight = is_options and "Access-Control-Request-Method" in request.headers
@ -32,4 +32,4 @@ async def impl(request: Request, handler: Handler) -> StreamResponse:
return resp return resp
return impl # type: ignore return impl # type: ignore[no-any-return]

View File

@ -10,7 +10,7 @@
There's also a pattern matching implementation here. There's also a pattern matching implementation here.
""" """
# mypy: allow-untyped-defs # mypy: allow-untyped-defs, allow-incomplete-defs
from typing import ( from typing import (
Any, Any,
@ -291,7 +291,7 @@ def __str__(self) -> Text:
""" """
return "".join(map(str, self.children)) return "".join(map(str, self.children))
def _eq(self, other) -> bool: def _eq(self, other: Base) -> bool:
"""Compare two nodes for equality.""" """Compare two nodes for equality."""
return (self.type, self.children) == (other.type, other.children) return (self.type, self.children) == (other.type, other.children)
@ -326,7 +326,7 @@ def prefix(self) -> Text:
return self.children[0].prefix return self.children[0].prefix
@prefix.setter @prefix.setter
def prefix(self, prefix) -> None: def prefix(self, prefix: Text) -> None:
if self.children: if self.children:
self.children[0].prefix = prefix self.children[0].prefix = prefix
@ -439,7 +439,7 @@ def __str__(self) -> Text:
""" """
return self._prefix + str(self.value) return self._prefix + str(self.value)
def _eq(self, other) -> bool: def _eq(self, other: "Leaf") -> bool:
"""Compare two nodes for equality.""" """Compare two nodes for equality."""
return (self.type, self.value) == (other.type, other.value) return (self.type, self.value) == (other.type, other.value)
@ -472,7 +472,7 @@ def prefix(self) -> Text:
return self._prefix return self._prefix
@prefix.setter @prefix.setter
def prefix(self, prefix) -> None: def prefix(self, prefix: Text) -> None:
self.changed() self.changed()
self._prefix = prefix self._prefix = prefix
@ -618,7 +618,7 @@ def __init__(
self.content = content self.content = content
self.name = name self.name = name
def match(self, node: NL, results=None): def match(self, node: NL, results=None) -> bool:
"""Override match() to insist on a leaf node.""" """Override match() to insist on a leaf node."""
if not isinstance(node, Leaf): if not isinstance(node, Leaf):
return False return False
@ -678,7 +678,7 @@ def __init__(
if isinstance(item, WildcardPattern): # type: ignore[unreachable] if isinstance(item, WildcardPattern): # type: ignore[unreachable]
self.wildcards = True # type: ignore[unreachable] self.wildcards = True # type: ignore[unreachable]
self.type = type self.type = type
self.content = newcontent self.content = newcontent # TODO: this is unbound when content is None
self.name = name self.name = name
def _submatch(self, node, results=None) -> bool: def _submatch(self, node, results=None) -> bool:
@ -920,7 +920,7 @@ def _recursive_matches(self, nodes, count) -> Iterator[Tuple[int, _Results]]:
class NegatedPattern(BasePattern): class NegatedPattern(BasePattern):
def __init__(self, content: Optional[Any] = None) -> None: def __init__(self, content: Optional[BasePattern] = None) -> None:
""" """
Initializer. Initializer.
@ -941,7 +941,7 @@ def match_seq(self, nodes, results=None) -> bool:
# We only match an empty sequence of nodes in its entirety # We only match an empty sequence of nodes in its entirety
return len(nodes) == 0 return len(nodes) == 0
def generate_matches(self, nodes) -> Iterator[Tuple[int, _Results]]: def generate_matches(self, nodes: List[NL]) -> Iterator[Tuple[int, _Results]]:
if self.content is None: if self.content is None:
# Return a match if there is an empty sequence # Return a match if there is an empty sequence
if len(nodes) == 0: if len(nodes) == 0:

View File

@ -26,7 +26,7 @@
from pytest import StashKey from pytest import StashKey
except ImportError: except ImportError:
# pytest < 7 # pytest < 7
from _pytest.store import StoreKey as StashKey from _pytest.store import StoreKey as StashKey # type: ignore[no-redef]
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -1,6 +1,6 @@
import re import re
import sys import sys
from typing import Any from typing import TYPE_CHECKING, Any, Callable, TypeVar
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -19,16 +19,22 @@
except ImportError as e: except ImportError as e:
raise RuntimeError("Please install Black with the 'd' extra") from e raise RuntimeError("Please install Black with the 'd' extra") from e
if TYPE_CHECKING:
F = TypeVar("F", bound=Callable[..., Any])
unittest_run_loop: Callable[[F], F] = lambda x: x
else:
try: try:
from aiohttp.test_utils import unittest_run_loop from aiohttp.test_utils import unittest_run_loop
except ImportError: except ImportError:
# unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and aiohttp 4 # unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and
# removed it. To maintain compatibility we can make our own no-op decorator. # aiohttp 4 removed it. To maintain compatibility we can make our own
def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any: # no-op decorator.
def unittest_run_loop(func, *args, **kwargs):
return func return func
@pytest.mark.blackd @pytest.mark.blackd
class BlackDTestCase(AioHTTPTestCase): class BlackDTestCase(AioHTTPTestCase): # type: ignore[misc]
def test_blackd_main(self) -> None: def test_blackd_main(self) -> None:
with patch("blackd.web.run_app"): with patch("blackd.web.run_app"):
result = CliRunner().invoke(blackd.main, []) result = CliRunner().invoke(blackd.main, [])