Skip to content

Commit 2c90480

Browse files
Use strict mypy checking (#3222)
Co-authored-by: Richard Si <[email protected]>
1 parent ba618a3 commit 2c90480

File tree

7 files changed

+59
-41
lines changed

7 files changed

+59
-41
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ repos:
4949
- types-typed-ast >= 1.4.1
5050
- click >= 8.1.0
5151
- platformdirs >= 2.1.0
52+
- pytest
53+
- hypothesis
5254

5355
- repo: https://github.com/pre-commit/mirrors-prettier
5456
rev: v2.7.1

mypy.ini

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,40 @@ python_version=3.6
77
mypy_path=src
88

99
show_column_numbers=True
10-
11-
# show error messages from unrelated files
12-
follow_imports=normal
13-
14-
# suppress errors about unsatisfied imports
15-
ignore_missing_imports=True
10+
show_error_codes=True
1611

1712
# be strict
18-
disallow_untyped_calls=True
19-
warn_return_any=True
20-
strict_optional=True
21-
warn_no_return=True
22-
warn_redundant_casts=True
23-
warn_unused_ignores=True
24-
disallow_any_generics=True
25-
no_implicit_optional=True
13+
strict=True
14+
15+
# except for...
16+
no_implicit_reexport = False
2617

2718
# Unreachable blocks have been an issue when compiling mypyc, let's try
2819
# to avoid 'em in the first place.
2920
warn_unreachable=True
3021

31-
# The following are off by default. Flip them on if you feel
32-
# adventurous.
33-
disallow_untyped_defs=True
34-
check_untyped_defs=True
35-
3622
[mypy-black]
3723
# The following is because of `patch_click()`. Remove when
3824
# we drop Python 3.6 support.
3925
warn_unused_ignores=False
26+
27+
[mypy-blib2to3.driver.*]
28+
ignore_missing_imports = True
29+
30+
[mypy-IPython.*]
31+
ignore_missing_imports = True
32+
33+
[mypy-colorama.*]
34+
ignore_missing_imports = True
35+
36+
[mypy-pathspec.*]
37+
ignore_missing_imports = True
38+
39+
[mypy-tokenize_rt.*]
40+
ignore_missing_imports = True
41+
42+
[mypy-uvloop.*]
43+
ignore_missing_imports = True
44+
45+
[mypy-_black_version.*]
46+
ignore_missing_imports = True

scripts/fuzz.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,8 @@ def test_idempotent_any_syntatically_valid_python(
8585
pass
8686
else:
8787
test = test_idempotent_any_syntatically_valid_python
88-
atheris.Setup(sys.argv, test.hypothesis.fuzz_one_input)
88+
atheris.Setup(
89+
sys.argv,
90+
test.hypothesis.fuzz_one_input, # type: ignore[attr-defined]
91+
)
8992
atheris.Fuzz()

src/blackd/middlewares.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
def cors(allow_headers: Iterable[str]) -> Middleware:
12-
@middleware
12+
@middleware # type: ignore[misc]
1313
async def impl(request: Request, handler: Handler) -> StreamResponse:
1414
is_options = request.method == "OPTIONS"
1515
is_preflight = is_options and "Access-Control-Request-Method" in request.headers
@@ -32,4 +32,4 @@ async def impl(request: Request, handler: Handler) -> StreamResponse:
3232

3333
return resp
3434

35-
return impl # type: ignore
35+
return impl # type: ignore[no-any-return]

src/blib2to3/pytree.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
There's also a pattern matching implementation here.
1111
"""
1212

13-
# mypy: allow-untyped-defs
13+
# mypy: allow-untyped-defs, allow-incomplete-defs
1414

1515
from typing import (
1616
Any,
@@ -291,7 +291,7 @@ def __str__(self) -> Text:
291291
"""
292292
return "".join(map(str, self.children))
293293

294-
def _eq(self, other) -> bool:
294+
def _eq(self, other: Base) -> bool:
295295
"""Compare two nodes for equality."""
296296
return (self.type, self.children) == (other.type, other.children)
297297

@@ -326,7 +326,7 @@ def prefix(self) -> Text:
326326
return self.children[0].prefix
327327

328328
@prefix.setter
329-
def prefix(self, prefix) -> None:
329+
def prefix(self, prefix: Text) -> None:
330330
if self.children:
331331
self.children[0].prefix = prefix
332332

@@ -439,7 +439,7 @@ def __str__(self) -> Text:
439439
"""
440440
return self._prefix + str(self.value)
441441

442-
def _eq(self, other) -> bool:
442+
def _eq(self, other: "Leaf") -> bool:
443443
"""Compare two nodes for equality."""
444444
return (self.type, self.value) == (other.type, other.value)
445445

@@ -472,7 +472,7 @@ def prefix(self) -> Text:
472472
return self._prefix
473473

474474
@prefix.setter
475-
def prefix(self, prefix) -> None:
475+
def prefix(self, prefix: Text) -> None:
476476
self.changed()
477477
self._prefix = prefix
478478

@@ -618,7 +618,7 @@ def __init__(
618618
self.content = content
619619
self.name = name
620620

621-
def match(self, node: NL, results=None):
621+
def match(self, node: NL, results=None) -> bool:
622622
"""Override match() to insist on a leaf node."""
623623
if not isinstance(node, Leaf):
624624
return False
@@ -678,7 +678,7 @@ def __init__(
678678
if isinstance(item, WildcardPattern): # type: ignore[unreachable]
679679
self.wildcards = True # type: ignore[unreachable]
680680
self.type = type
681-
self.content = newcontent
681+
self.content = newcontent # TODO: this is unbound when content is None
682682
self.name = name
683683

684684
def _submatch(self, node, results=None) -> bool:
@@ -920,7 +920,7 @@ def _recursive_matches(self, nodes, count) -> Iterator[Tuple[int, _Results]]:
920920

921921

922922
class NegatedPattern(BasePattern):
923-
def __init__(self, content: Optional[Any] = None) -> None:
923+
def __init__(self, content: Optional[BasePattern] = None) -> None:
924924
"""
925925
Initializer.
926926
@@ -941,7 +941,7 @@ def match_seq(self, nodes, results=None) -> bool:
941941
# We only match an empty sequence of nodes in its entirety
942942
return len(nodes) == 0
943943

944-
def generate_matches(self, nodes) -> Iterator[Tuple[int, _Results]]:
944+
def generate_matches(self, nodes: List[NL]) -> Iterator[Tuple[int, _Results]]:
945945
if self.content is None:
946946
# Return a match if there is an empty sequence
947947
if len(nodes) == 0:

tests/optional.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from pytest import StashKey
2727
except ImportError:
2828
# pytest < 7
29-
from _pytest.store import StoreKey as StashKey
29+
from _pytest.store import StoreKey as StashKey # type: ignore[no-redef]
3030

3131
log = logging.getLogger(__name__)
3232

tests/test_blackd.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import re
22
import sys
3-
from typing import Any
3+
from typing import TYPE_CHECKING, Any, Callable, TypeVar
44
from unittest.mock import patch
55

66
import pytest
@@ -19,16 +19,22 @@
1919
except ImportError as e:
2020
raise RuntimeError("Please install Black with the 'd' extra") from e
2121

22-
try:
23-
from aiohttp.test_utils import unittest_run_loop
24-
except ImportError:
25-
# unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and aiohttp 4
26-
# removed it. To maintain compatibility we can make our own no-op decorator.
27-
def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any:
28-
return func
22+
if TYPE_CHECKING:
23+
F = TypeVar("F", bound=Callable[..., Any])
24+
25+
unittest_run_loop: Callable[[F], F] = lambda x: x
26+
else:
27+
try:
28+
from aiohttp.test_utils import unittest_run_loop
29+
except ImportError:
30+
# unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and
31+
# aiohttp 4 removed it. To maintain compatibility we can make our own
32+
# no-op decorator.
33+
def unittest_run_loop(func, *args, **kwargs):
34+
return func
2935

3036
@pytest.mark.blackd
31-
class BlackDTestCase(AioHTTPTestCase):
37+
class BlackDTestCase(AioHTTPTestCase): # type: ignore[misc]
3238
def test_blackd_main(self) -> None:
3339
with patch("blackd.web.run_app"):
3440
result = CliRunner().invoke(blackd.main, [])

0 commit comments

Comments
 (0)