Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3

Ne paraqesim në vëmendjen tuaj pjesën e tretë të përkthimit të materialit në lidhje me rrugën që mori Dropbox gjatë zbatimit të një sistemi të kontrollit të tipit për kodin Python.

Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3

→ Pjesët e mëparshme: i parë и i dytë

Arritja e 4 milion rreshtave të kodit të shtypur

Një sfidë tjetër e madhe (dhe shqetësimi i dytë më i zakonshëm midis të anketuarve brenda vendit) ishte rritja e sasisë së kodit të mbuluar nga kontrollet e tipit në Dropbox. Ne kemi provuar disa mënyra për të zgjidhur këtë problem, nga rritja e natyrshme e madhësisë së bazës së kodit të shtypur te fokusimi i përpjekjeve të ekipit mypy në konkluzionet e tipit të automatizuar statik dhe dinamik. Në fund, dukej sikur nuk kishte një strategji të thjeshtë fituese, por ne ishim në gjendje të arrinim rritje të shpejtë në vëllimin e kodit të shënuar duke kombinuar shumë qasje.

Si rezultat, depoja jonë më e madhe e Python (me kodin mbështetës) ka gati 4 milionë rreshta kodi të shënuar. Puna për shtypjen e kodit statik përfundoi në afërsisht tre vjet. Mypy tani mbështet lloje të ndryshme të raporteve të mbulimit të kodit që e bëjnë më të lehtë monitorimin e progresit të shtypjes. Në veçanti, ne mund të gjenerojmë raporte mbi kodin me paqartësi në lloje, të tilla si, për shembull, përdorimi i qartë i një lloji Any në shënimet që nuk mund të verifikohen, ose me gjëra të tilla si importimi i bibliotekave të palëve të treta që nuk kanë shënime të tipit. Si pjesë e një projekti për të përmirësuar saktësinë e kontrollit të tipit në Dropbox, ne kontribuuam në përmirësimin e përkufizimeve të tipit (të ashtuquajturat skedarë cung) për disa biblioteka të njohura me burim të hapur në një depo të centralizuar të Python të daktilografuara.

Ne implementuam (dhe standardizuam në PEP-të pasuese) veçori të reja të sistemit të tipit që lejojnë lloje më të sakta për disa modele specifike Python. Një shembull i dukshëm i kësaj është TypeDict, i cili ofron lloje për fjalorë të ngjashëm me JSON që kanë një grup fiks çelësash vargu, secili me një vlerë të llojit të vet. Ne do të vazhdojmë të zgjerojmë sistemin e tipit. Hapi ynë i ardhshëm ka të ngjarë të jetë përmirësimi i mbështetjes për aftësitë numerike të Python.

Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3
Numri i rreshtave të kodit të shënuar: server

Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3
Numri i rreshtave të kodit të shënuar: klient

Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3
Numri total i rreshtave të kodit të shënuar

Këtu është një përmbledhje e veçorive kryesore të gjërave që bëmë për të rritur sasinë e kodit të shënuar në Dropbox:

Rigoroziteti i shënimeve. Ne gradualisht rritëm kërkesat për ashpërsinë e shënimit të kodit të ri. Ne filluam me këshilla për linjat që sugjeronin shtimin e shënimeve në skedarë që kishin tashmë disa shënime. Tani kërkojmë shënime të tipit në skedarët e rinj Python dhe në shumicën e skedarëve ekzistues.

Raportet e shtypjes. Ne i dërgojmë ekipeve raporte javore për nivelin e shtypjes së kodit të tyre dhe u japim këshilla se çfarë duhet të shënohet së pari.

Popullarizimi i mypy. Ne flasim për mypy në ngjarje dhe flasim me ekipe për t'i ndihmuar ata të fillojnë me shënimet e tipit.

Sondazhet. Ne kryejmë anketa periodike të përdoruesve për të identifikuar problemet kryesore. Ne jemi gati të shkojmë shumë larg në zgjidhjen e këtyre problemeve (madje edhe krijimin e një gjuhe të re për të shpejtuar mypy!).

Performanca. Ne kemi përmirësuar shumë performancën e mypy duke përdorur daemon dhe mypyc. Kjo u bë për të zbutur shqetësimet që lindin gjatë procesit të shënimit dhe për të qenë në gjendje të punoni me sasi të mëdha kodi.

Integrimi me redaktorët. Ne kemi ndërtuar mjete për të mbështetur ekzekutimin e mypy në redaktorët që janë të njohur në Dropbox. Kjo përfshin PyCharm, Vim dhe VS Code. Kjo thjeshtoi shumë procesin e shënimit të kodit dhe kontrollit të funksionalitetit të tij. Këto lloj veprimesh janë të zakonshme kur shënohet kodi ekzistues.

Analiza statike. Ne krijuam një mjet për të konkluduar nënshkrimet e funksionit duke përdorur mjete të analizës statike. Ky mjet mund të funksionojë vetëm në situata relativisht të thjeshta, por na ndihmoi të rrisim mbulimin e llojit të kodit pa shumë përpjekje.

Mbështetje për bibliotekat e palëve të treta. Shumë nga projektet tona përdorin paketën e veglave SQLAlchemy. Ai përfiton nga aftësitë dinamike të Python që llojet PEP 484 nuk janë në gjendje t'i modelojnë drejtpërdrejt. Ne, në përputhje me PEP 561, krijuam skedarin cung përkatës dhe shkruam një shtojcë për mypy (burim i hapur), i cili përmirëson mbështetjen e SQLAlchemy.

Vështirësitë që kemi hasur

Rruga drejt 4 milionë rreshtave të kodit të shtypur nuk ka qenë gjithmonë e lehtë për ne. Në këtë rrugë kemi hasur në shumë gropa dhe kemi bërë disa gabime. Këto janë disa nga problemet që kemi hasur. Shpresojmë që tregimi për to do t'i ndihmojë të tjerët të shmangin probleme të ngjashme.

Mungojnë skedarët. Ne filluam punën tonë duke kontrolluar vetëm një sasi të vogël skedarësh. Çdo gjë që nuk përfshihet në këto skedarë nuk u kontrollua. Skedarët u shtuan në listën e skanimit kur u shfaqën shënimet e para në to. Nëse diçka është importuar nga një modul i vendosur jashtë fushës së verifikimit, atëherë ne po flisnim për të punuar me vlera si Any, të cilat nuk u testuan fare. Kjo çoi në një humbje të konsiderueshme të saktësisë së shtypjes, veçanërisht në fazat e hershme të migrimit. Kjo qasje ka funksionuar çuditërisht mirë deri më tani, megjithëse një situatë tipike është se shtimi i skedarëve në objektin e rishikimit zbulon probleme në pjesë të tjera të bazës së kodeve. Në rastin më të keq, kur u bashkuan dy zona të izoluara të kodit, në të cilat, pavarësisht nga njëra-tjetra, llojet tashmë ishin kontrolluar, rezultoi se llojet e këtyre zonave ishin të papajtueshme me njëra-tjetrën. Kjo çoi në nevojën për të bërë shumë ndryshime në shënimet. Duke parë tani, kuptojmë se duhet të kishim shtuar më shpejt modulet kryesore të bibliotekës në zonën e kontrollit të tipit të mypy. Kjo do ta bënte punën tonë shumë më të parashikueshme.

Shënimi i kodit të vjetër. Kur filluam, kishim rreth 4 milionë rreshta të kodit ekzistues Python. Ishte e qartë se shënimi i gjithë këtij kodi nuk ishte një detyrë e lehtë. Ne kemi krijuar një mjet të quajtur PyAnnotate që mund të mbledhë informacione për llojin ndërsa testet kryhen dhe mund të shtojë shënime të tipit në kodin tuaj bazuar në informacionin e mbledhur. Megjithatë, ne nuk kemi vërejtur një adoptim veçanërisht të përhapur të këtij mjeti. Mbledhja e informacionit të llojit ishte e ngadaltë dhe shënimet e krijuara automatikisht shpesh kërkonin shumë modifikime manuale. Ne menduam ta përdornim këtë mjet automatikisht sa herë që rishikonim kodin, ose të mblidhnim informacione për llojin bazuar në analizimin e disa vëllimeve të vogla të kërkesave aktuale të rrjetit, por vendosëm të mos e bëjmë këtë, sepse secila qasje ishte shumë e rrezikshme.

Si rezultat, mund të vërehet se shumica e kodit u shënua manualisht nga pronarët e tij. Për ta drejtuar këtë proces në drejtimin e duhur, ne përgatisim raporte mbi modulet dhe funksionet veçanërisht të rëndësishme që duhet të shënohen. Për shembull, është e rëndësishme të sigurohen shënime të tipit për një modul bibliotekë që përdoret në qindra vende. Por një shërbim i vjetër që po zëvendësohet me një të ri nuk është më aq i rëndësishëm për t'u shënuar. Ne po eksperimentojmë gjithashtu me përdorimin e analizave statike për të gjeneruar shënime të tipit për kodin e vjetër.

Importet ciklike. Më lart, fola për importet ciklike (“ngatërresat e varësisë”), ekzistenca e të cilave e bëri të vështirë përshpejtimin e mypy. Ne gjithashtu duhej të punonim shumë që mypy të mbështeste të gjitha llojet e idiomave që shkaktohen nga këto importe ciklike. Së fundmi kemi përfunduar një projekt të madh të ridizajnimit të sistemit që rregulloi shumicën e problemeve të mypy në lidhje me importet rrethore. Këto probleme në fakt erdhën që në ditët e para të projektit, nga Alore, gjuha edukative në të cilën fillimisht ishte fokusuar projekti mypy. Sintaksa Alore e bën të lehtë zgjidhjen e problemeve me komandat e importit ciklik. Mypy modern ka trashëguar disa kufizime nga zbatimi i tij i mëparshëm, me mendje të thjeshtë (i cili ishte një përshtatje e shkëlqyeshme për Alore). Python e bën të vështirë punën me importe rrethore, kryesisht sepse shprehjet janë të paqarta. Për shembull, një operacion caktimi mund të përcaktojë një pseudonim tip. Mypy nuk është gjithmonë në gjendje të zbulojë gjëra të tilla derisa pjesa më e madhe e ciklit të importit të jetë përpunuar. Nuk kishte paqartësi të tilla në Alore. Vendimet e dobëta të marra në fazat e hershme të zhvillimit të sistemit mund të paraqesin një surprizë të pakëndshme për programuesin shumë vite më vonë.

Rezultatet: rruga drejt 5 milionë rreshtave të kodit dhe horizonte të reja

Projekti mypy ka bërë një rrugë të gjatë - nga prototipet e hershme në një sistem që kontrollon 4 milionë linja të llojeve të kodit të prodhimit. Ndërsa mypy evoluoi, sugjerimet e tipit të Python u standardizuan. Këto ditë, një ekosistem i fuqishëm është zhvilluar rreth shtypjes së kodit Python. Ka një vend për mbështetjen e bibliotekës, përmban mjete ndihmëse për IDE dhe redaktorë, ka disa sisteme kontrolli të tipit, secila prej të cilave ka të mirat dhe të këqijat e veta.

Edhe pse kontrolli i tipit është tashmë i dhënë në Dropbox, besoj se jemi ende në ditët e para të shtypjes së kodit Python. Unë mendoj se teknologjitë e kontrollit të tipit do të vazhdojnë të zhvillohen dhe përmirësohen.

Nëse nuk e keni përdorur tashmë kontrollin e tipit në projektin tuaj Python në shkallë të gjerë, atëherë dijeni se tani është një kohë shumë e mirë për të filluar të kaloni në shtypjen statike. Kam biseduar me ata që kanë bërë një tranzicion të ngjashëm. Asnjëri prej tyre nuk u pendua. Kontrollimi i tipit e bën Python një gjuhë që është shumë më e përshtatshme për zhvillimin e projekteve të mëdha sesa "Python i rregullt".

Të nderuar lexues! A përdorni kontrollin e tipit në projektet tuaja Python?

Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3
Rruga për të kontrolluar 4 milion rreshta të kodit Python. Pjesa 3

Burimi: www.habr.com

Shto një koment