Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3

Kami mempersembahkan kepada Anda bagian ketiga dari terjemahan materi tentang jalur yang diambil Dropbox saat menerapkan sistem pemeriksaan tipe untuk kode Python.

Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3

β†’ Bagian sebelumnya: pertama ΠΈ kedua

Mencapai 4 juta baris kode yang diketik

Tantangan besar lainnya (dan kekhawatiran paling umum kedua di antara mereka yang disurvei secara internal) adalah peningkatan jumlah kode yang dicakup oleh pemeriksaan tipe di Dropbox. Kami telah mencoba beberapa pendekatan untuk memecahkan masalah ini, mulai dari meningkatkan ukuran basis kode yang diketik secara alami hingga memfokuskan upaya tim mypy pada inferensi tipe otomatis statis dan dinamis. Pada akhirnya, sepertinya tidak ada strategi kemenangan yang sederhana, namun kami mampu mencapai pertumbuhan pesat dalam volume kode beranotasi dengan menggabungkan banyak pendekatan.

Hasilnya, repositori Python terbesar kami (dengan kode backend) memiliki hampir 4 juta baris kode beranotasi. Pekerjaan pengetikan kode statis selesai dalam waktu sekitar tiga tahun. Mypy sekarang mendukung berbagai jenis laporan cakupan kode yang memudahkan pemantauan kemajuan pengetikan. Secara khusus, kita dapat membuat laporan tentang kode dengan tipe yang ambigu, seperti, misalnya, penggunaan suatu tipe secara eksplisit Any dalam anotasi yang tidak dapat diverifikasi, atau dengan hal-hal seperti mengimpor perpustakaan pihak ketiga yang tidak memiliki anotasi tipe. Sebagai bagian dari proyek untuk meningkatkan keakuratan pemeriksaan tipe di Dropbox, kami berkontribusi untuk meningkatkan definisi tipe (yang disebut file stub) untuk beberapa pustaka sumber terbuka populer di repositori Python terpusat diketik.

Kami menerapkan (dan melakukan standarisasi pada PEP berikutnya) fitur baru dari sistem tipe yang memungkinkan tipe yang lebih tepat untuk beberapa pola Python tertentu. Contoh penting dari hal ini adalah TypeDict, yang menyediakan tipe untuk kamus mirip JSON yang memiliki sekumpulan kunci string tetap, masing-masing dengan nilai tipenya sendiri. Kami akan terus memperluas sistem tipe. Langkah kami berikutnya kemungkinan besar adalah meningkatkan dukungan untuk kemampuan numerik Python.

Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3
Jumlah baris kode beranotasi: server

Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3
Jumlah baris kode beranotasi: client

Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3
Jumlah total baris kode beranotasi

Berikut ikhtisar fitur utama dari hal-hal yang kami lakukan untuk meningkatkan jumlah kode beranotasi di Dropbox:

Ketelitian anotasi. Kami secara bertahap meningkatkan persyaratan ketatnya anotasi kode baru. Kami memulai dengan tips linter yang menyarankan penambahan anotasi ke file yang sudah memiliki beberapa anotasi. Kami sekarang memerlukan anotasi tipe pada file Python baru dan di sebagian besar file yang sudah ada.

Mengetik laporan. Kami mengirimkan laporan mingguan kepada tim tentang tingkat pengetikan kode mereka dan memberikan saran tentang apa yang harus diberi anotasi terlebih dahulu.

Mempopulerkan mypy. Kami membicarakan mypy di acara dan berbicara dengan tim untuk membantu mereka memulai anotasi tipe.

Jajak pendapat. Kami melakukan survei pengguna secara berkala untuk mengidentifikasi masalah utama. Kami siap melangkah lebih jauh dalam memecahkan masalah ini (bahkan menciptakan bahasa baru untuk mempercepat mypy!).

Pertunjukan. Kami telah meningkatkan kinerja mypy dengan menggunakan daemon dan mypyc. Hal ini dilakukan untuk memuluskan ketidaknyamanan yang timbul selama proses anotasi, dan agar dapat bekerja dengan kode dalam jumlah besar.

Integrasi dengan editor. Kami telah membuat alat untuk mendukung menjalankan mypy di editor yang populer di Dropbox. Ini termasuk PyCharm, Vim dan VS Code. Ini sangat menyederhanakan proses pembuatan anotasi kode dan memeriksa fungsinya. Jenis tindakan ini umum terjadi saat memberi anotasi pada kode yang ada.

Analisis statis. Kami membuat alat untuk menyimpulkan tanda tangan fungsi menggunakan alat analisis statis. Alat ini hanya dapat bekerja dalam situasi yang relatif sederhana, namun membantu kami meningkatkan cakupan jenis kode tanpa banyak usaha.

Dukungan untuk perpustakaan pihak ketiga. Banyak proyek kami menggunakan toolkit SQLAlchemy. Ini memanfaatkan kemampuan dinamis Python yang tidak dapat dimodelkan secara langsung oleh tipe PEP 484. Kami, sesuai dengan PEP 561, membuat file rintisan yang sesuai dan menulis plugin untuk mypy (sumber terbuka), yang meningkatkan dukungan SQLAlchemy.

Kesulitan yang kami temui

Jalan menuju 4 juta baris kode yang diketik tidak selalu mudah bagi kami. Di jalur ini kami menemui banyak jalan berlubang dan melakukan beberapa kesalahan. Ini adalah beberapa masalah yang kami temui. Kami berharap dengan menceritakannya akan membantu orang lain menghindari masalah serupa.

File hilang. Kami memulai pekerjaan kami dengan hanya memeriksa sejumlah kecil file. Apa pun yang tidak termasuk dalam file ini tidak diperiksa. File ditambahkan ke daftar pemindaian ketika anotasi pertama muncul di dalamnya. Jika sesuatu diimpor dari modul yang terletak di luar lingkup verifikasi, maka kita berbicara tentang bekerja dengan nilai-nilai seperti Any, yang tidak diuji sama sekali. Hal ini menyebabkan hilangnya akurasi pengetikan secara signifikan, terutama pada tahap awal migrasi. Pendekatan ini secara mengejutkan telah bekerja dengan baik sejauh ini, meskipun situasi yang umum terjadi adalah menambahkan file ke cakupan tinjauan akan mengungkapkan masalah di bagian lain dari basis kode. Dalam kasus terburuk, ketika dua area kode yang terisolasi digabungkan, yang tipenya sudah diperiksa secara independen satu sama lain, ternyata tipe area ini tidak kompatibel satu sama lain. Hal ini menyebabkan perlunya melakukan banyak perubahan pada anotasi. Melihat ke belakang sekarang, kami menyadari bahwa kami seharusnya menambahkan modul perpustakaan inti ke area pemeriksaan tipe mypy lebih cepat. Ini akan membuat pekerjaan kami lebih mudah diprediksi.

Menganotasi kode lama. Saat kami memulai, kami memiliki sekitar 4 juta baris kode Python yang ada. Jelas bahwa memberi anotasi pada semua kode ini bukanlah tugas yang mudah. Kami telah membuat alat bernama PyAnnotate yang dapat mengumpulkan informasi jenis saat pengujian dijalankan dan dapat menambahkan anotasi jenis ke kode Anda berdasarkan informasi yang dikumpulkan. Namun, kami belum melihat penerapan alat ini secara luas. Pengumpulan informasi jenis berjalan lambat, dan anotasi yang dibuat secara otomatis sering kali memerlukan banyak pengeditan manual. Kami berpikir untuk menjalankan alat ini secara otomatis setiap kali kami meninjau kode, atau mengumpulkan informasi jenis berdasarkan analisis sejumlah kecil permintaan jaringan aktual, namun memutuskan untuk tidak melakukannya karena pendekatan mana pun terlalu berisiko.

Hasilnya, dapat dicatat bahwa sebagian besar kode dianotasi secara manual oleh pemiliknya. Untuk memandu proses ini ke arah yang benar, kami menyiapkan laporan tentang modul dan fungsi penting yang perlu diberi anotasi. Misalnya, penting untuk menyediakan anotasi tipe untuk modul perpustakaan yang digunakan di ratusan tempat. Namun layanan lama yang digantikan dengan yang baru tidak lagi begitu penting untuk diberi anotasi. Kami juga bereksperimen dengan menggunakan analisis statis untuk menghasilkan anotasi tipe untuk kode lama.

Impor siklik. Di atas, saya berbicara tentang impor siklik (β€œkekusutan ketergantungan”), yang keberadaannya mempersulit percepatan mypy. Kami juga harus bekerja keras untuk membuat mypy mendukung semua jenis idiom yang disebabkan oleh impor siklik ini. Kami baru saja menyelesaikan proyek desain ulang sistem besar yang memperbaiki sebagian besar masalah mypy terkait impor sirkular. Masalah-masalah ini sebenarnya berasal dari hari-hari awal proyek, dari Alore, bahasa pendidikan yang awalnya menjadi fokus proyek mypy. Sintaks Alore memudahkan penyelesaian masalah dengan perintah impor siklik. Mypy modern mewarisi beberapa keterbatasan dari implementasi sebelumnya yang sederhana (yang sangat cocok untuk Alore). Python membuat pekerjaan dengan impor melingkar menjadi sulit, terutama karena ekspresi bersifat ambigu. Misalnya, operasi penugasan sebenarnya dapat mendefinisikan alias tipe. Mypy tidak selalu dapat mendeteksi hal-hal seperti ini sampai sebagian besar loop impor telah diproses. Tidak ada ambiguitas seperti itu di Alore. Keputusan buruk yang dibuat pada tahap awal pengembangan sistem dapat menimbulkan kejutan yang tidak menyenangkan bagi pemrogram beberapa tahun kemudian.

Hasil: jalan menuju 5 juta baris kode dan cakrawala baru

Proyek mypy telah berkembang pesat - dari prototipe awal hingga sistem yang mengontrol 4 juta baris jenis kode produksi. Seiring berkembangnya mypy, petunjuk tipe Python distandarisasi. Saat ini, ekosistem yang kuat telah berkembang seputar pengetikan kode Python. Ini memiliki tempat untuk dukungan perpustakaan, berisi alat bantu untuk IDE dan editor, memiliki beberapa jenis sistem kontrol, yang masing-masing memiliki kelebihan dan kekurangannya sendiri.

Meskipun pemeriksaan pengetikan sudah dilakukan di Dropbox, saya yakin kita masih dalam tahap awal pengetikan kode Python. Saya pikir teknologi pengecekan tipe akan terus berkembang dan meningkat.

Jika Anda belum pernah menggunakan pemeriksaan pengetikan dalam proyek Python skala besar Anda, ketahuilah bahwa sekarang adalah saat yang tepat untuk mulai beralih ke pengetikan statis. Saya telah berbicara dengan mereka yang telah melakukan transisi serupa. Tak satu pun dari mereka menyesalinya. Pemeriksaan tipe menjadikan Python bahasa yang lebih cocok untuk mengembangkan proyek besar dibandingkan β€œPython biasa”.

Pembaca yang terhormat Apakah Anda menggunakan pemeriksaan tipe di proyek Python Anda?

Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3
Jalur untuk memeriksa 4 juta baris kode Python. Bagian 3

Sumber: www.habr.com

Tambah komentar