Suporte do Quickfix para rastreios de Python


18

Digamos que eu tenha um script python com um erro de tempo de execução:

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

a = 1/0

que dá:

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

Eu quero que o Vim pule para a linha problemática desse arquivo (linha 3 neste caso). Eu sei que o Vim pode fazer isso porque funciona muito bem para detectar erros em tempo de compilação em C com o gccuso :makee a quickfixjanela.

saída quickfix do gcc

Claro, eu posso preencher a janela de correção rápida do Vim com :set makeprg=python3\ %e :make, em seguida , mas não pula para o número da linha para onde o traceback aponta. Quando olho para :copenele, apenas destaca a primeira linha do rastreamento e não posso pular para o número da linha relevante.

saída quickfix do python3

(Estou usando o Vim 7.4 no Debian jessie, caso isso importe.)

Minhas perguntas são:

  • Posso configurar o Vim para que ele saiba como obter o número da linha relevante de um rastreamento de Python?

  • Posso modificar o interpretador Python para cuspir um formato de erro que o Vim já sabe analisar e obter o número da linha relevante?


Você pode subclassificar o criador de logs em seu script para produzir pontos de retorno um por linha (veja aqui para começar), depois ajustar de errorformatacordo e escrever um plug-in de compilação para o Vim (ver :help :compilere :help write-compiler-plugin). Provavelmente não vale o esforço se você não sabe exatamente o que está fazendo e não está entusiasmado o suficiente para descobrir tudo sobre os documentos.
Sato Katsura

Eu fiz uma pergunta semelhante sobre StackOverflow, você pode encontrar essas respostas úteis stackoverflow.com/questions/11333112/...
jalanb

Respostas:


7

O Vim vem com um conjunto de scripts "compiladores", um dos quais é chamado "pyunit" . Se você executar :compiler pyunite depois :make(com o valor sugerido para 'makeprg'), o quickfix será preenchido conforme o esperado. No entanto, ele só funciona bem se houver um nível no rastreamento de pilha.

Melhorar esse script do compilador seria um exercício útil.

O plug-in unstack pode ser interessante, pois fornece um mecanismo geral para analisar e visualizar os locais relatados em um rastreamento de pilha e possui suporte a Python embutido.


4

Plug-in do compilador incorporado pyunit

Como já sugerido por jamessan , uma opção é usar o plug pyunit- in do compilador incorporado :

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

Isso tem o lado negativo, que recolhe o rastreamento de pilha em uma única mensagem de erro. Por exemplo, o seguinte script python:

def lumberjack():
    bright_side_of_death()

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

lumberjack()

... produz esta mensagem de erro:

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

Escrevendo seu próprio plug-in de compilador

Como alternativa, você pode fornecer seu próprio plug-in de compilador em ~/.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

Selecione o plug-in manualmente :compiler pythonou carregue-o automaticamente adicionando-o a ~/.vim/after/ftplugin/python.vim:

if !exists("current_compiler")
  compiler python
endif

Com o script python acima, o Vim preenche a janela do quickfix com:

|| 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

Veja :help write-compiler-pluginpara mais informações.


3

quickfix.py analisa o rastreamento em um formato de erro compatível com o vim. Aqui está um exemplo de executá-lo em um arquivo com uma única linha 1 / 0.

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

Por padrão, ele mostra os arquivos do usuário, mas também pode mostrar os arquivos do sistema (executando-o em um arquivo que contém 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>

Configuração:

Quando quickfix.pyestiver disponível no caminho atual, adicione as seguintes linhas no vimrc para usá-lo.

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

-1

Não é um método automático, mas o python Traceback indica o número da linha --- 3 no seu exemplo --- e, portanto, invocando o vim:

$ vim +3 example.py

abrirá o example.pycursor com a terceira linha.


2
Estou ciente disso, mas isso é sobre o suporte ao Quickfix. Depois de executar :makeum arquivo que já abri, é mais rápido usar :3para pular para a terceira linha do que fechar e reabrir. Além disso, fazer isso manualmente é um problema para rastreamentos de pilha mais complexos, e é por isso que desejo o suporte ao Quickfix.
Nathaniel M. Beaver
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.