4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə

Python kodu üçün tip yoxlama sistemini tətbiq edərkən Dropbox-un keçdiyi yol haqqında materialın tərcüməsinin üçüncü hissəsini diqqətinizə təqdim edirik.

4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə

→ Əvvəlki hissələr: ilk и Ikinci

Yazılan kodun 4 milyon sətirinə çatır

Digər əsas problem (və daxili sorğuda iştirak edənlər arasında ikinci ən ümumi narahatlıq) Dropbox-da növ yoxlamalarının əhatə etdiyi kodun miqdarının artırılması idi. Biz bu problemi həll etmək üçün bir neçə yanaşmanı sınamışıq, yığılmış kod bazasının ölçüsünü təbii şəkildə artırmaqdan mypy komandasının səylərini statik və dinamik avtomatlaşdırılmış tip nəticəsinə yönəltməyə qədər. Nəhayət, sadə bir uduş strategiyası olmadığı kimi görünürdü, lakin biz bir çox yanaşmaları birləşdirərək annotasiya edilmiş kodun həcmində sürətli artıma nail ola bildik.

Nəticədə, bizim ən böyük Python repozitorumuzda (backend kodu ilə) təxminən 4 milyon sətir annotasiya edilmiş kod var. Statik kodun yazılması üzrə işlər təxminən üç il ərzində tamamlandı. Mypy indi yazma tərəqqisinə nəzarəti asanlaşdıran müxtəlif növ kod əhatəsi hesabatlarını dəstəkləyir. Xüsusilə, biz növlərdə qeyri-müəyyənlikləri olan kod haqqında hesabatlar yarada bilərik, məsələn, bir növün açıq istifadəsi kimi Any yoxlanılması mümkün olmayan annotasiyalarda və ya tip annotasiyaları olmayan üçüncü tərəf kitabxanalarının idxalı kimi şeylərlə. Dropbox-da növün yoxlanılmasının düzgünlüyünü təkmilləşdirmək layihəsinin bir hissəsi olaraq, biz mərkəzləşdirilmiş Python repozitoriyasında bəzi məşhur açıq mənbəli kitabxanalar üçün tip təriflərinin (sub faylları adlanan) təkmilləşdirilməsinə töhfə verdik. tipli.

Biz bəzi spesifik Python nümunələri üçün daha dəqiq növlərə imkan verən tip sisteminin yeni xüsusiyyətlərini həyata keçirdik (və sonrakı PEP-lərdə standartlaşdırdıq). Bunun diqqətəlayiq nümunəsidir TypeDict, hər biri öz növünün dəyərinə malik olan sabit sətir düymələri dəstinə malik olan JSON kimi lüğətlər üçün növləri təmin edir. Biz tip sistemini genişləndirməyə davam edəcəyik. Növbəti addımımız çox güman ki, Python-un ədədi imkanları üçün dəstəyi təkmilləşdirmək olacaq.

4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə
Annotasiya edilmiş kodun sətirlərinin sayı: server

4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə
Annotasiya edilmiş kodun sətirlərinin sayı: müştəri

4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə
Annotasiya edilmiş kodun sətirlərinin ümumi sayı

Dropbox-da qeyd edilmiş kodun miqdarını artırmaq üçün gördüyümüz işlərin əsas xüsusiyyətlərinə nəzər salaq:

Annotasiya ciddiliyi. Yeni kodun annotasiyasının sərtliyinə dair tələbləri tədricən artırdıq. Artıq bəzi annotasiyaları olan fayllara qeydlər əlavə etməyi təklif edən linter məsləhətləri ilə başladıq. Biz indi yeni Python fayllarında və əksər mövcud fayllarda tip annotasiyaları tələb edirik.

Hesabatların yazılması. Biz komandalara kodların yazılma səviyyəsi ilə bağlı həftəlik hesabatlar göndəririk və ilk növbədə nəyin qeyd edilməli olduğuna dair məsləhətlər veririk.

Mypy-nin populyarlaşması. Tədbirlərdə mypy haqqında danışırıq və tip annotasiyalarına başlamağa kömək etmək üçün komandalarla danışırıq.

Anketlər. Biz əsas problemləri müəyyən etmək üçün vaxtaşırı istifadəçi sorğuları keçiririk. Biz bu problemlərin həllində kifayət qədər uzağa getməyə hazırıq (hətta mypy-ni sürətləndirmək üçün yeni bir dil yaratmaq!).

Performans. Daemon və mypyc-dən istifadə edərək mypy-nin performansını xeyli yaxşılaşdırdıq. Bu, annotasiya prosesi zamanı yaranan narahatçılıqları aradan qaldırmaq və böyük həcmdə kodlarla işləyə bilmək üçün edilib.

Redaktorlarla inteqrasiya. Biz Dropbox-da məşhur olan redaktorlarda mypy-nin işləməsini dəstəkləmək üçün alətlər hazırlamışıq. Buraya PyCharm, Vim və VS Kodu daxildir. Bu, kodun annotasiya edilməsi və onun funksionallığının yoxlanılması prosesini xeyli sadələşdirdi. Mövcud kodu şərh edərkən bu cür hərəkətlər ümumi olur.

Statik analiz. Statik analiz alətlərindən istifadə edərək funksiya imzalarını çıxarmaq üçün alət yaratdıq. Bu alət yalnız nisbətən sadə vəziyyətlərdə işləyə bilər, lakin o, bizə çox səy göstərmədən kod növünün əhatə dairəsini artırmağa kömək etdi.

Üçüncü tərəf kitabxanalarına dəstək. Bir çox layihələrimiz SQLAlchemy alət dəstindən istifadə edir. PEP 484 növlərinin birbaşa modelləşdirə bilmədiyi Python-un dinamik imkanlarından istifadə edir. PEP 561-ə uyğun olaraq, müvafiq stub faylını yaratdıq və mypy üçün plagin yazdıq (açıq mənbə), SQLAlchemy dəstəyini yaxşılaşdırır.

Qarşılaşdığımız çətinliklər

Yazılan kodun 4 milyon sətirinə gedən yol bizim üçün həmişə asan olmayıb. Bu yolda biz çoxlu çuxurlarla qarşılaşdıq və bir sıra səhvlərə yol verdik. Bunlar bizim qarşılaşdığımız problemlərdən bəziləridir. Ümid edirik ki, onlar haqqında danışmaq başqalarına oxşar problemlərdən qaçmağa kömək edəcək.

Çatışmayan fayllar. İşimizə yalnız az miqdarda faylları yoxlamaqla başladıq. Bu fayllara daxil olmayan heç bir şey yoxlanılmayıb. Fayllar ilk qeydlər görünəndə skan edilmiş siyahıya əlavə edildi. Əgər yoxlama çərçivəsindən kənarda yerləşən moduldan bir şey idxal edilibsə, o zaman biz aşağıdakı kimi dəyərlərlə işləməkdən danışırdıq. Any, ümumiyyətlə sınaqdan keçirilməmişdir. Bu, xüsusən miqrasiyanın ilkin mərhələlərində yazı düzgünlüyünün əhəmiyyətli dərəcədə itirilməsinə səbəb oldu. Bu yanaşma indiyə qədər təəccüblü dərəcədə yaxşı işləmişdir, baxmayaraq ki, tipik vəziyyət faylların nəzərdən keçirilməsinin əhatə dairəsinə əlavə edilməsinin kod bazasının digər hissələrində problemləri aşkar etməsidir. Ən pis halda, bir-birindən asılı olmayaraq növlərin artıq yoxlanıldığı iki təcrid olunmuş kod sahəsi birləşdirildikdə, bu sahələrin növlərinin bir-biri ilə uyğunsuz olduğu ortaya çıxdı. Bu, annotasiyalarda bir çox dəyişikliklərin edilməsi zərurətinə səbəb oldu. İndi geriyə nəzər saldıqda anlayırıq ki, biz mypy-nin tip yoxlama sahəsinə daha tez əsas kitabxana modullarını əlavə etməliydik. Bu, işimizi daha proqnozlaşdırıla bilən hala gətirərdi.

Köhnə kodu şərh edir. Başladığımız zaman bizdə təxminən 4 milyon sətir mövcud Python kodu var idi. Aydın idi ki, bütün bu kodu şərh etmək asan məsələ deyil. Biz PyAnnotate adlı alət yaratmışıq ki, o, testlər aparılarkən növ məlumatlarını toplaya və toplanmış məlumat əsasında kodunuza tip annotasiyaları əlavə edə bilər. Bununla belə, biz bu alətin xüsusilə geniş şəkildə qəbul edilməsini müşahidə etməmişik. Növ məlumatlarının toplanması ləng gedirdi və avtomatik olaraq yaradılan annotasiyalar çox vaxt əl ilə redaktə etməyi tələb edirdi. Biz kodu hər dəfə nəzərdən keçirəndə bu aləti avtomatik işə salmağı və ya bəzi kiçik həcmli faktiki şəbəkə sorğularının təhlili əsasında tip məlumatı toplamaq barədə düşündük, lakin hər iki yanaşma çox riskli olduğu üçün etməməyi qərara aldıq.

Nəticə olaraq qeyd etmək olar ki, kodun çox hissəsi sahibləri tərəfindən əl ilə qeyd edilib. Bu prosesi düzgün istiqamətə yönəltmək üçün biz qeyd edilməli olan xüsusilə vacib modullar və funksiyalar haqqında hesabatlar hazırlayırıq. Məsələn, yüzlərlə yerdə istifadə olunan kitabxana modulu üçün tip annotasiyaları təqdim etmək vacibdir. Ancaq yenisi ilə əvəz olunan köhnə xidmətə şərh əlavə etmək artıq o qədər də vacib deyil. Biz həmçinin köhnə kod üçün tip annotasiyaları yaratmaq üçün statik analizdən istifadə etməklə sınaqdan keçiririk.

Dövrlü idxal. Yuxarıda, mövcudluğu mypy sürətləndirməyi çətinləşdirən tsiklik idxaldan ("asılılıq dolaşıqları") danışdım. Biz də mypy-nin bu dövri idxalın səbəb olduğu hər cür deyimləri dəstəkləməsi üçün çox çalışmalı olduq. Bu yaxınlarda biz mypy-nin sirkulyar idxalla bağlı problemlərinin əksəriyyətini həll edən əsas sistem yenidən dizayn layihəsini tamamladıq. Bu problemlər əslində layihənin ilk günlərindən, mypy layihəsinin ilkin diqqət mərkəzində olduğu təhsil dili olan Aloredən qaynaqlanırdı. Alore sintaksisi siklik idxal əmrləri ilə problemləri həll etməyi asanlaşdırır. Müasir mypy, əvvəlki, sadə düşüncəli tətbiqindən bəzi məhdudiyyətləri miras almışdır (bu, Alore üçün çox uyğun idi). Python dairəvi idxal ilə işi çətinləşdirir, çünki ifadələr birmənalı deyil. Məsələn, təyinat əməliyyatı əslində tip ləqəbini müəyyən edə bilər. Mypy həmişə idxal dövrəsinin çox hissəsi emal olunana qədər bu kimi şeyləri aşkar edə bilmir. Aloredə belə anlaşılmazlıqlar yox idi. Sistemin inkişafının ilkin mərhələlərində qəbul edilən zəif qərarlar proqramçıya illər sonra xoşagəlməz sürpriz təqdim edə bilər.

Nəticələr: 5 milyon sətir kod və yeni üfüqlərə gedən yol

mypy layihəsi uzun bir yol keçmişdir - ilkin prototiplərdən 4 milyon sətir istehsal kodu növlərinə nəzarət edən sistemə qədər. Mypy inkişaf etdikcə, Python tipli göstərişlər standartlaşdırıldı. Bu günlərdə Python kodunu yazmaq ətrafında güclü bir ekosistem inkişaf etmişdir. Kitabxana dəstəyi üçün bir yerə malikdir, IDE və redaktorlar üçün köməkçi alətləri ehtiva edir, hər birinin öz müsbət və mənfi cəhətləri olan bir neçə tip idarəetmə sisteminə malikdir.

Dropbox-da tip yoxlanışı artıq verilmiş olsa da, mən inanıram ki, biz hələ Python kodunu yazmağın ilk günlərindəyik. Düşünürəm ki, tip yoxlama texnologiyaları inkişaf etməyə və təkmilləşməyə davam edəcək.

Əgər siz irimiqyaslı Python layihənizdə tip yoxlamasından hələ də istifadə etməmisinizsə, bilin ki, indi statik yazmağa keçmək üçün çox yaxşı vaxtdır. Oxşar keçidi edənlərlə danışmışam. Onların heç biri peşman olmadı. Növün yoxlanılması Python-u "adi Python" ilə müqayisədə böyük layihələrin inkişafı üçün daha uyğun bir dil edir.

Hörmətli oxucular! Python layihələrinizdə növ yoxlamasından istifadə edirsiniz?

4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə
4 milyon sətirlik Python kodunu yazmağa gedən yol. 3-ci hissə

Mənbə: www.habr.com

Добавить комментарий