De Wee fir 4 Millioune Linnen Python Code ze tippen. Deel 1

Haut bréngen mir op Är Opmierksamkeet den éischten Deel vun der Iwwersetzung vum Material iwwer wéi Dropbox mat Typ Kontroll vum Python Code handelt.

De Wee fir 4 Millioune Linnen Python Code ze tippen. Deel 1

Dropbox schreift vill am Python. Et ass eng Sprooch déi mir extrem wäit benotzen, souwuel fir Back-End Servicer wéi Desktop Client Uwendungen. Mir benotzen och Go, TypeScript a Rust vill, awer Python ass eis Haaptsprooch. Wann Dir eis Skala berücksichtegt, a mir schwätzen iwwer Millioune vu Python-Code Zeilen, huet sech erausgestallt datt déi dynamesch Schreifweis vun esou engem Code onnéideg komplizéiert säi Verständnis an huet ugefaang d'Aarbechtsproduktivitéit eescht ze beaflossen. Fir dëse Problem ze reduzéieren, hu mir ugefaang eise Code graduell op statesch Typprüfung mat mypy ze iwwersetzen. Dëst ass wahrscheinlech de populärste Standalone-Typ Kontrollsystem fir Python. Mypy ass en Open Source Projet, seng Haaptentwéckler schaffen an Dropbox.

Dropbox war eng vun den éischte Firmen fir statesch Typprüfung am Python Code op dëser Skala ëmzesetzen. Mypy gëtt haut an Dausende vu Projete benotzt. Dëst Tool onendlech Mol, wéi se soen, "am Schluecht getest." Mir sinn e laange Wee komm fir do ze kommen wou mir elo sinn. Ënnerwee goufen et vill Mëssgléckt Entreprisen a gescheitert Experimenter. Dëse Post befaasst d'Geschicht vu statesche Typprüfung am Python, vu senge rockegen Ufanks als Deel vu mengem Fuerschungsprojet, bis haut, wann d'Typprüfung an d'Typ Hiweis allgemeng ginn fir eng Onmass Entwéckler déi am Python schreiwen. Dës Mechanismen ginn elo vu villen Tools wéi IDEs a Code Analyser ënnerstëtzt.

Liest den zweeten Deel

Firwat ass Typprüfung néideg?

Wann Dir jeemools dynamesch getippten Python benotzt hutt, hutt Dir vläicht e bëssen Duercherneen firwat et zënter kuerzem sou e Geck ronderëm statesch Tippen a Mypy gouf. Oder vläicht gefällt Dir Python genee wéinst sengem dynamesche Tippen, a wat geschitt ass einfach opgeregt. De Schlëssel zum Wäert vum statesche Schreiwen ass d'Skala vun de Léisungen: wat Äre Projet méi grouss ass, wat Dir méi op statesch Schreiwen leet, an um Enn, wat Dir et wierklech braucht.

Ugeholl datt e bestëmmte Projet d'Gréisst vun Zéngdausende vu Linnen erreecht huet, an et huet sech erausgestallt datt verschidde Programméierer dru schaffen. Wann Dir en ähnleche Projet kuckt, baséiert op eiser Erfahrung, kënne mir soen datt säi Code ze verstoen ass de Schlëssel fir d'Entwéckler produktiv ze halen. Ouni Typ Annotatiounen, kann et schwéier sinn erauszefannen, zum Beispill, wéi eng Argumenter fir eng Funktioun weiderginn oder wéi eng Zorte eng Funktioun zréckginn. Hei sinn typesch Froen déi dacks schwéier ze beäntweren ouni Typ Annotatiounen ze benotzen:

  • Kann dës Funktioun zréck None?
  • Wat soll dëst Argument sinn? items?
  • Wat ass den Attribut Typ id: int ass et, str, oder vläicht e personaliséierten Typ?
  • Soll dëst Argument eng Lëscht sinn? Ass et méiglech en Tupel derbäi ze ginn?

Wann Dir de folgenden Typ-annotéierten Code Snippet kuckt a probéiert ähnlech Froen ze beäntweren, stellt sech eraus datt dëst déi einfachst Aufgab ass:

class Resource:
    id: bytes
    ...
    def read_metadata(self, 
                      items: Sequence[str]) -> Dict[str, MetadataItem]:
        ...

  • read_metadata geet net zréck None, well de Retour Typ ass net Optional[…].
  • Argument items ass eng Sequenz vu Linnen. Et kann net zoufälleg iteréiert ginn.
  • Attribut id ass eng String vu Bytes.

An enger idealer Welt géif een erwaarden datt all sou Subtletien an der agebauter Dokumentatioun (Docstring) beschriwwe ginn. Awer d'Erfahrung gëtt vill Beispiller vun der Tatsaach, datt esou Dokumentatioun dacks net am Code observéiert gëtt, mat deem Dir musst schaffen. Och wann esou Dokumentatioun am Code präsent ass, kann een net op seng absolut Richtegkeet zielen. Dës Dokumentatioun kann vague, ongenau an oppe fir Mëssverständnisser sinn. A groussen Teams oder grousse Projeten kann dëse Problem extrem akut ginn.

Iwwerdeems Python excels an de fréien oder Zwëschenstadien vu Projeten, kënnen iergendwann erfollegräich Projeten a Firmen déi Python benotzen déi vital Fro stellen: "Sollte mir alles an enger statesch getippten Sprooch iwwerschreiwe?".

Typprüfungssystemer wéi mypy léisen den uewe genannte Problem andeems en den Entwéckler eng formell Sprooch ubitt fir d'Typen ze beschreiwen, an andeems Dir iwwerpréift datt Typdeklaratioune mat der Programmimplementatioun passen (an, optional, andeems se no hirer Existenz iwwerpréift). Am Allgemengen kënne mir soen datt dës Systemer eppes wéi suergfälteg iwwerpréift Dokumentatioun zur Verfügung stellen.

D'Benotzung vun esou Systemer huet aner Virdeeler, a si scho komplett net-trivial:

  • Den Typprüfungssystem kann e puer kleng (an net sou kleng) Feeler erkennen. En typescht Beispill ass wa se vergiessen e Wäert ze veraarbecht None oder eng aner speziell Konditioun.
  • Code Refactoring ass immens vereinfacht well den Typprüfungssystem dacks ganz genau ass wéi de Code muss geännert ginn. Zur selwechter Zäit brauche mir net op 100% Code Ofdeckung mat Tester ze hoffen, wat op alle Fall normalerweis net machbar ass. Mir brauchen net an d'Tiefe vun der Stackspur ze verdéiwen fir d'Ursaach vum Problem erauszefannen.
  • Och op grousse Projeten, mypy kann dacks voll Typ Kontroll an engem Ëmwandlung vun enger Sekonn maachen. An d'Ausféierung vun Tester dauert normalerweis Zénger vu Sekonnen oder souguer Minutten. Den Typprüfungssystem gëtt dem Programméierer direkt Feedback an erlaabt him seng Aarbecht méi séier ze maachen. Hien brauch net méi fragil a schwéier ze erhalen Eenheetstester ze schreiwen, déi real Entitéite mat Spott a Patches ersetzen just fir Code Testresultater méi séier ze kréien.

IDEen an Redaktoren wéi PyCharm oder Visual Studio Code benotzen d'Kraaft vun Typannotatiounen fir Entwéckler mat Code Fäerdegstellung, Feeler Highlight, an Ënnerstëtzung fir allgemeng benotzt Sproochkonstruktiounen ze bidden. An dëst sinn nëmmen e puer vun de Virdeeler vum Tippen. Fir e puer Programméierer ass dëst alles d'Haaptargument fir ze tippen. Dëst ass eppes wat direkt no der Ëmsetzung profitéiert. Dëse Benotzungsfall fir Typen erfuerdert keen separaten Typprüfungssystem wéi mypy, obwuel et sollt bemierkt ginn datt mypy hëlleft Typ Annotatiounen konsequent mam Code ze halen.

Hannergrond vun mypy

D'Geschicht vu Mypy huet a Groussbritannien ugefaang, zu Cambridge, e puer Joer ier ech bei Dropbox ugeschloss sinn. Ech sinn am Kader vu menger Doktoratsfuerschung an der Vereenegung vu statesch getippten an dynamesche Sproochen involvéiert. Ech war inspiréiert vun engem Artikel iwwer inkrementell Tippen vum Jeremy Siek a Walid Taha, an vum Typed Racket Projet. Ech hu probéiert Weeër ze fannen fir déiselwecht Programméierungssprooch fir verschidde Projeten ze benotzen - vu klenge Skripte bis Codebasen, déi aus ville Millioune Linnen besteet. Gläichzäiteg wollt ech dofir suergen, datt e Projet vu jidder Gréisst net ze grouss Kompromëss muss maachen. E wichtege Bestanddeel vun dësem alles war d'Iddi fir sech lues a lues vun engem ongetypte Prototypprojet op eng ëmfaassend getest statesch getippte fäerdeg Produkt ze plënneren. Dës Iddien ginn hautdesdaags gréisstendeels selbstverständlech ugeholl, awer 2010 war et e Problem, deen nach aktiv exploréiert gouf.

Meng originell Aarbecht am Typprüfung war net op Python gezielt. Amplaz hunn ech eng kleng "hausgemaachte" Sprooch benotzt Alore. Hei ass e Beispill dat Iech léisst verstoen iwwer wat mir schwätzen (Typ Annotatiounen sinn hei fakultativ):

def Fib(n as Int) as Int
  if n <= 1
    return n
  else
    return Fib(n - 1) + Fib(n - 2)
  end
end

Eng vereinfacht Mammesprooch ze benotzen ass eng allgemeng Approche déi an der wëssenschaftlecher Fuerschung benotzt gëtt. Dëst ass sou, net zulescht well et Iech erlaabt séier Experimenter ze maachen, an och wéinst der Tatsaach, datt wat näischt mat der Studie ze dinn huet, einfach ignoréiert ka ginn. Real-Welt Programméierungssprooche tendéieren grouss-Skala Phänomener mat komplexen Implementatiounen ze sinn, an dëst verlangsamt d'Experimenter. All Resultater op Basis vun enger vereinfachter Sprooch kucken awer e bësse verdächteg aus, well beim Erhalen vun dëse Resultater kann de Fuerscher Iwwerleeungen, déi wichteg sinn fir d'praktesch Notzung vun de Sprooche geaffert hunn.

Mäin Typchecker fir Alore huet ganz villverspriechend ausgesinn, awer ech wollt et testen andeems ech mam richtege Code experimentéieren, deen, Dir kënnt soen, net an Alore geschriwwe gouf. Gléck fir mech war d'Alore Sprooch gréisstendeels op déiselwecht Iddien wéi Python baséiert. Et war einfach genuch den Typechecker nei ze maachen, sou datt et mat der Python Syntax a Semantik funktionnéiert. Dëst huet eis erlaabt ze probéieren Typ Checking am Open Source Python Code. Zousätzlech hunn ech en Transpiler geschriwwen fir de Code am Alore an de Python Code ze konvertéieren an et benotzt fir mäi Typechecker Code ze iwwersetzen. Elo hat ech en Typprüfungssystem am Python geschriwwen deen en Ënnerdeel vum Python ënnerstëtzt, eng Aart vun där Sprooch! (Verschidde architektonesch Entscheedungen déi Sënn gemaach hunn fir Alore ware schlecht fir Python passend, an dëst ass nach ëmmer an Deeler vun der mypy Codebase bemierkbar.)

Tatsächlech konnt d'Sprooch, déi vu mengem Typsystem ënnerstëtzt gëtt, net ganz Python op dësem Punkt genannt ginn: et war eng Variant vu Python wéinst e puer Aschränkungen vun der Python 3 Typ Annotatiounssyntax.

Et huet ausgesinn wéi eng Mëschung aus Java a Python:

int fib(int n):
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Eng vu mengen Iddien zu där Zäit war Typ Annotatiounen ze benotzen fir d'Performance ze verbesseren andeems dës Aart vu Python op C kompiléiert gëtt, oder vläicht JVM Bytecode. Ech sinn op d'Bühn komm fir e Compiler Prototyp ze schreiwen, awer ech hunn dës Iddi opginn, well d'Typprüfung selwer ganz nëtzlech ausgesäit.

Ech hunn um Enn mäi Projet um PyCon 2013 zu Santa Clara presentéiert. Ech hunn och iwwer dëst mam Guido van Rossum geschwat, dem benevolen Python-Diktator fir d'Liewen. Hien huet mech iwwerzeegt meng eege Syntax ze falen a mat der Standard Python 3 Syntax ze halen. Python 3 ënnerstëtzt Funktiounsannotatiounen, sou datt mäi Beispill ëmgeschriwwe ka ginn wéi hei ënnendrënner, wat zu engem normale Python Programm resultéiert:

def fib(n: int) -> int:
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Ech hu missen e puer Kompromësser maachen (fir d'éischt wëll ech bemierken datt ech aus dësem Grond meng eegen Syntax erfonnt hunn). Besonnesch Python 3.3, déi lescht Versioun vun der Sprooch zu där Zäit, huet keng variabel Annotatiounen ënnerstëtzt. Ech diskutéiert mat Guido per E-Mail verschidde Méiglechkeeten fir syntaktesch Design vun esou Annotatiounen. Mir hunn decidéiert Typ Kommentarer fir Variabelen ze benotzen. Dëst huet den Zweck gedéngt, awer war e bëssen ëmständlech (Python 3.6 huet eis eng méi schéin Syntax ginn):

products = []  # type: List[str]  # Eww

Typ Kommentarer koumen och praktesch fir Python 2 z'ënnerstëtzen, deen keng gebauter Ënnerstëtzung fir Typ Annotatiounen huet:

f fib(n):
    # type: (int) -> int
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Et huet sech erausgestallt datt dës (an aner) Ofdreiwungen net wierklech wichteg waren - d'Virdeeler vum statesche Tippen hunn gemengt datt d'Benotzer séier iwwer manner wéi ideal Syntax vergiess hunn. Zënter datt keng speziell syntaktesch Konstrukter am Typ-gecheckte Python Code benotzt goufen, hunn existent Python Tools a Codeveraarbechtungsprozesser weider normal geschafft, wat et vill méi einfach mécht fir Entwéckler dat neit Tool ze léieren.

De Guido huet mech och iwwerzeegt fir Dropbox matzemaachen nodeems ech meng Diplomaarbecht ofgeschloss hunn. Dëst ass wou den interessantsten Deel vun der Mypy Geschicht ufänkt.

Fir weidergitt ...

Léif Lieser! Wann Dir Python benotzt, sot eis w.e.g. iwwer d'Skala vun de Projeten déi Dir an dëser Sprooch entwéckelt.

De Wee fir 4 Millioune Linnen Python Code ze tippen. Deel 1
De Wee fir 4 Millioune Linnen Python Code ze tippen. Deel 1

Source: will.com

Setzt e Commentaire