Sanırım bir çözüm, statik yazım kurallarının olmaması nedeniyle kesin olmayabilir.
İstisnaları kontrol eden bir araçtan haberdar değilim, ancak ihtiyaçlarınıza uygun kendi aracınızı bulabilirsiniz (statik analizle biraz oynamak için iyi bir şans).
İlk girişim olarak, bir AST oluşturan, tüm Raisedüğümleri bulan ve ardından istisnaları artırmanın ortak modellerini bulmaya çalışan bir işlev yazabilirsiniz (örneğin, bir kurucuyu doğrudan çağırmak)
xAşağıdaki program olalım :
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
AST'yi aşağıdaki compilerpaketi kullanarak oluşturun :
tree = compiler.parse(x)
Ardından bir Raiseziyaretçi sınıfı tanımlayın :
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
Ve AST toplama Raisedüğümlerinde yürüyün :
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),
]
Derleyici sembol tablolarını kullanarak sembolleri çözerek, veri bağımlılıklarını analiz ederek, vb. Devam edebilirsiniz. Ya da sadece CallFunc(Name('IOError'), ...)"kesinlikle yükseltme anlamına gelmelidir" sonucuna varabilirsiniz, bu IOErrorhızlı pratik sonuçlar için oldukça uygundur :)
raisedizeler de yapabileceğinizi unutmayın, sadeceBaseExceptionalt sınıflar değil . Dolayısıyla, kontrolünüz dışındaki kitaplık kodunu çağırıyorsanızexcept Exception, dize istisnalarını yakalayamayacağı için bile yeterli değildir. Başkalarının da belirttiği gibi, burada yanlış ağaca havlıyorsunuz.