Saya kira solusi hanya bisa tidak tepat karena kurangnya aturan pengetikan statis.
Saya tidak mengetahui beberapa alat yang memeriksa pengecualian, tetapi Anda dapat menemukan alat Anda sendiri yang sesuai dengan kebutuhan Anda (peluang bagus untuk bermain sedikit dengan analisis statis).
Sebagai upaya pertama, Anda bisa menulis fungsi yang membangun AST, menemukan semua Raisenode, dan kemudian mencoba mencari pola umum untuk memunculkan pengecualian (misalnya memanggil konstruktor secara langsung)
Biarlah xprogram berikut ini:
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
Bangun AST menggunakan compilerpaket:
tree = compiler.parse(x)
Kemudian tentukan Raisekelas pengunjung:
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
Dan berjalan di Raisenode pengumpul 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),
]
Anda dapat melanjutkan dengan menyelesaikan simbol menggunakan tabel simbol kompilator, menganalisis dependensi data, dll. Atau Anda dapat menyimpulkan, CallFunc(Name('IOError'), ...)"seharusnya berarti menaikkan IOError", yang cukup OK untuk hasil praktis yang cepat :)
raisestring, bukan hanyaBaseExceptionsubclass. Jadi jika Anda memanggil ke kode perpustakaan yang di luar kendali Anda, bahkanexcept Exceptiontidak cukup, karena tidak akan menangkap pengecualian string. Seperti yang ditunjukkan orang lain, Anda menggonggong pohon yang salah di sini.