Immagino che una soluzione potrebbe essere solo imprecisa a causa della mancanza di regole di digitazione statiche.
Non sono a conoscenza di uno strumento che controlla le eccezioni, ma potresti trovare uno strumento personalizzato che corrisponda alle tue esigenze (una buona possibilità per giocare un po 'con l'analisi statica).
Come primo tentativo, potresti scrivere una funzione che costruisce un AST, trova tutto Raise nodi e quindi cerca di capire modelli comuni di generazione di eccezioni (ad esempio chiamando direttamente un costruttore)
Sia xil seguente programma:
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
Costruisci l'AST utilizzando il compilerpacchetto:
tree = compiler.parse(x)
Quindi definisci una Raiseclasse visitatore:
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
E percorri i Raisenodi di raccolta AST :
v = RaiseVisitor()
compiler.walk(tree, v)
>>> print v.nodes
[
Raise(
CallFunc(
Name('IOError'),
[Getattr(Name('errno'), 'ENOENT'), Const('not found')],
None, None),
None, None),
Raise(Name('e'), None, None),
]
Puoi continuare risolvendo i simboli usando le tabelle dei simboli del compilatore, analizzando le dipendenze dei dati, ecc. Oppure puoi semplicemente dedurre che CallFunc(Name('IOError'), ...)"dovrebbe sicuramente significare aumentare IOError", il che è abbastanza OK per risultati pratici rapidi :)
raisestringhe, non soloBaseExceptionsottoclassi. Quindi, se stai chiamando il codice della libreria che è fuori dal tuo controllo, ancheexcept Exceptionse non è sufficiente, poiché non cattura eccezioni di stringa. Come altri hanno sottolineato, qui stai abbaiando contro l'albero sbagliato.