Bemutatjuk Önöknek a Dropbox útjáról szóló anyag harmadik részének fordítását, ahol a Python-kód típusellenőrzési rendszerének bevezetéséről van szó.
→ Előző részek: és
4 millió sor típusozott kód elérése
Egy másik fontos feladat (ez volt a második legnépszerűbb probléma, ami foglalkoztatta a belső felmérések résztvevőit) a Dropbox kódjának típusellenőrzés alá vont terjedelmének növelése volt. Több megközelítést kipróbáltunk a feladat megoldására - a típusozott kódbázis természetes növekedésétől kezdve, a mypy csapat tagjainak statikus és dinamikus automatikus típuslevonásra irányuló erőfeszítéseiig. Végül az a benyomás alakult ki, hogy itt nincs egyszerű, nyerő stratégia, de sikerült gyors növekedést elérnünk az annotált kód mennyiségében, kombinálva számos megközelítést.
Ennek eredményeként a legnagyobb Python-repozitóriumunkban (háttérkód) az annotált kód sorainak száma közel 4 millióra emelkedett. A kód statikus típusozásának munkája körülbelül három évet vett igénybe. A Mypy most különböző típusok lefedettségi jelentéseit támogatja, amelyek megkönnyítik a típusozás előrehaladásának nyomon követését. Különösen képesek vagyunk jelentéseket készíteni a típusokkal kapcsolatos bizonytalanságokról, például a nyilvános típusok használatáról. Bármely annotáció, amelyet nem lehet ellenőrizni, vagy olyan külső könyvtárak importálásáról, amelyekben nincsenek típusannotációk. A Dropbox típusellenőrzésének pontosabbá tételére irányuló projekt keretében hozzájárultunk néhány népszerű nyílt forráskódú könyvtár típusdefinícióinak (úgynevezett stub fájlok) javításához a központosított Python-repozitóriumban. .
Új funkciókat valósítottunk meg (és szabványosítottunk a későbbi PEP-ekben) a típusaitalrendszerhez, amelyek lehetővé teszik pontosabb típusok használatát bizonyos specifikus Python mintákhoz. Ennek figyelemre méltó példája a TypeDict, amely típusokat biztosít a JSON-szerű szótárakhoz, amelyeknek rögzített számú karakterlánc-kulcsuk van, mindegyik saját típusú értékkel. Folytatni fogjuk a típusok rendszerének bővítését. Valószínűleg következő lépésünk a Python számokkal kapcsolatos funkcióinak támogatásának javítása lesz.

Annotált kód sorainak száma: szerver

Az annotált kód sorainak száma: ügyfél

Az annotált kód teljes sorainak száma
Íme egy áttekintés a Dropbox-ban végrehajtott főbb lépésekről az annotált kód mennyiségének növelése érdekében:
Az annotálás szigorúsága. Fokozatosan növeltük az új kód annotálására vonatkozó követelmények szigorát. Elkezdtük a lintelési javaslatokkal, amelyek azt javasolták, hogy annotációkat adjunk azokhoz a fájlokhoz, amelyekben már vannak annotációk. Most már típusannotációkat követelünk meg az új Python fájlokban és a meglévő fájlok többségében.
Típus jelentések. Minden héten jelentéseket küldünk a csapatoknak a kódjaik típusossági szintjéről, és tanácsokat adunk arról, hogy mit érdemes elsőként annotálni.
A mypy népszerűsítése. Beszélünk a mypy-ról különféle eseményeken, és kapcsolatba lépünk a csapatokkal, segítve őket az annotációk használatának megkezdésében.
Kérdőívek. Időszakos felméréseket végzünk a felhasználók számára a legfőbb problémák feltárására. Készen állunk arra, hogy messzire elmenjünk ezek megoldása érdekében (akár új nyelv létrehozásáig is a mypy felgyorsítása érdekében!).
Teljesítmény. Jelentősen javítottuk a mypy teljesítményét a démon és mypyc használatával. Ezt azért tettük, hogy simábbá tegyük az annotálási folyamatot, és lehetőséget biztosítsunk nagyobb kódmennyiséggel való munkára.
Integráció a szerkesztőkbe. Olyan eszközöket hoztunk létre, amelyek támogatják a mypy futtatását a Dropboxban népszerű szerkesztőkben. Ezek közé tartozik a PyCharm, Vim és VS Code. Ez jelentősen megkönnyítette a kód annotálásának és működésének ellenőrzésének folyamatát. Az ilyen lépések általában jellemzőek a meglévő kód annotálásakor.
Statikus elemzés. Olyan eszközt hoztunk létre, amely funkciók aláírásait állítja elő statikus elemzési eszközök segítségével. Ez az eszköz csak viszonylag egyszerű helyzetekben működik, de segített nekünk anélkül, hogy komoly erőfeszítéseket tennénk, növelni a kód típusokkal való lefedettségét.
Harmadik féltől származó könyvtárak támogatása. Sok projektünkben használunk SQLAlchemy eszközkészletet. Ez dinamikus Python lehetőségeket használ, amelyeket a PEP 484 típusai nem tudnak közvetlenül modellezni. A PEP 561 szerint létrehoztuk a megfelelő stub fájlt és írtunk egy plugint a mypy-hoz.), amely javítja az SQLAlchemy támogatását.
Nehezenségek, amelyekkel szembesültünk
Az út 4 millió sor típusos kódhoz nem mindig volt könnyű számunkra. Ezen az úton rengeteg gödörbe ütköztünk és több hibát követtünk el. Íme néhány probléma, amellyel szembesültünk. Reméljük, hogy a róluk szóló beszámoló segít másoknak elkerülni hasonlóakat.
Hiányzó fájlok. A munkát csak egy kis mennyiségű fájl ellenőrzésével kezdtük. Minden, ami nem tartozott e fájlok körébe, nem lett ellenőrizve. A fájlok a vizsgálati listára akkor kerültek fel, amikor az első megjegyzések megjelentek bennük. Ha valami egy olyan modulból importálódott, amely a vizsgálat területén kívül volt, akkor az a típusú értékek kezelése volt Bármely, amelyeket egyáltalán nem ellenőriztek. Ez jelentős típusossági pontosság-veszteséghez vezetett, különösen a migráció korai szakaszában. Ez a megközelítés meglepően jól működött, bár az tipikus helyzet az volt, amikor fájlok hozzáadása a vizsgálati területhez problémákat tárt fel a kódalap más részein. A legrosszabb esetben, amikor két elszigetelt kódterület egyesült, amelyek önállóan már ellenőrzés alatt álltak, kiderült, hogy ezek a területek nem voltak kompatibilisek egymással. Ez szükségessé tette a megjegyzések számos módosítását. Most visszatekintve rájövünk, hogy sokkal korábban kellett volna az alap könyvtári modulokat a mypy típusellenőrzési körébe felvennünk. Ez sokkal kiszámíthatóbbá tette volna a munkánkat.
Régi kód annotálása. Amikor elkezdtük a munkát, körülbelül 4 millió sor már meglévő Python kódunk volt. Nyilvánvaló volt, hogy ennek a kódnak a teljes annotálása nem könnyű feladat. Készítettünk egy eszközt, PyAnnotate néven, amely képes összegyűjteni a típusinformációkat a tesztek futása közben, és képes hozzáadni a kódhoz a típusannotációkat az összegyűjtött adatok alapján. Azonban nem tapasztaltunk különösebb elterjedtséget ezzel az eszközzel kapcsolatban. A típusinformációk összegyűjtése lassú volt, a automatikusan generált annotációk gyakran sok kézi javítást igényeltek. Gondolkodtunk azon, hogy automatikusan futtassuk ezt az eszközt minden kódellenőrzés során, vagy hogy a típusinformációkat valamilyen kis mennyiségű valódi hálózati kérés elemzéséből gyűjtsük, de úgy döntöttünk, hogy ezt nem tesszük, mivel bármelyik megközelítés túl kockázatos lenne.
Végezetül megjegyezhetjük, hogy a kód nagy része manuálisan lett annotálva a tulajdonosai által. Mi, hogy ezt a folyamatot a helyes irányba tereljük, fontos modulok és funkciók jelentését készítjük, amelyeket annotálni kell. Például fontos, hogy a többszörösen használt könyvtári modult típusannotációkkal lássuk el. A régi szolgáltatást, amelyet egy új vált fel, már nem annyira fontos annotálni. Ezenkívül statikus elemzést is alkalmazunk a típusannotációk generálására a régi kódhoz.
Ciklikus importok. A ciklikus importokról (a „függőségek gubancáról”) már beszéltem, amelyek létezése megnehezítette a mypy felgyorsítását. Emellett komoly munkát kellett végeznünk, hogy a mypy támogatni tudja az összes olyan idiomát, amelyek ezen ciklikus importok miatt merülnek fel. Nemrég fejeztük be egy nagyszabású rendszerújraírási projektet, amely a mypy ciklikus importokkal kapcsolatos problémáinak többségét javította. Ezek a problémák, valójában, a projekt korai napjaiból származtak, még Alore-ból, a mypy eredetileg orientált tanulmányi nyelvéből. Az Alore szintaxis lehetővé teszi a ciklikus importparancsok problémáinak könnyű kezelését. A modern mypy örökölt néhány korai, egyszerűsített megvalósításából származó korlátot (amely kiválóan alkalmas volt az Alore-hoz). A Python a ciklikus importok kezelését főként a kifejezések egyértelműtlensége miatt bonyolítja. Például, egy érték hozzárendelésének során ténylegesen típusaliast lehet definiálni. A mypy nem mindig képes ezeket a dolgokat felderíteni, amíg a ciklus nagy része nem feldolgozott. Az Alore-ban nem voltak ilyen egyértelműtlenségek. A rendszer korai fejlesztési szakaszában hozott rossz döntések évek múlva kellemetlen meglepetést okozhatnak a programozónak.
Összegzés: az 5 millió sor kódhoz és új horizontokhoz vezető út
A mypy projekt hosszú utat tett meg – a korai prototípusoktól a rendszerig, amelynek segítségével a 4 millió soros termelési kód típusa ellenőrizhető. A mypy fejlődése során standardizálták a típusokkal kapcsolatos javaslatokat a Pythonban. Manapság egy erős ökoszisztéma fejlődött ki a Python-kódok típusossága körül. Ezen belül helyet kaptak a könyvtárak támogatása, IDE-k és szerkesztők segédeszközei, továbbá több típusellenőrző rendszer, mindegyiknek megvannak a maga előnyei és hátrányai.
Bár a típusellenőrzés már a Dropboxban magától értetődőnek tekinthető, biztos vagyok benne, hogy még mindig a Python-kódok típusosságának hajnalán élünk. Azt gondolom, hogy a típusellenőrző technológiák továbbra is fejlődnek és javulnak majd.
Ha még nem használtál típusellenőrzést a nagy léptékű Python-projektedben, tudd, hogy most van itt az ideje a statikus típusozásra való átállásnak. Beszéltem olyanokkal, akik már végrehajtották ezt az átmenetet. Senki sem bánta meg. A típusellenőrzés a Pythont olyan nyelvvé alakítja, ami sokkal jobban megfelel a nagy projektek fejlesztéséhez, mint a "szokásos Python".
Használjátok a CI/CD technológiákat a projektjeitekben? Használsz típusellenőrzést a Python-projektjeidben?
Forrás: habr.com
