Show HN: Wat – Inspeksi mendalam objek Python
(github.com/igrek51)- WAT adalah inspector untuk cepat memahami identitas objek yang tidak dikenal di runtime Python; tipe, nilai, atribut, metode, tipe induk, signature, dokumentasi, hingga source code bisa diperiksa sekaligus
- Cara penggunaan dasar adalah
wat / object, yang bekerja sama sepertiwat(object), dan mendukung berbagai sintaks sepertiwat.short / 'foo','foo' | wat.short,wat('foo', short=True) - Modifier seperti
.short,.dunder,.long,.code,.caller,.public,.all,.ret,.strdapat dirangkai untuk menyesuaikan cakupan output, cara pengembalian, output berwarna, dan penampilan lokasi pemanggilan - Instalasi dapat dilakukan dengan
pip install watlaluimport wat; untuk debugging cepat, snippet Insta-Load juga bisa ditempelkan ke sesi Python agar dapat digunakan di sesi yang sama tanpa instalasi - Contoh seperti Django
User,re.match,pathlib,colorsys.hsv_to_rgb,typing.List[str],str | Nonemenunjukkan bahwa WAT dapat dipakai untuk debugging, eksplorasi REPL, dan mempelajari internal Python
Apa yang dilakukan WAT
- WAT adalah alat untuk menjelajahi dan menginspeksi objek Python saat runtime
- Saat sulit memahami apa sebenarnya objek yang tidak dikenal, Anda dapat menyelidiki identitas objek tersebut di konsol Python dengan inspector
wat - Jika menjalankan
wat / objectpadaobjectapa pun, informasi berikut dapat diperiksa- type objek
- nilai yang diformat
- variabel dan metode
- tipe induk
- signature
- dokumentasi
- source code
- Inspeksi mendalam yang sama juga dapat digunakan dengan sintaks
wat(object) Watdiperkenalkan sebagai variasi dari kata Inggriswhat, yang dipakai untuk mengekspresikan kebingungan atau rasa tidak nyaman
Penggunaan dasar dan sintaks
- Untuk input cepat, digunakan operator pembagian
wat / foosama denganwat(foo)
- Beberapa sintaks dapat digunakan untuk inspeksi yang sama
wat.short / 'foo': sintaks untuk input cepatwat.short('foo')wat('foo', short=True): sintaks Python yang natural'foo' | wat.short: sintaks gaya Unix pipe
- Perilaku inspeksi dapat disesuaikan dalam bentuk
wat.modifier / foo - Modifier dapat dirangkai, contohnya
wat.short.str.gray / 'foo' - Karena objek di Python mencakup bukan hanya struktur data, tetapi juga fungsi, kelas, modul, tipe bawaan, dan lain-lain,
watdapat menjelajahi objek apa pun - Jika mengetik
watdi interpreter, Anda dapat melihat bantuan untuk objekwatitu sendiri
Menyesuaikan cakupan inspeksi dengan Modifier
.shortatau.smenyembunyikan atribut seperti variabel dan metode di dalam objek, lalu hanya mencetak nilai, tipe, tipe induk, signature, dan dokumentasi.dundermenampilkan atribut dunder yang diawali dengan__.longmenampilkan nilai dan docstring tanpa dipersingkat.codemenampilkan source code fungsi, metode, dan kelas.nodocsmenyembunyikan dokumentasi fungsi dan kelas.callermenampilkan bagaimana dan di mana inspeksi dipanggil, dan bekerja pada file non-REPL.publicmenyembunyikan atribut private dan hanya menampilkan atribut public.allmenyertakan semua informasi yang memungkinkan.retmengembalikan lagi objek setelah inspeksi.strmengembalikan string hasil alih-alih mencetak output.graymenonaktifkan output berwarna di konsol.colormemaksa output berwarna di konsolwat.localsmenginspeksi variabel lokal, danwat.globalsmenginspeksi variabel global
Instalasi dan Insta-Load
- Alur instalasi dengan pip adalah sebagai berikut
pip install wat- Di Python,
import wat
- Paket
wattidak memiliki dependensi eksternal - Untuk debugging cepat, tersedia metode Insta-Load yang dapat digunakan dalam sesi Python yang sama tanpa instalasi
- Insta-Load dilakukan dengan mengimpor
base64,zlib, lalu memulihkan string kode yang dikompresi dan dienkode, kemudian menjalankannya denganexec(..., globals())di interpreter sebagai Python snippet - Setelah menjalankan snippet Insta-Load, object
watdapat digunakan - Sebelum menjalankan snippet, disarankan untuk memverifikasi apa yang akan dijalankan
- Isi kode yang diekstrak dapat diperiksa terlebih dahulu dengan
print(zlib.decompress(base64.b64decode(code)).decode()) - Menempelkan isi
inspection.pyke interpreter juga memberi efek yang sama - Juga disarankan opsi memasang paket dengan pip dan meninjau kodenya
- Isi kode yang diekstrak dapat diperiksa terlebih dahulu dengan
- WAT dapat dimuat dari satu glyph Unicode
- Loader berbasis string Unicode berupa mekanisme yang mengubah string panjang berisi emoji dan combining character menjadi byte dengan
ord(c) & 255, lalu menjalankannya denganexec(...)setelahzlib.decompress(...)
Memahami tipe objek dan cara penggunaannya
- Di Python sebagai bahasa bertipe dinamis, terkadang sulit memahami tipe objek; WAT Inspector menampilkan nama tipe dan modul asal tipe tersebut
- Contoh pemeriksaan tipe menampilkan nilai, tipe, dan panjang sekaligus
wat.short / (1,)mencetak nilai(1,), tipetuple, panjang1wat.short / {None}mencetak nilai{None}, tipeset, panjang1
- Dalam contoh objek Django
User,wat.short / usermencetakstr: admin,repr: <User: admin>, tipedjango.contrib.auth.models.User, dan daftar tipe induk - Setelah mengetahui tipe sebenarnya, Anda dapat menambahkan type annotation di kode untuk mengurangi kebingungan berikutnya
- Saat memahami cara memakai objek yang tidak dikenal, daftar metode, signature, dan docstring dapat dicetak
- Contoh yang diberikan adalah
wat / ['foo'] - Jika ingin melihat docstring lengkap, gunakan
wat.long
- Contoh yang diberikan adalah
- Untuk memahami cara memakai fungsi, docstring dan signature fungsi dapat dilihat
- Contoh yang diberikan adalah
wat / str.split
- Contoh yang diberikan adalah
Menjelajahi atribut, modul, dan source code
- Untuk memeriksa bagian dalam objek target inspeksi, atribut dan tipe tiap atribut dapat didaftarkan
- Contoh yang diberikan adalah
wat / re.match('(\d)_(.*)', '1_title')
- Contoh yang diberikan adalah
- Ini juga dapat digunakan untuk menjelajahi modul, dengan menampilkan fungsi, kelas, dan submodul dari modul yang dipilih
- Ada contoh menjalankan
wat / pathlibsetelahimport pathlib - Setelah itu dapat menjelajah lebih dalam seperti
wat / pathlib.fnmatch
- Ada contoh menjalankan
- WAT Inspector secara default menyembunyikan atribut yang diawali dengan
__- Atribut dunder dapat dilihat dengan
wat.dunder / {}
- Atribut dunder dapat dilihat dengan
- Untuk memeriksa bagaimana fungsi sebenarnya bekerja, source code dapat dilihat
- Ada contoh menjalankan
wat.code / colorsys.hsv_to_rgbsetelahimport colorsys
- Ada contoh menjalankan
- dict dan list bersarang diformat dalam bentuk berindentasi yang mudah dibaca
Sesi debugging dan inspeksi variabel
- Setelah menjalankan debugger interaktif dengan
breakpoint()di Python, Anda dapat menginspeksi objek di tempat tersebut - Contoh Pdb adalah menginspeksi variabel lokal dengan
wat / foosetelahimport watatau menempelkan snippet Insta-Load, lalu melanjutkan eksekusi denganc - Variabel lokal dan global masing-masing dapat diperiksa dengan
wat.localsdanwat.globals - Jika
wat()dipanggil tanpa argumen, variabel lokal pada stack pemanggil akan dicetak dengan judulLocal variables
Contoh mempelajari internal Python
- Termasuk contoh penggunaan untuk memahami cara kerja internal Python
reversed([]) == reversed([])bernilaiFalse, danwat.s / reversed([])menunjukkan bahwa nilainya adalah objectlist_reverseiteratordan tipenyalist_reverseiteratorwat / type('ObjectCreator', (), {})menampilkan nilai dari kelas yang dibuat secara dinamis, tipetype, dansignature: class ObjectCreator()wat / typemenampilkan nilaitypeitu sendiri, tipetype, signatureclass type(…), dokumentasitype(object) -> the object's type,type(name, bases, dict, **kwds) -> a new type, atribut public sepertimro, dan lain-lainwat.s / List[str]menampilkan nilaityping.List[str], tipetyping._GenericAlias, tipe induktyping._BaseGenericAlias,typing._Final, dan signaturedef List(*args, **kwargs)wat(str | None)menampilkan nilaistr | Nonedan tipetypes.UnionType- Contoh penjelajahan objek bawaan Python yang diberikan adalah
wat / __builtins__,wat / ... - WAT itu sendiri juga dapat diinspeksi
- Contoh yang diberikan adalah
wat.dunder / wat,wat.code / wat.__truediv__
- Contoh yang diberikan adalah
Ringkasan cara kerja internal
inspect_format(obj, *, short=False, dunder=False, nodocs=False, long=False, code=False, caller=False, public=False, all=False)menyusun hasil inspeksi objek menjadi string- Jika
all=True,dunder,long,code, dancallerikut diaktifkan - Jika
public=True, output private dinonaktifkan - Jika
sys.stdout.isatty()bernilai true, lebar terminal diambil dan garis pemisah─ditambahkan di atas dan bawah output
- Jika
- Output inspeksi dibuat dalam urutan bagian nilai objek, representasi string, tipe, tipe induk, panjang, signature, dokumentasi, source code, dan atribut
- Inspeksi atribut menelusuri
dir(obj)berdasarkan urutan nama- Atribut dunder dikecualikan jika pengaturan
dundermati - Atribut private yang diawali
_dikecualikan jika pengaturan private mati - Jika
getattr(obj, key)menghasilkanBaseException, objek exception tersebut digunakan sebagai nilai
- Atribut dunder dikecualikan jika pengaturan
- Objek callable memformat signature berdasarkan
inspect.signature(obj)- Jika gagal, signature pengganti dalam bentuk
(...)dikembalikan - Kelas diberi prefiks
class, coroutine function diberiasync def, dan fungsi, metode, builtin, serta objek yang memiliki__name__diberi prefiksdef
- Jika gagal, signature pengganti dalam bentuk
- Jika
code=Truedan objek adalah kelas atau callable, source code dicetak denganinspect.getsource(obj)- Jika terjadi
OSError,TypeError, atauIndentationError, pesan kegagalan dikembalikan
- Jika terjadi
- Formatter dict dan list mengembalikan
ERROR: too deeply nestedjika kedalaman indentasi melebihi 30
Output berwarna dan tema
- Output berwarna dapat dikontrol dengan environment variable
WAT_COLOR="false"menonaktifkan output berwarna di konsolWAT_COLOR="true"memaksa output berwarna bahkan di lingkungan non-tty
- Tema warna dapat dikustomisasi dengan environment variable
WAT_COLORS - Tema default adalah pemetaan kode warna ANSI dalam bentuk
BAR=0;34,TRAIT=1;34,HEAD=1;37,STR=0;32,NUMBER=0;31,NONE=0;35,TRUE=1;32,FALSE=1;31,DOCS=2;37,KEYWORD=0;34,CALLABLE=1;32,VARIABLE=1;33,CODE=0;33 _strip_color(text)menghapus ANSI escape sequence dengan regular expression
Inspirasi
- WAT terinspirasi oleh Rich Inspect
1 komentar
Komentar Hacker News
Wah, ini keren sekali. Dulu saya pernah memakai python-ls[0] untuk kegunaan yang mirip, tapi karena alasan yang sudah tidak saya ingat, ada sesuatu yang rusak dan proyeknya juga sudah tidak dipelihara lagi
Kemungkinan akan saya tambahkan ke kotak peralatan debugging saya yang terutama berisi snoop[1] dan pdbpp. Satu hal yang saya harapkan dari wat adalah semacam widget ipy yang memudahkan penjelajahan objek di Jupyter
Hack exec base64-nya juga saya suka. Saya sudah lama memakai Python, tetapi belum pernah terpikir atau melihat hal itu sampai sekarang, jadi saya pasti akan mencobanya untuk beberapa keperluan ke depan
[0] https://github.com/gabrielcnr/python-ls
[1] https://pypi.org/project/snoop/
Kelihatannya menarik. Saya selalu memakai dir di Python, dan saat dokumentasinya kurang bagus, kadang itu malah lebih berguna daripada dokumentasi resmi
Shell interaktif adalah salah satu kekuatan utama Python yang sebenarnya, jadi cukup mengejutkan tidak ada lebih banyak alat atau inovasi baru seperti ini di sekitarnya
Ini terlihat seperti versi icecream lawas yang lebih mencolok
https://github.com/gruns/icecream
Kalau belum tahu, lihat juga daftar implementasi untuk bahasa lain di bagian bawah
https://github.com/gruns/icecream#icecream-in-other-language...
Alat seperti ini memang berguna
20 tahun lalu saya membuat inspektor objek untuk Zope
Sekarang saya memakai devtools setiap hari, dan sesekali memakai icecream dan q. Wat juga akan saya coba
from wat import watKarakter proyeknya sudah sekeren ini, jadi agak mengejutkan mereka tidak menyediakan
import watsaja dengan sintaks penggunaan yang sama. Dengan begitu pengguna yang penasaran bisa melakukan wat/wat dan menemukan triknya sendiriimport watmemang akan lebih bagus, tetapi di Python ada batasan bahwa modul tidak bisa dibuat callable. Karena itu jadinyafrom wat import watyang lebih panjangSaya tidak yakin, tetapi
import wat; wat.wat / objectmungkin malah lebih nyamanIni terlihat sangat berguna, tetapi apakah hanya saya yang terganggu dengan tren belakangan ini yang mengatasnamakan keterbacaan namun meng-overload operator yang sama sekali tidak terkait, dalam hal ini operator
//di sini adalah pilihan yang aneh. Meski begitu, tetap disayangkan bahwaistidak bisa di-overload. Secara realistis,wat(foo)saja mungkin sudah cukupUntuk menghindari import yang merepotkan, Anda juga bisa menambahkan ini ke file
$PYTHONSTARTUPtry:from wat import watexcept ImportError:passPada akhirnya saya mencetak output-nya lalu menaruhnya di direktori yang ditunjuk oleh
PYTHONPATHagar selalu bisa dipakaiKita lihat saja apakah saya akan terus memakainya
Wah, kalau alat seperti ini ada saat saya belajar Python, rasanya akan mengubah segalanya. Saat belajar sebuah bahasa, melihat apa yang terjadi di dalam itu adalah jalur yang sangat penting, sementara debugging bawaan Python, kalau dinilai sebaik-baiknya pun, cenderung mengecewakan
Saya malah memasang pry dan akhirnya jadi penggemar Ruby yang fanatik, tetapi alat ini mungkin bisa membuat saya mencoba Python lagi
Penulisnya memakai modul inspect Python dari pustaka standar secara internal untuk menyediakan fitur ini. Tentu saja mereka juga menambahkan banyak nilai tambah di atasnya
Lihat saja
inspection.pydi modul watDi baris ke-2 ada ini:
import inspect as std_inspect“Kalau Anda ingin cepat men-debug sesuatu, Anda bisa memakai inspektor ini di sesi yang sama tanpa memasang apa pun”
“Tempelkan cuplikan ini ke interpreter Python untuk memuatnya secara instan”
Gagasan menaruh salinan penuh seluruh proyek di README proyek dalam bentuk data terkompresi yang di-encode dengan base64 cukup cerdik
Ini sangat cocok terutama untuk proyek seperti ini, yang mungkin tidak terpikir untuk dipasang lebih dulu di lingkungan tempat Anda justru nanti benar-benar membutuhkannya