Ich denke, eine Lösung könnte nur ungenau sein, weil statische Typisierungsregeln fehlen.
Mir ist kein Tool bekannt, das Ausnahmen überprüft, aber Sie könnten ein eigenes Tool entwickeln, das Ihren Anforderungen entspricht (eine gute Chance, ein wenig mit statischer Analyse zu spielen).
Als ersten Versuch könnten Sie eine Funktion schreiben, die einen AST erstellt, alle RaiseKnoten findet und dann versucht, allgemeine Muster für das Auslösen von Ausnahmen herauszufinden (z. B. direktes Aufrufen eines Konstruktors).
Sei xfolgendes Programm:
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
Erstellen Sie den AST mit dem compilerPaket:
tree = compiler.parse(x)
Definieren Sie dann eine RaiseBesucherklasse:
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
Und gehen Sie die AST-Sammelknoten Raiseentlang:
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),
]
Sie können fortfahren, indem Sie Symbole mithilfe von Compilersymboltabellen auflösen, Datenabhängigkeiten analysieren usw. Oder Sie können einfach ableiten, dass CallFunc(Name('IOError'), ...)"definitiv eine Erhöhung bedeuten sollte IOError", was für schnelle praktische Ergebnisse völlig in Ordnung ist :)
raiseZeichenfolgen und nicht nurBaseExceptionUnterklassen verwenden können. Wenn Sie also Bibliothekscode aufrufen, der außerhalb Ihrer Kontrolleexcept Exceptionliegt, reicht dies nicht aus, da keine Zeichenfolgenausnahmen abgefangen werden. Wie andere bereits betont haben, bellen Sie hier den falschen Baum an.