2010-02-19 13 views
20

Sto lavorando a un progetto abbastanza complesso e di volta in volta devo restringere i problemi guardando le tracce dello stack. Sono molto lunghi e coinvolgono contemporaneamente il "mio" codice, il codice della libreria standard e il codice delle librerie di terze parti. Il più delle volte il vero problema è nel "mio" codice e individuarlo immediatamente in una traccia di stack è un po 'difficile per gli occhi. Sotto "my" code intendo il codice che si trova nella directory di lavoro corrente.Evidenziazione delle tracce dello stack python

Quindi ho capito che voglio qualcosa che colorizzi le tracce dello stack e le linee di evidenziazione che sono mie. Confronta original a highlighted.

ho potuto scrivere uno script python che potrei usare in questo modo:

nosetests | colorize_stack_trace.py 

ma credo che ci sia un modo più rapido e più elegante per fare questo usando set di strumenti di Linux. Qualche idea?

UPD:

Utilizzando supercat suggerito da Dennis Williamson, il risultato intermedio sta seguendo la funzione bash:

pyst() { 
    rc=/tmp/spcrc; 
    echo '#################### ### # # # ########################################' > $rc; 
    echo '      blk 0 r ^(.*)$' >> $rc; 
    echo '      mag b 0 r ^\s*File "'`pwd`'/(.*)"' >> $rc; 
    spc -c $rc; 
} 

Ora posso fare:

nosetests 2>&1 | pyst 
Non

troppo eleganti, ma funziona in una certa misura. Sono rimasti due problemi:

  1. Non riesco a vedere alcun output prima del completamento di nosetests. Cioè Non vedo i progressi.
  2. Devo scrivere 2> & 1 ancora e ancora.

UPD 2:

Chiedendo a questa domanda ho dovuto principalmente nosetests in mente. E ho appena trovato un'ottima soluzione: plug-in rednose nose. Mette in evidenza percorsi che sono locali e fanno molte cose più leggibili a portata di mano.

Tornando alla domanda originale: i problemi che ho notato con il supercat non si riferiscono ad esso completamente ma è un problema di streaming shell Unix, flushing, piping, reindirizzamento. Quindi come risposta alla domanda ho chiesto accetto una risposta che suggerisca la supercat.

+0

rednose è bello. Puoi averlo abilitato di default aggiungendo 'rednose = 1' al tuo' .noserc' –

risposta

6

Dai uno sguardo allo Supercat (spc). Fa l'evidenziazione ANSI e HTML e può essere configurato per il tuo particolare output. Viene fornito con alcuni file di configurazione per i file di codice sorgente in C e Python, ad esempio e file di registro, Changelogs, diffs e altri.

Sulla base suggerimento di Dave Kirby per vim, questo fa qualcosa di simile:

less -p regex file_name 

O

some_command | less -p regex 
1

Forse potresti usare il modulo cgitb (breve documento ufficiale here) come punto di partenza (crea dei simpatici traceback HTML). Dovrebbe essere relativamente semplice apportare le modifiche necessarie (ad esempio, aggiungere un tag del colore in base al percorso del file). Ma ovviamente questo è fattibile solo se sei disposto ad usare il browser per visualizzare le tracce.

+0

Grazie per il suggerimento, ma è un po 'strano usare il browser per visualizzare i risultati del test. Puzza di script di azione e QUnit. Non è flessibile come può essere :) – nkrkv

+0

@nailxx Si potrebbe voler guardare oltre. Dal documento ufficiale: 'È stato originariamente progettato per visualizzare informazioni di traceback estese in HTML per gli script CGI. In seguito è stato generalizzato anche per visualizzare queste informazioni in testo semplice. –

0

Come punto di partenza per la colorazione (e in caso contrario la formattazione) del testo, probabilmente si vorrà osservare lo curses library. Vedi anche this how-to, che sembra utile.

Per quanto riguarda l'override della gestione degli errori incorporata di Python per tutti i programmi ... Non l'ho mai provato, ma penserei che ciò implicherebbe alcune modifiche di livello relativamente basso. Puoi sempre avvolgere il tuo codice in un enorme tentativo/eccetto il blocco, ma presumo che tu non voglia farlo.Sono favorevole all'approccio più Unix di scrivere un piccolo script che fa una cosa, e lo fa bene: prendi un input e, se è una traccia stack, coloralo. Altrimenti, passa il testo invariato. Usare una pipa, come hai suggerito, potrebbe essere il modo migliore. (In questo caso, per pipe stderr si dovrebbe fare qualcosa di simile, che unisce lo stderr con stdout prima delle connessioni: cmd1 2>&1 | cmd2)

-1

Caricare il testo in vim:

nosetests | vim - 

Set vim per evidenzia tutte le linee che corrispondono a una ricerca

:set hlsearch 

Cerca linee con "il vostro" percorso

/.*/path/to/my/code.* 

Voila - verrà evidenziato tutte le linee con il vostro percorso.

Se si desidera evidenziare la riga successiva e allora si può fare anche questo:

/.*/path/to/my/code.*\n.* 
20

In realtà, c'è una grande biblioteca della sintassi Python evidenziazione chiamato Pygments, che è anche in grado di evidenziare traceback. Ecco uno example (il pastebin qui usa Pygments).

Quindi, tutto quello che dovete fare è:

$ easy_install pygments # downloads and installs pygments 
$ cat traceback.txt | pygmentize -l pytb 

"pytb" è la scorciatoia per il PythonTracebackLexer. C'è anche un lexer speciale per Python 3 Traceback incluso, che si chiama "py3tb".

È possibile formattare l'output in vari formati (inclusi html, latex, svg, diversi formati di immagine e così via). Ma c'è anche un formattatore terminale disponibile che potrebbe essere simile a questo (e se vi state chiedendo ... ovviamente ci sono diversi temi di colore disponibili!):

Pygments Console Traceback Highlighting http://www.tux21b.org/public/pygments-pytb.png

È possibile utilizzare -f html per selezionare un altro formattatore (in questo caso, il formattatore HTML).

saluti,
Christoph

+0

L'opzione Cool, può essere una buona alternativa allo spc – nkrkv

+0

+1 per Pygments. Sono le ginocchia delle api. – jathanism

+2

C'è un modo per pitone di colorare magicamente i traceback, senza collegare nulla a nessun altro strumento? – azmeuk

0

Inoltre è possibile aprire il file con vim traceback, utilizzando :cfile comando. Quindi è possibile aprire l'elenco interattivo dei file evidenziato in traceback utilizzando il comando :copen e saltare tra questi file utilizzando l'insieme di comandi relativi di vim.

0

C'è un bel modulo solo per questo scopo:

Non vi resta che scaricarlo e installarlo tramite pip:

pip install colored-traceback 

Import in un file di livello superiore del progetto, per exmapl e in questo modo:

if DEBUG: 
    import colored_traceback 
    colored_traceback.add_hook() 

E si ottiene una traceback del genere per ogni file subalterno (i colori variano):

Traceback (most recent call last): 
    File "./workflowy.py", line 525, in <module> 
    main() 
    File "./workflowy.py", line 37, in main 
    projects = cli.load_json(args, input_is_pipe) 
    File "./workflowy.py", line 153, in load_json 
    return json.load(sys.stdin) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 290, in load 
    **kw) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads 
    return _default_decoder.decode(s) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 383, in raw_decode 
    raise ValueError("No JSON object could be decoded") 
ValueError: No JSON object could be decoded 
Problemi correlati