Prise en charge de Quickfix pour les retraits Python

18

Disons que j'ai un script python avec une erreur d'exécution:

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

a = 1/0

qui donne:

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

Je veux que Vim passe à la ligne problématique de ce fichier (ligne 3 dans ce cas). Je sais que Vim peut le faire car cela fonctionne très bien pour détecter les erreurs au moment de la compilation en C avec l' gccaide de :makeet la quickfixfenêtre.

sortie quickfix de gcc

Bien sûr, je peux remplir la fenêtre de correction rapide de Vim avec :set makeprg=python3\ %puis :make, mais il ne saute pas au numéro de ligne vers lequel pointe le traçage. Quand je regarde :copendedans, il met juste en évidence la première ligne de la trace, et je ne peux pas passer au numéro de ligne correspondant.

sortie quickfix de python3

(J'utilise Vim 7.4 sur Debian jessieau cas où cela compte.)

Mes questions sont:

  • Puis-je configurer Vim pour qu'il sache comment obtenir le numéro de ligne approprié à partir d'un suivi Python?

  • Puis-je modifier l'interpréteur Python pour cracher un format d'erreur que Vim sait déjà comment analyser et obtenir le numéro de ligne approprié?

Nathaniel M. Beaver
la source
Vous pouvez sous-classer l'enregistreur dans votre script pour produire des points de trace un par ligne (voir ici pour commencer), puis ajuster en errorformatconséquence et écrire un plugin de compilation pour Vim (voir :help :compileret :help write-compiler-plugin). Cela ne vaut probablement pas la peine si vous ne savez pas exactement ce que vous faites et si vous n'êtes pas assez enthousiaste pour tout extraire des documents.
Sato Katsura du
J'ai posé une question similaire sur StackOverflow, vous pouvez trouver ces réponses utiles stackoverflow.com/questions/11333112/…
jalanb

Réponses:

7

Vim est livré avec un ensemble de scripts "compilateur", dont l'un est appelé "pyunit" . Si vous exécutez :compiler pyunitpuis :make(avec la valeur suggérée pour 'makeprg'), quickfix est renseigné comme prévu. Cependant, cela ne fonctionne bien que s'il y a un niveau dans la trace de la pile.

Améliorer ce script de compilation serait un exercice utile.

Le plugin unstack peut être intéressant, car il fournit un mécanisme général pour analyser et afficher les emplacements signalés dans une trace de pile et prend en charge Python.

jamessan
la source
4

Plugin de compilation intégré pyunit

Comme déjà suggéré par jamessan , une option consiste à utiliser le plugin de compilation intégré pyunit:

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

Cela a l'inconvénient de réduire la trace de la pile en un seul message d'erreur. Par exemple, le script python suivant:

def lumberjack():
    bright_side_of_death()

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

lumberjack()

... produit ce message d'erreur:

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

Écrire votre propre plugin de compilation

Comme alternative, vous pouvez fournir votre propre plugin de compilation dans ~/.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

Sélectionnez le plugin manuellement avec :compiler pythonou chargez-le automatiquement en l'ajoutant à ~/.vim/after/ftplugin/python.vim:

if !exists("current_compiler")
  compiler python
endif

Avec le script python d'en haut, Vim remplit la fenêtre quickfix avec:

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

Voir :help write-compiler-pluginpour plus d'informations.

siho
la source
3

quickfix.py analyse le traceback dans un format d'erreur compatible avec vim. Voici un exemple d'exécution sur un fichier avec une seule ligne 1 / 0.

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

Par défaut, il affiche les fichiers utilisateur, mais il peut également afficher les fichiers système (en l'exécutant sur un fichier contenant 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>

Configuration:

Lorsque quickfix.pyest disponible dans le chemin d'accès actuel, ajoutez les lignes suivantes dans le vimrc pour l'utiliser.

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

Ce n'est pas une méthode automatique mais le Python Traceback indique le numéro de ligne --- 3 dans votre exemple --- et donc invoque vim:

$ vim +3 example.py

ouvrira le example.pyavec le curseur sur la troisième ligne.

Chris Hanning
la source
2
J'en suis conscient, mais il s'agit du support Quickfix. Après avoir exécuté :makeun fichier que j'ai déjà ouvert, il est plus rapide d'utiliser :3pour passer à la troisième ligne que pour fermer et rouvrir. De plus, faire cela manuellement est pénible pour les traces de pile plus complexes, c'est pourquoi je veux un support Quickfix.
Nathaniel M. Beaver