I've used mypy --strict
properly so far, but I was wondering if it was really strict, so I decided to check if there were any important options that were not enabled.
** The following is the latest version 0.770 as of the posting date **
The following 6 warning options are not enabled by --strict
.
--disallow-any-unimported
--disallow-any-expr
--disallow-any-decorated
--disallow-any-explicit
--warn-unreachable
--warn-incomplete-stub
First, the warning options displayed by mypy --help
are summarized below as to whether they are enabled by --strict
.
However, it does not include the options that are turned on by default as shown below (mypy --help
will display the options to suppress each).
--strict-optional
--warn-no-return
--disallow-untyped-globals
--disallow-redefinition
Enabled with --strict
: ✅ / Disabled: ❌
Config file
option | description | |
---|---|---|
✅ | --warn-unused-configs |
Warn about unused '[mypy- |
Disallow dynamic typing
option | description | |
---|---|---|
❌ | --disallow-any-unimported |
Disallow Any types resulting from unfollowed imports |
❌ | --disallow-any-expr |
Disallow all expressions that have type Any |
❌ | --disallow-any-decorated |
Disallow functions that have Any in their signature after decorator transformation |
❌ | --disallow-any-explicit |
Disallow explicit Any in type positions |
✅ | --disallow-any-generics |
Disallow usage of generic types that do not specify explicit type parameters |
✅ | --disallow-subclassing-any |
Disallow subclassing values of type Any when defining classes |
Untyped definitions and calls
option | description | |
---|---|---|
✅ | --disallow-untyped-calls |
Disallow calling functions without type annotations from functions with type annotations |
✅ | --disallow-untyped-defs |
Disallow defining functions without type annotations or with incomplete type annotations |
✅ | --disallow-incomplete-defs |
Disallow defining functions with incomplete type annotations |
✅ | --check-untyped-defs |
Type check the interior of functions without type annotations |
✅ | --disallow-untyped-decorators |
Disallow decorating typed functions with untyped decorators |
None and Optional handling
option | description | |
---|---|---|
✅ | --no-implicit-optional |
Don't assume arguments with default values of None are Optional |
Configuring warnings
option | description | |
---|---|---|
✅ | --warn-redundant-casts |
Warn about casting an expression to its inferred type |
✅ | --warn-unused-ignores |
Warn about unneeded # type: ignore comments |
✅ | --warn-return-any |
Warn about returning values of type Any from non-Any typed functions |
❌ | --warn-unreachable |
Warn about statements or expressions inferred to be unreachable or redundant |
Miscellaneous strictness flags
option | description | |
---|---|---|
✅ | --no-implicit-reexport |
Treat imports as private unless aliased |
✅ | --strict-equality |
Prohibit equality, identity, and container checks for non-overlapping types |
Advanced options
option | description | |
---|---|---|
❌ | --warn-incomplete-stub |
Warn if missing type annotation in typeshed, only relevant with --disallow-untyped-defs or --disallow-incomplete-defs enabled |
--disallow-any-unimported
Without the stub, the type of the external library would be an alias for typing.Any
, but warn you that you are using it.
sample.py
import numpy as np # type: ignore
def func() -> np.ndarray:
return np.array(1)
$ mypy --strict --show-error-code --pretty sample.py
Success: no issues found in 1 source file
$ mypy --disallow-any-unimported --show-error-code --pretty sample.py
sample.py:3: error: Return type becomes "Any" due to an unfollowed import [no-any-unimported]
def func() -> np.ndarray:
^
Found 1 error in 1 file (checked 1 source file)
You can change it as follows.
- def func() -> np.ndarray:
+ def func() -> t.Any:
I was wondering if it would be full of ʻAny, but it may be quite possible because
np.ndarrayis also just an illusion after all. I think that there are times when I write
np.ndarray` as a comment, so I think that it is an individual decision.
--disallow-any-expr
Warning for expressions containing typing.Any
.
Out with np.array (1) + np.array (2)
. You can do almost nothing without creating a stub.
--disallow-any-decorated
Warning that the function after passing through the decorator has typing.Any
in the argument or return value.
sample.py
from abc import ABC, abstractmethod
from functools import wraps
import typing as t
class A(ABC):
@abstractmethod
def func_a(a: t.Any) -> None:
pass
def deco(f: t.Callable[[int], int]) -> t.Callable[[int], t.Any]:
@wraps(f)
def wrapper(a: int) -> t.Any:
return t.cast(t.Any, f(a))
return wrapper
@deco
def func_b(a: int) -> int:
return 0
$ mypy --strict --show-error-code --pretty sample.py
Success: no issues found in 1 source file
$ mypy --disallow-any-decorated --show-error-code --pretty sample.py
sample.py:8: error: Type of decorated function contains type "Any" ("Callable[[Any], None]") [misc]
def func_a(a: t.Any) -> None:
^
sample.py:21: error: Type of decorated function contains type "Any" ("Callable[[int], Any]") [misc]
def func_b(a: int) -> int:
^
Found 2 errors in 1 file (checked 1 source file)
Unless an ordinary function adds --disallow-any-explicit
, you can use typing.Any
as an argument, but I don't understand the meaning of specializing only the decorator (and --disallow-". I don't feel like I can do any-explicit
).
--disallow-any-explicit
Warn explicit typing.Any
. Strict.
--warn-unreachable
Warning for non-delivery code.
sample.py
def process(x: int) -> None:
if isinstance(x, int) or x > 7:
print(str(x) + "bad")
else:
print(str(x) + "bad")
(The code of https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-warn-unreachable was changed a little.)
$ mypy --strict --show-error-code --pretty sample.py
Success: no issues found in 1 source file
$ mypy --warn-unreachable --show-error-code --pretty sample.py
sample.py:2: error: Right operand of 'or' is never evaluated [unreachable]
if isinstance(x, int) or x > 7:
^
sample.py:5: error: Statement is unreachable [unreachable]
print(str(x) + "bad")
^
Found 2 errors in 1 file (checked 1 source file)
Not all non-delivery codes can be detected, but isn't it bad?
--warn-incomplete-stub
Warning for stubs. I'm not sure because stubgen
doesn't work in the first place.
In the documentation
This flag is mainly intended to be used by people who want contribute to typeshed and would like a convenient way to find gaps and omissions.
Is it okay because it says?
Personally, in addition to --strict
, I thought that the following two could be considered.
--disallow-any-unimported
--warn-unreachable
In the first place, mypy is used only by inertia, so if there is something easy to use around Pyright, Pyre, pytype, I would like to switch.
Miscellaneous comparison
Tool name | language | GitHub repository | Star number(2020/5/2 22:41 Currently) |
---|---|---|---|
mypy | Python | https://github.com/python/mypy | 8379 |
pytype | Python | https://github.com/google/pytype | 2629 |
Pyre | OCaml | https://github.com/facebook/pyre-check | 3334 |
Pyright | TypeScript | https://github.com/microsoft/pyright | 5107 |
--Official document
Recommended Posts