Dukungan perbaikan cepat untuk tracebacks Python

18

Katakanlah saya memiliki skrip python dengan kesalahan runtime:

$ cat example.py  
#! /usr/bin/env python3

a = 1/0

pemberian yang mana:

$ python3 example.py 
Traceback (most recent call last):
  File "example.py", line 3, in <module>
    a = 1/0
ZeroDivisionError: division by zero

Saya ingin Vim melompat ke baris bermasalah dari file itu (baris 3 dalam kasus ini). Saya tahu Vim dapat melakukan ini karena berfungsi dengan baik untuk menangkap kesalahan pada waktu kompilasi di C dengan gccmenggunakan :makedan quickfixjendela.

output perbaikan cepat dari gcc

Tentu, saya dapat mengisi jendela perbaikan cepat Vim dengan :set makeprg=python3\ %dan kemudian :make, tetapi tidak melompat ke nomor baris tempat traceback menunjuk. Ketika saya melihatnya :copenhanya menyoroti baris pertama jejak, dan saya tidak bisa melompat ke nomor baris yang relevan.

output perbaikan cepat dari python3

(Saya menggunakan Vim 7.4 di Debian jessiejika itu penting.)

Pertanyaan saya adalah:

  • Bisakah saya mengonfigurasi Vim sehingga ia tahu cara mendapatkan nomor baris yang relevan dari traceback Python?

  • Bisakah saya memodifikasi juru bahasa Python untuk memuntahkan format kesalahan yang Vim sudah tahu bagaimana mem-parsing dan mendapatkan nomor baris yang relevan?

Nathaniel M. Beaver
sumber
Anda bisa membuat subkelas logger dalam skrip Anda untuk menghasilkan traceback point satu per baris (lihat di sini untuk memulai), lalu sesuaikan errorformatdan tulis plugin kompiler untuk Vim (lihat :help :compilerdan :help write-compiler-plugin). Mungkin tidak sepadan dengan usaha jika Anda tidak tahu persis apa yang Anda lakukan dan Anda tidak cukup antusias untuk menggali semuanya dari dokumen.
Sato Katsura
Saya mengajukan pertanyaan serupa pada StackOverflow, Anda mungkin menemukan jawaban-jawaban yang berguna stackoverflow.com/questions/11333112/…
jalanb

Jawaban:

7

Vim hadir dengan sekumpulan skrip "compiler", salah satunya disebut "pyunit" . Jika Anda menjalankan :compiler pyunitdan kemudian :make(dengan nilai yang disarankan untuk 'makeprg'), perbaikan cepat diisi seperti yang Anda harapkan. Namun, itu hanya berfungsi dengan baik jika ada satu level ke jejak stack.

Meningkatkan skrip kompiler akan menjadi latihan yang bermanfaat.

The unstack Plugin mungkin menarik, karena menyediakan mekanisme umum untuk mengurai dan melihat lokasi dilaporkan dalam setumpuk jejak dan memiliki dukungan Python dibangun di.

jamessan
sumber
4

Plugin kompiler bawaan pyunit

Seperti yang sudah disarankan oleh jamessan , satu opsi adalah menggunakan plugin kompiler bawaan pyunit:

:compiler pyunit
:set makeprg=python3\ %
:make

Ini memiliki downside, bahwa itu mengurangkan jejak stack ke pesan kesalahan tunggal. Misalnya skrip python berikut:

def lumberjack():
    bright_side_of_death()

def bright_side_of_death():
    return tuple()[0]

lumberjack()

... menghasilkan pesan kesalahan ini:

|| Traceback (most recent call last):
lumberjack.py|7|  IndexError: tuple index out of range

Menulis plugin kompiler Anda sendiri

Sebagai alternatif, Anda dapat menyediakan plugin kompiler Anda sendiri di ~/.vim/compiler/python.vim:

if exists("current_compiler")
  finish
endif
let current_compiler = "python"

let s:cpo_save = &cpo
set cpo&vim

CompilerSet errorformat=
      \%*\\sFile\ \"%f\"\\,\ line\ %l\\,\ %m,
      \%*\\sFile\ \"%f\"\\,\ line\ %l,
CompilerSet makeprg=python3\ %

let &cpo = s:cpo_save
unlet s:cpo_save

Pilih plugin secara manual :compiler python, atau muat secara otomatis dengan menambahkan ini ke ~/.vim/after/ftplugin/python.vim:

if !exists("current_compiler")
  compiler python
endif

Dengan skrip python dari atas, Vim mengisi jendela perbaikan cepat dengan:

|| Traceback (most recent call last):
lumberjack.py|7| in <module>
||     lumberjack()
lumberjack.py|2| in lumberjack
||     bright_side_of_death()
lumberjack.py|5| in bright_side_of_death
||     return tuple()[0]
|| IndexError: tuple index out of range

Lihat :help write-compiler-pluginuntuk informasi lebih lanjut.

siho
sumber
3

quickfix.py mem-parsing traceback ke dalam format kesalahan yang ramah-vim. Berikut adalah contoh menjalankannya pada file dengan satu baris 1 / 0.

❯❯❯ quickfix.py tests/errors/div_by_zero.py
"tests/errors/div_by_zero.py":1: ZeroDivisionError: division by zero

Secara default, ini menunjukkan file pengguna, tetapi juga dapat menampilkan file sistem (menjalankannya pada file yang mengandung import os; os.environ['123']):

❯❯❯ quickfix.py -a /tmp/test.py                                                                                                        
"/usr/lib/lib/python3.7/os.py":678: KeyError: '123'
"/tmp/test.py":1: in function <module>

Konfigurasi:

Ketika quickfix.pytersedia di jalur saat ini, tambahkan baris berikut di vimrc untuk menggunakannya.

if has("autocmd")
  autocmd FileType python setlocal makeprg=quickfix.py\ %
  autocmd FileType python setlocal errorformat=%E\"%f\":%l:%m,
endif
jadelord
sumber
-1

Bukan metode otomatis tetapi Traceback python menyatakan nomor baris --- 3 dalam contoh Anda --- dan dengan demikian menjalankan vim:

$ vim +3 example.py

akan membuka example.pydengan kursor di baris ketiga.

Chris Hanning
sumber
2
Saya mengetahui hal itu, tetapi ini tentang dukungan Quickfix. Setelah saya menjalankan :makefile yang sudah saya buka, lebih cepat digunakan :3untuk melompat ke baris ketiga daripada menutup dan membuka kembali. Selain itu, melakukan ini secara manual sangat menyebalkan untuk jejak tumpukan yang lebih kompleks, itulah sebabnya saya ingin dukungan Quickfix.
Nathaniel M. Beaver