19 Nouveaux diplômés. Depuis cette année, j'ai touché au côté serveur et fait diverses choses.
Cette fois, je vais parler de la façon d'afficher l'augmentation / la diminution de la sortie d'erreur mypy d'une manière facile à comprendre en conjonction avec git.
C'est un outil qui effectue une analyse statique pour les annotations de type en python. Je vous recommande de lire l'article de l'ancêtre. mypy le fera J'ai fait mypy
Le début du problème était que la version de mypy dans mon cas n'avait pas été mise à jour depuis longtemps (0,540). Si vous regardez la Note de publication, elle indique vendredi 20 octobre 2017, etc.
Lorsque j'ai essayé d'installer la dernière version localement avec une sensation de légèreté, j'ai eu beaucoup d'erreurs liées aux éléments de contrôle ajoutés dans la mise à jour. Si vous ajoutez l'option de le supprimer pour le moment, cela passera, mais ... c'est ...
Et j'ai essayé de corriger l'erreur en cours, mais cela devenait douloureux normalement. Étant donné que les erreurs sont inégalement réparties dans tout le code du projet, ce qui est assez important, il est mentalement pénible qu'aucune amélioration ne puisse être constatée en le corrigeant un peu ...
C'est impossible. Visualisons ...
La visualisation est une exagération (car ce sont des informations qui peuvent être vues depuis le début). Ne serait-il pas bien si la liste des erreurs que j'ai écrasées était affichée de manière facile à comprendre? J'ai pensé. La politique est simple: exécutez mypy deux fois avant et après le changement pour obtenir un diff. Il existe une politique selon laquelle il devrait être possible de faire quelque chose en appelant la différence entre l'arbre de travail et HEAD en conjonction avec git. Le temps d'exécution sera doublé, mais d'un autre côté, mypy ne peut être ciblé que sur le fichier de différence, donc je vais continuer avec l'espoir que tout va bien.
C'est pourquoi je l'ai fait. https://github.com/fujita-ma/mymypy
Il n'y a aucune raison sérieuse d'écrire dans la rouille, Comme il y avait beaucoup de traitement de texte ligne par ligne, je pense qu'il était facile d'écrire le traitement d'itérateur sans stress. C'est correct d'utiliser python, mais pour être honnête, je voulais le faire dans un langage que je n'utilisais pas au travail.
Essayez-le avec le code de l'exemple mypy. http://www.mypy-lang.org/examples.html
main.py
class BankAccount:
def __init__(self, initial_balance=0):
self.balance = initial_balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
def overdrawn(self):
return self.balance < 0
my_account = BankAccount(15)
my_account.withdraw(5)
print(my_account.balance)
Lançons mypy.
❯ mypy --strict ./
main.py:2: error: Function is missing a type annotation
main.py:4: error: Function is missing a type annotation
main.py:6: error: Function is missing a type annotation
main.py:8: error: Function is missing a return type annotation
main.py:11: error: Call to untyped function "BankAccount" in typed context
J'obtiens une erreur. Après avoir validé cela une fois, modifiez certaines annotations et essayez d'exécuter respectivement mypy et mymypy.
main.py
class BankAccount:
def __init__(self, initial_balance: int = 0) -> None: # Annotated
self.balance = initial_balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
def overdrawn(self):
return self.balance < 0
my_account = BankAccount(15)
my_account.withdraw(5)
print(my_account.balance)
❯ mypy --strict ./
main.py:4: error: Function is missing a type annotation
main.py:6: error: Function is missing a type annotation
main.py:8: error: Function is missing a return type annotation
main.py:12: error: Call to untyped function "withdraw" in typed context
❯ mymypy
main.py
-main.py:2:_: error: Function is missing a type annotation
main.py:4:4: error: Function is missing a type annotation
main.py:6:6: error: Function is missing a type annotation
main.py:8:8: error: Function is missing a return type annotation
-main.py:11:11: error: Call to untyped function "BankAccount" in typed context
+main.py:12:12: error: Call to untyped function "withdraw" in typed context
L'erreur écrasée est surlignée en rouge! De plus, en tant que sous-produit, l'erreur ajoutée est surlignée en vert. Il est courant que vous corrigiez une erreur et obteniez une autre erreur cachée. Je vais tout écraser correctement.
Si vous ajoutez correctement toutes les annotations, cela ressemblera à ↓.
main.py
class BankAccount:
def __init__(self, initial_balance: int = 0) -> None:
self.balance = initial_balance
def deposit(self, amount: int) -> None:
self.balance += amount
def withdraw(self, amount: int) -> None:
self.balance -= amount
def overdrawn(self) -> bool:
return self.balance < 0
my_account = BankAccount(15)
my_account.withdraw(5)
print(my_account.balance)
❯ mypy --strict ./
❯ mymypy
main.py
-main.py:2:_: error: Function is missing a type annotation
-main.py:4:_: error: Function is missing a type annotation
-main.py:6:_: error: Function is missing a type annotation
-main.py:8:_: error: Function is missing a return type annotation
-main.py:11:11: error: Call to untyped function "BankAccount" in typed context
J'ai pu écraser 5 erreurs par mon propre travail. Je suis heureux.
Jouons un peu.
Les révisions sont gérées selon git diff
, donc si vous spécifiez un commit approprié, vous pouvez faire la différence entre elles.
Jetez un œil au dépôt de mypy pour détecter les commits.
a5005f4aa977e4911bce5c828fd707ca8680d592
The `inner_types` attribute seems to have no effect.
J'ai trouvé un commit qui semble avoir été refactorisé.
Clonons-le et exécutons-le sur mymypy.
❯ mymypy a5005f4~ a5005f4
mypy/checker.py
mypy/checker.py:64:64: error: Module 'mypy.semanal' has no attribute 'set_callable_name'
-mypy/checker.py:2813:_: error: Too many arguments for "PartialType"
-mypy/checker.py:2823:_: error: Too many arguments for "PartialType"
mypy/checker.py:2959:2959: error: unused 'type: ignore' comment
-mypy/checker.py:3022:_: error: "PartialType" has no attribute "inner_types"
-mypy/checker.py:3024:_: error: "PartialType" has no attribute "inner_types"
mypy/checker.py:4137:4133: error: unused 'type: ignore' comment
-mypy/checker.py:4311:_: error: "PartialType" has no attribute "inner_types"
mypy/checkexpr.py
mypy/checkexpr.py:203:203: error: unused 'type: ignore' comment
-mypy/checkexpr.py:592:_: error: "PartialType" has no attribute "inner_types"
-mypy/checkexpr.py:606:_: error: "PartialType" has no attribute "inner_types"
mypy/checkexpr.py:2368:2361: error: Returning Any from function declared to return "Optional[str]"
mypy/checkexpr.py:3003:2996: error: unused 'type: ignore' comment
mypy/type_visitor.py
mypy/type_visitor.py:167:167: error: unused 'type: ignore' comment
mypy/type_visitor.py:207:207: error: unused 'type: ignore' comment
mypy/type_visitor.py:229:229: error: unused 'type: ignore' comment
-mypy/type_visitor.py:293:_: error: "PartialType" has no attribute "inner_types"
mypy/types.py
mypy/types.py:190:190: error: unused 'type: ignore' comment
mypy/types.py:497:497: error: Returning Any from function declared to return "T"
mypy/types.py:520:520: error: Returning Any from function declared to return "T"
mypy/types.py:808:808: error: Returning Any from function declared to return "Union[Dict[str, Any], str]"
mypy/types.py:1557:1557: error: Returning Any from function declared to return "T"
mypy/types.py:1669:1669: error: Returning Any from function declared to return "T"
mypy/types.py:1789:1786: error: Returning Any from function declared to return "T"
mypy/types.py:1844:1841: error: unused 'type: ignore' comment
mypy/types.py:1889:1886: error: Returning Any from function declared to return "T"
Vous pouvez voir l'effet de la refactorisation. Amusant ✌ ('ω' ✌) Trois ✌ ('ω') ✌ Trois (✌'ω ') ✌ (Mot mort)
Je l'ai fait avec une politique appropriée après un changement d'humeur, mais je suis satisfait car il a pu s'afficher avec un bon feeling. Je vais l'utiliser pour mon entreprise car c'est une bonne affaire. ~~ Si vous l'utilisez réellement, vous trouverez de nombreux bugs ~~
Recommended Posts