Jalur pikeun typechecking 4 juta garis kode Python. Bagian 1

Dinten ieu kami nengetan bagian kahiji tina tarjamahan bahan ngeunaan kumaha Dropbox nguruskeun kontrol tipe kode Python.

Jalur pikeun typechecking 4 juta garis kode Python. Bagian 1

Dropbox nyerat seueur dina Python. Ieu mangrupikeun basa anu kami anggo sacara lega, boh pikeun jasa back-end sareng aplikasi klien desktop. Urang ogé ngagunakeun Go, TypeScript sareng Rust pisan, tapi Python mangrupikeun basa utama urang. Tempo skala urang, sarta kami ngobrol ngeunaan jutaan garis kode Python, tétéla yén ketikan dinamis kode sapertos unnecessarily nyusahkeun pamahaman sarta mimiti mangaruhan serius produktivitas tanaga gawé. Pikeun mitigate masalah ieu, urang geus dimimitian laun transisi kode urang ka tipe statik mariksa maké mypy. Ieu sigana sistem cek tipe mandiri anu paling populér pikeun Python. Mypy mangrupikeun proyék open source, pamekar utamina damel di Dropbox.

Dropbox mangrupikeun salah sahiji perusahaan munggaran anu ngalaksanakeun pamariksaan tipe statik dina kode Python dina skala ieu. Mypy dianggo dina rébuan proyék ayeuna. alat ieu countless kali, sabab nyebutkeun, "diuji dina perangna." Kami parantos jauh dugi ka tempat kami ayeuna. Sapanjang jalan, aya seueur usaha anu gagal sareng percobaan anu gagal. Tulisan ieu nyertakeun sajarah pamariksaan tipe statik dina Python, ti mimiti taringgul na salaku bagian tina proyék panalungtikan kuring, dugi ka ayeuna, nalika mariksa jinis sareng hinting ngetik parantos biasa pikeun pamekar anu teu kaétang anu nyerat dina Python. Mékanisme ieu ayeuna dirojong ku seueur alat sapertos IDE sareng analisa kode.

Maca bagian kadua

Naha pamariksaan jinis diperyogikeun?

Upami anjeun kantos nganggo Python anu diketik dinamis, anjeun tiasa gaduh kabingungan naha aya ribut-ribut ngeunaan ngetik statik sareng mypy akhir-akhir ieu. Atawa meureun anjeun resep Python persis kusabab ketikan dinamis na, sarta naon anu lumangsung ngan upsets anjeun. Konci pikeun nilai ketikan statik nyaéta skala solusi: langkung ageung proyék anjeun, langkung condong kana ngetik statik, sareng tungtungna, anjeun peryogi pisan.

Anggap hiji proyék tangtu geus ngahontal ukuran puluhan rébu garis, sarta tétéla yén sababaraha programer keur dipake dina eta. Ningali proyék anu sami, dumasar kana pangalaman urang, urang tiasa nyarios yén pamahaman kode na bakal janten konci pikeun ngajaga pamekar produktif. Tanpa annotations tipe, bisa jadi hésé angka kaluar, Contona, naon alesan pikeun lulus ka fungsi, atawa naon jenis fungsi bisa balik. Ieu patarosan umum anu sering hese dijawab tanpa nganggo anotasi jinis:

  • Dupi fungsi ieu balik None?
  • Naon kedah argumen ieu? items?
  • Naon jenis atribut id: int éta, str, atawa meureun sababaraha tipe custom?
  • Kedah argumen ieu daptar? Naha mungkin ngaliwat tuple ka dinya?

Lamun nempo snippet kode tipe-annotated handap sarta coba ngajawab patarosan sarupa, tétéla yén ieu téh tugas pangbasajanna:

class Resource:
    id: bytes
    ...
    def read_metadata(self, 
                      items: Sequence[str]) -> Dict[str, MetadataItem]:
        ...

  • read_metadata teu balik None, Kusabab tipe balik henteu Optional[…].
  • Argumen items mangrupa runtuyan garis. Éta henteu tiasa diulang sacara acak.
  • Atribut id mangrupa string of bait.

Dina dunya idéal, hiji bakal nyangka yén sakabéh subtleties sapertos bakal dijelaskeun dina dokuméntasi diwangun-di (docstring). Tapi pangalaman masihan seueur conto kanyataan yén dokuméntasi sapertos kitu sering henteu dititénan dina kode anu anjeun kedah damel. Sanaos dokuméntasi sapertos kitu aya dina kodeu, anjeun moal tiasa ngandelkeun kabeneran mutlakna. Dokuméntasi ieu tiasa samar, teu akurat, sareng kabuka pikeun salah paham. Dina tim ageung atanapi proyék ageung, masalah ieu tiasa janten parah pisan.

Nalika Python unggul dina tahap awal atanapi pertengahan proyék, dina sababaraha waktos proyék suksés sareng perusahaan anu nganggo Python tiasa nyanghareupan patarosan anu penting: "Naha urang kedah nyerat deui sadayana dina basa anu diketik sacara statik?".

Sistem mariksa jinis sapertos mypy ngarengsekeun masalah di luhur ku nyayogikeun basa formal pikeun pamekar pikeun ngajelaskeun jinis, sareng ku mariksa yén deklarasi jinis cocog sareng palaksanaan program (sareng, sacara opsional, mariksa ayana). Sacara umum, urang bisa disebutkeun yen sistem ieu nempatkeun di pembuangan urang hal kawas dokuméntasi dipariksa taliti.

Pamakéan sistem sapertos kitu ngagaduhan kauntungan anu sanés, sareng aranjeunna parantos teu pati penting:

  • Sistim mariksa tipe bisa ngadeteksi sababaraha leutik (jeung teu jadi leutik) kasalahan. Hiji conto has nyaéta nalika maranéhna poho ngolah nilai a None atawa sababaraha kaayaan husus sejenna.
  • Refactoring kode disederhanakeun pisan sabab sistem pamariksaan jinis sering akurat pisan ngeunaan kode anu kedah dirobih. Dina waktos anu sami, urang henteu kedah ngarepkeun liputan kode 100% kalayan tés, anu, dina sagala hal, biasana henteu tiasa dilaksanakeun. Urang teu kudu delve kana bojong renik tumpukan pikeun manggihan cukang lantaranana.
  • Malah dina proyék-proyék ageung, mypy sering tiasa ngalakukeun pamariksaan tipe lengkep dina sakedap. Sareng palaksanaan tés biasana nyandak puluhan detik atanapi bahkan menit. Sistem pamariksaan jinis masihan eupan balik instan ka programer sareng ngamungkinkeun anjeunna ngalaksanakeun tugasna langkung gancang. Anjeunna henteu kedah nyerat deui anu rapuh sareng sesah pikeun ngajaga tés unit anu ngagentos éntitas nyata kalayan moyok sareng patch ngan pikeun kéngingkeun hasil tés kode langkung gancang.

IDE sareng éditor sapertos PyCharm atanapi Visual Studio Code nganggo kakuatan jinis anotasi pikeun nyayogikeun para pamekar kalayan ngalengkepan kode, panyorot kasalahan, sareng dukungan pikeun konstruksi basa anu biasa dianggo. Sareng ieu mangrupikeun sababaraha kauntungan tina ngetik. Kanggo sababaraha programer, sadaya ieu mangrupikeun argumen utama pikeun ngetik. Ieu hiji hal anu nguntungkeun langsung saatos palaksanaan. Kasus pamakean ieu pikeun jinis henteu meryogikeun sistem pamariksaan jinis anu misah sapertos mypy, sanaos kedah diperhatoskeun yén mypy ngabantosan tetep anotasi jinis konsisten sareng kode.

Latar tukang mypy

Sajarah mypy dimimitian di Inggris, di Cambridge, sababaraha taun sateuacan abdi gabung Dropbox. Kuring geus kalibet, salaku bagian tina panalungtikan doktor kuring, dina ngahijikeun basa diketik statis tur dinamis. Kuring diideuan ku artikel ngeunaan ketak incremental ku Jeremy Siek sareng Walid Taha, sareng ku proyék Typed Racket. Kuring diusahakeun neangan cara ngagunakeun basa programming sarua pikeun sagala rupa proyék - ti Aksara leutik nepi ka kode basa diwangun ku loba jutaan garis. Dina waktos anu sami, kuring hoyong mastikeun yén dina proyék skala naon waé, saurang henteu kedah ngadamel kompromi anu ageung teuing. Bagian anu penting tina sadayana ieu nyaéta ideu laun-laun ngalih tina proyék prototipe anu teu diketik ka produk réngsé anu diketik sacara statik sacara komprehensif. Dinten ayeuna, ideu ieu umumna dianggap biasa, tapi dina taun 2010 éta mangrupikeun masalah anu masih aktip digali.

Karya aslina kuring dina tipe mariksa teu aimed di Python. Gantina, kuring ngagunakeun basa "homemade" leutik Alore. Ieu conto anu bakal ngantep anjeun ngartos naon anu urang bahas (jenis annotations opsional di dieu):

def Fib(n as Int) as Int
  if n <= 1
    return n
  else
    return Fib(n - 1) + Fib(n - 2)
  end
end

Ngagunakeun basa asli saderhana mangrupakeun pendekatan umum dipaké dina panalungtikan ilmiah. Ieu kitu, teu saeutik sabab ngidinan Anjeun pikeun gancang ngalakonan percobaan, sarta ogé alatan kanyataan yén naon teu aya hubunganana jeung panalungtikan bisa gampang dipaliré. Basa pamrograman dunya nyata condong janten fenomena skala ageung kalayan palaksanaan anu rumit, sareng ieu ngalambatkeun ékspérimén. Sanajan kitu, sagala hasil dumasar kana basa disederhanakeun kasampak saeutik curiga, saprak dina meunangkeun hasil ieu panalungtik bisa geus kurban tinimbangan penting pikeun pamakéan praktis basa.

Pamariksaan jinis kuring pikeun Alore katingalina ngajangjikeun, tapi kuring hoyong nguji éta ku ékspérimén sareng kode nyata, anu, anjeun tiasa nyarios, henteu ditulis dina Alore. Kabeneran pikeun kuring, basa Alore sakitu legana dumasar kana ideu anu sami sareng Python. Ieu cukup gampang pikeun nyieun deui typechecker supados tiasa dianggo sareng sintaksis sareng semantik Python. Ieu ngamungkinkeun urang pikeun nyobaan ngetik dina kodeu Python open source. Salaku tambahan, kuring nyerat transpiler pikeun ngarobih kode anu ditulis dina Alore kana kode Python sareng dianggo pikeun narjamahkeun kode typechecker kuring. Ayeuna kuring ngagaduhan sistem cek tipe anu ditulis dina Python anu ngadukung sawaréh tina Python, sababaraha jinis basa éta! (Kaputusan arsitéktur tangtu anu asup akal pikeun Alore kirang cocog pikeun Python, sareng ieu masih katingali dina bagian tina mypy codebase.)

Nyatana, basa anu dirojong ku sistem jinis kuring henteu tiasa disebat Python dina waktos ieu: éta mangrupikeun varian Python kusabab sababaraha watesan sintaksis anotasi jinis Python 3.

Sigana mah campuran Java sareng Python:

int fib(int n):
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Salah sahiji pamendak kuring dina waktos éta nyaéta ngagunakeun jinis annotations pikeun ningkatkeun kamampuan ku nyusun jenis Python ieu kana C, atanapi panginten JVM bytecode. Kuring nepi ka tahap nulis prototipe kompiler, tapi kuring ditinggalkeun gagasan ieu, saprak tipe mariksa sorangan kasampak rada mangpaat.

Kuring réngsé nepi presenting proyék kuring di PyCon 2013 di Santa Clara. Kuring ogé dikaitkeun ieu kalawan Guido van Rossum, diktator Python benevolent pikeun hirup. Anjeunna ngayakinkeun kuring pikeun leupaskeun sintaksis kuring sorangan sareng lengket kana sintaksis Python standar 3. Python 3 ngadukung annotations fungsi, ku kituna conto kuring tiasa ditulis deui sapertos anu dipidangkeun di handap ieu, hasilna program Python normal:

def fib(n: int) -> int:
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Kuring kungsi nyieun sababaraha compromises (mimiti sadayana, abdi hoyong dicatet yén kuring nimukeun sintaksis sorangan pikeun alesan ieu). Khususna, Python 3.3, versi basa panganyarna dina waktos éta, henteu ngadukung annotations variabel. Kuring dibahas kalawan Guido ku e-mail rupa kemungkinan pikeun desain sintaksis annotations misalna. Urang mutuskeun pikeun ngagunakeun tipe komentar pikeun variabel. Ieu nyayogikeun tujuan anu dimaksud, tapi rada pajeujeut (Python 3.6 masihan kami sintaksis anu langkung saé):

products = []  # type: List[str]  # Eww

Koméntar ngetik ogé tiasa dianggo pikeun ngadukung Python 2, anu henteu ngagaduhan dukungan anu diwangun pikeun anotasi jinis:

f fib(n):
    # type: (int) -> int
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Tétéla yén trade-off ieu (sareng sanésna) henteu penting pisan - mangpaat ketikan statik hartosna yén pangguna énggal-énggal hilap kana sintaksis anu kirang sampurna. Kusabab euweuh constructs sintaksis husus dipaké dina kode Python tipe-dipariksa, parabot Python aya jeung prosés ngolah kode terus dianggo normal, sahingga leuwih gampang pikeun pamekar pikeun neuleuman alat anyar.

Guido ogé ngayakinkeun kuring pikeun ngiluan Dropbox saatos kuring réngsé tesis sarjana. Ieu dimana bagian paling narik tina carita mypy dimimitian.

Ngalajengkeun…

Pamiarsa Hadirin! Upami anjeun nganggo Python, punten wartosan kami ngeunaan skala proyék anu anjeun kembangkeun dina basa ieu.

Jalur pikeun typechecking 4 juta garis kode Python. Bagian 1
Jalur pikeun typechecking 4 juta garis kode Python. Bagian 1

sumber: www.habr.com

Tambahkeun komentar