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 Raise
Knoten findet und dann versucht, allgemeine Muster für das Auslösen von Ausnahmen herauszufinden (z. B. direktes Aufrufen eines Konstruktors).
Sei x
folgendes Programm:
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
Erstellen Sie den AST mit dem compiler
Paket:
tree = compiler.parse(x)
Definieren Sie dann eine Raise
Besucherklasse:
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
Und gehen Sie die AST-Sammelknoten Raise
entlang:
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 :)
raise
Zeichenfolgen und nicht nurBaseException
Unterklassen verwenden können. Wenn Sie also Bibliothekscode aufrufen, der außerhalb Ihrer Kontrolleexcept Exception
liegt, reicht dies nicht aus, da keine Zeichenfolgenausnahmen abgefangen werden. Wie andere bereits betont haben, bellen Sie hier den falschen Baum an.