[PYTHON] Ich habe tatsächlich statisch ein passendes Snippet mit mypy getippt

Referenz:

Ich habe versucht, statische Typen zu überprüfen, indem ich dem Code des Befehls, den ich zuvor in Python geschrieben habe, eine Typanmerkung von mypy hinzugefügt habe.

Viele Standard-Bibliotheksstubs sind bereits in mypy definiert, aber ich hatte nicht genügend Klassen und Methoden für die Module argparse, operator und itertools, die in diesem Befehl verwendet wurden. Deshalb habe ich versucht, die Stubs selbst zu definieren. Es war ein wenig schwierig, weil ich nicht an die Definition dieses Stubs gewöhnt war.

stubs/argparse.py


from typing import Any, List, Sequence, Undefined

class Namespace:
    def __init__(self) -> None:
        self.commands = Undefined(List[str])
        self.is_all = Undefined(bool)
        self.is_silent = Undefined(bool)

class ArgumentParser:
    def set_defaults(self, **kwargs: Any) -> None: pass
    def add_argument(self, *args: Sequence[str], **kwargs: Any) -> None: pass
    def parse_args(self, args: Sequence[str], namespace: Namespace = None) -> Namespace: pass

stubs/itertools.py


from typing import Iterable, typevar

_T = typevar('_T')

class chain:
    @classmethod
    def from_iterable(cls, iterable: Iterable[Iterable[_T]]) -> Iterable[_T]: pass

stubs/operator.py


from typing import Any, Function, Sequence, typevar

_T = typevar('_T')

def itemgetter(item: _T, *items: Sequence[_T]) -> Function[[Any], _T]: pass

Legen Sie Umgebungsvariablen fest, um Ihre definierten Stubs für mypy sichtbar zu machen.

python


(mypy)$ export MYPYPATH=./stubs/

Eigentlich war ich ein wenig verwirrt, weil es nicht funktioniert hat, weil ich die Typanmerkung geschrieben habe, während ich die Definition des Stubs und die Typprüfung wiederholt habe. Ich denke, es ist eine Frage der Vertrautheit.

Schließlich habe ich die Typanmerkung zu der Quelle des Befehls [which_with_static_typed.py] hinzugefügt (https://bitbucket.org/t2y/misc/src/0d4cdb82627db0c5abeaead22f56d02b6dc8ed7e/which/which_with_static_defed).

Das Diff mit dem Originalcode sieht so aus.

python


$ diff -u which.py which_with_statically_typed.py 
--- which.py	2014-12-26 12:22:31.000000000 +0900
+++ which_with_statically_typed.py	2014-12-26 16:06:28.000000000 +0900
@@ -7,8 +7,10 @@
 from os.path import join as pathjoin
 from operator import itemgetter
 
+from typing import List, Sequence, Tuple  # pragma: no flakes
 
-def search(cmd, paths, is_all=False):
+
+def search(cmd: str, paths: List[str], is_all: bool=False):
     for path in paths:
         for match in glob.glob(pathjoin(path, cmd)):
             if os.access(match, os.X_OK):
@@ -17,7 +19,7 @@
                     raise StopIteration
 
 
-def parse_argument(args=None):
+def parse_argument(args: Sequence[str]=None) -> argparse.Namespace:
     parser = argparse.ArgumentParser()
     parser.set_defaults(is_all=False, is_silent=False, commands=[])
     parser.add_argument(
@@ -29,23 +31,23 @@
         help="No output, just return 0 if any of the executables are found, "
              "or 1 if none are found.")
     parser.add_argument("commands", nargs="*")
-    args = parser.parse_args(args or sys.argv[1:])
-    return args
+    namespace = parser.parse_args(args or sys.argv[1:])
+    return namespace
 
 
-def main(cmd_args=None):
+def main(cmd_args: Sequence[str]=None) -> int:
     args = parse_argument(cmd_args)
     if not args.commands:
         print('Usage: python which.py cmd1 [cmd2 ...]')
         return 0
 
     env_paths = os.environ['PATH'].split(':')
-    result = []
+    result = []  # type: List[Tuple[int, List[str]]]
     for cmd in args.commands:
         founds = list(search(cmd, env_paths, args.is_all))
         result.append((0, founds) if founds else (1, [cmd]))
 
-    status_code = max(map(itemgetter(0), result))
+    status_code = max(map(itemgetter(0), result))  # type: int
     if not args.is_silent:
         cmd_paths = [paths for ret_val, paths in result if ret_val == 0]
         for cmd_path in chain.from_iterable(cmd_paths):

Die gesamte Quelle befindet sich unter misc / which.

Recommended Posts

Ich habe tatsächlich statisch ein passendes Snippet mit mypy getippt
Ich habe mit Python eine Lotterie gemacht.
Ich habe mit Python einen Daemon erstellt
Ich habe versucht, eine Blockchain zu implementieren, die tatsächlich mit ungefähr 170 Zeilen funktioniert
Ich habe mit Python einen Zeichenzähler erstellt
Ich habe eine Heatmap mit Seaborn [Python] gezeichnet.
Ich habe eine funktionale Sprache mit Python ausprobiert
Was ich mit Python-Arrays gemacht habe
Ich habe mit Python eine Hex-Map erstellt
Ich habe ein Lebensspiel mit Numpy gemacht
Eine typisierte Welt, die mit Python beginnt
Ich habe einen Hanko-Generator mit GAN gemacht
Ich habe mit Python ein schurkenhaftes Spiel gemacht
Ich habe mit Python einen einfachen Blackjack gemacht
Ich habe mit Python eine Einstellungsdatei erstellt
Ich habe eine WEB-Bewerbung bei Django gemacht
Ich habe mit Python einen Neuronensimulator erstellt
Ich habe einen Stempelersatzbot mit Linie gemacht
Ich habe mit Python eine Bot-Wettervorhersage gemacht.
Ich habe eine GUI-App mit Python + PyQt5 erstellt
Ich habe versucht, mit Python einen Twitter-Blocker für faule Mädchen zu machen
Ich möchte ein Spiel mit Python machen
Ich habe ein verrücktes Ding namens getipptes Tupel gemacht
[Python] Ich habe mit Tkinter einen Youtube Downloader erstellt.
Ich erhalte einen UnicodeDecodeError, wenn ich mit mod_wsgi laufe
Ich habe eine einfache Brieftasche aus Bitcoin mit Pycoin gemacht
Ich habe einen LINE Bot mit Serverless Framework erstellt!
Ich habe mit Diamond gespielt, einem Tool zum Sammeln von Metriken
Ich habe mit Numpy eine Grafik mit Zufallszahlen erstellt
Ich möchte mit Python in eine Datei schreiben
Ich habe versucht, die Datenbank (sqlite3) mit kivy zu verwenden
Ich habe mit Python ein Bin-Picking-Spiel gemacht
Mattermost Bot mit Python gemacht (+ Flask)