2 poin oleh GN⁺ 2024-07-26 | 1 komentar | Bagikan ke WhatsApp
  • 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 seperti wat(object), dan mendukung berbagai sintaks seperti wat.short / 'foo', 'foo' | wat.short, wat('foo', short=True)
  • Modifier seperti .short, .dunder, .long, .code, .caller, .public, .all, .ret, .str dapat dirangkai untuk menyesuaikan cakupan output, cara pengembalian, output berwarna, dan penampilan lokasi pemanggilan
  • Instalasi dapat dilakukan dengan pip install wat lalu import 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 | None menunjukkan 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 / object pada object apa 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)
  • Wat diperkenalkan sebagai variasi dari kata Inggris what, yang dipakai untuk mengekspresikan kebingungan atau rasa tidak nyaman

Penggunaan dasar dan sintaks

  • Untuk input cepat, digunakan operator pembagian
    • wat / foo sama dengan wat(foo)
  • Beberapa sintaks dapat digunakan untuk inspeksi yang sama
    • wat.short / 'foo': sintaks untuk input cepat
    • wat.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, wat dapat menjelajahi objek apa pun
  • Jika mengetik wat di interpreter, Anda dapat melihat bantuan untuk objek wat itu sendiri

Menyesuaikan cakupan inspeksi dengan Modifier

  • .short atau .s menyembunyikan atribut seperti variabel dan metode di dalam objek, lalu hanya mencetak nilai, tipe, tipe induk, signature, dan dokumentasi
  • .dunder menampilkan atribut dunder yang diawali dengan __
  • .long menampilkan nilai dan docstring tanpa dipersingkat
  • .code menampilkan source code fungsi, metode, dan kelas
  • .nodocs menyembunyikan dokumentasi fungsi dan kelas
  • .caller menampilkan bagaimana dan di mana inspeksi dipanggil, dan bekerja pada file non-REPL
  • .public menyembunyikan atribut private dan hanya menampilkan atribut public
  • .all menyertakan semua informasi yang memungkinkan
  • .ret mengembalikan lagi objek setelah inspeksi
  • .str mengembalikan string hasil alih-alih mencetak output
  • .gray menonaktifkan output berwarna di konsol
  • .color memaksa output berwarna di konsol
  • wat.locals menginspeksi variabel lokal, dan wat.globals menginspeksi variabel global

Instalasi dan Insta-Load

  • Alur instalasi dengan pip adalah sebagai berikut
    • pip install wat
    • Di Python, import wat
  • Paket wat tidak 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 dengan exec(..., globals()) di interpreter sebagai Python snippet
  • Setelah menjalankan snippet Insta-Load, object wat dapat 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.py ke interpreter juga memberi efek yang sama
    • Juga disarankan opsi memasang paket dengan pip dan meninjau kodenya
  • 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 dengan exec(...) setelah zlib.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,), tipe tuple, panjang 1
    • wat.short / {None} mencetak nilai {None}, tipe set, panjang 1
  • Dalam contoh objek Django User, wat.short / user mencetak str: admin, repr: <User: admin>, tipe django.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
  • Untuk memahami cara memakai fungsi, docstring dan signature fungsi dapat dilihat
    • Contoh yang diberikan adalah wat / str.split

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')
  • Ini juga dapat digunakan untuk menjelajahi modul, dengan menampilkan fungsi, kelas, dan submodul dari modul yang dipilih
    • Ada contoh menjalankan wat / pathlib setelah import pathlib
    • Setelah itu dapat menjelajah lebih dalam seperti wat / pathlib.fnmatch
  • WAT Inspector secara default menyembunyikan atribut yang diawali dengan __
    • Atribut dunder dapat dilihat dengan wat.dunder / {}
  • Untuk memeriksa bagaimana fungsi sebenarnya bekerja, source code dapat dilihat
    • Ada contoh menjalankan wat.code / colorsys.hsv_to_rgb setelah import colorsys
  • 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 / foo setelah import wat atau menempelkan snippet Insta-Load, lalu melanjutkan eksekusi dengan c
  • Variabel lokal dan global masing-masing dapat diperiksa dengan wat.locals dan wat.globals
  • Jika wat() dipanggil tanpa argumen, variabel lokal pada stack pemanggil akan dicetak dengan judul Local variables

Contoh mempelajari internal Python

  • Termasuk contoh penggunaan untuk memahami cara kerja internal Python
  • reversed([]) == reversed([]) bernilai False, dan wat.s / reversed([]) menunjukkan bahwa nilainya adalah object list_reverseiterator dan tipenya list_reverseiterator
  • wat / type('ObjectCreator', (), {}) menampilkan nilai dari kelas yang dibuat secara dinamis, tipe type, dan signature: class ObjectCreator()
  • wat / type menampilkan nilai type itu sendiri, tipe type, signature class type(…), dokumentasi type(object) -> the object's type, type(name, bases, dict, **kwds) -> a new type, atribut public seperti mro, dan lain-lain
  • wat.s / List[str] menampilkan nilai typing.List[str], tipe typing._GenericAlias, tipe induk typing._BaseGenericAlias, typing._Final, dan signature def List(*args, **kwargs)
  • wat(str | None) menampilkan nilai str | None dan tipe types.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__

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, dan caller ikut 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
  • 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 dunder mati
    • Atribut private yang diawali _ dikecualikan jika pengaturan private mati
    • Jika getattr(obj, key) menghasilkan BaseException, objek exception tersebut digunakan sebagai nilai
  • Objek callable memformat signature berdasarkan inspect.signature(obj)
    • Jika gagal, signature pengganti dalam bentuk (...) dikembalikan
    • Kelas diberi prefiks class , coroutine function diberi async def , dan fungsi, metode, builtin, serta objek yang memiliki __name__ diberi prefiks def
  • Jika code=True dan objek adalah kelas atau callable, source code dicetak dengan inspect.getsource(obj)
    • Jika terjadi OSError, TypeError, atau IndentationError, pesan kegagalan dikembalikan
  • Formatter dict dan list mengembalikan ERROR: too deeply nested jika kedalaman indentasi melebihi 30

Output berwarna dan tema

  • Output berwarna dapat dikontrol dengan environment variable
    • WAT_COLOR="false" menonaktifkan output berwarna di konsol
    • WAT_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

1 komentar

 
GN⁺ 2024-07-26
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

    • Ada juga fungsi help(). Itu benar-benar berguna
  • 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 wat
    Karakter proyeknya sudah sekeren ini, jadi agak mengejutkan mereka tidak menyediakan import wat saja dengan sintaks penggunaan yang sama. Dengan begitu pengguna yang penasaran bisa melakukan wat/wat dan menemukan triknya sendiri

    • import wat memang akan lebih bagus, tetapi di Python ada batasan bahwa modul tidak bisa dibuat callable. Karena itu jadinya from wat import wat yang lebih panjang
      Saya tidak yakin, tetapi import wat; wat.wat / object mungkin malah lebih nyaman
  • Ini 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 /

    • Saya setuju bahwa overload / di sini adalah pilihan yang aneh. Meski begitu, tetap disayangkan bahwa is tidak bisa di-overload. Secara realistis, wat(foo) saja mungkin sudah cukup
  • Untuk menghindari import yang merepotkan, Anda juga bisa menambahkan ini ke file $PYTHONSTARTUP
    try:
    from wat import wat
    except ImportError:
    pass

    • Anda bahkan bisa menambahkan importir inline base64 yang cukup keren
      Pada akhirnya saya mencetak output-nya lalu menaruhnya di direktori yang ditunjuk oleh PYTHONPATH agar selalu bisa dipakai
      Kita 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.py di modul wat
    Di 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