[PYTHON] [mypy] Résumé des options non activées par `--strict`

J'ai utilisé correctement mypy --strict jusqu'à présent, mais je me demandais si c'était vraiment strict, j'ai donc décidé de vérifier s'il y avait des options importantes qui n'étaient pas activées.

** Ce qui suit est la dernière version 0.770 à la date de publication **

Conclusion

Les 6 options d'avertissement suivantes ne sont pas activées par --strict.

Si chaque option est valide

Tout d'abord, les options d'avertissement affichées par mypy --help sont résumées ci-dessous si elles sont activées par --strict.

Cependant, il n'inclut pas les options qui sont activées par défaut comme indiqué ci-dessous (mypy --help affichera les options pour les supprimer).

Activé avec --strict: ✅ / Désactivé: ❌

Config file

option description
--warn-unused-configs Warn about unused '[mypy-]' config sections

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

Pour les options qui ne sont pas activées

--disallow-any-unimported

Sans le stub, le type de la bibliothèque externe serait un alias pour typing.Any, mais vous avertit que vous l'utilisez.

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)

Vous pouvez le modifier comme suit.

- def func() -> np.ndarray:
+ def func() -> t.Any:

Je me demandais si ce serait plein de ʻAny, mais c'est peut-être tout à fait possible parce que np.ndarray` est aussi juste une illusion après tout. Je pense qu'il y a des moments où j'écris «np.ndarray» comme commentaire, donc je pense que c'est une décision individuelle.

--disallow-any-expr

Avertissement pour les expressions contenant typing.Any. Fini avec np.array (1) + np.array (2). Vous ne pouvez presque rien faire sans créer un talon.

--disallow-any-decorated

Attention, la fonction après avoir traversé le décorateur a typing.Any dans l'argument ou la valeur de retour.

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)

À moins qu'une fonction normale ajoute --disallow-any-explicit, vous pouvez utiliser typing.Any comme argument, mais je ne comprends pas le sens de spécialiser uniquement le décorateur (et` --disallow- ". Je ne pense pas que tout explicite puisse être fait).

--disallow-any-explicit

Avertir explicite "typing.Any". Strict.

--warn-unreachable

Avertissement pour code de non-livraison.

sample.py


def process(x: int) -> None:
    if isinstance(x, int) or x > 7:
        print(str(x) + "bad")
    else:
        print(str(x) + "bad")

(Le code de https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-warn-unreachable a été légèrement modifié.)

$ 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)

Tous les codes de non-livraison ne peuvent pas être détectés, mais n'est-ce pas mauvais?

--warn-incomplete-stub

Avertissement pour les talons. Je ne suis pas sûr parce que stubgen ne fonctionne pas en premier lieu. Dans le document

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.

Est-ce que ça va parce que ça dit?

Impressions

Personnellement, en plus de «--strict», j'ai pensé que les deux suivants pourraient être envisagés.

En premier lieu, mypy n'est utilisé que par inertie, donc s'il y a quelque chose de facile à utiliser autour de Pyright, Pyre, pytype, je voudrais changer.

Comparaison divers

Nom de l'outil Langue Dépôt GitHub Numéro étoile(2020/5/2 22:41 Actuellement)
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

référence

--Document officiel

Recommended Posts

[mypy] Résumé des options non activées par `--strict`
Résumé de l'implémentation de base par PyTorch
Résumé des pages d'hébergement de la bibliothèque par langue
Résumé de la méthode de connexion par DB de SQL Alchemy
Récapitulatif des options gcc (mises à jour de temps en temps)
Résumé super (concis) de la classification des images par ArcFace
Résumé des articles sur Python du chercheur Yukiya dans une société pharmaceutique
Résumé de séparation de l'environnement de développement par chroot de divers Linux