Quickfix-Unterstützung für Python-Tracebacks

18

Angenommen, ich habe ein Python-Skript mit einem Laufzeitfehler:

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

a = 1/0

was gibt:

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

Ich möchte, dass Vim zur problematischen Zeile dieser Datei (in diesem Fall Zeile 3) springt. Ich weiß, dass Vim dies kann, weil es gut funktioniert, um Fehler beim Kompilieren in C mit gccusing :makeund dem quickfixFenster abzufangen.

Quickfix-Ausgabe von gcc

Klar, ich kann das Quickfix-Fenster von Vim mit :set makeprg=python3\ %und füllen :make, aber es springt nicht zu der Zeilennummer, auf die das Traceback verweist. Wenn ich hineinschaue :copen, hebt es nur die erste Zeile der Kurve hervor und ich kann nicht zur entsprechenden Zeilennummer springen.

Quickfix-Ausgabe von Python3

(Ich benutze Vim 7.4 unter Debian, jessiefalls es darauf ankommt.)

Meine Fragen sind:

  • Kann ich Vim so konfigurieren, dass es weiß, wie die relevante Zeilennummer von einem Python-Traceback stammt?

  • Kann ich den Python-Interpreter so ändern, dass er ein Fehlerformat ausgibt, von dem Vim bereits weiß, wie man die relevante Zeilennummer analysiert und abruft?

Nathaniel M. Beaver
quelle
Sie können den Logger in Ihrem Skript in Unterklassen unterteilen, um Traceback-Punkte pro Zeile zu erstellen (siehe hier , um zu beginnen), dann entsprechend anpassen errorformatund ein Compiler-Plugin für Vim schreiben (siehe :help :compilerund :help write-compiler-plugin). Die Mühe lohnt sich wahrscheinlich nicht, wenn Sie nicht genau wissen , was Sie tun, und nicht enthusiastisch genug sind, um alles aus den Dokumenten herauszuholen.
Sato Katsura
Ich habe eine ähnliche Frage zu StackOverflow gestellt. Sie finden diese Antworten möglicherweise nützlich unter stackoverflow.com/questions/11333112/…
jalanb 16.10.15

Antworten:

7

Vim wird mit einer Reihe von "Compiler " -Skripten geliefert , von denen eines "Pyunit" heißt . Wenn Sie ausführen :compiler pyunitund dann :make(mit Ihrem vorgeschlagenen Wert für 'makeprg'), wird Quickfix wie erwartet ausgefüllt. Dies funktioniert jedoch nur, wenn der Stack-Trace eine Ebene aufweist.

Die Verbesserung dieses Compilerskripts wäre eine nützliche Übung.

Das Unstack- Plugin kann von Interesse sein, da es einen allgemeinen Mechanismus zum Analysieren und Anzeigen der in einem Stack-Trace gemeldeten Speicherorte bietet und Python-Unterstützung integriert ist.

Jamessan
quelle
4

Eingebautes Compiler-Plugin pyunit

Wie bereits von jamessan vorgeschlagen , besteht eine Möglichkeit darin, das eingebaute Compiler-Plugin zu verwenden pyunit:

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

Dies hat den Nachteil, dass der Stack-Trace zu einer einzigen Fehlermeldung reduziert wird. Zum Beispiel das folgende Python-Skript:

def lumberjack():
    bright_side_of_death()

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

lumberjack()

... erzeugt diese Fehlermeldung:

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

Schreiben Sie Ihr eigenes Compiler-Plugin

Alternativ können Sie Ihr eigenes Compiler-Plugin bereitstellen ~/.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

Wählen Sie das Plugin manuell mit aus :compiler pythonoder laden Sie es automatisch, indem Sie dies hinzufügen zu ~/.vim/after/ftplugin/python.vim:

if !exists("current_compiler")
  compiler python
endif

Mit dem Python-Skript von oben füllt Vim das Quickfix-Fenster mit:

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

Siehe :help write-compiler-pluginfür weitere Informationen.

siho
quelle
3

quickfix.py analysiert das Traceback in ein vim-freundliches Fehlerformat. Hier ist ein Beispiel für die Ausführung in einer Datei mit einer einzelnen Zeile 1 / 0.

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

Standardmäßig werden Benutzerdateien angezeigt, es können jedoch auch Systemdateien angezeigt werden (die auf einer Datei ausgeführt werden, die Folgendes enthält 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>

Aufbau:

Wenn quickfix.pyim aktuellen Pfad verfügbar, fügen Sie die folgenden Zeilen in den vimrc ein, um ihn zu verwenden.

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

Keine automatische Methode, aber das Python-Traceback gibt die Zeilennummer --- 3 in Ihrem Beispiel --- an und ruft so vim auf:

$ vim +3 example.py

öffnet das example.pymit dem Cursor in der dritten Zeile.

Chris Hanning
quelle
2
Mir ist das bewusst, aber hier geht es um die Unterstützung von Quickfix. Nachdem ich :makeeine bereits geöffnete Datei ausgeführt habe, können Sie schneller :3in die dritte Zeile springen, als sie schließen und erneut öffnen. Das manuelle Ausführen ist auch eine Herausforderung für komplexere Stack-Traces. Aus diesem Grund möchte ich Quickfix-Unterstützung.
Nathaniel M. Beaver