Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3

Ipinakita namin sa iyong pansin ang ikatlong bahagi ng pagsasalin ng materyal tungkol sa landas na tinahak ng Dropbox noong nagpapatupad ng sistema ng pagsusuri ng uri para sa Python code.

Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3

β†’ Mga nakaraang bahagi: muna ΠΈ pangalawa

Umaabot sa 4 na milyong linya ng na-type na code

Ang isa pang malaking hamon (at ang pangalawang pinakakaraniwang alalahanin sa mga na-survey sa loob) ay ang pagtaas ng dami ng code na sakop ng mga uri ng check sa Dropbox. Sinubukan namin ang ilang mga diskarte upang malutas ang problemang ito, mula sa natural na pagpapalaki ng laki ng nai-type na codebase hanggang sa pagtutuon ng mga pagsisikap ng mypy team sa static at dynamic na awtomatikong uri ng inference. Sa huli, tila walang simpleng diskarte sa panalong, ngunit nagawa naming makamit ang mabilis na paglaki sa dami ng naka-annotate na code sa pamamagitan ng pagsasama-sama ng maraming diskarte.

Bilang resulta, ang aming pinakamalaking repositoryo ng Python (na may backend code) ay may halos 4 na milyong linya ng annotated code. Ang gawain sa static na pag-type ng code ay natapos sa humigit-kumulang tatlong taon. Sinusuportahan na ngayon ng Mypy ang iba't ibang uri ng mga ulat sa saklaw ng code na nagpapadali sa pagsubaybay sa pag-usad ng pagta-type. Sa partikular, maaari kaming bumuo ng mga ulat sa code na may mga kalabuan sa mga uri, tulad ng, halimbawa, tahasang paggamit ng isang uri Any sa mga anotasyon na hindi ma-verify, o sa mga bagay tulad ng pag-import ng mga third-party na library na walang mga uri ng anotasyon. Bilang bahagi ng isang proyekto upang mapabuti ang katumpakan ng pagsuri ng uri sa Dropbox, nag-ambag kami sa pagpapabuti ng mga kahulugan ng uri (tinatawag na stub file) para sa ilang sikat na open source na aklatan sa isang sentralisadong imbakan ng Python nai-type.

Ipinatupad namin (at na-standardize sa mga kasunod na PEP) ang mga bagong feature ng uri ng system na nagbibigay-daan sa mas tumpak na mga uri para sa ilang partikular na pattern ng Python. Ang isang kapansin-pansing halimbawa nito ay TypeDict, na nagbibigay ng mga uri para sa mala-JSON na mga diksyunaryo na may nakapirming hanay ng mga string key, bawat isa ay may sariling halaga ng sarili nitong uri. Patuloy naming palalawakin ang uri ng sistema. Ang aming susunod na hakbang ay malamang na pagbutihin ang suporta para sa mga kakayahan sa numero ng Python.

Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3
Bilang ng mga linya ng annotated code: server

Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3
Bilang ng mga linya ng annotated code: client

Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3
Kabuuang bilang ng mga linya ng annotated code

Narito ang isang pangkalahatang-ideya ng mga pangunahing tampok ng mga bagay na ginawa namin upang madagdagan ang dami ng na-annotate na code sa Dropbox:

Kahigpitan ng anotasyon. Unti-unti naming dinagdagan ang mga kinakailangan para sa hirap ng pag-annotate ng bagong code. Nagsimula kami sa mga linter tip na nagmungkahi ng pagdaragdag ng mga anotasyon sa mga file na mayroon nang ilang anotasyon. Nangangailangan na kami ngayon ng mga uri ng anotasyon sa mga bagong file ng Python at sa karamihan ng mga kasalukuyang file.

Pag-type ng mga ulat. Nagpapadala kami sa mga koponan ng lingguhang ulat sa antas ng pag-type sa kanilang code at nagbibigay ng payo sa kung ano ang dapat na unang i-annotate.

Popularisasyon ng mypy. Pinag-uusapan namin ang mypy sa mga kaganapan at nakikipag-usap kami sa mga team para tulungan silang makapagsimula sa mga uri ng anotasyon.

Mga botohan. Nagsasagawa kami ng pana-panahong mga survey ng gumagamit upang matukoy ang mga pangunahing problema. Kami ay handa na pumunta sa malayo sa paglutas ng mga problemang ito (kahit na ang paglikha ng isang bagong wika upang mapabilis ang mypy!).

Pagganap. Lubos naming napabuti ang pagganap ng mypy sa pamamagitan ng paggamit ng daemon at mypyc. Ginawa ito para maayos ang mga abala na nanggagaling sa panahon ng proseso ng anotasyon, at upang makapagtrabaho sa malalaking halaga ng code.

Pagsasama sa mga editor. Bumuo kami ng mga tool upang suportahan ang pagpapatakbo ng mypy sa mga editor na sikat sa Dropbox. Kabilang dito ang PyCharm, Vim at VS Code. Lubos nitong pinasimple ang proseso ng pag-annotate sa code at pagsuri sa functionality nito. Ang mga uri ng pagkilos na ito ay karaniwan kapag nag-annotate ng umiiral na code.

Static na pagsusuri. Gumawa kami ng tool para maghinuha ng mga function signature gamit ang static analysis tool. Ang tool na ito ay maaari lamang gumana sa medyo simpleng mga sitwasyon, ngunit nakatulong ito sa amin na mapataas ang aming saklaw ng uri ng code nang walang labis na pagsisikap.

Suporta para sa mga aklatan ng ikatlong partido. Marami sa aming mga proyekto ang gumagamit ng toolkit ng SQLAlchemy. Sinasamantala nito ang mga pabago-bagong kakayahan ng Python na ang mga uri ng PEP 484 ay hindi direktang maimodelo. Kami, alinsunod sa PEP 561, ay lumikha ng kaukulang stub file at nagsulat ng isang plugin para sa mypy (open source), na nagpapabuti sa suporta ng SQLAlchemy.

Mga paghihirap na aming naranasan

Ang landas sa 4 na milyong linya ng na-type na code ay hindi palaging madali para sa amin. Sa landas na ito nakatagpo kami ng maraming lubak at nakagawa ng ilang pagkakamali. Ito ang ilan sa mga problemang naranasan namin. Inaasahan namin na ang pagsasabi tungkol sa kanila ay makakatulong sa iba na maiwasan ang mga katulad na problema.

Mga nawawalang file. Sinimulan namin ang aming trabaho sa pamamagitan ng pagsuri lamang ng maliit na halaga ng mga file. Ang anumang bagay na hindi kasama sa mga file na ito ay hindi nasuri. Ang mga file ay idinagdag sa listahan ng pag-scan nang lumitaw ang mga unang anotasyon sa kanila. Kung ang isang bagay ay na-import mula sa isang module na matatagpuan sa labas ng saklaw ng pag-verify, pagkatapos ay pinag-uusapan natin ang tungkol sa pagtatrabaho sa mga halaga tulad ng Any, na hindi nasubok sa lahat. Nagdulot ito ng malaking pagkawala ng katumpakan ng pag-type, lalo na sa mga unang yugto ng paglipat. Ang diskarte na ito ay gumagana nang mahusay sa ngayon, kahit na ang isang karaniwang sitwasyon ay ang pagdaragdag ng mga file sa saklaw ng pagsusuri ay nagpapakita ng mga problema sa ibang bahagi ng codebase. Sa pinakamasamang kaso, kapag ang dalawang nakahiwalay na mga lugar ng code ay pinagsama, kung saan, nang nakapag-iisa sa bawat isa, ang mga uri ay nasuri na, lumabas na ang mga uri ng mga lugar na ito ay hindi tugma sa bawat isa. Naging dahilan ito sa pangangailangang gumawa ng maraming pagbabago sa mga anotasyon. Sa pagbabalik-tanaw ngayon, napagtanto namin na dapat ay nagdagdag kami ng mga pangunahing module ng library sa lugar ng pagsusuri ng uri ng mypy nang mas maaga. Gagawin nitong mas predictable ang ating trabaho.

Pag-annotate ng lumang code. Noong nagsimula kami, mayroon kaming humigit-kumulang 4 na milyong linya ng umiiral na Python code. Malinaw na ang pag-annotate sa lahat ng code na ito ay hindi isang madaling gawain. Gumawa kami ng tool na tinatawag na PyAnnotate na maaaring mangolekta ng impormasyon ng uri habang tumatakbo ang mga pagsubok at maaaring magdagdag ng mga anotasyon ng uri sa iyong code batay sa impormasyong nakolekta. Gayunpaman, hindi namin napansin ang isang partikular na malawakang paggamit ng tool na ito. Ang impormasyon sa uri ng pangangalap ay mabagal, at ang mga awtomatikong nabuong anotasyon ay kadalasang nangangailangan ng maraming manu-manong pag-edit. Naisip namin na awtomatikong patakbuhin ang tool na ito sa tuwing susuriin namin ang code, o pagkolekta ng uri ng impormasyon batay sa pagsusuri ng ilang maliit na dami ng aktwal na mga kahilingan sa network, ngunit nagpasya kaming huwag gawin dahil masyadong mapanganib ang alinmang diskarte.

Bilang resulta, mapapansing ang karamihan sa code ay manu-manong na-annotate ng mga may-ari nito. Upang gabayan ang prosesong ito sa tamang direksyon, naghahanda kami ng mga ulat sa partikular na mahahalagang module at function na kailangang i-annotate. Halimbawa, mahalagang magbigay ng mga uri ng anotasyon para sa isang module ng library na ginagamit sa daan-daang lugar. Ngunit ang isang lumang serbisyo na pinapalitan ng bago ay hindi na napakahalagang i-annotate. Nag-eeksperimento rin kami sa paggamit ng static na pagsusuri upang bumuo ng mga uri ng anotasyon para sa legacy na code.

Paikot na pag-import. Sa itaas, pinag-usapan ko ang tungkol sa mga cyclic na pag-import (ang "dependency tangles"), na ang pagkakaroon nito ay naging mahirap na pabilisin ang mypy. Kinailangan din naming magtrabaho nang husto upang masuportahan ng mypy ang lahat ng uri ng mga idyoma na dulot ng mga paikot na pag-import na ito. Nakumpleto namin kamakailan ang isang pangunahing proyekto sa muling pagdidisenyo ng system na nag-ayos ng karamihan sa mga isyu ng mypy tungkol sa mga pabilog na pag-import. Ang mga problemang ito ay talagang nagmula sa mga unang araw ng proyekto, mula sa Alore, ang wikang pang-edukasyon kung saan orihinal na nakatuon ang mypy project. Pinapadali ng alore syntax ang paglutas ng mga problema sa mga cyclic import command. Ang modernong mypy ay nagmana ng ilang mga limitasyon mula sa maaga, hindi sopistikadong pagpapatupad nito (na isang mahusay na akma para sa Alore). Pinapahirap ng Python ang pagtatrabaho sa mga pabilog na pag-import, pangunahin dahil ang mga expression ay hindi maliwanag. Halimbawa, ang isang pagpapatakbo ng pagtatalaga ay maaaring aktwal na tumukoy ng isang uri ng alias. Ang Mypy ay hindi palaging nakaka-detect ng mga bagay na tulad nito hanggang sa maproseso ang karamihan sa loop ng pag-import. Walang ganoong kalabuan sa Alore. Ang mga mahihirap na desisyon na ginawa sa mga unang yugto ng pag-unlad ng system ay maaaring magpakita ng isang hindi kasiya-siyang sorpresa sa programmer pagkalipas ng maraming taon.

Mga resulta: ang landas sa 5 milyong linya ng code at mga bagong abot-tanaw

Malayo na ang narating ng mypy project - mula sa mga unang prototype hanggang sa isang system na kumokontrol sa 4 na milyong linya ng mga uri ng production code. Habang umuunlad ang mypy, ang mga uri ng pahiwatig ng Python ay na-standardize. Sa mga araw na ito, isang malakas na ecosystem ang nabuo sa paligid ng pag-type ng Python code. Mayroon itong lugar para sa suporta sa library, naglalaman ito ng mga pantulong na tool para sa mga IDE at editor, mayroon itong ilang uri ng mga control system, bawat isa ay may sariling mga kalamangan at kahinaan.

Kahit na ang pagsuri ng uri ay ibinigay na sa Dropbox, naniniwala ako na tayo ay nasa mga unang araw pa lamang ng pag-type ng Python code. Sa tingin ko, ang mga teknolohiya ng pagsuri sa uri ay patuloy na uunlad at pagbutihin.

Kung hindi mo pa nagagamit ang type checking sa iyong malakihang proyekto sa Python, alamin na ngayon ay isang napakagandang oras upang simulan ang paglipat sa static na pag-type. Nakipag-usap ako sa mga gumawa ng katulad na paglipat. Walang nagsisi sa kanila. Ang pagsuri ng uri ay ginagawang isang wika ang Python na mas angkop sa pagbuo ng malalaking proyekto kaysa sa "regular na Python."

Minamahal na mambabasa! Gumagamit ka ba ng type checking sa iyong mga proyekto sa Python?

Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3
Ang landas sa pag-typecheck ng 4 na milyong linya ng Python code. Bahagi 3

Pinagmulan: www.habr.com

Magdagdag ng komento