Ang dalan sa pag-typecheck sa 4 ka milyon nga linya sa Python code. Bahin 2

Karon among gipatik ang ikaduhang bahin sa paghubad sa materyal bahin sa giunsa pag-organisar sa Dropbox ang tipo nga kontrol sa daghang milyon nga linya sa Python code.

Ang dalan sa pag-typecheck sa 4 ka milyon nga linya sa Python code. Bahin 2

β†’ Basaha ang unang bahin

Opisyal nga suporta sa tipo (PEP 484)

Gipahigayon namo ang among unang seryoso nga mga eksperimento sa mypy sa Dropbox atol sa Hack Week 2014. Ang Hack Week usa ka usa ka semana nga kalihokan nga gidumala sa Dropbox. Niini nga panahon, ang mga empleyado mahimong magtrabaho sa bisan unsang gusto nila! Ang pipila sa labing inila nga mga proyekto sa teknolohiya sa Dropbox nagsugod sa mga panghitabo nga sama niini. Ingon usa ka sangputanan sa kini nga eksperimento, nakahinapos kami nga ang mypy daw nagsaad, bisan kung ang proyekto dili pa andam alang sa kaylap nga paggamit.

Niadtong panahona, ang ideya sa pag-standardize sa Python type hinting system naa sa hangin. Sama sa akong giingon, tungod kay ang Python 3.0 posible nga magamit ang mga anotasyon sa tipo alang sa mga gimbuhaton, apan kini mga arbitraryong ekspresyon lamang, nga wala gihubit nga syntax ug semantics. Atol sa pagpatuman sa programa, kini nga mga anotasyon, sa kasagaran, gibalewala lang. Pagkahuman sa Hack Week, nagsugod kami sa pagtrabaho sa pag-standardize sa mga semantiko. Kini nga trabaho misangpot sa pagtungha PEP 484 (Guido van Rossum, Łukasz Langa ug ako nagtinabangay niini nga dokumento).

Ang atong mga motibo mahimong tan-awon sa duha ka bahin. Una, kami naglaum nga ang tibuok Python ekosistema mahimong mosagop sa usa ka komon nga paagi sa paggamit sa matang pahiwatig (usa ka termino nga gigamit sa Python ingon nga katumbas sa "type annotation"). Kini, tungod sa posible nga mga risgo, mas maayo kay sa paggamit sa daghang dili magkauyon nga mga pamaagi. Ikaduha, gusto namon nga dayag nga hisgutan ang mga mekanismo sa anotasyon sa tipo sa daghang mga miyembro sa komunidad sa Python. Kini nga tinguha usa ka bahin nga gidiktar sa kamatuoran nga dili kita gusto nga tan-awon sama sa "mga apostata" gikan sa mga batakang ideya sa pinulongan sa mga mata sa halapad nga masa sa Python programmer. Kini usa ka dinamikong gi-type nga lengguwahe, nga nailhan nga "pag-type sa itik". Sa komunidad, sa sinugdanan, ang usa ka medyo kadudahan nga kinaiya sa ideya sa static nga pag-type dili makatabang apan motungha. Apan kana nga sentimento sa kadugayan nawala human kini nahimong tin-aw nga ang static nga pag-type dili kinahanglan nga mandatory (ug pagkahuman nahibal-an sa mga tawo nga kini mapuslanon).

Ang tipo nga hint syntax nga sa kadugayan gisagop susama kaayo sa gisuportahan sa mypy niadtong panahona. Ang PEP 484 gipagawas uban ang Python 3.5 kaniadtong 2015. Ang Python dili na usa ka dinamikong gi-type nga pinulongan. Gusto nakong hunahunaon kini nga panghitabo isip usa ka mahinungdanong milestone sa kasaysayan sa Python.

Pagsugod sa paglalin

Sa katapusan sa 2015, ang Dropbox naghimo og usa ka grupo sa tulo ka mga tawo aron magtrabaho sa mypy. Naglakip sila Guido van Rossum, Greg Price ug David Fisher. Gikan nianang higayuna, ang sitwasyon nagsugod sa hilabihan ka paspas. Ang una nga babag sa pagtubo sa mypy mao ang pasundayag. Sama sa akong gipasabot sa ibabaw, sa unang mga adlaw sa proyekto naghunahuna ko sa paghubad sa mypy nga pagpatuman ngadto sa C, apan kini nga ideya wala na sa listahan sa pagkakaron. Kami naipit sa pagpadagan sa sistema gamit ang CPython interpreter, nga dili igo nga paspas alang sa mga himan sama sa mypy. (Ang proyekto sa PyPy, usa ka alternatibo nga pagpatuman sa Python nga adunay JIT compiler, wala usab makatabang kanamo.)

Maayo na lang, pipila ka mga pag-uswag sa algorithm ang nakatabang kanamo dinhi. Ang unang gamhanan nga "accelerator" mao ang pagpatuman sa incremental checking. Ang ideya sa luyo niini nga pag-uswag yano ra: kung ang tanan nga mga dependency sa module wala mausab sukad sa miaging run sa mypy, nan mahimo namong gamiton ang data nga na-cache sa miaging run samtang nagtrabaho uban ang mga dependency. Kinahanglan lang namon nga himuon ang pagsusi sa tipo sa giusab nga mga file ug sa mga file nga nagdepende kanila. Ang Mypy mipadayon pa og gamay: kung ang eksternal nga interface sa usa ka module wala mausab, ang mypy nagtuo nga ang ubang mga module nga nag-import niini nga module dili na kinahanglan nga susihon pag-usab.

Ang incremental nga pagsusi nakatabang kaayo kanamo sa pag-annotate sa daghang gidaghanon sa kasamtangan nga code. Ang punto mao nga kini nga proseso kasagaran naglakip sa daghang mga iterative run sa mypy samtang ang mga anotasyon anam-anam nga gidugang sa code ug anam-anam nga gipauswag. Ang una nga pagdagan sa mypy hinay pa kaayo tungod kay kini adunay daghang mga dependency nga susihon. Dayon, aron mapaayo ang sitwasyon, gipatuman namo ang usa ka hilit nga mekanismo sa pag-cache. Kung ang mypy nakamatikod nga ang lokal nga cache lagmit nga wala na sa petsa, kini nag-download sa kasamtangan nga cache snapshot alang sa tibuok codebase gikan sa sentralisadong repositoryo. Naghimo kini og incremental check gamit kini nga snapshot. Nagdala kini kanamo usa pa ka dako nga lakang padulong sa pagdugang sa pasundayag sa mypy.

Kini usa ka yugto sa paspas ug natural nga pagsagop sa tipo nga pagsusi sa Dropbox. Sa pagtapos sa 2016, naa na miy gibana-bana nga 420000 ka linya sa Python code nga naay type annotation. Daghang tiggamit ang madasigon bahin sa pagsusi sa tipo. Nagkadaghan ang mga team sa pag-uswag nga naggamit sa Dropbox mypy.

Maayo ra ang tanan kaniadto, apan daghan pa kami nga buhaton. Nagsugod kami sa paghimo sa matag-panahon nga internal nga mga survey sa tiggamit aron mahibal-an ang mga lugar nga adunay problema sa proyekto ug masabtan kung unsa nga mga isyu ang kinahanglan nga sulbaron una (kini nga praktis gigamit gihapon sa kompanya karon). Ang labing importante, ingon nga kini nahimong klaro, mao ang duha ka mga buluhaton. Una, kinahanglan namon ang dugang nga tipo sa pagsakup sa code, ikaduha, kinahanglan namon ang mypy aron molihok nga mas paspas. Klaro kaayo nga ang among trabaho aron mapadali ang mypy ug ipatuman kini sa mga proyekto sa kompanya layo pa sa pagkakompleto. Kami, nga hingpit nga nahibal-an ang kamahinungdanon niining duha ka mga buluhaton, nagsugod sa pagsulbad niini.

Dugang produktibidad!

Ang mga incremental nga pagsusi naghimo sa mypy nga mas paspas, apan ang himan dili pa igo nga paspas. Daghang mga incremental nga tseke milungtad og mga usa ka minuto. Ang hinungdan niini mao ang cyclical imports. Tingali dili kini makapakurat sa bisan kinsa nga nagtrabaho sa daghang mga codebase nga gisulat sa Python. Kami adunay mga set sa gatusan ka mga module, nga ang matag usa dili direkta nga nag-import sa tanan nga uban pa. Kung nabag-o ang bisan unsang file sa usa ka loop sa pag-import, kinahanglan nga iproseso sa mypy ang tanan nga mga file sa kana nga loop, ug kasagaran bisan unsang mga module nga nag-import sa mga module gikan sa kana nga loop. Usa sa ingon nga siklo mao ang dili maayo nga "dependency tangle" nga hinungdan sa daghang kasamok sa Dropbox. Sa higayon nga kini nga istruktura adunay daghang gatos nga mga module, samtang kini gi-import, direkta o dili direkta, daghang mga pagsulay, gigamit usab kini sa code sa produksiyon.

Among gikonsiderar ang posibilidad sa "pagtangtang" sa mga circular dependencies, apan wala kami mga kahinguhaan sa pagbuhat niini. Daghan kaayo ang code nga dili namo pamilyar. Ingon usa ka sangputanan, nakahimo kami usa ka alternatibong pamaagi. Nakahukom kami nga buhaton dayon ang mypy bisan sa presensya sa "dependency tangles". Nakab-ot namo kini nga tumong gamit ang mypy daemon. Ang usa ka daemon usa ka proseso sa server nga nagpatuman sa duha ka makapaikag nga kapabilidad. Una, kini nagtipig impormasyon bahin sa tibuok codebase sa memorya. Nagpasabot kini nga sa matag higayon nga magpadagan ka sa mypy, dili nimo kinahanglan nga ikarga ang mga naka-cache nga datos nga may kalabotan sa libu-libo nga mga gi-import nga dependency. Ikaduha, mabinantayon siya, sa lebel sa gagmay nga mga yunit sa istruktura, nag-analisar sa mga dependency tali sa mga gimbuhaton ug uban pang mga entidad. Pananglitan, kung ang function foo nagtawag ug function bar, unya adunay pagsalig foo gikan sa bar. Sa diha nga ang usa ka file mausab, ang daemon una, sa pag-inusara, moproseso lamang sa giusab nga file. Gitan-aw dayon niini ang makita sa gawas nga mga pagbag-o sa kana nga file, sama sa giusab nga mga pirma sa function. Ang daemon naggamit ug detalyadong impormasyon bahin sa mga import para lang sa pag-double check niadtong mga function nga aktuwal nga naggamit sa giusab nga function. Kasagaran, sa kini nga pamaagi, kinahanglan nimo nga susihon ang pipila ka mga gimbuhaton.

Ang pagpatuman niining tanan dili sayon, tungod kay ang orihinal nga mypy nga pagpatuman gipunting pag-ayo sa pagproseso sa usa ka file matag higayon. Kinahanglan namon nga atubangon ang daghang mga kahimtang sa borderline, ang panghitabo nga nanginahanglan balik-balik nga pagsusi sa mga kaso diin adunay nausab sa code. Pananglitan, kini mahitabo kung ang usa ka klase gi-assign sa usa ka bag-ong base nga klase. Sa dihang nahimo na namo ang among gusto, among napakunhod ang oras sa pagpatuman sa kadaghanang mga incremental check ngadto sa pipila lang ka segundos. Daw isa ini ka daku nga kadalag-an para sa amon.

Mas produktibo pa!

Uban sa hilit nga caching nga akong gihisgutan sa ibabaw, ang mypy daemon halos hingpit nga nasulbad ang mga problema nga motumaw kung ang usa ka programmer kanunay nga nagpadagan sa pagsusi sa tipo, nga naghimo mga pagbag-o sa gamay nga gidaghanon sa mga file. Bisan pa, ang pasundayag sa sistema sa labing gamay nga paborable nga kaso sa paggamit layo pa sa kamalaumon. Ang usa ka limpyo nga pagsugod sa mypy mahimong molungtad sa 15 minuto. Ug kini labaw pa sa among kalipay. Kada semana ang sitwasyon nahimong mas grabe samtang ang mga programmer nagpadayon sa pagsulat sa bag-ong code ug nagdugang sa mga anotasyon sa kasamtangan nga code. Ang among mga tiggamit gigutom pa alang sa dugang nga pasundayag, apan nalipay kami nga nahimamat sila sa tungatunga.

Nakahukom kami nga mobalik sa usa sa mga naunang ideya bahin sa mypy. Nga mao, aron ma-convert ang Python code ngadto sa C code. Ang pag-eksperimento sa Cython (usa ka sistema nga nagtugot kanimo sa paghubad sa code nga gisulat sa Python ngadto sa C code) wala maghatag kanamo sa bisan unsang makita nga pagpadali, mao nga nakahukom kami nga buhion ang ideya sa pagsulat sa among kaugalingong compiler. Tungod kay ang mypy codebase (gisulat sa Python) naa na sa tanan nga kinahanglan nga tipo nga anotasyon, among gihunahuna nga angayan nga sulayan nga gamiton kini nga mga anotasyon aron mapadali ang sistema. Naghimo dayon ako usa ka prototype aron sulayan kini nga ideya. Nagpakita kini og labaw pa sa 10 ka pilo nga pagtaas sa performance sa nagkalain-laing micro-benchmarks. Ang among ideya mao ang pag-compile sa Python modules ngadto sa C modules gamit ang Cython, ug ang paghimo sa type annotation ngadto sa run-time type checks (kasagaran ang type nga annotation wala tagda sa run-time ug gigamit lang sa type checking systems ). Nagplano kami sa paghubad sa mypy nga pagpatuman gikan sa Python ngadto sa usa ka pinulongan nga gidisenyo nga statically type, nga tan-awon (ug, sa kasagaran, magtrabaho) sama gayud sa Python. (Kini nga matang sa cross-language migration nahimong usa ka tradisyon sa mypy project. Ang orihinal nga mypy nga pagpatuman gisulat sa Alore, unya adunay syntactic hybrid sa Java ug Python).

Ang pag-focus sa CPython extension API mao ang yawe aron dili mawala ang mga kapabilidad sa pagdumala sa proyekto. Wala namo kinahanglana nga ipatuman ang usa ka virtual machine o bisan unsang mga librarya nga gikinahanglan sa mypy. Dugang pa, aduna pa kitay access sa tibuok Python ecosystem ug sa tanang gamit (sama sa pytest). Nagpasabot kini nga mahimo namong ipadayon ang paggamit sa gihubad nga Python code sa panahon sa pag-uswag, nga nagtugot kanamo sa pagpadayon sa pagtrabaho uban ang usa ka paspas kaayo nga sumbanan sa paghimo sa mga pagbag-o sa code ug pagsulay niini, imbes nga maghulat sa code nga ma-compile. Morag maayo kaayo ang among gibuhat sa paglingkod sa duha ka lingkuranan, ingnon ta, ug ganahan mi.

Ang compiler, nga among gitawag nga mypyc (tungod kay gigamit niini ang mypy isip front-end alang sa pag-analisar sa mga tipo), nahimo nga usa ka malampuson nga proyekto. Sa kinatibuk-an, nakab-ot namo ang gibana-bana nga 4x speedup alang sa kanunay nga mypy run nga walay caching. Ang pagpalambo sa kinauyokan sa mypyc nga proyekto mikuha sa usa ka gamay nga team ni Michael Sullivan, Ivan Levkivsky, Hugh Hahn, ug sa akong kaugalingon mga 4 ka bulan sa kalendaryo. Kini nga kantidad sa trabaho mas gamay kaysa kung unsa ang kinahanglan aron masulat pag-usab ang mypy, pananglitan, sa C++ o Go. Ug kinahanglan namon nga maghimo labi ka gamay nga mga pagbag-o sa proyekto kaysa kinahanglan namon buhaton kung gisulat kini pag-usab sa lain nga lengguwahe. Naglaum usab kami nga madala namo ang mypyc sa ingon nga lebel nga magamit kini sa ubang mga programmer sa Dropbox sa pagtipon ug pagpadali sa ilang code.

Aron makab-ot kini nga lebel sa pasundayag, kinahanglan namon nga magamit ang pipila nga makapaikag nga mga solusyon sa engineering. Sa ingon, ang compiler makapadali sa daghang mga operasyon pinaagi sa paggamit sa paspas, ubos nga lebel nga C constructs. Pananglitan, ang usa ka compiler function call gihubad ngadto sa usa ka C function call. Ug ang ingon nga tawag labi ka paspas kaysa pagtawag sa usa ka gihubad nga function. Ang ubang mga operasyon, sama sa pagpangita sa diksyonaryo, apil gihapon gamit ang regular nga C-API nga mga tawag gikan sa CPython, nga gamay ra nga mas paspas kung giipon. Nakuha namon ang dugang nga load sa sistema nga gihimo pinaagi sa paghubad, apan kini sa kini nga kaso naghatag lamang og gamay nga ganansya sa mga termino sa pasundayag.

Aron mahibal-an ang labing kasagaran nga "hinay" nga mga operasyon, gihimo namon ang pag-profile sa code. Armado sa kini nga datos, gisulayan namon nga i-tweak ang mypyc aron makamugna kini og mas paspas nga C code alang sa ingon nga mga operasyon, o isulat pag-usab ang katugbang nga code sa Python gamit ang mas paspas nga mga operasyon (ug usahay wala kami igo nga yano nga solusyon alang niana o uban pang problema) . Ang pagsulat pag-usab sa Python code kasagaran mas sayon ​​​​nga solusyon sa problema kay sa paghimo sa compiler nga awtomatik nga mohimo sa samang pagbag-o. Sa taas nga termino, gusto namong i-automate ang daghan niini nga mga pagbag-o, apan sa panahon nga kami naka-focus sa pagpadali sa mypy nga adunay gamay nga paningkamot. Ug sa paglihok padulong niini nga katuyoan, giputol namon ang daghang mga kanto.

Ipadayon…

Minahal nga magbabasa! Unsa ang imong mga impresyon sa mypy nga proyekto sa dihang nahibal-an nimo ang paglungtad niini?

Ang dalan sa pag-typecheck sa 4 ka milyon nga linya sa Python code. Bahin 2
Ang dalan sa pag-typecheck sa 4 ka milyon nga linya sa Python code. Bahin 2

Source: www.habr.com

Idugang sa usa ka comment