Bagaimana cara menggunakan dependensi pihak ketiga dengan plugin Sublime Text dengan benar?

Saya mencoba menulis plugin untuk Sublime Text 3.

Saya harus menggunakan beberapa paket pihak ketiga dalam kode saya. Saya telah berhasil membuat kode berfungsi dengan menyalin paket secara manual ke /home/user/.config/sublime-text-3/Packages/User/, lalu saya menggunakan impor relatif untuk mendapatkan kode yang diperlukan. Bagaimana cara saya mendistribusikan plugin ke pengguna akhir? Memberitahu mereka untuk menyalin dependensi yang diperlukan ke lokasi yang sesuai tentu saja bukan cara yang tepat. Bagaimana modul pihak ketiga dapat digunakan dengan benar dengan plugin Sublime Text? Saya tidak dapat menemukan dokumentasi apa pun secara online; yang saya lihat hanyalah rekomendasi untuk meletakkan modul di folder tersebut.


person adder    schedule 13.04.2020    source sumber


Jawaban (1)


Sublime menggunakan interpreter Python bawaannya sendiri (saat ini Python 3.3.6 meskipun versi berikutnya juga akan mendukung Python 3.8) dan dengan demikian Sublime juga akan mengabaikan versi Python apa pun yang mungkin atau mungkin belum Anda instal di sistem Anda. sebagai perpustakaan apa pun yang diinstal untuk versi itu.

Oleh karena itu, jika Anda ingin menggunakan modul eksternal (selanjutnya dependencies) Anda perlu melakukan pekerjaan ekstra. Ada berbagai cara untuk mencapai hal ini, masing-masing dengan kelebihan dan kekurangannya masing-masing.

Berikut ini daftar berbagai cara yang dapat Anda lakukan untuk mencapai hal ini; semuanya memerlukan sedikit pemahaman tentang cara kerja modul dengan Python untuk memahami apa yang terjadi. Secara umum, kecuali jalur yang terlibat, tidak ada yang terlalu "Sublime Text" tentang mekanisme yang dimainkan.

CATATAN: Di bawah ini akurat pada saat jawaban ini dibuat. Namun ada rencana untuk Kontrol Paket untuk mengubah cara kerjanya dengan dependensi yang akan datang yang mungkin mengubah beberapa aspek dari hal ini.

Hal ini terkait dengan versi Sublime mendatang yang mendukung beberapa versi Python (dan cara mendukungnya) yang tidak didukung oleh mekanisme Kontrol Paket saat ini.

Saat ini masih belum jelas apakah perubahan tersebut akan membawa cara baru untuk menentukan dependensi atau hanya cara kerja internal dari cara instalasi dependensi yang akan berubah. Namun, mekanisme yang ada mungkin tetap berlaku meskipun hanya untuk kompatibilitas ke belakang.

Semua cara untuk mengakses Python dependency dari plugin Sublime melibatkan penempatan kodenya di tempat di mana juru bahasa Python akan mencarinya. Hal ini mirip dengan cara Python standar melakukan sesuatu, hanya saja lokasi yang dicentang terdapat dalam area yang digunakan Sublime untuk menyimpan konfigurasi Anda (disebut sebagai direktori Data) dan alih-alih interpreter Python yang berdiri sendiri, Python berjalan di tuan rumah plugin.

Isi perpustakaan ke dalam folder Lib

Sejak versi 3.0 (build 3143), Sublime akan membuat folder bernama Lib di direktori data dan di dalamnya ada direktori berdasarkan nama versi Python. Jika Anda menggunakan Preferences > Browse Packages dan naik satu level folder, Anda akan melihat Lib, dan di dalamnya ada folder bernama mis. python3.3 (atau jika Anda menggunakan versi yang lebih baru, python33 dan python38).

Direktori tersebut langsung ada di Python sys.path secara default, jadi apa pun yang ditempatkan di dalamnya akan segera tersedia untuk plugin apa pun seperti halnya pustaka Python biasa (atau yang ada di dalamnya). Anda dapat menganggap folder ini mirip dengan folder site-packages dengan Python standar.

Jadi, metode apa pun yang Anda gunakan untuk menginstal pustaka Python standar dapat digunakan selama hasilnya adalah file yang berakhir di folder ini. Misalnya, Anda dapat menginstal perpustakaan melalui pip dan kemudian menyalin file secara manual ke lokasi tersebut dari site-packages, menginstal secara manual dari sumber, dll.

Lib/python3.3/
|-- librarya
|   `-- file1.py
|-- libraryb
|   `-- file2.py
`-- singlefile.py

Pembatasan versi berlaku di sini; dependency yang ingin digunakan harus mendukung versi Python yang digunakan Sublime, jika tidak maka tidak akan berfungsi. Hal ini sangat penting untuk pustaka Python dengan komponen asli (misalnya .dll, .so atau .dylib), yang mungkin memerlukan kompilasi kode secara manual.

Metode ini tidak otomatis; Anda harus melakukannya untuk menggunakan paket Anda secara lokal, dan siapa pun yang ingin menggunakan paket Anda juga harus melakukannya. Karena Sublime saat ini menggunakan versi Python yang lebih lama, mendapatkan versi perpustakaan yang benar juga bisa menjadi masalah.

Di masa depan, Kontrol Paket akan menginstal dependencies di lokasi ini (Akan menambahkan folder khusus untuk tujuan ini selama menjalankan hingga versi 3.0), tetapi pada saat saya menulis jawaban ini, hal tersebut tidak terjadi saat ini.

Jual dependensi Anda langsung di dalam paket Anda sendiri

Folder Packages juga ada di sys.path secara default; beginilah cara Sublime menemukan dan memuat paket. Hal ini berlaku baik untuk folder fisik Packages, maupun folder paket "virtual" yang berisi konten file sublime-package.

Misalnya, seseorang dapat mengakses kelas yang menyediakan perintah exec melalui:

from Default.exec import ExecCommand

Ini akan berfungsi meskipun file exec.py sebenarnya disimpan di Default.sublime-package di folder instalasi teks Sublime dan tidak ada secara fisik di folder Packages.

Sebagai hasilnya, Anda dapat vendor dependencies apa pun yang Anda perlukan langsung di dalam paket Anda sendiri. Ini bisa berupa paket User atau paket lain yang Anda buat.

Penting untuk dicatat bahwa Sublime akan memperlakukan file Python apa pun di tingkat atas sebuah paket sebagai plugin dan mencoba memuatnya sebagai satu. Oleh karena itu, penting jika Anda menggunakan rute ini untuk membuat sub-folder di paket Anda dan meletakkan perpustakaan di sana.

MyPackage/
|-- alibrary
|   `-- code.py
`-- my_plugin.py

Dengan struktur ini, Anda dapat mengakses modul secara langsung:

import MyPackage.alibrary 

from MyPackage.alibrary import someSymbol

Tidak semua modul Python dapat menggunakan metode ini secara langsung tanpa modifikasi; beberapa perubahan kode di dependency mungkin diperlukan untuk memungkinkan bagian perpustakaan yang berbeda melihat bagian lain dari perpustakaan itu sendiri, misalnya jika perpustakaan tidak menggunakan import relatif untuk mendapatkan file saudaranya. Pembatasan lisensi juga dapat menghalangi hal ini, tergantung pada perpustakaan yang Anda gunakan.

Di sisi lain, ini secara langsung mengunci versi perpustakaan yang Anda gunakan persis dengan versi yang Anda uji, yang memastikan bahwa Anda tidak akan mengalami kejutan yang tidak semestinya di kemudian hari.

Dengan menggunakan metode ini, apa pun yang Anda lakukan untuk mendistribusikan paket Anda secara otomatis juga akan mendistribusikan pustaka vendor yang ada di dalamnya. Jadi jika Anda mendistribusikan dengan Package Control, Anda tidak perlu melakukan sesuatu yang khusus dan itu akan Just Work™.

Ubah sys.path untuk menunjuk ke lokasi khusus

Python yang ditanamkan ke Sublime masih merupakan Python standar, jadi jika diinginkan, Anda dapat memanipulasi sys.path secara manual yang menjelaskan folder mana yang akan dicari paketnya sehingga akan terlihat di tempat yang Anda pilih selain lokasi standar yang disiapkan Sublime secara otomatis.

Hal ini umumnya bukan ide yang baik karena jika dilakukan secara tidak benar, segala sesuatunya dapat berubah menjadi seperti buah pir dengan cepat. Ini juga masih mengharuskan Anda menginstal sendiri perpustakaan secara manual di suatu tempat terlebih dahulu, dan dalam hal ini Anda lebih baik menggunakan folder Lib seperti dijelaskan di atas, yang sudah ada di sys.path.

Saya akan menganggap metode ini sebagai solusi tingkat lanjut dan mungkin Anda gunakan untuk tujuan pengujian selama pengembangan tetapi sebaliknya bukan sesuatu yang akan dihadapi pengguna. Jika Anda berencana untuk mendistribusikan paket Anda melalui Kontrol Paket, peninjauan paket Anda kemungkinan akan mengembalikan manipulasi sys.path dengan permintaan untuk menggunakan metode lain.

Gunakan sistem Ketergantungan Kontrol Paket (dan ketergantungan ada)

Kontrol paket berisi mekanisme ketergantungan yang menggunakan kombinasi dua metode sebelumnya untuk menyediakan cara memasang ketergantungan secara otomatis. Terdapat juga daftar dependensi yang tersedia, meskipun daftar tersebut mungkin tidak lengkap.

Jika dependency yang ingin Anda gunakan sudah tersedia, Anda siap melakukannya. Ada dua cara berbeda untuk menyatakan bahwa Anda memerlukan satu atau lebih dependensi pada paket Anda.

CATATAN: Kontrol Paket saat ini tidak mendukung dependensi dependensi; jika ketergantungan mengharuskan perpustakaan lain juga diinstal, Anda perlu menyebutkan keduanya secara eksplisit.

Yang pertama melibatkan penambahan kunci dependencies ke entri paket Anda di file saluran kontrol paket. Ini adalah langkah yang akan Anda ambil saat Anda menambahkan paket Anda ke Kontrol Paket, yang merupakan sesuatu yang berada di luar cakupan jawaban ini.

Saat Anda sedang mengembangkan paket Anda (atau jika Anda memutuskan tidak ingin mendistribusikan paket Anda melalui Kontrol Paket setelah selesai), maka Anda dapat menambahkan file dependencies.json ke dalam root paket Anda (sebuah contoh file dependencies.json tersedia untuk menggambarkan hal ini).

Setelah Anda melakukannya, Anda dapat memilih Package Control: Satisfy Dependencies dari perintah Palette untuk mengunduh Kontrol Paket dan menginstal ketergantungan untuk Anda (jika diperlukan).

Langkah ini otomatis jika paket Anda didistribusikan dan diinstal oleh Package Control; jika tidak, Anda perlu memberi tahu pengguna Anda untuk mengambil langkah ini setelah mereka menginstal paket.

Gunakan sistem Ketergantungan Kontrol Paket (tetapi ketergantungan tidak ada)

Metode yang digunakan Kontrol Paket untuk menginstal dependencies adalah, sebagaimana diuraikan di bagian atas pertanyaan, dapat berubah di beberapa titik dalam waktu dekat (mungkin dalam waktu dekat). Ini mungkin mempengaruhi petunjuk di sini. Mekanisme keseluruhan mungkin tetap sama dalam hal pengaturan, hanya lokasi instalasi yang berubah, namun hal tersebut masih harus dilihat saat ini.

Kontrol Paket menginstal dependensi melalui kombinasi khusus vendoring dan juga manipulasi sys.path untuk memungkinkan sesuatu ditemukan. Untuk melakukannya, Anda perlu menata ketergantungan Anda dengan cara tertentu dan menyediakan beberapa metadata tambahan juga.

Tata letak paket yang berisi ketergantungan saat Anda membangunnya akan memiliki struktur yang mirip dengan berikut:

Packages/my_dependency/
├── .sublime-dependency
└── prefix
    └── my_dependency
        └── file.py

Kontrol Paket menginstal dependency sebagai Paket, dan karena Sublime memperlakukan setiap file Python di root paket sebagai plugin, kode untuk ketergantungan tidak disimpan di tingkat atas paket. Seperti yang terlihat di atas, konten sebenarnya dari ketergantungan disimpan di dalam folder berlabel prefix di atas (lebih lanjut tentang itu sebentar lagi).

Ketika ketergantungan diinstal, Kontrol Paket menambahkan entri ke paket 0_package_control_loader khusus yang menyebabkan folder prefix ditambahkan ke sys.path, yang membuat semua yang ada di dalamnya tersedia untuk pernyataan import seperti biasa. Inilah sebabnya mengapa ada duplikasi yang melekat pada nama perpustakaan (my_dependency dalam contoh ini).

Mengenai folder prefix, ini sebenarnya tidak dinamai demikian dan malah memiliki nama khusus yang menentukan kombinasi versi Sublime Text, platform, dan arsitektur tempat dependensi tersedia (penting untuk perpustakaan yang berisi binari, misalnya).

Nama folder prefix sebenarnya mengikuti bentuk {st_version}_{os}_{arch}, {st_version}_{os}, {st_version} atau all. {st_version} bisa jadi st2 atau st3, {os} bisa jadi windows, linux atau osx dan {arch} bisa jadi x32 atau x64.

Jadi bisa dikatakan bahwa ketergantungan Anda hanya mendukung st3, st3_linux, st3_windows_x64 atau kombinasi keduanya. Untuk sesuatu dengan kode asli, Anda dapat menentukan beberapa versi berbeda dengan memiliki banyak folder, meskipun biasanya all digunakan ketika dependency berisi kode Python murni yang akan berfungsi terlepas dari versi, OS, atau arsitektur Sublime.

Dalam contoh ini, jika kita berasumsi bahwa folder prefix diberi nama all karena my_dependency adalah Python murni, maka hasil dari pemasangan ketergantungan ini adalah Packages/my_dependency/all akan ditambahkan ke sys.path, artinya jika Anda import my_dependency Anda mendapatkan kode dari di dalam folder itu.

Selama pengembangan (atau jika Anda tidak ingin mendistribusikan ketergantungan Anda melalui Kontrol Paket), Anda membuat file .sublime-dependency di root paket seperti yang ditunjukkan di atas. Ini harus berupa file teks dengan satu baris yang berisi 2 digit angka (misalnya 01 atau 50). Ini mengontrol urutan setiap dependensi yang diinstal akan ditambahkan ke sys.path. Anda biasanya akan memilih angka yang lebih rendah jika dependensi Anda tidak memiliki dependensi lain dan nilai yang lebih tinggi jika ada (sehingga akan dimasukkan setelah dependensi tersebut).

Setelah Anda memiliki ketergantungan awal dalam format yang benar di folder Packages, Anda akan menggunakan perintah Package Control: Install Local Dependency dari Palet Perintah, lalu pilih nama ketergantungan Anda.

Hal ini menyebabkan Kontrol Paket "menginstal" ketergantungan (yaitu memperbarui paket 0_package_control_loader) untuk membuat ketergantungan aktif. Langkah ini biasanya diambil oleh Package Control secara otomatis saat menginstal dependensi untuk pertama kalinya, jadi jika Anda juga mendistribusikan dependensi secara manual, Anda perlu memberikan instruksi untuk melakukan langkah ini.

person OdatNurd    schedule 14.04.2020